00001 // -*- c++ -*- 00002 00003 // This file is part of the Collective Variables module (Colvars). 00004 // The original version of Colvars and its updates are located at: 00005 // https://github.com/Colvars/colvars 00006 // Please update all Colvars source files before making any changes. 00007 // If you wish to distribute your changes, please submit them to the 00008 // Colvars repository at GitHub. 00009 00010 #ifndef COLVARSCRIPT_H 00011 #define COLVARSCRIPT_H 00012 00013 #include <string> 00014 #include <vector> 00015 #include <map> 00016 00017 #include "colvarmodule.h" 00018 #include "colvarvalue.h" 00019 #include "colvarbias.h" 00020 #include "colvarproxy.h" 00021 00022 00023 // Only these error values are part of the scripting interface 00024 #define COLVARSCRIPT_ERROR -1 00025 #define COLVARSCRIPT_OK 0 00026 00027 00028 class colvarscript { 00029 00030 private: 00031 00032 colvarproxy *proxy_; 00033 colvarmodule *colvars; 00034 00035 inline colvarscript() {} // no-argument construction forbidden 00036 00037 public: 00038 00039 friend class colvarproxy; 00040 00041 colvarscript(colvarproxy *p, colvarmodule *m); 00042 00043 ~colvarscript(); 00044 00046 std::string str_result_; 00047 00049 int run(int objc, unsigned char *const objv[]); 00050 00052 inline std::string const &str_result() const 00053 { 00054 return str_result_; 00055 } 00056 00058 inline std::string &modify_str_result() 00059 { 00060 return str_result_; 00061 } 00062 00064 int set_result_str(std::string const &s); 00065 00067 int clear_str_result(); 00068 00070 void add_error_msg(std::string const &s); 00071 00073 enum command { 00074 #define CVSCRIPT_ENUM_COMM(COMM) COMM, 00075 #undef CVSCRIPT 00076 #define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \ 00077 CVSCRIPT_ENUM_COMM(COMM) 00078 #ifdef COLVARSCRIPT_COMMANDS_H 00079 #undef COLVARSCRIPT_COMMANDS_H 00080 #endif 00081 #include "colvarscript_commands.h" 00082 #undef COLVARSCRIPT_COMMANDS_H 00083 #undef CVSCRIPT 00084 #undef CVSCRIPT_ENUM_COMM 00085 cv_n_commands 00086 }; 00087 00089 enum Object_type { 00090 use_module, 00091 use_colvar, 00092 use_bias 00093 }; 00094 00096 std::string get_cmd_prefix(Object_type t); 00097 00099 template<Object_type T> 00100 unsigned char *get_cmd_arg(int iarg, int objc, unsigned char *const objv[]); 00101 00103 unsigned char *get_module_cmd_arg(int iarg, int objc, 00104 unsigned char *const objv[]); 00105 00107 unsigned char *get_colvar_cmd_arg(int iarg, int objc, 00108 unsigned char *const objv[]); 00109 00111 unsigned char *get_bias_cmd_arg(int iarg, int objc, 00112 unsigned char *const objv[]); 00113 00115 template<Object_type T> 00116 int check_cmd_nargs(char const *cmd, int objc, 00117 int n_args_min, int n_args_max); 00118 00120 int check_module_cmd_nargs(char const *cmd, int objc, 00121 int n_args_min, int n_args_max); 00122 00124 int check_colvar_cmd_nargs(char const *cmd, int objc, 00125 int n_args_min, int n_args_max); 00126 00128 int check_bias_cmd_nargs(char const *cmd, int objc, 00129 int n_args_min, int n_args_max); 00130 00132 template<colvarscript::Object_type T> 00133 int cmd_arg_shift(); 00134 00136 inline char const **get_command_names() const 00137 { 00138 return cmd_names; 00139 } 00140 00143 char const *get_command_help(char const *cmd); 00144 00147 char const *get_command_rethelp(char const *cmd); 00148 00154 char const *get_command_arghelp(char const *cmd, int i); 00155 00158 int get_command_n_args_min(char const *cmd); 00159 00162 int get_command_n_args_max(char const *cmd); 00163 00166 char const *get_command_full_help(char const *cmd); 00167 00170 std::string get_cmdline_help_summary(Object_type t); 00171 00175 std::string get_command_cmdline_syntax(Object_type t, command c); 00176 00180 std::string get_command_cmdline_help(Object_type t, std::string const &cmd); 00181 00183 int unsupported_op(); 00184 00186 inline colvarmodule *module() 00187 { 00188 return this->colvars; 00189 } 00190 00192 inline colvarproxy *proxy() 00193 { 00194 return this->proxy_; 00195 } 00196 00197 // Input functions - get the string reps of script argument objects 00198 00200 char *obj_to_str(unsigned char *obj); 00201 00203 std::vector<std::string> obj_to_str_vector(unsigned char *obj); 00204 00205 00206 // Output functions - convert internal objects to representations suitable 00207 // for use in the scripting language. At the moment only conversion to C 00208 // strings is supported, and obj is assumed to be a char * pointer. 00209 00211 int set_result_int(int const &x, unsigned char *obj = NULL); 00212 00214 int set_result_int_vec(std::vector<int> const &x, unsigned char *obj = NULL); 00215 00217 int set_result_long_int(long int const &x, unsigned char *obj = NULL); 00218 00220 int set_result_long_int_vec(std::vector<long int> const &x, 00221 unsigned char *obj = NULL); 00222 00224 int set_result_real(cvm::real const &x, unsigned char *obj = NULL); 00225 00227 int set_result_real_vec(std::vector<cvm::real> const &x, 00228 unsigned char *obj = NULL); 00229 00231 int set_result_rvector(cvm::rvector const &x, unsigned char *obj = NULL); 00232 00234 int set_result_rvector_vec(std::vector<cvm::rvector> const &x, 00235 unsigned char *obj = NULL); 00236 00238 int set_result_colvarvalue(colvarvalue const &x, unsigned char *obj = NULL); 00239 00241 int set_result_colvarvalue_vec(std::vector<colvarvalue> const &x, 00242 unsigned char *obj = NULL); 00243 00244 private: 00245 00247 int init_commands(); 00248 00250 int init_command(colvarscript::command const &comm, 00251 char const *name, char const *help, 00252 int n_args_min, int n_args_max, char const *arghelp, 00253 int (*fn)(void *, int, unsigned char * const *)); 00254 00255 public: // TODO this function will be removed soon 00256 00258 int proc_features(colvardeps *obj, 00259 int argc, unsigned char *const argv[]); 00260 00261 private: // TODO 00262 00264 std::map<std::string, command> cmd_str_map; 00265 00267 char const **cmd_names; 00268 00270 std::vector<std::string> cmd_help; 00271 00273 std::vector<std::string> cmd_rethelp; 00274 00276 std::vector<size_t> cmd_n_args_min; 00277 00279 std::vector<size_t> cmd_n_args_max; 00280 00282 std::vector< std::vector<std::string> > cmd_arghelp; 00283 00285 std::vector<std::string> cmd_full_help; 00286 00288 std::vector<int (*)(void *, int, unsigned char * const *)> cmd_fns; 00289 00291 inline int (*get_cmd_fn(std::string const &cmd_key))(void *, 00292 int, 00293 unsigned char * const *) 00294 { 00295 if (cmd_str_map.count(cmd_key) > 0) { 00296 return cmd_fns[cmd_str_map[cmd_key]]; 00297 } 00298 return NULL; 00299 } 00300 00302 template <typename T> 00303 int set_result_text(T const &x, unsigned char *obj); 00304 00306 template <typename T> 00307 int pack_vector_elements_text(std::vector<T> const &x, std::string &x_str); 00308 00310 int set_result_text_from_str(std::string const &x_str, unsigned char *obj); 00311 00312 00313 }; 00314 00315 00317 inline static colvarscript *colvarscript_obj() 00318 { 00319 return cvm::main()->proxy->script; 00320 } 00321 00322 00324 inline static colvar *colvar_obj(void *pobj) 00325 { 00326 return reinterpret_cast<colvar *>(pobj); 00327 } 00328 00329 00331 inline static colvarbias *colvarbias_obj(void *pobj) 00332 { 00333 return reinterpret_cast<colvarbias *>(pobj); 00334 } 00335 00336 00337 00338 template<colvarscript::Object_type T> 00339 unsigned char *colvarscript::get_cmd_arg(int iarg, 00340 int objc, 00341 unsigned char *const objv[]) 00342 { 00343 int const shift = cmd_arg_shift<T>(); 00344 return (shift+iarg < objc) ? objv[shift+iarg] : NULL; 00345 } 00346 00347 00348 inline unsigned char *colvarscript::get_module_cmd_arg(int iarg, int objc, 00349 unsigned char *const objv[]) 00350 { 00351 return get_cmd_arg<use_module>(iarg, objc, objv); 00352 } 00353 00354 00355 inline unsigned char *colvarscript::get_colvar_cmd_arg(int iarg, int objc, 00356 unsigned char *const objv[]) 00357 { 00358 return get_cmd_arg<use_colvar>(iarg, objc, objv); 00359 } 00360 00361 00362 inline unsigned char *colvarscript::get_bias_cmd_arg(int iarg, int objc, 00363 unsigned char *const objv[]) 00364 { 00365 return get_cmd_arg<use_bias>(iarg, objc, objv); 00366 } 00367 00368 00369 template<colvarscript::Object_type T> 00370 int colvarscript::check_cmd_nargs(char const *cmd, 00371 int objc, 00372 int n_args_min, 00373 int n_args_max) 00374 { 00375 int const shift = cmd_arg_shift<T>(); 00376 if (objc < shift+n_args_min) { 00377 add_error_msg("Insufficient number of arguments ("+cvm::to_str(objc)+ 00378 ") for script function \""+std::string(cmd)+ 00379 "\":\n"+get_command_full_help(cmd)); 00380 return COLVARSCRIPT_ERROR; 00381 } 00382 if (objc > shift+n_args_max) { 00383 add_error_msg("Too many arguments ("+cvm::to_str(objc)+ 00384 ") for script function \""+std::string(cmd)+ 00385 "\":\n"+get_command_full_help(cmd)); 00386 return COLVARSCRIPT_ERROR; 00387 } 00388 return COLVARSCRIPT_OK; 00389 } 00390 00391 00392 inline int colvarscript::check_module_cmd_nargs(char const *cmd, 00393 int objc, 00394 int n_args_min, 00395 int n_args_max) 00396 { 00397 return check_cmd_nargs<use_module>(cmd, objc, n_args_min, n_args_max); 00398 } 00399 00400 00401 inline int colvarscript::check_colvar_cmd_nargs(char const *cmd, 00402 int objc, 00403 int n_args_min, 00404 int n_args_max) 00405 { 00406 return check_cmd_nargs<use_colvar>(cmd, objc, n_args_min, n_args_max); 00407 } 00408 00409 00410 inline int colvarscript::check_bias_cmd_nargs(char const *cmd, 00411 int objc, 00412 int n_args_min, 00413 int n_args_max) 00414 { 00415 return check_cmd_nargs<use_bias>(cmd, objc, n_args_min, n_args_max); 00416 } 00417 00418 00419 template<colvarscript::Object_type T> 00420 int colvarscript::cmd_arg_shift() 00421 { 00422 int shift = 0; 00423 if (T == use_module) { 00424 // "cv" and "COMMAND" are 1st and 2nd argument, and shift is equal to 2 00425 shift = 2; 00426 } else if (T == use_colvar) { 00427 // Same as above with additional arguments "colvar" and "NAME" 00428 shift = 4; 00429 } else if (T == use_bias) { 00430 shift = 4; 00431 } 00432 return shift; 00433 } 00434 00435 00436 extern "C" { 00437 00439 int run_colvarscript_command(int objc, unsigned char *const objv[]); 00440 00442 const char * get_colvarscript_result(); 00443 00444 } 00445 00446 00447 #endif // #ifndef COLVARSCRIPT_H