ParseOptions.h

Go to the documentation of this file.
00001 
00007 /*
00008    Simplifies the interaction with the ConfigList.  This allows you to
00009    define a set of dependencies in the configuration file, along with
00010    default values, ranges, and units.  Then, given the ConfigList, this
00011    checks the list for valid entries and reads those values, warns for
00012    unneeded options, and errors for stuff it couldn't understand, or
00013    were out of range or in the wrong units, ...
00014 */
00015 
00016 #ifndef PARSEOPTIONS_H
00017 
00018 #define PARSEOPTIONS_H
00019 
00020 #include "common.h"
00021 #include "Vector.h"
00022 
00023 class StringList;
00024 class ConfigList;
00025 
00026 enum Range { FREE_RANGE, POSITIVE, NOT_NEGATIVE , NEGATIVE, NOT_POSITIVE };
00027 // const char *string(Range r); // for printing the range
00028 enum Units { N_UNIT, N_FSEC, N_NSEC, N_SEC, N_MIN, N_HOUR, N_ANGSTROM, N_NANOMETER, N_METER, 
00029              N_KCAL, N_KJOULE, N_EV, N_KELVIN, N_UNITS_UNDEFINED};
00030 // const char *string(Units u); // for printing the units
00031 BigReal convert(Units to, Units from);//return 0 if stupid (like METER to SEC)
00032 
00033 #define PARSE_FLOAT (BigReal *) NULL
00034 #define PARSE_BIGREAL (BigReal *) NULL
00035 #define PARSE_VECTOR (Vector *) NULL
00036 #define PARSE_INT (int *) NULL
00037 #define PARSE_BOOL (int *) NULL
00038 #define PARSE_STRING (char *) NULL
00039 #define PARSE_ANYTHING (StringList **) NULL
00040 #define PARSE_MULTIPLES (StringList **) NULL, TRUE
00041 
00042 class ParseOptions {
00043  public:
00044    
00045    class DataElement {
00046     public:
00047       enum data_types {UNDEF, FLOAT, VECTOR, UINT, INT, BOOL, STRINGLIST, STRING};
00048       int index;
00049       char *name;        // name of the variable
00050       int is_optional;
00051       int is_defined;
00052       char *parent;     // I need this for "forward" definitions
00053       DataElement *parent_ptr;
00054       char *error_message;
00055       data_types type;
00056       int has_default;
00057       int many_allowed;  // only used by StringList; otherwise assumed FALSE
00058       union {
00059          BigReal fdef;     // the default data value
00060          int idef;
00061          unsigned int uidef;
00062          // there is no default element for the StringList or String
00063       };
00064       Vector vdef;        // seperate since it has its own constructor
00065       union {
00066          BigReal *fptr;     // the element to set
00067          int *iptr;
00068          unsigned int *uiptr;
00069          Vector *vptr;
00070          StringList **slptr; // for string lists
00071          char *sptr;     // for strings
00072       };
00073       union {           // the actual data
00074          BigReal fdata;
00075          int idata;
00076          int uidata;
00077          StringList *sldata;  // this points directly to the ConfigList, so
00078       };                     // it had better not be deallocated.
00079       Vector vdata;
00080       Range range;
00081       Units units;
00082          
00083     private:
00084       void init(const char *newname, const char *newparent, int optional,
00085                 const char *err);
00086     public:
00087       ~DataElement(void);
00088       // FLOAT
00089       DataElement(const char *newname, const char *newparent, int optional,
00090                   const char *err, BigReal *ptr, BigReal defalt);
00091       DataElement(const char *newname, const char *newparent, int optional,
00092                   const char *err, BigReal *ptr);
00093       // VECTOR
00094       DataElement(const char *newname, const char *newparent, int optional,
00095                   const char *err, Vector *ptr, Vector defalt);
00096       DataElement(const char *newname, const char *newparent, int optional,
00097                   const char *err, Vector *ptr);
00098       
00099       // INT and BOOL
00100       DataElement(const char *newname, const char *newparent, int optional,
00101                   const char *err, int *ptr, int defalt);
00102       DataElement(const char *newname, const char *newparent, int optional,
00103                   const char *err, int *ptr);
00104 
00105       //  UNSIGNED INT
00106       DataElement(const char *newname, const char *newparent, int optional,
00107                   const char *err, unsigned int *ptr, unsigned int defalt);
00108       DataElement(const char *newname, const char *newparent, int optional,
00109                   const char *err, unsigned int *ptr);
00110 
00111       // STRINGLIST
00112       DataElement(const char *newname, const char *newparent, int optional,
00113                   const char *err, StringList **ptr, int many_allowed = FALSE);
00114       // STRING
00115       DataElement(const char *newname, const char *newparent, int optional,
00116                   const char *err, char *ptr);
00117    };
00118  private:
00119    ConfigList const *configList;
00120    DataElement **data_array;
00121    int array_size;
00122    int array_max_size;
00123    void add_element(DataElement *el);
00124    int make_dependencies(DataElement *el);
00125 
00126    // indicates if the string is TRUE (1), FALSE (0), or unknown (-1)
00127    // if it can't figure it out
00128    int atoBool(const char *s);
00129    // convert from a string to Units, returns UNITS_UNDEFINED if error
00130    Units atoUnits(const char *s);
00131 
00132    // tells if this node has children (TRUE for yes)
00133    Bool is_parent_node(DataElement *el);
00134 
00135  public:
00136    ParseOptions(void);
00137    ~ParseOptions(void);
00138    // returns 1 if everything okay, or 0 if already defined
00139    // the msg is printed to namdErr if it was required and not
00140    // defined and no default exists
00141    int require(const char *newname, const char *parent, const char *msg,
00142                BigReal *ptr, BigReal defalt);
00143    int require(const char *newname, const char *parent, const char *msg,
00144                BigReal *ptr);
00145    
00146    int require(const char *newname, const char *parent, const char *msg,
00147                Vector *ptr, Vector defalt);
00148    int require(const char *newname, const char *parent, const char *msg,
00149                Vector *ptr);
00150    
00151    int require(const char *newname, const char *parent, const char *msg,
00152                int *ptr, int defalt);
00153    int require(const char *newname, const char *parent, const char *msg,
00154                int *ptr);
00155 
00156    int require(const char *newname, const char *parent, const char *msg,
00157                unsigned int *ptr, unsigned int defalt);
00158    int require(const char *newname, const char *parent, const char *msg,
00159                unsigned int *ptr);
00160 
00161    // a "boolean" version, which can convert a string to 1 if true
00162    // and 0 if false;  everywhere else this looks like an int
00163    // (now, if we have a real Boolean type, we wouldn't need this 'B')
00164    int requireB(const char *newname, const char *parent, const char *msg,
00165                 int *ptr, int defalt);
00166    int requireB(const char *newname, const char *parent, const char *msg,
00167                 int *ptr);
00168    // for the StringList; there is no default version
00169    int require(const char *newname, const char *parent, const char *msg,
00170                StringList **ptr = NULL, int many_allowed = FALSE);
00171    // Strings don't have a default version, either
00172    int require(const char *newname, const char *parent, const char *msg,
00173                char *ptr);
00174    
00175    int optional(const char *newname, const char *parent, const char *msg,
00176                 BigReal *ptr, BigReal defalt);
00177    int optional(const char *newname, const char *parent, const char *msg,
00178                 BigReal *ptr);
00179 
00180    int optional(const char *newname, const char *parent, const char *msg,
00181                 Vector *ptr, Vector defalt);
00182    int optional(const char *newname, const char *parent, const char *msg,
00183                 Vector *ptr);
00184 
00185    int optional(const char *newname, const char *parent, const char *msg,
00186                 int *ptr, int defalt);
00187    int optional(const char *newname, const char *parent, const char *msg,
00188                 int *ptr);
00189 
00190    int optional(const char *newname, const char *parent, const char *msg,
00191                 unsigned int *ptr, unsigned int defalt);
00192    int optional(const char *newname, const char *parent, const char *msg,
00193                 unsigned int *ptr);
00194 
00195    int optionalB(const char *newname, const char *parent, const char *msg,
00196                  int *ptr, int defalt);
00197    int optionalB(const char *newname, const char *parent, const char *msg,
00198                  int *ptr);
00199 
00200    int optional(const char *newname, const char *parent, const char *msg,
00201                 StringList **ptr = NULL, int many_allowed = FALSE);
00202    int optional(const char *newname, const char *parent, const char *msg,
00203                 char *ptr);
00204    
00205 
00206    // get the range of the given variable
00207    Range range(const char *name);
00208    // set the range of the given variable
00209    void range(const char *name, Range newrange);
00210  private:
00211    // find the children of the given element; used by check_consistency
00212    int check_children(int idx, int *flg);
00213 
00214    // read a string into the appropriate data type; do units if need be
00215    Bool scan_float(DataElement *el, const char *s);
00216    Bool scan_int(DataElement *el, const char *s);
00217    Bool scan_uint(DataElement *el, const char *s);
00218    Bool scan_bool(DataElement *el, const char *s);
00219    Bool scan_vector(DataElement *el, const char *s);
00220 
00221    // check if the range is correct and, if not NULL, set the variable
00222    // (at this point, the new value already exists in the data element)
00223    Bool set_float(DataElement *el);
00224    void set_vector(DataElement *el);
00225    Bool set_int(DataElement *el);
00226    Bool set_uint(DataElement *el);
00227    void set_bool(DataElement *el);
00228    void set_stringlist(DataElement *el);  //  also checks for 'many_allowed'
00229    void set_string(DataElement *el);
00230  public:
00231    // make sure the options were defined properly; return TRUE okay, FALSE not
00232    Bool check_consistency(void);
00233    // returns TRUE if everything set okay or FALSE if not
00234    Bool set(const ConfigList& configlist);
00235 
00236    // find the specified element.  Returns NULL if not found;
00237  private:
00238    DataElement *internal_find(const char *name);
00239  public:
00240    // special accessor for ScriptTcl
00241    char* getfromptr(const char* name, char *outbuf);
00242    int istruefromptr(const char* name);
00243    int issetfromptr(const char* name);
00244    // get the specified element.  Returns FALSE if not found or undefined;
00245    // prints warning if had to do a type conversion
00246    Bool get(const char* name, int *val);
00247    Bool get(const char* name, BigReal *val);
00248    Bool get(const char* name, Vector *val);
00249    Bool get(const char* name, StringList **val);
00250    Bool get(const char* name, char *val, int n=0);
00251 
00252    // number of elements for the given name
00253    int num(const char* name);
00254    // does the given element exist?
00255    Bool defined(const char *name);
00256    Bool exists(const char *name);
00257 
00258    // get/ set the units and scale for the given variable
00259    Bool units(const char *name, Units units);
00260    Bool units(const char *name, Units *units);
00261 };
00262 
00263 #endif
00264 

Generated on Tue Sep 19 01:17:13 2017 for NAMD by  doxygen 1.4.7