00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include <cstdlib>
00011 #include <cstring>
00012 #include <sstream>
00013
00014 #include "colvarproxy.h"
00015 #include "colvardeps.h"
00016 #include "colvarscript.h"
00017 #include "colvarscript_commands.h"
00018
00019
00020
00021 #ifdef COLVARS_TCL
00028 extern "C" int tcl_run_colvarscript_command(ClientData clientData,
00029 Tcl_Interp *interp_in,
00030 int objc, Tcl_Obj *const objv[]);
00031 #endif
00032
00033
00034 colvarscript::colvarscript(colvarproxy *p, colvarmodule *m)
00035 : proxy_(p),
00036 colvars(m)
00037 {
00038 cmd_names = NULL;
00039 init_commands();
00040 #ifdef COLVARS_TCL
00041
00042 proxy()->init_tcl_pointers();
00043
00044 Tcl_Interp *const interp = proxy()->get_tcl_interp();
00045 if (interp == NULL) {
00046 cvm::error("Error: trying to construct colvarscript without a Tcl interpreter.\n");
00047 return;
00048 }
00049 Tcl_DeleteCommand(interp, "cv");
00050 Tcl_CreateObjCommand(interp, "cv", tcl_run_colvarscript_command,
00051 (ClientData) this, (Tcl_CmdDeleteProc *) NULL);
00052 cvm::log("Redefining the Tcl \"cv\" command to the new script interface.\n");
00053 #endif
00054 }
00055
00056
00057 colvarscript::~colvarscript()
00058 {
00059 if (cmd_names) {
00060 delete [] cmd_names;
00061 cmd_names = NULL;
00062 }
00063 }
00064
00065
00066 int colvarscript::init_commands()
00067 {
00068 if (cvm::debug()) {
00069 cvm::log("Called colvarcript::init_commands()\n");
00070 }
00071
00072 cmd_help.resize(colvarscript::cv_n_commands);
00073 cmd_rethelp.resize(colvarscript::cv_n_commands);
00074 cmd_n_args_min.resize(colvarscript::cv_n_commands);
00075 cmd_n_args_max.resize(colvarscript::cv_n_commands);
00076 cmd_arghelp.resize(colvarscript::cv_n_commands);
00077 cmd_full_help.resize(colvarscript::cv_n_commands);
00078 cmd_fns.resize(colvarscript::cv_n_commands);
00079
00080 if (cmd_names) {
00081 delete [] cmd_names;
00082 cmd_names = NULL;
00083 }
00084 cmd_names = new char const * [colvarscript::cv_n_commands];
00085
00086 #undef COLVARSCRIPT_COMMANDS_H // disable include guard
00087 #if defined(CVSCRIPT)
00088 #undef CVSCRIPT // disable default macro
00089 #endif
00090 #define CVSCRIPT_COMM_INIT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGHELP) { \
00091 init_command(COMM,#COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGHELP,&(CVSCRIPT_COMM_FNAME(COMM))); \
00092 }
00093 #define CVSCRIPT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS,FN_BODY) \
00094 CVSCRIPT_COMM_INIT(COMM,HELP,N_ARGS_MIN,N_ARGS_MAX,ARGS)
00095
00096 #include "colvarscript_commands.h"
00097
00098 #undef CVSCRIPT_COMM_INIT
00099 #undef CVSCRIPT
00100
00101 return COLVARS_OK;
00102 }
00103
00104
00105 int colvarscript::init_command(colvarscript::command const &comm,
00106 char const *name, char const *help,
00107 int n_args_min, int n_args_max,
00108 char const *arghelp,
00109 int (*fn)(void *, int, unsigned char * const *))
00110 {
00111 cmd_str_map[std::string(name)] = comm;
00112 cmd_names[comm] = name;
00113
00114
00115 {
00116 std::string const help_str(help);
00117 std::istringstream is(help_str);
00118 std::string line;
00119 std::getline(is, line);
00120 cmd_help[comm] = line;
00121 cmd_rethelp[comm] = "";
00122 while (std::getline(is, line)) {
00123 cmd_rethelp[comm] += line + "\n";
00124 }
00125 }
00126
00127
00128 cmd_n_args_min[comm] = n_args_min;
00129 cmd_n_args_max[comm] = n_args_max;
00130 {
00131 std::string const arghelp_str(arghelp);
00132 std::istringstream is(arghelp_str);
00133 std::string line;
00134 for (int iarg = 0; iarg < n_args_max; iarg++) {
00135 if (! std::getline(is, line)) {
00136 return cvm::error("Error: could not initialize help string for scripting "
00137 "command \""+std::string(name)+"\".\n", COLVARS_BUG_ERROR);
00138 }
00139 cmd_arghelp[comm].push_back(line);
00140 }
00141 }
00142
00143 cmd_full_help[comm] = cmd_help[comm]+"\n";
00144 if (cmd_n_args_min[comm] > 0) {
00145 cmd_full_help[comm] += "\nParameters\n";
00146 cmd_full_help[comm] += "----------\n\n";
00147 size_t i;
00148 for (i = 0; i < cmd_n_args_min[comm]; i++) {
00149 cmd_full_help[comm] += cmd_arghelp[comm][i]+"\n";
00150 }
00151 for (i = cmd_n_args_min[comm]; i < cmd_n_args_max[comm]; i++) {
00152 cmd_full_help[comm] += cmd_arghelp[comm][i]+" (optional)\n";
00153 }
00154 }
00155 if (cmd_rethelp[comm].size() > 0) {
00156 cmd_full_help[comm] += "\nReturns\n";
00157 cmd_full_help[comm] += "-------\n\n";
00158 cmd_full_help[comm] += cmd_rethelp[comm]+"\n";
00159 }
00160
00161 cmd_fns[comm] = fn;
00162 if (cvm::debug()) {
00163 cvm::log("Defined command \""+std::string(name)+"\", with help string:\n");
00164 cvm::log(get_command_full_help(name));
00165 }
00166
00167 return COLVARS_OK;
00168 }
00169
00170
00171 std::string colvarscript::get_cmd_prefix(colvarscript::Object_type t)
00172 {
00173 switch (t) {
00174 case use_module:
00175 return std::string("cv_"); break;
00176 case use_colvar:
00177 return std::string("colvar_"); break;
00178 case use_bias:
00179 return std::string("bias_"); break;
00180 default:
00181 cvm::error("Error: undefined colvarscript object type.", COLVARS_BUG_ERROR);
00182 return std::string("");
00183 }
00184 }
00185
00186
00187
00188 char const *colvarscript::get_command_help(char const *cmd)
00189 {
00190 if (cmd_str_map.count(cmd) > 0) {
00191 colvarscript::command const c = cmd_str_map[std::string(cmd)];
00192 return cmd_help[c].c_str();
00193 }
00194 cvm::error("Error: command "+std::string(cmd)+
00195 " is not implemented.\n", COLVARS_INPUT_ERROR);
00196 return NULL;
00197 }
00198
00199
00200 char const *colvarscript::get_command_rethelp(char const *cmd)
00201 {
00202 if (cmd_str_map.count(cmd) > 0) {
00203 colvarscript::command const c = cmd_str_map[std::string(cmd)];
00204 return cmd_rethelp[c].c_str();
00205 }
00206 cvm::error("Error: command "+std::string(cmd)+
00207 " is not implemented.\n", COLVARS_INPUT_ERROR);
00208 return NULL;
00209 }
00210
00211
00212 char const *colvarscript::get_command_arghelp(char const *cmd, int i)
00213 {
00214 if (cmd_str_map.count(cmd) > 0) {
00215 colvarscript::command const c = cmd_str_map[std::string(cmd)];
00216 return cmd_arghelp[c][i].c_str();
00217 }
00218 cvm::error("Error: command "+std::string(cmd)+
00219 " is not implemented.\n", COLVARS_INPUT_ERROR);
00220 return NULL;
00221 }
00222
00223
00224 int colvarscript::get_command_n_args_min(char const *cmd)
00225 {
00226 if (cmd_str_map.count(cmd) > 0) {
00227 colvarscript::command const c = cmd_str_map[std::string(cmd)];
00228 return cmd_n_args_min[c];
00229 }
00230 cvm::error("Error: command "+std::string(cmd)+
00231 " is not implemented.\n", COLVARS_INPUT_ERROR);
00232 return -1;
00233 }
00234
00235
00236 int colvarscript::get_command_n_args_max(char const *cmd)
00237 {
00238 if (cmd_str_map.count(cmd) > 0) {
00239 colvarscript::command const c = cmd_str_map[std::string(cmd)];
00240 return cmd_n_args_max[c];
00241 }
00242 cvm::error("Error: command "+std::string(cmd)+
00243 " is not implemented.\n", COLVARS_INPUT_ERROR);
00244 return -1;
00245 }
00246
00247
00248 char const *colvarscript::get_command_full_help(char const *cmd)
00249 {
00250 if (cmd_str_map.count(cmd) > 0) {
00251 colvarscript::command const c = cmd_str_map[std::string(cmd)];
00252 return cmd_full_help[c].c_str();
00253 }
00254 cvm::error("Error: command "+std::string(cmd)+
00255 " is not implemented.\n", COLVARS_INPUT_ERROR);
00256 return NULL;
00257 }
00258
00259
00260 std::string colvarscript::get_command_cmdline_syntax(colvarscript::Object_type t,
00261 colvarscript::command cmd)
00262 {
00263 std::string const prefix = get_cmd_prefix(t);
00264 std::string const cmdstr(cmd_names[cmd]);
00265
00266
00267 std::string const cmdline_cmd(cmdstr, prefix.size());
00268 std::string cmdline_args;
00269
00270 size_t i;
00271 for (i = 0; i < cmd_n_args_min[cmd]; i++) {
00272 std::string const &arghelp = cmd_arghelp[cmd][i];
00273 size_t space = arghelp.find(" : ");
00274 cmdline_args += " <"+cmd_arghelp[cmd][i].substr(0, space)+">";
00275 }
00276 for (i = cmd_n_args_min[cmd]; i < cmd_n_args_max[cmd]; i++) {
00277 std::string const &arghelp = cmd_arghelp[cmd][i];
00278 size_t space = arghelp.find(" : ");
00279 cmdline_args += " ["+cmd_arghelp[cmd][i].substr(0, space)+"]";
00280 }
00281
00282 switch (t) {
00283 case use_module:
00284 return std::string("cv "+cmdline_cmd+cmdline_args); break;
00285 case use_colvar:
00286 return std::string("cv colvar name "+cmdline_cmd+cmdline_args); break;
00287 case use_bias:
00288 return std::string("cv bias name "+cmdline_cmd+cmdline_args); break;
00289 default:
00290
00291 return std::string("");
00292 }
00293
00294 return std::string("");
00295 }
00296
00297
00298 std::string colvarscript::get_cmdline_help_summary(colvarscript::Object_type t)
00299 {
00300 std::string output;
00301 output += "List of commands:\n\n";
00302
00303 for (size_t i = 0; i < cmd_help.size(); i++) {
00304 std::string const prefix = get_cmd_prefix(t);
00305 command const c = cmd_str_map[std::string(cmd_names[i])];
00306 if (std::string(cmd_names[i], prefix.size()) == prefix) {
00307 output += get_command_cmdline_syntax(t, c)+std::string("\n");
00308 }
00309 }
00310 if (t == use_module) {
00311 output += "\nFor detailed help on each command use:\n"
00312 " cv help <command>\n";
00313 output += "\nTo list all commands acting on collective variables use:\n"
00314 " cv help colvar\n";
00315 output += "\nTo list all commands acting on biases use:\n"
00316 " cv help bias\n";
00317 }
00318 if (t == use_colvar) {
00319 output += "\nFor detailed help on each command use:\n"
00320 " cv colvar name help <command> (\"name\" does not need to exist)\n";
00321 }
00322 if (t == use_bias) {
00323 output += "\nFor detailed help on each command use:\n"
00324 " cv bias name help <command> (\"name\" does not need to exist)\n";
00325 }
00326 return output;
00327 }
00328
00329
00330 std::string colvarscript::get_command_cmdline_help(colvarscript::Object_type t,
00331 std::string const &cmd)
00332 {
00333 std::string const cmdkey(get_cmd_prefix(t)+cmd);
00334 if (cmd_str_map.count(cmdkey) > 0) {
00335 command const c = cmd_str_map[cmdkey];
00336 return get_command_cmdline_syntax(t, c)+"\n\n"+
00337 get_command_full_help(cmd_names[c]);
00338 }
00339 cvm::set_error_bits(COLVARS_INPUT_ERROR);
00340 return std::string("Could not find scripting command \""+cmd+"\".");
00341 }
00342
00343
00344 int colvarscript::run(int objc, unsigned char *const objv[])
00345 {
00346 clear_str_result();
00347
00348 if (cvm::debug()) {
00349 cvm::log("Called script run with " + cvm::to_str(objc) + " args:");
00350 for (int i = 0; i < objc; i++) {
00351 cvm::log(obj_to_str(objv[i]));
00352 }
00353 }
00354
00355 if (objc < 2) {
00356 set_result_str("No commands given: use \"cv help\" "
00357 "for a list of commands.");
00358 return COLVARSCRIPT_ERROR;
00359 }
00360
00361
00362 std::string const main_cmd(std::string(obj_to_str(objv[0])));
00363
00364
00365 std::string const cmd(obj_to_str(objv[1]));
00366
00367
00368 std::string cmdline(main_cmd+std::string(" ")+cmd);
00369
00370
00371 int (*cmd_fn)(void *, int, unsigned char * const *) = NULL;
00372
00373
00374 void *obj_for_cmd = NULL;
00375
00376 if (cmd == "colvar") {
00377
00378 if (objc < 4) {
00379 add_error_msg("Missing parameters: use \""+main_cmd+
00380 " help colvar\" for a summary");
00381 return COLVARSCRIPT_ERROR;
00382 }
00383 std::string const name(obj_to_str(objv[2]));
00384 std::string const subcmd(obj_to_str(objv[3]));
00385 obj_for_cmd = reinterpret_cast<void *>(cvm::colvar_by_name(name));
00386 if (obj_for_cmd == NULL) {
00387 if (subcmd != std::string("help")) {
00388
00389 add_error_msg("Colvar not found: " + name);
00390 return COLVARSCRIPT_ERROR;
00391 }
00392 }
00393 cmd_fn = get_cmd_fn(get_cmd_prefix(use_colvar)+subcmd);
00394 cmdline += std::string(" name ")+subcmd;
00395 if (objc > 4) {
00396 cmdline += " ...";
00397 }
00398
00399 } else if (cmd == "bias") {
00400
00401 if (objc < 4) {
00402 add_error_msg("Missing parameters: use \""+main_cmd+
00403 " help bias\" for a summary");
00404 return COLVARSCRIPT_ERROR;
00405 }
00406 std::string const name(obj_to_str(objv[2]));
00407 std::string const subcmd(obj_to_str(objv[3]));
00408 obj_for_cmd = reinterpret_cast<void *>(cvm::bias_by_name(name));
00409 if (obj_for_cmd == NULL) {
00410 if ((subcmd == "") || (subcmd != std::string("help"))) {
00411
00412 add_error_msg("Bias not found: " + name);
00413 return COLVARSCRIPT_ERROR;
00414 }
00415 }
00416 cmd_fn = get_cmd_fn(get_cmd_prefix(use_bias)+subcmd);
00417 cmdline += std::string(" name ")+subcmd;
00418 if (objc > 4) {
00419 cmdline += " ...";
00420 }
00421
00422 } else {
00423
00424 cmd_fn = get_cmd_fn(get_cmd_prefix(use_module)+cmd);
00425 obj_for_cmd = reinterpret_cast<void *>(this);
00426
00427 if (objc > 2) {
00428 cmdline += " ...";
00429 }
00430 }
00431
00432 int error_code = COLVARS_OK;
00433
00434
00435 if (cmd_fn) {
00436 error_code = (*cmd_fn)(obj_for_cmd, objc, objv);
00437 } else {
00438 add_error_msg("Syntax error: "+cmdline+"\n"
00439 " Run \"cv help\" or \"cv help <command>\" "
00440 "to get the correct syntax.\n");
00441 error_code = COLVARSCRIPT_ERROR;
00442 }
00443
00444 return error_code;
00445 }
00446
00447
00448 char *colvarscript::obj_to_str(unsigned char *obj)
00449 {
00450 char *strobj = reinterpret_cast<char *>(obj);
00451 if (cvm::debug()) {
00452 cvm::log("Using simple-cast script::obj_to_str(): result = \"" +
00453 (strobj ? std::string(strobj) : std::string("(null)")) + "\"");
00454 }
00455 return strobj;
00456 }
00457
00458
00459 std::vector<std::string> colvarscript::obj_to_str_vector(unsigned char *obj)
00460 {
00461 if (cvm::debug()) {
00462 cvm::log("Using simple-cast colvarscript::obj_to_str_vector().\n");
00463 }
00464
00465 std::vector<std::string> new_result;
00466 std::string const str(reinterpret_cast<char *>(obj));
00467
00468
00469
00470
00471 for (size_t i = 0; i < str.length(); i++) {
00472 char const c = str[i];
00473 if (c == '\"') {
00474 i++;
00475 if (i >= str.length()) {
00476 cvm::error("Error: could not split the following string:\n"+
00477 str+"\n", COLVARS_INPUT_ERROR);
00478 break;
00479 }
00480 new_result.push_back(std::string(""));
00481 while (str[i] != '\"') {
00482 new_result.back().append(1, str[i]);
00483 if (i >= str.length()) {
00484 cvm::error("Error: could not split the following string:\n"+
00485 str+"\n", COLVARS_INPUT_ERROR);
00486 break;
00487 } else {
00488 i++;
00489 }
00490 }
00491 }
00492 }
00493
00494 if (cvm::debug()) {
00495 cvm::log("result = "+cvm::to_str(new_result)+".\n");
00496 }
00497
00498 return new_result;
00499 }
00500
00501
00502 int colvarscript::proc_features(colvardeps *obj,
00503 int objc, unsigned char *const objv[]) {
00504
00505
00506 std::string const subcmd(obj_to_str(objv[3]));
00507
00508 if (cvm::debug()) {
00509 cvm::log("Called proc_features() with " + cvm::to_str(objc) + " args:");
00510 for (int i = 0; i < objc; i++) {
00511 cvm::log(obj_to_str(objv[i]));
00512 }
00513 }
00514
00515 if ((subcmd == "get") || (subcmd == "set")) {
00516 std::vector<colvardeps::feature *> const &features = obj->features();
00517 std::string const req_feature(obj_to_str(objv[4]));
00518 colvardeps::feature *f = NULL;
00519 int fid = 0;
00520 for (fid = 0; fid < int(features.size()); fid++) {
00521 if (features[fid]->description ==
00522 colvarparse::to_lower_cppstr(req_feature)) {
00523 f = features[fid];
00524 break;
00525 }
00526 }
00527
00528 if (f == NULL) {
00529
00530 add_error_msg("Error: feature \""+req_feature+"\" does not exist.\n");
00531 return COLVARSCRIPT_ERROR;
00532
00533 } else {
00534
00535 if (! obj->is_available(fid)) {
00536 add_error_msg("Error: feature \""+req_feature+"\" is unavailable.\n");
00537 return COLVARSCRIPT_ERROR;
00538 }
00539
00540 if (subcmd == "get") {
00541 set_result_str(cvm::to_str(obj->is_enabled(fid) ? 1 : 0));
00542 return COLVARS_OK;
00543 }
00544
00545 if (subcmd == "set") {
00546 if (objc == 6) {
00547 std::string const yesno =
00548 colvarparse::to_lower_cppstr(std::string(obj_to_str(objv[5])));
00549 if ((yesno == std::string("yes")) ||
00550 (yesno == std::string("on")) ||
00551 (yesno == std::string("1"))) {
00552 obj->enable(fid);
00553 return COLVARS_OK;
00554 } else if ((yesno == std::string("no")) ||
00555 (yesno == std::string("off")) ||
00556 (yesno == std::string("0"))) {
00557 obj->disable(fid);
00558 return COLVARS_OK;
00559 }
00560 }
00561 add_error_msg("Missing value when setting feature \""+req_feature+
00562 "\".\n");
00563 return COLVARSCRIPT_ERROR;
00564 }
00565 }
00566 }
00567
00568
00569 return COLVARSCRIPT_ERROR;
00570 }
00571
00572
00573 int colvarscript::unsupported_op()
00574 {
00575 return cvm::error("Error: unsupported script operation.\n",
00576 COLVARS_NOT_IMPLEMENTED);
00577 }
00578
00579
00580 int colvarscript::set_result_str(std::string const &s)
00581 {
00582 if (cvm::get_error() != COLVARS_OK) {
00583
00584 modify_str_result() += s;
00585 } else {
00586 modify_str_result() = s;
00587 }
00588 return COLVARS_OK;
00589 }
00590
00591
00592 void colvarscript::add_error_msg(std::string const &s)
00593 {
00594 modify_str_result() += s;
00595
00596 if (s[s.size()-1] != '\n') {
00597 modify_str_result() += "\n";
00598 }
00599 }
00600
00601
00602 int colvarscript::clear_str_result()
00603 {
00604 modify_str_result().clear();
00605 return COLVARS_OK;
00606 }
00607
00608
00609 extern "C"
00610 int run_colvarscript_command(int objc, unsigned char *const objv[])
00611 {
00612 colvarmodule *cv = cvm::main();
00613 colvarscript *script = cv ? cv->proxy->script : NULL;
00614 if (!script) {
00615 cvm::error("Called run_colvarscript_command without a script object.\n",
00616 COLVARS_BUG_ERROR);
00617 return -1;
00618 }
00619 int retval = script->run(objc, objv);
00620 return retval;
00621 }
00622
00623
00624 extern "C"
00625 const char * get_colvarscript_result()
00626 {
00627 colvarscript *script = colvarscript_obj();
00628 if (!script) {
00629 cvm::error("Called get_colvarscript_result without a script object.\n");
00630 return NULL;
00631 }
00632 return script->str_result().c_str();
00633 }
00634
00635
00636 #if defined(COLVARS_TCL)
00637
00638 #if defined(VMDTCL)
00639
00640 int tcl_colvars_vmd_init(Tcl_Interp *interp, int molid);
00641 #endif
00642
00643 #if !defined(VMDTCL) && !defined(NAMD_TCL)
00644
00645 extern "C" {
00646 int Colvars_Init(Tcl_Interp *interp) {
00647 colvarproxy *proxy = new colvarproxy();
00648 colvarmodule *colvars = new colvarmodule(proxy);
00649 proxy->set_tcl_interp(interp);
00650 proxy->colvars = colvars;
00651 Tcl_CreateObjCommand(interp, "cv", tcl_run_colvarscript_command,
00652 (ClientData *) NULL, (Tcl_CmdDeleteProc *) NULL);
00653 Tcl_EvalEx(interp, "package provide colvars", -1, 0);
00654 return TCL_OK;
00655 }
00656 }
00657 #endif
00658
00659
00660 extern "C" int tcl_run_colvarscript_command(ClientData ,
00661 Tcl_Interp *my_interp,
00662 int objc, Tcl_Obj *const objv[])
00663 {
00664 colvarmodule *colvars = cvm::main();
00665
00666 if (!colvars) {
00667 #if defined(VMDTCL)
00668
00669 if (objc == 2) {
00670 if (!strcmp(Tcl_GetString(objv[1]), "molid")) {
00671
00672 Tcl_SetResult(my_interp, (char *) "-1", TCL_STATIC);
00673 }
00674 if (!strcmp(Tcl_GetString(objv[1]), "delete") ||
00675 !strcmp(Tcl_GetString(objv[1]), "reset")) {
00676
00677 Tcl_SetResult(my_interp, NULL, TCL_STATIC);
00678 }
00679 if (!strcmp(Tcl_GetString(objv[1]), "help")) {
00680
00681 Tcl_SetResult(my_interp,
00682 (char *) "First, setup the Colvars module with: "
00683 "cv molid <id>|top", TCL_STATIC);
00684 }
00685 return TCL_OK;
00686 }
00687
00688 if (objc >= 3) {
00689
00690 if (!strcmp(Tcl_GetString(objv[1]), "molid")) {
00691 int molid = -(1<<16);
00692 if (strcmp(Tcl_GetString(objv[2]), "top")) {
00693
00694 Tcl_GetIntFromObj(my_interp, objv[2], &molid);
00695 }
00696 return tcl_colvars_vmd_init(my_interp, molid);
00697 } else {
00698 Tcl_SetResult(my_interp, (char *) "Syntax error. First, setup the Colvars module with cv molid <id>|top", TCL_STATIC);
00699 return TCL_ERROR;
00700 }
00701 }
00702
00703 Tcl_SetResult(my_interp, (char *) "First, setup the Colvars module with: "
00704 "cv molid <id>|top", TCL_STATIC);
00705
00706 #else
00707 Tcl_SetResult(my_interp,
00708 const_cast<char *>("Error: Colvars module not yet initialized"),
00709 TCL_STATIC);
00710 #endif
00711 return TCL_ERROR;
00712 }
00713
00714 colvarproxy *proxy = colvars->proxy;
00715 Tcl_Interp *interp = my_interp ? my_interp : proxy->get_tcl_interp();
00716 colvarscript *script = colvarscript_obj();
00717 if (!script) {
00718 char const *errstr = "Called tcl_run_colvarscript_command "
00719 "without a Colvars script interface set up.\n";
00720 Tcl_SetResult(interp, const_cast<char *>(errstr), TCL_VOLATILE);
00721 return TCL_ERROR;
00722 }
00723
00724 cvm::clear_error();
00725
00726 unsigned char * arg_pointers_[100];
00727 if (objc > 100) {
00728 std::string const errstr = "Too many positional arguments ("+
00729 cvm::to_str(objc)+") passed to the \"cv\" command.\n";
00730 Tcl_SetResult(interp, const_cast<char *>(errstr.c_str()), TCL_VOLATILE);
00731 return TCL_ERROR;
00732 }
00733 for (int i = 0; i < objc; i++) {
00734 arg_pointers_[i] = reinterpret_cast<unsigned char *>(const_cast<char *>(proxy->tcl_get_str(objv[i])));
00735 }
00736 int retval = script->run(objc, arg_pointers_);
00737
00738 std::string result = proxy->get_error_msgs() + script->str_result();
00739
00740 Tcl_SetResult(interp, const_cast<char *>(result.c_str()),
00741 TCL_VOLATILE);
00742
00743 if (proxy->delete_requested()) {
00744 if (!proxy->simulation_running()) {
00745
00746 Tcl_SetResult(interp,
00747 const_cast<char *>("Deleting Colvars module"
00748 ": to recreate, use cv molid <molecule ID>"),
00749 TCL_STATIC);
00750 }
00751 delete proxy;
00752 proxy = NULL;
00753 }
00754
00755 return (retval == COLVARS_OK) ? TCL_OK : TCL_ERROR;
00756 }
00757
00758 #endif // #if defined(COLVARS_TCL)
00759
00760
00761
00762
00763 int colvarscript::set_result_text_from_str(std::string const &x_str,
00764 unsigned char *obj) {
00765 if (obj) {
00766 strcpy(reinterpret_cast<char *>(obj), x_str.c_str());
00767 } else {
00768 set_result_str(x_str);
00769 }
00770 return COLVARS_OK;
00771 }
00772
00773
00774
00775 template <typename T>
00776 int colvarscript::set_result_text(T const &x, unsigned char *obj) {
00777 std::string const x_str = x.to_simple_string();
00778 return set_result_text_from_str(x_str, obj);
00779 }
00780
00781
00782 template <typename T>
00783 int colvarscript::pack_vector_elements_text(std::vector<T> const &x,
00784 std::string &x_str) {
00785 x_str.clear();
00786 for (size_t i = 0; i < x.size(); ++i) {
00787 if (i > 0) x_str.append(1, ' ');
00788 x_str += cvm::to_str(x[i]);
00789 }
00790 return COLVARS_OK;
00791 }
00792
00793
00794
00795
00796 template <>
00797 int colvarscript::set_result_text(int const &x, unsigned char *obj) {
00798 std::string const x_str = cvm::to_str(x);
00799 return set_result_text_from_str(x_str, obj);
00800 }
00801
00802 template <>
00803 int colvarscript::set_result_text(std::vector<int> const &x,
00804 unsigned char *obj) {
00805 std::string x_str("");
00806 pack_vector_elements_text<int>(x, x_str);
00807 return set_result_text_from_str(x_str, obj);
00808 }
00809
00810
00811 template <>
00812 int colvarscript::set_result_text(long int const &x, unsigned char *obj) {
00813 std::string const x_str = cvm::to_str(x);
00814 return set_result_text_from_str(x_str, obj);
00815 }
00816
00817 template <>
00818 int colvarscript::set_result_text(std::vector<long int> const &x,
00819 unsigned char *obj) {
00820 std::string x_str("");
00821 pack_vector_elements_text<long int>(x, x_str);
00822 return set_result_text_from_str(x_str, obj);
00823 }
00824
00825
00826 template <>
00827 int colvarscript::set_result_text(cvm::real const &x, unsigned char *obj) {
00828 std::string const x_str = cvm::to_str(x);
00829 return set_result_text_from_str(x_str, obj);
00830 }
00831
00832 template <>
00833 int colvarscript::set_result_text(std::vector<cvm::real> const &x,
00834 unsigned char *obj) {
00835 std::string x_str("");
00836 pack_vector_elements_text<cvm::real>(x, x_str);
00837 return set_result_text_from_str(x_str, obj);
00838 }
00839
00840
00841
00842
00843
00844 template <>
00845 int colvarscript::set_result_text(std::vector<cvm::rvector> const &x,
00846 unsigned char *obj) {
00847 std::string x_str("");
00848 for (size_t i = 0; i < x.size(); i++) {
00849 if (i > 0) x_str.append(1, ' ');
00850 x_str += "{ "+x[i].to_simple_string()+" }";
00851 }
00852 return set_result_text_from_str(x_str, obj);
00853 }
00854
00855 template <>
00856 int colvarscript::set_result_text(std::vector<colvarvalue> const &x,
00857 unsigned char *obj) {
00858 std::string x_str("");
00859 for (size_t i = 0; i < x.size(); i++) {
00860 if (i > 0) x_str.append(1, ' ');
00861 x_str += "{ "+x[i].to_simple_string()+" }";
00862 }
00863 return set_result_text_from_str(x_str, obj);
00864 }
00865
00866
00867
00868
00869 int colvarscript::set_result_int(int const &x, unsigned char *obj) {
00870 return set_result_text<int>(x, obj);
00871 }
00872
00873 int colvarscript::set_result_int_vec(std::vector<int> const &x,
00874 unsigned char *obj) {
00875 return set_result_text< std::vector<int> >(x, obj);
00876 }
00877
00878
00879 int colvarscript::set_result_long_int(long int const &x, unsigned char *obj) {
00880 return set_result_text<long int>(x, obj);
00881 }
00882
00883 int colvarscript::set_result_long_int_vec(std::vector<long int> const &x,
00884 unsigned char *obj) {
00885 return set_result_text< std::vector<long int> >(x, obj);
00886 }
00887
00888
00889 int colvarscript::set_result_real(cvm::real const &x, unsigned char *obj) {
00890 return set_result_text<cvm::real>(x, obj);
00891 }
00892
00893 int colvarscript::set_result_real_vec(std::vector<cvm::real> const &x,
00894 unsigned char *obj) {
00895 return set_result_text< std::vector<cvm::real> >(x, obj);
00896 }
00897
00898
00899 int colvarscript::set_result_rvector(cvm::rvector const &x, unsigned char *obj) {
00900 return set_result_text<cvm::rvector>(x, obj);
00901 }
00902
00903 int colvarscript::set_result_rvector_vec(std::vector<cvm::rvector> const &x,
00904 unsigned char *obj) {
00905 return set_result_text< std::vector<cvm::rvector> >(x, obj);
00906 }
00907
00908
00909 int colvarscript::set_result_colvarvalue(colvarvalue const &x,
00910 unsigned char *obj) {
00911 return set_result_text<colvarvalue>(x, obj);
00912 }
00913
00914 int colvarscript::set_result_colvarvalue_vec(std::vector<colvarvalue> const &x,
00915 unsigned char *obj) {
00916 return set_result_text< std::vector<colvarvalue> >(x, obj);
00917 }