diff --git a/src/include/parser.h b/src/include/parser.h index 89d5d075..bf37ae5a 100644 --- a/src/include/parser.h +++ b/src/include/parser.h @@ -15,25 +15,25 @@ inline void force_locale() { } class cmdline_parser { - int argc,i; - char **argv; + int argc, i; + char **argv; public: cmdline_parser() { force_locale(); } - void open(int argc_in,char *argv_in[]); - int get(char *&arg,char *&val); - void ack(char *arg,char *val); - void close(); + void open(int argc_in, char *argv_in[]); + int get(char *&arg, char *&val); + void ack(char *arg, char *val); + void close(); }; class file_parser { - FILE *fp; - int iline; - char line[1024]; + FILE *fp; + int iline; + char line[1024]; public: file_parser() { force_locale(); } - int open(const char *file); - int get(char *&arg,char *&val); - void close(); + int open(const char *file); + int get(char *&arg,char *&val); + void close(); }; #endif diff --git a/src/include/read_config.h b/src/include/read_config.h index beb45496..41bbefe4 100644 --- a/src/include/read_config.h +++ b/src/include/read_config.h @@ -4,18 +4,23 @@ class configuration { public: - int minit,maxit; - double tol,newton_dmax; - int verbose; - char plot_device[64]; - double plot_interval; - char input_file[256]; - char param_file[256]; - char output_file[256]; - configuration(int argc,char *argv[]); - ~configuration(){}; - void missing_argument(const char *arg); - int check_arg(const char *arg,const char *val); + int minit,maxit; + double tol,newton_dmax; + int verbose; bool noplot; + char plot_device[64]; + double plot_interval; + char input_file[256]; + char param_file[256]; + char output_file[256]; + + configuration(); + ~configuration(){}; + + void read_config(int argc, char *argv[]); // wrapper around the following 2 methods + void read_config_file(); + void read_command_line(int argc, char *argv[]); + + int parse_arg(const char *arg,const char *val); }; diff --git a/src/include/star.h b/src/include/star.h index 04e34b00..80640632 100644 --- a/src/include/star.h +++ b/src/include/star.h @@ -88,7 +88,7 @@ class star2d { virtual void atmosphere(); virtual int init(const char *input_file, const char *param_file, int argc, char *argv[]); - virtual int check_arg(char *arg, char *val, int *change_grid); + virtual int parse_arg(char *arg, char *val, int *change_grid); virtual int read(const char *input_file, int dim = 2); int hdf5_read(const char *input_file, int dim); virtual void write(const char *output_file) const; @@ -181,7 +181,7 @@ class star1d : public star2d { star1d(const star1d &); star1d &operator=(const star1d &); virtual int init(const char *input_file, const char *param_file, int argc, char *argv[]); - virtual int check_arg(char *arg, char *val, int *change_grid); + virtual int parse_arg(char *arg, char *val, int *change_grid); virtual int read(const char *input_file, int dim = 1); virtual void dump_info(); diff --git a/src/main/polytrope1d.cpp b/src/main/polytrope1d.cpp index 40e7101a..571261cd 100644 --- a/src/main/polytrope1d.cpp +++ b/src/main/polytrope1d.cpp @@ -36,7 +36,8 @@ int main(int argc,char *argv[]) { int nit,last_it; tiempo t; - configuration config(argc, argv); + configuration config; + config.read_config(argc, argv); signal(SIGINT, sig_handler); diff --git a/src/main/read_config.cpp b/src/main/read_config.cpp index 3ab8fc32..1c51fca4 100644 --- a/src/main/read_config.cpp +++ b/src/main/read_config.cpp @@ -8,14 +8,8 @@ #include "read_config.h" #include "matplotlib.h" -configuration::configuration(int argc,char *argv[]) { - - int i, k; - char *arg,*val; - char file[256]; - cmdline_parser cmd; - file_parser fp; - +configuration::configuration() { + // These are default values aimed to be replaced by config file values then command line ones verbose=1; strcpy(plot_device,"/NULL"); plot_interval=10; @@ -27,39 +21,78 @@ configuration::configuration(int argc,char *argv[]) { tol=1e-8; newton_dmax=0.5; noplot = false; +} + +void configuration::read_config(int argc, char *argv[]) { + // To ensure command line argument's precendence (complying with documentation) + // over the configuration file argument these methods must be called IN THIS ORDER + + read_config_file(); // 1st --> default values + read_command_line(argc, argv); // 2nd --> can erase default config file values +} + + +void configuration::read_config_file() { + char *arg,*val; + int err_code, line; + char file[256]; + file_parser fp; + + // Write in file the path to the default config file sprintf(file, "%s/ester/star.cfg", ESTER_DATADIR); - if(!fp.open(file)) - printf("Can't open configuration file %s\n",file); - else { - while((k=fp.get(arg,val))) { - if((i=check_arg(arg,val))) { - printf("Syntax error in configuration file %s, line %d\n",file,k); - if(i==2) missing_argument(arg); - if(i==1) { - printf("Unknown parameter %s\n",arg); - exit(1); - } - } - } - fp.close(); + + // Try opening the file, get 1 on error + if(fp.open(file)){ + printf("Can't open configuration file %s\n", file); + ester_err(strerror(errno)); } - cmd.open(argc,argv); - while(int err_code=cmd.get(arg,val)) { - if(err_code==-1) exit(1); - err_code=check_arg(arg,val); - if(err_code==2) missing_argument(arg); - if(err_code==0) cmd.ack(arg,val); + // iterate over each line/arg of the config file + while((line = fp.get(arg, val))) { + if((err_code = parse_arg(arg, val))) { + printf("Syntax error in configuration file %s, line %d\n", file, line); + if(err_code == 2) + ester_err("%s: Argument to '%s' missing", file, arg); + if(err_code == 1) + ester_err("%s: Unknown parameter '%s'", file, arg); + } } - cmd.close(); + fp.close(); +} + + +void configuration::read_command_line(int argc, char *argv[]) { + char *arg,*val; + int err_code; + cmdline_parser cmd; + + cmd.open(argc, argv); + while(err_code = cmd.get(arg, val)) { + if(err_code == -1) + ester_err("Invalid argument %s", arg); + + err_code = parse_arg(arg,val); + // We ignore Error Code 1 (unknown parameter) on purpose: it might be interpreted by star1d::init later + if(err_code == 2) + ester_err("Argument to '%s' missing", arg); + if(err_code == 0) + cmd.ack(arg,val); + } + cmd.close(); if (noplot == false) plt::init(); } -int configuration::check_arg(const char *arg,const char *val) { +int configuration::parse_arg(const char *arg,const char *val) { + /* + Return codes: + 0: No Error + 1: Unknown paramter + 2: Missing value + */ int err=0; if(!strcmp(arg,"v0")) @@ -127,7 +160,3 @@ int configuration::check_arg(const char *arg,const char *val) { return err; } - -void configuration::missing_argument(const char *arg) { - ester_err("Error: Argument to '%s' missing", arg); -} diff --git a/src/main/star1d.cpp b/src/main/star1d.cpp index 7271cda7..52322157 100644 --- a/src/main/star1d.cpp +++ b/src/main/star1d.cpp @@ -36,9 +36,11 @@ int main(int argc,char *argv[]) { int nit,last_it; double err; tiempo t; - // double t_plot; - configuration config(argc, argv); + // Create config object + configuration config; + // Parse configuration file star.cfg and command line simulation parameters (not star ones) + config.read_config(argc, argv); signal(SIGINT, sig_handler); @@ -47,7 +49,8 @@ int main(int argc,char *argv[]) { star1d A; solver *op; - if(A.init(config.input_file,config.param_file,argc,argv)) { + // Parse configutation file 1d_default.par and command line star parameters + if(A.init(config.input_file, config.param_file, argc, argv)) { ester_err("Could not initialize star"); return 1; } diff --git a/src/main/star2d.cpp b/src/main/star2d.cpp index 7d3bb337..b876302f 100644 --- a/src/main/star2d.cpp +++ b/src/main/star2d.cpp @@ -20,10 +20,14 @@ int main(int argc,char *argv[]) { int nit,last_it; double err=1; double t_plot; - configuration config(argc,argv); tiempo t; // figure *fig = NULL; - + + // Create config object + configuration config; + // Parse configuration file star.cfg and command line simulation parameters (not star ones) + config.read_config(argc, argv); + signal(SIGINT,sig_handler); plt::figure(1, 10, 4); @@ -38,7 +42,7 @@ int main(int argc,char *argv[]) { star2d A; solver *op; - if(A.init(config.input_file,config.param_file,argc,argv)) { + if(A.init(config.input_file, config.param_file, argc, argv)) { ester_err("Could not initialize star"); return 1; } diff --git a/src/main/star_evol.cpp b/src/main/star_evol.cpp index 62affccd..a834de9e 100644 --- a/src/main/star_evol.cpp +++ b/src/main/star_evol.cpp @@ -11,15 +11,18 @@ int main(int argc,char *argv[]) { - configuration config(argc,argv); + configuration config; + config.read_config(argc, argv); // Should we called only read_config_file here ? + cmdline_parser cmd; double dXc=0.05,Xcmin=0.05; char *arg,*val; cmd.open(argc,argv); - while(int err_code=cmd.get(arg,val)) { - if(err_code==-1) exit(1); + while(int err_code = cmd.get(arg,val)) { + if(err_code == -1) + ester_err("Invalid argument %s", arg); err_code=0; if(!strcmp(arg,"dXc")) { if(val==NULL) err_code=2; diff --git a/src/star/star1d_class.cpp b/src/star/star1d_class.cpp index 86ec087c..934c12fe 100644 --- a/src/star/star1d_class.cpp +++ b/src/star/star1d_class.cpp @@ -48,23 +48,21 @@ int star1d::init(const char *input_file, const char *param_file, int argc, char printf("Error reading input file: %s\n", input_file); return 1; } - map0=map; + map0 = map; } else { - if(!fp.open(default_params)) { + if(fp.open(default_params)) { printf("Can't open default parameters file %s\n", default_params); return 1; } else { - while((k=fp.get(arg, val))) { - if((i=check_arg(arg, val, &change_grid))) { + while((k = fp.get(arg, val))) { + if((i = parse_arg(arg, val, &change_grid))) { printf("Syntax error in parameters file %s, line %d\n", param_file, k); - if(i==2) { - printf("Error: Argument to '%s' missing\n", arg); - exit(EXIT_FAILURE); + if(i == 2) { + ester_err("%s: Argument to '%s' missing", default_params, arg); } - if(i==1) { - printf("Unknown parameter %s\n", arg); - exit(EXIT_FAILURE); + if(i == 1) { + ester_err("%s: Unknown parameter %s", default_params, arg); } } } @@ -74,21 +72,19 @@ int star1d::init(const char *input_file, const char *param_file, int argc, char } if(*param_file) { - if(!fp.open(param_file)) { + if(fp.open(param_file)) { printf("Can't open parameters file %s\n", param_file); return 1; } else { - while((k=fp.get(arg, val))) { - if((i=check_arg(arg, val, &change_grid))) { + while((k = fp.get(arg, val))) { + if((i = parse_arg(arg, val, &change_grid))) { printf("Syntax error in parameters file %s, line %d\n", param_file, k); - if(i==2) { - printf("Error: Argument to '%s' missing\n", arg); - exit(EXIT_FAILURE); + if(i == 2) { + ester_err("%s: Argument to '%s' missing", param_file, arg); } - if(i==1) { - printf("Unknown parameter %s\n", arg); - exit(EXIT_FAILURE); + if(i == 1) { + ester_err("%s: Unknown parameter %s", param_file, arg); } } } @@ -97,16 +93,16 @@ int star1d::init(const char *input_file, const char *param_file, int argc, char } cmd.open(argc, argv); - while(int err_code=cmd.get(arg, val)) { - if(err_code==-1) exit(1); - err_code=check_arg(arg, val, &change_grid); - if(err_code==2) { - fprintf(stderr, "Error: Argument to '%s' missing\n", arg); - exit(EXIT_FAILURE); + while(int err_code = cmd.get(arg, val)) { + if(err_code == -1) // Normally this can't happen because an Invalid Argument would already have been found in read_command_line + ester_err("Invalid argument %s", arg); + + err_code=parse_arg(arg, val, &change_grid); + if(err_code == 2) { + ester_err("Argument to '%s' missing", arg); } - if(err_code==1) { - fprintf(stderr, "Unknown parameter '%s'\n", arg); - exit(EXIT_FAILURE); + if(err_code == 1) { + ester_err("Unknown parameter %s", arg); } cmd.ack(arg, val); } @@ -163,7 +159,7 @@ int star1d::init(const char *input_file, const char *param_file, int argc, char return 0; } -int star1d::check_arg(char *arg, char *val, int *change_grid) { +int star1d::parse_arg(char *arg, char *val, int *change_grid) { if(!strcmp(arg, "nth")) { return 1; } else if(!strcmp(arg, "nex")) { @@ -173,7 +169,7 @@ int star1d::check_arg(char *arg, char *val, int *change_grid) { } else if(!strcmp(arg, "Ekman")) { return 1; } - return star2d::check_arg(arg, val, change_grid); + return star2d::parse_arg(arg, val, change_grid); } diff --git a/src/star/star2d_class.cpp b/src/star/star2d_class.cpp index 1ef15d6c..d9c81936 100644 --- a/src/star/star2d_class.cpp +++ b/src/star/star2d_class.cpp @@ -526,12 +526,12 @@ int star2d::init(const char *input_file,const char *param_file,int argc,char *ar } map0=map; } else { - if(!fp.open(default_params)) { + if(fp.open(default_params)) { ester_err("Can't open default parameters file %s\n", default_params); } else { while((k=fp.get(arg,val))) { - if((i=check_arg(arg,val,&change_grid))) { + if((i=parse_arg(arg,val,&change_grid))) { ester_err("Syntax error in parameters file %s, line %d\n",default_params,k); if(i==2) { ester_err("Error: Argument to '%s' missing\n",arg); @@ -549,13 +549,13 @@ int star2d::init(const char *input_file,const char *param_file,int argc,char *ar } if(*param_file) { - if(!fp.open(param_file)) { + if(fp.open(param_file)) { ester_err("Can't open parameters file %s\n",param_file); return 1; } else { while((k=fp.get(arg,val))) { - if((i=check_arg(arg,val,&change_grid))) { + if((i=parse_arg(arg,val,&change_grid))) { ester_err("Syntax error in parameters file %s, line %d\n", param_file, k); if(i==2) { @@ -574,8 +574,10 @@ int star2d::init(const char *input_file,const char *param_file,int argc,char *ar cmd.open(argc,argv); while(int err_code=cmd.get(arg,val)) { - if(err_code==-1) exit(1); - err_code=check_arg(arg,val,&change_grid); + if(err_code == -1) // Normally this can't happen because an Invalid Argument would already have been found in read_command_line + ester_err("Invalid argument %s", arg); + + err_code=parse_arg(arg,val,&change_grid); if(err_code==2) { ester_err("Error: Argument to '%s' missing\n",arg); return 1; @@ -665,7 +667,7 @@ void star2d::interp(remapper *red) { } extern bool dump_jac; -int star2d::check_arg(char *arg,char *val,int *change_grid) { +int star2d::parse_arg(char *arg,char *val,int *change_grid) { int err=0,i; char *tok; diff --git a/src/utils/parser.cpp b/src/utils/parser.cpp index 80977b4d..6845d769 100644 --- a/src/utils/parser.cpp +++ b/src/utils/parser.cpp @@ -8,26 +8,27 @@ extern "C" { } void cmdline_parser::open(int argc_in, char *argv_in[]) { - - argc=argc_in; - argv=argv_in; - i=1; - + argc = argc_in; + argv = argv_in; + i = 1; } int cmdline_parser::get(char *&arg,char *&val) { - + /* + Return codes: + -1: Invalid Parameter (missing '-' probably) + 0: End Of List, no more parameters to get + 1: No Error + */ if(i>=argc) return 0; - while(argv[i][0]=='\0') { + while(argv[i][0]=='\0') { // Ignore already parsed arguments i++; if(i==argc) break; } if(i==argc) return 0; if(argv[i][0]!='-') { - printf("Invalid argument %s\n",argv[i]); - arg=argv[i]+1; + arg=argv[i]; val=NULL; - i++; return -1; } arg=argv[i]+1; @@ -50,20 +51,19 @@ int cmdline_parser::get(char *&arg,char *&val) { } void cmdline_parser::ack(char *arg,char *val) { - - *(arg-1)='\0'; - if(val!=NULL) *val='\0'; - + // Acknoledge, argument parsed successfully + *(arg-1) = '\0'; + if(val != NULL) + *val = '\0'; } void cmdline_parser::close(){} int file_parser::open(const char *file) { - iline=0; - if(!(fp=fopen(file,"rt"))) return 0; - return 1; + fp = fopen(file,"rt"); + return (fp == NULL); // return 1 on error (fp == NULL), else 0 } int file_parser::get(char *&arg,char *&val){ diff --git a/utils/starR/star1dR_class.cpp b/utils/starR/star1dR_class.cpp index 91962f8c..7edb3c7c 100644 --- a/utils/starR/star1dR_class.cpp +++ b/utils/starR/star1dR_class.cpp @@ -4,7 +4,7 @@ star1dR::star1dR() {Teff_obj=-1;} -int star1dR::check_arg(char *arg,char *val,int *change_grid) { +int star1dR::parse_arg(char *arg,char *val,int *change_grid) { if(!strcmp(arg,"R")) { if(val==NULL) return 2; @@ -23,7 +23,7 @@ int star1dR::check_arg(char *arg,char *val,int *change_grid) { return 1; } - return star1d::check_arg(arg,val,change_grid); + return star1d::parse_arg(arg,val,change_grid); } diff --git a/utils/starR/star2dR_class.cpp b/utils/starR/star2dR_class.cpp index d3c551ac..f5767312 100644 --- a/utils/starR/star2dR_class.cpp +++ b/utils/starR/star2dR_class.cpp @@ -4,7 +4,7 @@ star2dR::star2dR() {Teff_obj=-1;Re_obj=-1;} -int star2dR::check_arg(char *arg,char *val,int *change_grid) { +int star2dR::parse_arg(char *arg,char *val,int *change_grid) { if(!strcmp(arg,"R")||!strcmp(arg,"Rp")) { if(val==NULL) return 2; @@ -31,7 +31,7 @@ int star2dR::check_arg(char *arg,char *val,int *change_grid) { return 1; } - return star2d::check_arg(arg,val,change_grid); + return star2d::parse_arg(arg,val,change_grid); } solver *star2dR::init_solver(int nvar_add) { diff --git a/utils/starR/starR.h b/utils/starR/starR.h index 88000f1c..6a36c6ca 100644 --- a/utils/starR/starR.h +++ b/utils/starR/starR.h @@ -7,7 +7,7 @@ class star1dR: public star1d { public: star1dR(); double Teff_obj; - int check_arg(char *arg,char *val,int *change_grid); + int parse_arg(char *arg,char *val,int *change_grid); solver *init_solver(int nvar_add=0); void register_variables(solver *); double solve(solver *); @@ -22,7 +22,7 @@ class star2dR: public star2d { public: star2dR(); double Teff_obj,Re_obj; - int check_arg(char *arg,char *val,int *change_grid); + int parse_arg(char *arg,char *val,int *change_grid); solver *init_solver(int nvar_add=0); void register_variables(solver *); double solve(solver *);