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)