33     default: 
return "error in rstring(Range )";
    38   "", 
"fs", 
"ns", 
"sec", 
"min", 
"hr", 
"A", 
"nm", 
"m", 
    39   "kcal", 
"kJ", 
"eV", 
"K", 
"undefined units"    68 Units ParseOptions::atoUnits(
const char *s) {
    73    if (!strcasecmp(s, 
"Angstrom")) 
return N_ANGSTROM;
    74    if (!strcasecmp(s, 
"kcal/mol")) 
return N_KCAL;
    75    if (!strcasecmp(s, 
"kJ/mol")) 
return N_KJOULE;
    83    1, 1, 1000, 1E15, 60E15, 3600E15, 1, 10, 1E10, 1, 1/4.1855, 1/23.052,
   116   char *tmp = 
new char[strlen(newname)+1];
   117   strcpy(tmp, newname);
   122 void ParseOptions::DataElement::init(
const char *newname,
   123      const char *newparent, 
int optional, 
const char *err) {
   140 #define dataelement_cons_macro_default(Mtype, MType, Mptr, Mdef) \   141 ParseOptions::DataElement::DataElement(const char *newname,      \   142      const char *newparent, int optional, const char *err,       \   143      Mtype *ptr, Mtype defalt)                                   \   145    init(newname, newparent, optional, err);                      \   149    has_default = TRUE;                                           \   150    if ( ptr ) *ptr = defalt;                                     \   153 #define dataelement_cons_macro(Mtype, MType, Mptr) \   154 ParseOptions::DataElement::DataElement(const char *newname,      \   155      const char *newparent, int optional, const char *err,       \   158    init(newname, newparent, optional, err);                      \   182    init(newname, newparent, 
optional, err);
   191    if (name) 
delete[] name;
   192    if (parent) 
delete[] parent;
   193    if (error_message) 
delete[] error_message;
   205                                       "Error in ParseOptions",
   213    for (
int i=0; i<array_size; i++) {
   214       delete data_array[i];
   216    delete [] data_array;
   220 void ParseOptions::add_element(DataElement *el) {
   221    if (array_size == array_max_size) {   
   222       array_max_size += 30;
   223       DataElement **tmp = 
new DataElement*[array_max_size]; 
   224       memcpy(tmp, data_array, array_size * 
sizeof(DataElement *)); 
   225       delete [] data_array;
   228    el->
index = array_size;       
   229    data_array[array_size++] = el;
   234 int ParseOptions::make_dependencies(DataElement *el) {
   237    if (!strcasecmp(el->name, el->parent)) {
   241    for (i=0; i<array_size; i++) {
   242       if (!strcasecmp(data_array[i]->name, el->name) &&
   243           el != data_array[i]) {
   249    for (i=0; i<array_size; i++) {
   250       if (!strcasecmp(data_array[i]->name, el->parent)) {
   251          el->parent_ptr = data_array[i];
   258    for (i=0; i<array_size; i++) {
   259       if (!data_array[i]->parent_ptr) {
   260          if (!strcasecmp(data_array[i]->parent,
   271 #define parse_input_macro_default(fctnname, type, optional)           \   272 int ParseOptions::fctnname(const char *parent, const char *newname,   \   273                           const char *msg, type *ptr, type defalt)    \   275    DataElement *tmp = new DataElement(newname, parent, optional, msg, \   277    if (!make_dependencies(tmp)) {                                     \   278       iout << iERROR << "ParseOption '" << newname << "' already exists" << "\n" << endi; \   284 #define parse_input_macro(fctnname, type, optional)                   \   285 int ParseOptions::fctnname(const char *parent, const char *newname,   \   286                           const char *msg, type *ptr)                 \   288    DataElement *tmp = new DataElement(newname, parent, optional, msg, \   290    if (!make_dependencies(tmp)) {                                     \   291       iout << iERROR << "ParseOption '" << newname << "' already exists" << "\n" << endi; \   297 #define parse_input_macro_default_b(fctnname, type, optional, extra)  \   298 int ParseOptions::fctnname(const char *parent, const char *newname,   \   299                           const char *msg, type *ptr, type defalt)    \   301    DataElement *tmp = new DataElement(newname, parent, optional, msg, \   303    if (!make_dependencies(tmp)) {                                     \   304       iout << iERROR << "ParseOption '" << newname << "' already exists" << "\n" << endi; \   311 #define parse_input_macro_b(fctnname, type, optional, extra)                 \   312 int ParseOptions::fctnname(const char *parent, const char *newname,   \   313                           const char *msg, type *ptr)                 \   315    DataElement *tmp = new DataElement(newname, parent, optional, msg, \   317    if (!make_dependencies(tmp)) {                                     \   318       iout << iERROR << "ParseOption '" << newname << "' already exists" << "\n" << endi; \   352 #define parse_stringlist_macro(fctn, xxx) \   353 int ParseOptions::fctn(const char *parent, const char *newname, \   354                           const char *msg, StringList **ptr, int many_allowed)\   356    DataElement *tmp = new DataElement(newname, parent, xxx, msg,             \   357                                       ptr, many_allowed);                    \   358    if (!make_dependencies(tmp)) {                                            \   359       iout << iERROR << "ParseOption '" << newname << "' already exists" << "\n" << endi;\   372 int ParseOptions::check_children(
int idx, 
int *flgs)
   378    for (
int i=0; i<array_size; i++) {
   379       if (data_array[i]->parent_ptr == data_array[idx]) {
   380          if (!check_children(i, flgs)) {
   395       int has_error = 
FALSE;
   396       for(i=1; i<array_size; i++) {
   397          if (!data_array[i]->parent_ptr) {
   399             iout << 
iERROR << 
"Configuration element '" << data_array[i]->
name   400                     << 
"' defined, but the parent element" << 
"\n" << 
endi;
   402                     << 
"to be found" << 
"\n" << 
endi;
   406       if (has_error) 
return 0;
   410    int *arr = 
new int[array_size];
   411    for (i=0; i<array_size; i++) {  
   414    if (!check_children(0, arr)) {
   416       iout << 
iERROR << 
"Loop found in ParseOptions data" << 
"\n" << 
endi;
   423       int has_error = 
FALSE;
   424       for (i=1; i<array_size; i++) {
   427             if (has_error == 
FALSE) { 
   429                    << 
"Found data in ParseOptions which are inaccessible "   430                    << 
"to" << 
"\n" << 
endi;
   432                   << 
"the main data hierarchy.  Errors in:" << 
"\n" << 
endi;
   436                     << data_array[i]->
parent << 
"'" << 
"\n" << 
endi;
   450 int ParseOptions::atoBool(
const char *s)
   452    if (!strcasecmp(s, 
"on")) 
return 1;
   453    if (!strcasecmp(s, 
"off")) 
return 0;
   454    if (!strcasecmp(s, 
"true")) 
return 1;
   455    if (!strcasecmp(s, 
"false")) 
return 0;
   456    if (!strcasecmp(s, 
"yes")) 
return 1;
   457    if (!strcasecmp(s, 
"no")) 
return 0;
   458    if (!strcasecmp(s, 
"1")) 
return 1;
   459    if (!strcasecmp(s, 
"0")) 
return 0;
   469 Bool ParseOptions::is_parent_node(DataElement *el) {
   470    for (
int i=1; i<array_size; i++) {
   471       if (data_array[i]->parent_ptr == el) {
   480 Bool ParseOptions::scan_float(DataElement *data, 
const char *s)
   486    int count = sscanf(s, 
"%lf%s%s", &input_value, units_str, tmp_str);
   487    if (count > 1 && units_str[0] == 
'.' &&
   488        input_value == (
double)(
long int)input_value) {  
   490      count = sscanf(s, 
"%ld.%s%s", &input_long, units_str, tmp_str);
   491      if ( count < 1 || input_value != (
double)input_long ) {
   493                  << data->name << 
" = " << s << 
"'\n" << 
endi;
   503       Units u = atoUnits(units_str);
   505          iout << 
iERROR << 
"Could not understand units '" << units_str
   506                  << 
"' in option '" << data->name << 
" = " << s
   513                  << 
"' to '" << 
ustring(data->units) << 
"' for option '"   514                  << data->name << 
"'" << 
"\n" << 
endi;
   518       data->fdata = fval * scale;
   522       iout << 
iERROR << 
"Expecting value and optional units for option '"   523               << data->name << 
"'" << 
"\n" << 
endi;
   526       iout << 
iERROR << 
"Too much information given to '" << data -> name 
   527       << 
" = " <<  s << 
"'" << 
"\n" << 
endi;
   528       iout << 
iERROR << 
"  - expecting a value and optional units" << 
"\n" << 
endi;
   534 Bool ParseOptions::scan_vector(DataElement *data, 
const char *s)
   538       iout << 
iERROR << 
"Could not translate the value '" << s << 
"'" << 
"\n" << 
endi;
   539       iout << 
iERROR << 
"  into a Vector for the option '" << data->name << 
"'"   549 Bool ParseOptions::scan_int(DataElement *data, 
const char *s)
   554    int count = sscanf(s, 
"%d%s%s", &ival, units_str, tmp_str);
   559    iout << 
iERROR << 
"Expecting only a number for '" << data->name
   560            << 
"' input, got: " << s << 
"\n" << 
endi;
   566 Bool ParseOptions::scan_uint(DataElement *data, 
const char *s)
   571    int count = sscanf(s, 
"%u%s%s", &ival, units_str, tmp_str);
   576    iout << 
iERROR << 
"Expecting only a number for '" << data->name
   577            << 
"' input, got: " << s << 
"\n" << 
endi;
   581 Bool ParseOptions::scan_bool(DataElement *data, 
const char *s)
   583    int tmp = atoBool(s);  
   587         iout << 
iERROR << 
"ParseOptions can't understand '" << s << 
"' for the "   589         iout << 
iERROR << 
" Boolean variable '" << data->name << 
"'"  << 
"\n" << 
endi;
   603 #define set_macro(type, field, fieldptr)                 \   604 int ParseOptions::set_##type(DataElement *el)            \   606    if (el->range == FREE_RANGE ||                        \   607        (el->range == POSITIVE && el->field > 0) ||       \   608        (el->range == NOT_NEGATIVE && el->field >= 0) ||  \   609        (el->range == NEGATIVE && el->field < 0) ||       \   610        (el->range == NOT_POSITIVE && el->field <= 0)) {  \   611       if (el->fieldptr) *(el->fieldptr) = el->field;     \   614    iout << iERROR << "'" << el->name << "' was set to " << el->field << " but it " \   615            << "should be " << rstring(el->range)          \   624 #define simple_set_macro(type, field, fieldptr)   \   625 void ParseOptions::set_##type(DataElement *el)     \   627    if (el->fieldptr) *(el->fieldptr) = el->field;    \   635 void ParseOptions::set_string(DataElement *el)   
   637    if (el->sptr) strcpy(el->sptr, el->sldata->data);  
   648    int has_error = 
FALSE;
   649    int *checked = 
new int[array_size];
   655    for (i=0; i<array_size; i++) 
   668       for (i=1; i<array_size; i++) 
   670          data = data_array[i];
   674          if (!checked[data->
index] &&
   675              checked[data-> parent_ptr -> index] &&
   676              data -> parent_ptr -> is_defined) 
   693                   iout << 
iERROR << 
"  in the configuration file are not allowed" << 
"\n" << 
endi;
   702                   if (!scan_float(data, slptr->
data)) 
   707                   if (!scan_vector(data, slptr->
data)) 
   712                   if (!scan_int(data, slptr->
data)) 
   717                   if (!scan_uint(data, slptr->
data)) 
   722                   if (!scan_bool(data, slptr->
data)) 
   732                   iout << 
iERROR << 
"Unknown ParseOption data type " << (int)(data->
type) << 
" for "   733                           << 
"variable " << data->
name << 
"\n" << 
endi;
   762                         iout << 
iERROR << 
"Unknown ParseOption data type " << (int)(data->
type) << 
" for "   763                                 << 
"variable " << data->
name << 
"\n" << 
endi;
   777                   iout << 
iERROR << 
"'" << data->
name << 
"' is a required configuration option" << 
"\n" << 
endi;
   793                   if (!set_float(data)) 
   814                   if (is_parent_node(data)) 
   824                   set_stringlist(data);
   847       for (
int i=1; i<array_size; i++) 
   850             data = data_array[i];
   855                     << 
"The following variables were set in the\n";
   857                     << 
"configuration file but will be ignored:\n" << 
endi;
   873       for (ptr = clist.
head(); ptr != NULL; ptr = ptr -> 
next) {
   874          if (!
exists(ptr -> name)) {
   879                   << 
"The following variables were set in the\n";
   881                   << 
"configuration file but are NOT VALID\n" << 
endi;
   895    for (
int i=1; i<array_size; i++) {
   896       if (!strcasecmp(name, data_array[i]->name)) {
   897          return data_array[i];
   907    if (internal_find(name)) {
   915    if (!name) 
return FALSE;
   917    if (!tmp) 
return FALSE;
   925 #define PRINT_DOUBLE(BUF,VAL) Tcl_PrintDouble(0,VAL,BUF)   929   buf += strlen(buf); buf[0] = 
' '; ++buf;
   931   buf += strlen(buf); buf[0] = 
' '; ++buf;
   933   buf += strlen(buf); buf[0] = 
' '; buf[1] = 0;
   940    if ( ! name ) 
NAMD_bug(
"ParseOptions::getfromptr called with null name");
   941    if ( ! outbuf ) 
NAMD_bug(
"ParseOptions::getfromptr called with null outbuf");
   943    if ( el == NULL ) 
return 0;
   951       if ( el->
iptr ) sprintf(outbuf,
"%d", *(el->
iptr));
   952       else sprintf(outbuf,
"%d", el->
idata);
   968          << 
"Unknown data type " << (int)(el->
type) << 
" for '" << name << 
"'"   977    if ( ! name ) 
NAMD_bug(
"ParseOptions::getfromptr called with null name");
   979    if ( el == NULL ) 
return -1;
   981    if ( el->
iptr ) 
return ((*(el->
iptr)) ? 1 : 0);
   983    return (el->
idata ? 1 : 0);
   988    if ( ! name ) 
NAMD_bug(
"ParseOptions::getfromptr called with null name");
   990    if ( el == NULL ) 
return -1;
   999    if (!val) 
return FALSE;
  1007          << 
"ParseOptions doing a conversion from float to int for '"  1008          << name << 
"'" << 
"\n" << 
endi;
  1009       *val = (int) el->
fdata;
  1018          << 
"ParseOptions doing a conversion from StringList[0] to int "  1019          << 
"for '" << name << 
"'" << 
"\n" << 
endi;
  1024           << 
"ParseOptions cannot convert from Vector to int for '"  1025           << name << 
"'" << 
"\n" << 
endi;
  1029          << 
"Unknown data type " << (int)(el->
type) << 
" for '" << name << 
"'"  1036    if (!val) 
return FALSE;
  1041    switch (el -> type) {
  1047          << 
"ParseOptions doing a conversion from int to float '"  1048          << name << 
"'" << 
"\n" << 
endi;
  1053          << 
"ParseOptions doing a conversion from boolean to float for '"  1054          << name << 
"'" << 
"\n" << 
endi;
  1060         << 
"ParseOptions doing a conversion from StringList[0] to float "  1061         << 
"for '" << name << 
"'" << 
"\n" << 
endi;
  1066           << 
"ParseOptions cannot convert from Vector to float for '"  1067           << name << 
"'" << 
"\n" << 
endi;
  1071          << 
"Unknown data type " << (int)(el->
type) << 
" for '" << name << 
"'"  1077    if (!val) 
return FALSE;
  1082    switch (el -> type) {
  1085          << 
"ParseOptions cannot convert from float to Vector for '"  1086          << name << 
"'" << 
"\n" << 
endi;
  1090          << 
"ParseOptions cannot convert from int to Vector for '"  1091          << name << 
"'" << 
"\n" << 
endi;
  1096          << 
"ParseOptions doing a conversion from StringList[0] to "  1097          << 
"Vector for '" << name << 
"'" << 
"\n" << 
endi;
  1113          << 
"Unknown data type " << (int)(el->
type) << 
" for '" << name << 
"'"  1120    if (!val) 
return FALSE;
  1127    if (!configList) { 
return FALSE; }
  1128    *val = configList->
find(name);
  1129    if (!*val) { 
return FALSE; }  
  1136    if (!val || n<0) {
return FALSE;}
  1140    while (i>0 && tmp) { 
  1145       strcpy(val, tmp->
data);
  1156    if (!el || !el ->is_defined) {
  1163    if (!
get(name, &tmp)) { 
return 0; }
  1179          << 
"Trying to set the range of undefined variable '"  1180          << name << 
"'" << 
"\n" << 
endi;
  1183    el->
range = newrange;
  1191          << 
"Trying to get the range of undefined variable '"  1192          << name << 
"'" << 
"\n" << 
endi;
  1204         << name << 
" not found so units not set" << 
"\n" << 
endi;
  1211         << 
"Cannot set units '" << 
ustring(
units) << 
"' for option '"  1212         << name << 
"'; wrong data type" << 
"\n" << 
endi;
  1225          << 
"'" << name << 
"' doesn't exist so cannot get its units"  1232          << 
"Can only get units for FLOAT and INT variables, and '"  1233          << name << 
"' isn't one of those" << 
"\n" << 
endi;
 static char * Strdup(const char *newname)
 
BigReal convert(Units to, Units from)
 
#define simple_set_macro(type, field, fieldptr)
 
DataElement(const char *newname, const char *newparent, int optional, const char *err, BigReal *ptr, BigReal defalt)
 
#define parse_input_macro_default_b(fctnname, type, optional, extra)
 
#define set_macro(type, field, fieldptr)
 
const char * ustring(Units u)
 
Bool defined(const char *name)
 
Bool units(const char *name, Units units)
 
#define parse_input_macro_default(fctnname, type, optional)
routines to add dependencies to the array 
 
static void PRINT_VECTOR(char *buf, Vector val)
 
#define dataelement_cons_macro_default(Mtype, MType, Mptr, Mdef)
 
std::ostream & endi(std::ostream &s)
 
std::ostream & iWARN(std::ostream &s)
 
int optionalB(const char *newname, const char *parent, const char *msg, int *ptr, int defalt)
 
char * getfromptr(const char *name, char *outbuf)
 
int require(const char *newname, const char *parent, const char *msg, BigReal *ptr, BigReal defalt)
 
const char * rstring(Range r)
 
int num(const char *name)
 
static Units next(Units u)
 
#define parse_stringlist_macro(fctn, xxx)
 
Bool set(const ConfigList &configlist)
 
#define parse_input_macro_b(fctnname, type, optional, extra)
 
void NAMD_bug(const char *err_msg)
 
ConfigListNode * head(void) const
 
#define PRINT_DOUBLE(BUF, VAL)
 
int istruefromptr(const char *name)
 
static const char * unit_string_array[N_UNITS_UNDEFINED+1]
 
static BigReal scaling_factors[N_UNITS_UNDEFINED+1]
 
#define parse_input_macro(fctnname, type, optional)
 
int optional(const char *newname, const char *parent, const char *msg, BigReal *ptr, BigReal defalt)
 
Bool get(const char *name, int *val)
 
Range range(const char *name)
 
#define dataelement_cons_macro(Mtype, MType, Mptr)
 
std::ostream & iERROR(std::ostream &s)
 
Bool check_consistency(void)
 
int issetfromptr(const char *name)
 
StringList * find(const char *name) const
 
int requireB(const char *newname, const char *parent, const char *msg, int *ptr, int defalt)
 
Bool exists(const char *name)