00001
00006 #ifndef ___CMDPARAM_H___
00007 #define ___CMDPARAM_H___
00008
00009 #include <stdio.h>
00010
00011 #include "ipc.h"
00012 #include "stringparser.h"
00013
00014
00015
00016
00017
00018 #define PARAM_STRING 0
00019 #define PARAM_BOOL 1
00020 #define PARAM_INT 2
00021 #define PARAM_DOUBLE 3
00022
00023
00024
00025
00027 #define PARAM_NN(type,name,location,doc) \
00028 params_define_param(#name,type,False,(void*)location); \
00029 params_define_doc(#name,doc)
00030
00031
00033 #define PARAM_LL(type,name,location,lower,doc) \
00034 params_define_param(#name,type,False,(void*)location); \
00035 params_add_lower_bound_int(#name,lower); \
00036 params_define_doc(#name,doc)
00037
00038
00040 #define PARAM_II(type,name,location,lower,upper,doc) \
00041 params_define_param(#name,type,False,(void*)location); \
00042 params_add_lower_bound_int(#name,lower); \
00043 params_add_upper_bound_int(#name,upper); \
00044 params_define_doc(#name,doc)
00045
00046
00047
00048
00049 #define PARAM_N(type,name,doc) \
00050 params_define_param(#name,type,False,(void*)&name); \
00051 params_define_doc(#name,doc)
00052
00053 #define PARAM_L(type,name,lower,doc) \
00054 params_define_param(#name,type,False,(void*)&name); \
00055 params_add_lower_bound_int(#name,lower); \
00056 params_define_doc(#name,doc)
00057
00058 #define PARAM_I(type,name,lower,upper,doc) \
00059 params_define_param(#name,type,False,(void*)&name); \
00060 params_add_lower_bound_int(#name,lower); \
00061 params_add_upper_bound_int(#name,upper); \
00062 params_define_doc(#name,doc)
00063
00064
00065 00066 00067 00068 00069
00070
00072 #define CONST_I(name,value,is_param,doc) \
00073 { static int param_const_name=value; \
00074 params_define_param(#name,PARAM_INT,!is_param,(void*)¶m_const_name); \
00075 params_add_lower_bound_int(#name,value); \
00076 params_add_upper_bound_int(#name,value); \
00077 params_define_doc(#name,doc); }
00078
00079
00081 #define CONST_B(name,value,is_param,doc) \
00082 { static int param_const_name=value; \
00083 params_define_param(#name,PARAM_BOOL,!is_param,(void*)¶m_const_name); \
00084 params_add_lower_bound_int(#name,value); \
00085 params_add_upper_bound_int(#name,value); \
00086 params_define_doc(#name,doc); }
00087
00088
00090 #define CONST_F(name,value,is_param,doc) \
00091 { static double param_const_name=value; \
00092 params_define_param(#name,PARAM_DOUBLE,!is_param,(void*)¶m_const_name); \
00093 params_define_doc(#name,doc); }
00094
00095
00097 #define CONST_S(name,is_param,doc) \
00098 { static char param_const_name[]=""; \
00099 params_define_param(#name,PARAM_STRING,!is_param,(void*)¶m_const_name); \
00100 params_define_doc(#name,doc); }
00101
00102
00103
00105 #define CMD_MAX_ARGUMENTS 64
00106
00108 #define CMD_MAX_LINE_LENGTH 2048
00109
00110
00111 00112 00113 00114 00115
00116 typedef int cmdstat;
00117 #define CMD_NO_ERROR 0
00118 #define CMD_FATAL_ERROR -20000
00119 #define CMD_MISC_ERROR -20001
00120 #define CMD_FILE_ERROR -20002
00121 #define CMD_PARAMETER_ERROR -20003
00122 #define CMD_MEMORY_ERROR -20004
00123 #define CMD_PREREQ_ERROR -20005
00124 #define CMD_EMPTY -20006
00125 #define CMD_PARSE_ERROR -20007
00126 #define CMD_NEVER_CALLED -20008
00127 #define CMD_SIGINT_ERROR -20009
00129
00130 #define CMD_ARGS int argc, const char *argv[]
00131 #define CMD_UNUSED_ARGS int, const char *[]
00132 typedef cmdstat (*commandfunptr)( CMD_ARGS );
00133
00134
00140 class CmdWrapper {
00141 public:
00142 CmdWrapper() { }
00143 virtual ~CmdWrapper() { }
00145 virtual cmdstat operator() ( CMD_ARGS )=0;
00146 };
00147
00148
00150 #define CMD_DECLARE(name) \
00151 cmdstat cmd_ ## name ( CMD_ARGS ); \
00152 struct cmdobj_ ## name : public CmdWrapper { \
00153 cmdstat operator() ( CMD_ARGS ) { \
00154 return cmd_ ## name(argc,argv); \
00155 } \
00156 }
00157
00159 #define CMDOBJ_DOC(name,prereq,cargs,numargs,usage,doc) \
00160 cmddefs_define_command(#name,new cmdobj_ ## name(cargs),numargs,False); \
00161 cmddefs_define_command_doc(#name,usage,doc); \
00162 cmddefs_define_command_prereq(#name,prereq)
00163
00164
00166 #define CMD_DOC(name,prereq,numargs,usage,doc) \
00167 CMDOBJ_DOC(name,prereq,,numargs,usage,doc)
00168
00169
00174 #define CMDOBJ_DEFINE_CATCHUP(cargs,numargs,name,usage,doc) \
00175 cmddefs_define_command(#name,new cmdobj_ ## name(cargs),numargs,True); \
00176 cmddefs_define_command_doc(#name,usage,doc)
00177
00178
00180 #define CMD_DEFINE_CATCHUP(numargs,name,usage,doc) \
00181 CMDOBJ_DEFINE_CATCHUP(,numargs,name,usage,doc)
00182
00183
00185 #define CMDOBJ_DECLARE(Owner,name) \
00186 cmdstat cmd_ ## name ( CMD_ARGS ); \
00187 class cmdobj_ ## name : public CmdWrapper { \
00188 Owner* owner; \
00189 public: \
00190 cmdobj_ ## name (Owner* owner_i) : owner(owner_i) { }; \
00191 cmdstat operator() ( CMD_ARGS ) { \
00192 return owner->cmd_ ## name (argc,argv); \
00193 } \
00194 }; \
00195 friend class cmdobj_ ## name
00196
00197
00199 typedef int (*CmdDefs_LineGenerator)( void );
00200 extern char cmddefs_line_buffer[CMD_MAX_LINE_LENGTH+1+sizeof(int)];
00201
00203 typedef int HooklistNum;
00204
00205
00207 #define SETFN_ARGS const char* name, void* param, const void* newvalue
00208 typedef cmdstat (*ParamSetFn)( SETFN_ARGS );
00209
00210
00216 class SetFnWrapper {
00217 public:
00218 SetFnWrapper() { }
00219 virtual ~SetFnWrapper() { }
00221 virtual cmdstat operator() ( SETFN_ARGS )=0;
00222 };
00223
00224 #define SETFN_DECLARE(fnname) \
00225 cmdstat fnname( SETFN_ARGS ); \
00226 struct setfnobj_ ## fnname : public SetFnWrapper { \
00227 cmdstat operator() ( SETFN_ARGS ) { \
00228 return fnname(name,param,newvalue); \
00229 } \
00230 }
00231
00232
00233
00234 #define SETFNOBJ_DEFINE(cargs,paramname,fnname) \
00235 params_define_setfn(#paramname,new setfnobj_ ## fnname(cargs))
00236
00238 #define SETFN_DEFINE(paramname,fnname) \
00239 SETFNOBJ_DEFINE(,paramname,fnname)
00240
00241
00243 #define SETFNOBJ_DECLARE(Owner,fnname) \
00244 cmdstat fnname ( SETFN_ARGS ); \
00245 class setfnobj_ ## fnname : public SetFnWrapper { \
00246 Owner* owner; \
00247 public: \
00248 setfnobj_ ## fnname (Owner* owner_i) : owner(owner_i) { }; \
00249 cmdstat operator() ( SETFN_ARGS ) { \
00250 return owner->fnname(name,param,newvalue); \
00251 } \
00252 }; \
00253 friend class setfnobj_ ## fnname
00254
00255
00256
00257 extern int cmdparam_warn_unknown;
00258 extern int cmdparam_changes_verbose;
00259 extern int command_num_called;
00260
00261
00262
00263 cmdstat cmd_set( CMD_ARGS );
00264 cmdstat cmd_hook( CMD_ARGS );
00265
00266
00267 char* cmdparams_completion_generator(char *text, int state);
00268 void cmdparam_init_hook(void);
00269 int cmdparams_print_doc(FILE *fp, const char* name);
00270 int cmdparam_save_current_state(const char * filename);
00271 char* cmdparam_dupstr (const char *str);
00272 cmdstat cmdparam_set( const char *name, const char *expr );
00273
00274 void params_add_lower_bound_int(const char *name, int lower_bound);
00275 void params_add_upper_bound_int(const char *name, int upper_bound);
00276 int params_check_all( void );
00277 char* params_completion_generator (char *text, int state);
00278 void params_define_doc( const char* name, const char *doc );
00279 int params_define_param(const char *name, int type, int is_constant, void *pointer);
00280 void params_define_setfn( const char* name, SetFnWrapper* setfn );
00281 void params_define_default_expr(const char *name, const char *expr);
00282 int params_is_constant(int idx);
00283 void params_log(void);
00284 double* params_lookup_double(const char *name);
00285 int params_num_total(void);
00286 void params_print_all(FILE *fp);
00287 void params_print_constants(FILE *fp);
00288 void params_print_constants_doc(FILE *file);
00289 void params_print_doc(FILE *fp, const char* name);
00290 void params_print_doc_for_index(FILE *fp, int idx);
00291 void params_print_parameters(FILE *fp);
00292 void params_print_parameters_doc(FILE *file);
00293 void params_print_parameters_doc(FILE *fp);
00294 int params_print_to_str(int number, char *str, size_t nchars);
00295 void params_update_all_default_values( void );
00296 void params_update_default_value(const char* name);
00297
00298 long cmdi(const char* str);
00299 double cmdf(const char* str);
00300 const char * cmds(const char* str);
00301
00302 char* cmddefs_completion_generator (char *text, int state);
00303 void cmddefs_declare_prereq_status( const char * name, cmdstat status );
00304 void cmddefs_define_command( const char* name, CmdWrapper* function, int minargs, int exec_for_catchups );
00305 void cmddefs_define_command_doc( const char* name, const char *usage, const char *doc );
00306 void cmddefs_define_command_prereq( const char* name, const char *prereq );
00307 int cmddefs_exec_batch(CmdDefs_LineGenerator fn, const char * description);
00308 int cmddefs_exec_file(const char *filename);
00309 cmdstat cmddefs_exec_by_name(const char* name, CMD_ARGS);
00310 cmdstat cmddefs_exec_str(const char* cmdtxt);
00311 int cmddefs_num_total(void);
00312 void cmddefs_print_all(FILE *fp);
00313 void cmddefs_print_all_doc(FILE *file);
00314 void cmddefs_print_doc(FILE *fp, const char* name);
00315 void cmddefs_print_doc_for_index(FILE *fp, int idx);
00316
00317 void hooklists_empty_list(HooklistNum hooklistnum);
00318 void hooklists_reset_list(HooklistNum hooklist);
00319 void hooklists_run_list(HooklistNum hooklist, int counter, int catchuponly);
00320 int hooklists_define_list( const char * listname, const char *countername );
00321
00322
00324 class CmdParamStringParser : public StringParser {
00325 public:
00326 CmdParamStringParser() { };
00327 virtual ~CmdParamStringParser() { }
00328 CmdParamStringParser(const CmdParamStringParser& other) : StringParser(other) { }
00329 virtual StringParser* clone() const { return new CmdParamStringParser(*this); };
00330
00331 virtual double& parse(const string& s, double& x) const { return x = cmdf(s.c_str()); }
00332 virtual int& parse(const string& s, int& x) const { return x = cmdi(s.c_str()); }
00333 virtual string& parse(const string& s, string& x) const { return x = cmds(s.c_str()); }
00334
00335 virtual double*& parse(const string& s, double*& x) const {
00336 if (!ispointer(s))
00337 parse(s,*x);
00338 else {
00339 00340
00341 double* ptr=params_lookup_double(s.c_str()+1);
00342 if (ptr) x=ptr;
00343 else ipc_notify(IPC_ONE,IPC_ERROR,
00344 "ValueGenerator: Could not get a type double pointer from %s",
00345 s.c_str());
00346 }
00347
00348 return x;
00349 }
00350
00351 00352
00353 virtual string parse(const string& s) const
00354 { return StringParser::parse(s); }
00355 virtual arglist& parse(const string& s, arglist& x) const
00356 { return StringParser::parse(s,x); }
00357
00358 virtual void error(const string& s) const { ipc_notify(IPC_ONE,IPC_ERROR,s.c_str()); }
00359
00360 private:
00361 virtual bool ispointer(const string& s) const {
00362 istrstream ist(s.c_str(),s.length());
00363 unsigned char w;
00364 ist >> w;
00365 return (w == '&');
00366 }
00367 };
00368
00369
00370
00371 00372 00373 00374 00375 00376 00377 00378 00379 00380 00381 00382
00383 #define CMD_ARG_ITERATORS \
00384 StringParser::arglist argl(&argv[0],&argv[argc]);\
00385 StringParser::argptr args=argl.begin();\
00386 StringParser::argptr end =argl.end();\
00387 const CmdParamStringParser p
00388
00389
00390 #define CMD_ARG_LIST \
00391 StringParser::arglist argl(&argv[0],&argv[argc]);\
00392 const CmdParamStringParser p;\
00393 StringArgs arglist(p, argl.begin(), argl.end())
00394
00395 #endif