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    //
00176    // XXX prototypes for optional reverse "newname" and "parent"
00177    // (the argument names in a prototype don't matter
00178    // but it makes the code more difficult to understand)
00179    //
00180    int optional(const char *newname, const char *parent, const char *msg,
00181                 BigReal *ptr, BigReal defalt);
00182    int optional(const char *newname, const char *parent, const char *msg,
00183                 BigReal *ptr);
00184 
00185    int optional(const char *newname, const char *parent, const char *msg,
00186                 Vector *ptr, Vector defalt);
00187    int optional(const char *newname, const char *parent, const char *msg,
00188                 Vector *ptr);
00189 
00190    int optional(const char *newname, const char *parent, const char *msg,
00191                 int *ptr, int defalt);
00192    int optional(const char *newname, const char *parent, const char *msg,
00193                 int *ptr);
00194 
00195    int optional(const char *newname, const char *parent, const char *msg,
00196                 unsigned int *ptr, unsigned int defalt);
00197    int optional(const char *newname, const char *parent, const char *msg,
00198                 unsigned int *ptr);
00199 
00200    int optionalB(const char *newname, const char *parent, const char *msg,
00201                  int *ptr, int defalt);
00202    int optionalB(const char *newname, const char *parent, const char *msg,
00203                  int *ptr);
00204 
00205    int optional(const char *newname, const char *parent, const char *msg,
00206                 StringList **ptr = NULL, int many_allowed = FALSE);
00207    int optional(const char *newname, const char *parent, const char *msg,
00208                 char *ptr);
00209    
00210 
00211    // get the range of the given variable
00212    Range range(const char *name);
00213    // set the range of the given variable
00214    void range(const char *name, Range newrange);
00215  private:
00216    // find the children of the given element; used by check_consistency
00217    int check_children(int idx, int *flg);
00218 
00219    // read a string into the appropriate data type; do units if need be
00220    Bool scan_float(DataElement *el, const char *s);
00221    Bool scan_int(DataElement *el, const char *s);
00222    Bool scan_uint(DataElement *el, const char *s);
00223    Bool scan_bool(DataElement *el, const char *s);
00224    Bool scan_vector(DataElement *el, const char *s);
00225 
00226    // check if the range is correct and, if not NULL, set the variable
00227    // (at this point, the new value already exists in the data element)
00228    Bool set_float(DataElement *el);
00229    void set_vector(DataElement *el);
00230    Bool set_int(DataElement *el);
00231    Bool set_uint(DataElement *el);
00232    void set_bool(DataElement *el);
00233    void set_stringlist(DataElement *el);  //  also checks for 'many_allowed'
00234    void set_string(DataElement *el);
00235  public:
00236    // make sure the options were defined properly; return TRUE okay, FALSE not
00237    Bool check_consistency(void);
00238    // returns TRUE if everything set okay or FALSE if not
00239    Bool set(const ConfigList& configlist);
00240 
00241    // find the specified element.  Returns NULL if not found;
00242  private:
00243    DataElement *internal_find(const char *name);
00244  public:
00245    // special accessor for ScriptTcl
00246    char* getfromptr(const char* name, char *outbuf);
00247    int istruefromptr(const char* name);
00248    int issetfromptr(const char* name);
00249    // get the specified element.  Returns FALSE if not found or undefined;
00250    // prints warning if had to do a type conversion
00251    Bool get(const char* name, int *val);
00252    Bool get(const char* name, BigReal *val);
00253    Bool get(const char* name, Vector *val);
00254    Bool get(const char* name, StringList **val);
00255    Bool get(const char* name, char *val, int n=0);
00256 
00257    // number of elements for the given name
00258    int num(const char* name);
00259    // does the given element exist?
00260    Bool defined(const char *name);
00261    Bool exists(const char *name);
00262 
00263    // get/ set the units and scale for the given variable
00264    Bool units(const char *name, Units units);
00265    Bool units(const char *name, Units *units);
00266 };
00267 
00268 #endif
00269 

Generated on Thu Jun 21 01:17:16 2018 for NAMD by  doxygen 1.4.7