libStatGen Software  1
Parameters.h
00001 /*
00002  *  Copyright (C) 2010-2012  Regents of the University of Michigan
00003  *
00004  *   This program is free software: you can redistribute it and/or modify
00005  *   it under the terms of the GNU General Public License as published by
00006  *   the Free Software Foundation, either version 3 of the License, or
00007  *   (at your option) any later version.
00008  *
00009  *   This program is distributed in the hope that it will be useful,
00010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *   GNU General Public License for more details.
00013  *
00014  *   You should have received a copy of the GNU General Public License
00015  *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016  */
00017 
00018 #ifndef __PARAMETERS_H__
00019 #define __PARAMETERS_H__
00020 
00021 #include "StringMap.h"
00022 #include "PhoneHome.h"
00023 
00024 #include <ctype.h>
00025 #include <stddef.h>
00026 
00027 class ParameterList;
00028 
00029 class Parameter
00030 {
00031 protected:
00032 
00033     static const char PARAM_STR_SEP = ',';
00034     char ch;
00035     char * description;
00036     void * var;
00037 
00038     static int nameCol;
00039     static int statusCol;
00040 
00041     virtual void Translate(const char * value) = 0;
00042     virtual bool TranslateExtras(const char * value, const char * extras);
00043 
00044     static bool CheckInteger(const char * value);
00045     static bool CheckDouble(const char * value);
00046 
00047     String * warnings;
00048     bool myNoPhoneHome;
00049     String myVersion;
00050 
00051 public:
00052 
00053     Parameter(char c, const char * desc, void * v);
00054 
00055     virtual ~Parameter()
00056     {
00057         delete [] description;
00058     }
00059 
00060     virtual bool Read(int argc, char ** argv, int argn);
00061     virtual void Status() = 0;
00062     virtual void addParamsToString(String& params)
00063     {
00064         if(var != NULL)
00065         {
00066             if(!params.IsEmpty())
00067             {
00068                 params += PARAM_STR_SEP;
00069             }
00070             params += description;
00071         }
00072     }
00073 
00074 
00075     static void SetNameLen(int len)
00076     {
00077         nameCol = len;
00078     }
00079     static void SetStatusLen(int len)
00080     {
00081         statusCol = len;
00082     }
00083 
00084     void SetWarningBuffer(String & buffer)
00085     {
00086         warnings = &buffer;
00087     }
00088     void warning(const char * format, ...);
00089 
00090     friend class ParameterList;
00091 };
00092 
00093 class IntParameter : public Parameter
00094 {
00095 public:
00096     IntParameter(char c, const char * desc, int & v)
00097         : Parameter(c, desc, &v)
00098     {}
00099 
00100     virtual void Status();
00101 
00102 protected:
00103     virtual void Translate(const char * value);
00104     virtual bool TranslateExtras(const char * value, const char * extras);
00105 };
00106 
00107 class HiddenInteger : public IntParameter
00108 {
00109 public:
00110     HiddenInteger(char c, const char * desc, int & v)
00111         : IntParameter(c, desc, v)
00112     {}
00113 
00114     virtual void Status() { }
00115 };
00116 
00117 
00118 class SwitchParameter : public Parameter
00119 {
00120 public:
00121     SwitchParameter(char c, const char * desc, bool & v)
00122         : Parameter(c, desc, &v)
00123     {}
00124 
00125     virtual void Status();
00126 
00127 protected:
00128     virtual void Translate(const char * value);
00129 };
00130 
00131 class HiddenSwitch : public SwitchParameter
00132 {
00133 public:
00134     HiddenSwitch(char c, const char * desc, bool & v)
00135         : SwitchParameter(c, desc, v)
00136     {}
00137 
00138     virtual void Status() { }
00139 };
00140 
00141 class DoubleParameter : public Parameter
00142 {
00143 public:
00144     DoubleParameter(char c, const char * desc, double & v);
00145 
00146     virtual void Status();
00147 
00148     DoubleParameter & SetPrecision(int precision)
00149     {
00150         this->precision = precision;
00151 
00152         return *this;
00153     }
00154 
00155 protected:
00156     virtual void Translate(const char * value);
00157     virtual bool TranslateExtras(const char * value, const char * extras);
00158 
00159     int precision;
00160 };
00161 
00162 class HiddenDouble : public DoubleParameter
00163 {
00164 public:
00165     HiddenDouble(char c, const char * desc, double &v)
00166         : DoubleParameter(c, desc, v)
00167     {}
00168 
00169     virtual void Status() { }
00170 };
00171 
00172 class StringParameter : public Parameter
00173 {
00174 public:
00175     StringParameter(char c, const char * desc, String & v, bool allowBlank = true)
00176             : Parameter(c, desc, &v)
00177     {
00178         required = !allowBlank;
00179     }
00180 
00181     virtual void Status();
00182 
00183 protected:
00184     bool required;
00185 
00186     virtual void Translate(const char * value);
00187     virtual bool TranslateExtras(const char * value, const char * extras);
00188 };
00189 
00190 class HiddenString : public StringParameter
00191 {
00192 public:
00193     HiddenString(char c, const char * desc, String & v)
00194         : StringParameter(c, desc, v)
00195     {}
00196 
00197     virtual void Status() { }
00198 };
00199 
00200 struct OptionList
00201 {
00202     char     ch;
00203     char *   description;
00204     int      code;
00205 };
00206 
00207 #define BEGIN_OPTION_LIST(name)     ; OptionList name[] = {
00208 #define END_OPTION_LIST(none)       , {0, none, 0} };
00209 
00210 class ListParameter : public Parameter
00211 {
00212 public:
00213     ListParameter(char c, const char * desc, int & v, OptionList * opt);
00214 
00215     virtual void Status();
00216 
00217 protected:
00218     String       key;
00219     OptionList * options;
00220     virtual void Translate(const char * value);
00221 };
00222 
00223 class SetParameter : public Parameter
00224 {
00225 public:
00226     SetParameter(char c, const char * desc, int & v, OptionList * opt);
00227 
00228     virtual void Status();
00229 
00230 protected:
00231     String       key;
00232     OptionList * options;
00233     virtual void Translate(const char * value);
00234 };
00235 
00236 struct LongParameterList
00237 {
00238     const char * description;
00239     void * value;
00240     bool exclusive;
00241     int  type;
00242     bool touched;
00243 };
00244 
00245 #define LP_BOOL_PARAMETER     1
00246 #define LP_INT_PARAMETER      2
00247 #define LP_DOUBLE_PARAMETER   3
00248 #define LP_STRING_PARAMETER   4
00249 #define LP_LEGACY_PARAMETERS  99
00250 #define LP_PHONEHOME_VERSION   98
00251 
00252 #define BEGIN_LONG_PARAMETERS(array)   LongParameterList array[] = {\
00253                                               { NULL,  NULL,      false,  0, 0},
00254 #define LONG_PARAMETER_GROUP(label)           { label, NULL,      false,  0, 0},
00255 #define LONG_PARAMETER(label,boolptr)         { label, boolptr,   false,  1, 0},
00256 #define EXCLUSIVE_PARAMETER(label,boolptr)    { label, boolptr,   true,   1, 0},
00257 #define LONG_INTPARAMETER(label,intptr)       { label, intptr,    false,  2, 0},
00258 #define LONG_SMARTINTPARAMETER(label,intptr)  { label, intptr,    true,   2, 0},
00259 #define LONG_DOUBLEPARAMETER(label,doubleptr) { label, doubleptr, false,  3, 0},
00260 #define LONG_STRINGPARAMETER(label,stringptr) { label, stringptr, false,  4, 0},
00261 #define LONG_PHONEHOME(version)               { "PhoneHome", NULL, false,  0, 0}, { version, NULL,    false,  LP_PHONEHOME_VERSION, 0}, {"phoneHomeThinning", &PhoneHome::allThinning, false, LP_INT_PARAMETER, 0},
00262 #define BEGIN_LEGACY_PARAMETERS()             { "$$$", NULL,      false, 99, 0},
00263 #define END_LONG_PARAMETERS()                 { NULL,  NULL,      false,  0, 0}};
00264 
00265 class LongParameters : public Parameter
00266 {
00267 public:
00268     LongParameters(const char * desc, LongParameterList * list);
00269 
00270     virtual void Status();
00271     virtual void addParamsToString(String& params);
00272 
00273     LongParameters * SetPrecision(int precision)
00274     {
00275         this->precision = precision;
00276 
00277         return this;
00278     }
00279 
00280 protected:
00281     StringMap index;
00282     StringMap legacyIndex;
00283 
00284     LongParameterList * list;
00285     int group_len;
00286     int precision;
00287 
00288     virtual void Translate(const char * value);
00289     virtual bool TranslateExtras(const char * value, const char * extras);
00290 
00291     void ExplainAmbiguity(const char * value);
00292 
00293     void Status(LongParameterList * ptr, int & line_len, bool & need_a_comma);
00294 };
00295 
00296 class ParameterList
00297 {
00298 protected:
00299     Parameter ** pl;
00300     int count;
00301     int size;
00302 
00303     void MakeString(int argc, char ** argv, int start = 1);
00304     void HandlePhoneHome(int argc, char ** argv, int start);
00305 
00306 public:
00307     char * string;
00308 
00309     ParameterList(int s = 36)
00310     {
00311         size = s;
00312         count = 0;
00313         pl = new Parameter * [size];
00314         string = NULL;
00315     }
00316 
00317     virtual ~ParameterList();
00318 
00319     void Add(Parameter * p);
00320 
00321     // Tries to process all command line arguments
00322     virtual void Read(int argc, char ** argv, int start = 1);
00323 
00324     // Allows for trailing, unprocessed, filenames in the command line
00325     // The number of translated argv[] items is returned
00326     virtual int ReadWithTrailer(int argc, char ** argv, int start = 1);
00327 
00328     // Outputs summary of parameter switches and settings
00329     virtual void Status();
00330 
00331     // Keeps track of warnings generated during parameter processing
00332     String  warnings;
00333     String  messages;
00334 
00335     // Functions that gracefully enforce parameter settings
00336     void Enforce(bool & var, bool value, const char * reason, ...);
00337     void Enforce(int & var, int value, const char * reason, ...);
00338     void Enforce(double & var, double value, const char * reason, ...);
00339     void Enforce(String & var, const char * value, const char * reason, ...);
00340 };
00341 
00342 
00343 // Container for holding the long parameter list.
00344 // Allows parameters to be added.
00345 // Allows users to not have to use BEGIN_LONG_PARAMETERS or to understand
00346 // the details of a LongParameterList.
00347 class LongParamContainer
00348 {
00349 public:
00350     LongParamContainer();
00351     ~LongParamContainer();
00352 
00353     // Get a pointer to the LongParameterList.
00354     inline LongParameterList* getLongParameterList()
00355     { return(myArray); }
00356 
00357     void add(const char * label, void * val, bool excl, 
00358              int paramType, bool touch = 0);
00359 
00360     inline void addGroup(const char * label)
00361     { add(label, NULL, false, 0, 0); }
00362 
00363     inline void addBool(const char * label, void * boolptr)
00364     { add(label, boolptr, false, LP_BOOL_PARAMETER, 0); }
00365 
00366     inline void addExclusiveBool(const char * label, void * boolptr)
00367     { add(label, boolptr, true, LP_BOOL_PARAMETER, 0); }
00368 
00369     inline void addInt(const char * label, void * intptr)
00370     { add(label, intptr, false, LP_INT_PARAMETER, 0); }
00371 
00372     inline void addSmartInt(const char * label, void * intptr)
00373     { add(label, intptr, true, LP_INT_PARAMETER, 0); }
00374 
00375     inline void addDouble(const char * label, void * doubleptr)
00376     { add(label, doubleptr, false, LP_DOUBLE_PARAMETER, 0); }
00377 
00378     inline void addString(const char * label, void * stringptr)
00379     { add(label, stringptr, false, LP_STRING_PARAMETER, 0); }
00380 
00381     inline void addPhoneHome(const char* version)
00382     { 
00383         add("PhoneHome", NULL, false,  0, 0);
00384         add(version, NULL,    false,  LP_PHONEHOME_VERSION, 0);
00385         add("phoneHomeThinning", &PhoneHome::allThinning, false, LP_INT_PARAMETER, 0);
00386     }
00387 
00388     inline void startLegacyParams()
00389     { add("$$$", NULL, false, 99, 0); }
00390 
00391 private:
00392     // At most 100 parameters are allowed.
00393     static const int MAX_PARAM_ARRAY_SIZE = 100;
00394     LongParameterList myArray[MAX_PARAM_ARRAY_SIZE];
00395 
00396     int myEndIndex;
00397 };
00398 
00399 
00400 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends