00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef _OASYS_TCL_COMMAND_H_
00018 #define _OASYS_TCL_COMMAND_H_
00019
00020 #include <list>
00021 #include <map>
00022 #include <string>
00023
00024 #include <stdarg.h>
00025 #include <tcl.h>
00026
00027 #include <netinet/in.h>
00028
00029 #include "../compat/inttypes.h"
00030 #include "../debug/DebugUtils.h"
00031 #include "../util/Options.h"
00032 #include "../util/Singleton.h"
00033 #include "../util/StringBuffer.h"
00034
00035 namespace oasys {
00036
00037
00038 class Lock;
00039 class Opt;
00040 class TclCommandInterp;
00041 class TclCommand;
00042
00046 typedef std::list<TclCommand*> TclCommandList;
00047
00054 class TclCommandInterp : public Logger {
00055 public:
00061 static TclCommandInterp* instance() {
00062 ASSERT(instance_ != NULL);
00063 return instance_;
00064 }
00065
00069 static int init(char* objv0, bool no_default_cmds = false);
00070
00074 static void shutdown();
00075
00080 int exec_file(const char* file);
00081
00087 int exec_command(const char* command);
00088
00092 void command_server(const char* prompt, in_addr_t addr, u_int16_t port);
00093
00097 void command_loop(const char* prompt);
00098
00102 void event_loop();
00103
00108 void exit_event_loop();
00109
00119 static int tcl_cmd(ClientData client_data, Tcl_Interp* interp,
00120 int objc, Tcl_Obj* const* objv);
00121
00125 void reg(TclCommand* module);
00126
00132 bool lookup(const char* command, TclCommand** commandp = NULL);
00133
00139 static void auto_reg(TclCommand* module);
00140
00144 void reg_atexit(void(*fn)(void*), void* data);
00145
00149 void set_result(const char* result);
00150
00154 void set_objresult(Tcl_Obj* obj);
00155
00159 void append_result(const char* result);
00160
00164 void resultf(const char* fmt, ...) PRINTFLIKE(2, 3);
00165
00169 void append_resultf(const char* fmt, ...) PRINTFLIKE(2, 3);
00170
00181 void wrong_num_args(int objc, const char** objv, int parsed,
00182 int min, int max);
00183
00194 void wrong_num_args(int objc, Tcl_Obj** objv, int parsed,
00195 int min, int max);
00196
00200 const char* get_result();
00201
00205 const TclCommandList* commands() { return &commands_; }
00206
00207 protected:
00211 TclCommandInterp();
00212
00216 int do_init(char* objv0, bool no_default_cmds);
00217
00221 ~TclCommandInterp();
00222
00223 Lock* lock_;
00224 Tcl_Interp* interp_;
00225
00226 TclCommandList commands_;
00227 static TclCommandList* auto_reg_;
00228
00229 static TclCommandInterp* instance_;
00230 };
00231
00241 class TclCommand : public Logger {
00242 public:
00249 TclCommand(const char* name, const char* theNamespace = 0);
00250 virtual ~TclCommand();
00251
00261 virtual int exec(int objc, Tcl_Obj** objv, Tcl_Interp* interp);
00262
00272 virtual int exec(int argc, const char** argv, Tcl_Interp* interp);
00273
00280 virtual int cmd_info(Tcl_Interp* interp);
00281
00291 virtual int cmd_set(int objc, Tcl_Obj** objv, Tcl_Interp* interp);
00292
00296 const char* name() const { return name_.c_str(); }
00297
00301 virtual const char* help_string() { return help_.c_str(); }
00302
00306 bool hasBindings() { return ! bindings_.empty(); }
00307
00308 protected:
00309 friend class TclCommandInterp;
00310
00311 std::string name_;
00312 StringBuffer help_;
00313 bool do_builtins_;
00314
00315
00319 typedef std::map<std::string, Opt*> BindingTable;
00320
00324 BindingTable bindings_;
00325
00329 void bind_var(Opt* opt);
00330
00334 void unbind(const char* name);
00335
00339 void set_result(const char* result)
00340 {
00341 TclCommandInterp::instance()->set_result(result);
00342 }
00343
00347 void set_objresult(Tcl_Obj* obj)
00348 {
00349 TclCommandInterp::instance()->set_objresult(obj);
00350 }
00351
00355 void append_result(const char* result)
00356 {
00357 TclCommandInterp::instance()->append_result(result);
00358 }
00359
00363 void resultf(const char* fmt, ...) PRINTFLIKE(2, 3);
00364
00368 void append_resultf(const char* fmt, ...) PRINTFLIKE(2, 3);
00369
00380 void wrong_num_args(int objc, const char** objv, int parsed,
00381 int min, int max)
00382 {
00383 TclCommandInterp::instance()->
00384 wrong_num_args(objc, objv, parsed, min, max);
00385 }
00386
00397 void wrong_num_args(int objc, Tcl_Obj** objv, int parsed,
00398 int min, int max)
00399 {
00400 TclCommandInterp::instance()->
00401 wrong_num_args(objc, objv, parsed, min, max);
00402 }
00403
00408 void add_to_help(const char* subcmd, const char* help_str)
00409 {
00410 help_.appendf("%s %s\n", name(), subcmd);
00411 if (help_str) {
00412 help_.appendf("\t%s\n", help_str);
00413 }
00414 help_.append("\n");
00415 }
00416 };
00417
00421 class AutoTclCommand : public TclCommand {
00422 public:
00423 AutoTclCommand(const char* name, const char* theNamespace = 0)
00424 : TclCommand(name, theNamespace)
00425 {
00426 TclCommandInterp::auto_reg(this);
00427 }
00428 };
00429
00430 }
00431
00432 #endif