/*v 0.2
simple parameters parsing helper
Example of code usage:
double param1; add_double_param(param1); //add "param1" to be recognized as input parameter
int param2; add_int_param(param2);
string par3; add_string_param(par3);
...
assert(load_parameters("input_parameters.txt")); //read parameters from input file
assert(cmdline_parameters(argc,argv)); //can be overriden by commandline, eg. ./simul [any_pars_without_minus] -param1 value1 -param3 value3
print_parameters(); //dump table of parameters values
Configuration file example (input_parameters.txt):
------
#any comment starts with '#'
#any numbers of blanks around
param1 3.14
#what is the meaning of life?
param2 42
-----
*/#ifndef PARAMSHELP#define PARAMSHELP#include<string>#include<sstream>#include<assert.h>#include<stdio.h>
using std::string;
using std::stringstream;
#define MAX_PARAMS 500//buffer for parameter names and pointers to//variables used for them in the main programdouble *double_pars[MAX_PARAMS];
string double_par_name[MAX_PARAMS];
int double_count=0;
#define add_double_param(par) \
assert(double_count!=MAX_PARAMS);\
double_pars[double_count]=∥\
/*(*double_pars[double_count])=0;*/\
double_par_name[double_count++]=#par; int *int_pars[MAX_PARAMS];
string int_par_name[MAX_PARAMS];
int int_count=0;
#define add_int_param(par) \
assert(int_count!=MAX_PARAMS);\
int_pars[int_count]=∥\
/*(*int_pars[int_count])=0;*/\
int_par_name[int_count++]=#par; string *string_pars[MAX_PARAMS];
string string_par_name[MAX_PARAMS];
int string_count=0;
#define add_string_param(par) \
assert(string_count!=MAX_PARAMS);\
string_pars[string_count]=∥\
/*(*int_pars[int_count])=0;*/\
string_par_name[string_count++]=#par; //parse one parameter on the given config line; returns 1 if line format is recognized//result is put directly into global parameterintparse_param(string line){
if (line.empty()) return1;
string par1,par2; //line should be pair of inputsstringstreamparser(line);
if (!(parser>>par1)) return1; //whitespace lineif (par1[0]=='#') return1; //just commentif (par1[0]=='-') par1=par1.substr(1); //allow "-param" in commandline if (!(parser>>par2)) return0; //missing valueint i;
for (i=0; i<double_count; i++) //double parametersif (par1==double_par_name[i]){
if (!(stringstream(par2)>>*(double_pars[i]))) return0;
return1;
}
for (i=0; i<int_count; i++) //integer parametersif (par1==int_par_name[i]){
if (!(stringstream(par2)>>*(int_pars[i]))) return0;
return1;
}
for (i=0; i<string_count; i++) //string parameters, we do not allow blanksif (par1==string_par_name[i]){
(*(string_pars[i]))=par2;
return1;
}
fprintf(stderr, "Unknown input parameter found.\n");
return0; //no recognized parameter found
}//parse//load parameters from file, returns 0 on errorintload_parameters(charconst *file){
FILE *f=fopen(file,"r");
if (f==NULL) { fprintf(stderr, "File with input parameters not found.\n"); return0; }
char line[4096];
while ( fgets(line,sizeof(line),f) != NULL )
if (!parse_param(line)) return0;
fclose(f);
return1;
}//load_parameters//load parameters from commandline ("-param value" vector)//expecting standard argc, argv arguments//we allow different parameters on cmdline when they don't use "-" (eg. ./simul input.txt -param val)intcmdline_parameters(int argc, char *argv[]){
argc--;
int i=0;
while (argc>++i) {
strings(argv[i]);
if (s.empty()) continue;
if (s[0]!='-') continue;
if (!parse_param(s+" "+string(argv[i+1]))) return0;
i++; //jump over the value (can be negative, ie "-")
}
return1;
}//cmdline_parametersvoidprint_parameters(){
for (int i=0; i<int_count;i++)
fprintf(stderr,"%s:\t%d\n",int_par_name[i].c_str(),*(int_pars[i]));
for (int i=0; i<double_count;i++)
fprintf(stderr,"%s:\t%lf\n",double_par_name[i].c_str(),*(double_pars[i]));
for (int i=0; i<string_count;i++)
fprintf(stderr,"%s:\t%s\n",string_par_name[i].c_str(),string_pars[i]->c_str());
}//print_parameters#endif