TclCommand.h

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 #ifndef _OASYS_TCL_COMMAND_H_
00039 #define _OASYS_TCL_COMMAND_H_
00040 
00041 #include <list> 
00042 #include <map>
00043 #include <string>
00044 
00045 #include <stdarg.h>
00046 #include <tcl.h>
00047 
00048 #include <netinet/in.h>
00049 
00050 #include "../compat/inttypes.h"
00051 #include "../debug/DebugUtils.h"
00052 #include "../util/Singleton.h"
00053 #include "../util/StringBuffer.h"
00054 
00055 namespace oasys {
00056 
00057 // forward decls
00058 class TclCommandInterp;
00059 class TclCommand;
00060 class Lock;
00061 
00065 typedef std::list<TclCommand*> TclCommandList;
00066 
00073 class TclCommandInterp : public Logger {
00074 public:
00080     static TclCommandInterp* instance() {
00081         ASSERT(instance_ != NULL);
00082         return instance_;
00083     }
00084 
00088     static int init(char* objv0, bool no_default_cmds = false);
00089 
00093     static void shutdown();
00094 
00099     int exec_file(const char* file);
00100 
00106     int exec_command(const char* command);
00107 
00111     void command_server(const char* prompt, in_addr_t addr, u_int16_t port);
00112 
00116     void command_loop(const char* prompt);
00117 
00121     void event_loop();
00122 
00127     void exit_event_loop();
00128 
00138     static int tcl_cmd(ClientData client_data, Tcl_Interp* interp,
00139                        int objc, Tcl_Obj* const* objv);
00140 
00144     void reg(TclCommand* module);
00145 
00151     bool lookup(const char* command, TclCommand** commandp = NULL);
00152 
00158     static void auto_reg(TclCommand* module);
00159 
00163     void reg_atexit(void(*fn)(void*), void* data);
00164 
00168     void set_result(const char* result);
00169 
00173     void set_objresult(Tcl_Obj* obj);
00174 
00178     void append_result(const char* result);
00179 
00183     void resultf(const char* fmt, ...) PRINTFLIKE(2, 3);
00184 
00188     void append_resultf(const char* fmt, ...) PRINTFLIKE(2, 3);
00189     
00193     void vresultf(const char* fmt, va_list ap, bool append);
00194 
00205     void wrong_num_args(int objc, const char** objv, int parsed,
00206                         int min, int max);
00207 
00218     void wrong_num_args(int objc, Tcl_Obj** objv, int parsed,
00219                         int min, int max);
00220 
00224     const char* get_result();
00225 
00229     const TclCommandList* commands() { return &commands_; }
00230     
00231 protected:
00235     TclCommandInterp();
00236 
00240     int do_init(char* objv0, bool no_default_cmds);
00241     
00245     ~TclCommandInterp();
00246     
00247     Lock* lock_;                        
00248     Tcl_Interp* interp_;                
00249 
00250     TclCommandList commands_;           
00251     static TclCommandList* auto_reg_;   
00252 
00253     static TclCommandInterp* instance_; 
00254 };
00255 
00265 class TclCommand : public Logger {
00266 public:
00273     TclCommand(const char* name, const char* theNamespace = 0);
00274     virtual ~TclCommand();
00275     
00285     virtual int exec(int objc, Tcl_Obj** objv, Tcl_Interp* interp);
00286 
00296     virtual int exec(int argc, const char** argv, Tcl_Interp* interp);
00297 
00304     virtual int cmd_info(Tcl_Interp* interp);
00305 
00315     virtual int cmd_set(int objc, Tcl_Obj** objv, Tcl_Interp* interp);
00316     
00320     const char* name() const { return name_.c_str(); }
00321 
00325     virtual const char* help_string() { return help_.c_str(); }
00326 
00330     bool hasBindings() { return ! bindings_.empty(); }
00331 
00332 protected:
00333     friend class TclCommandInterp;
00334     
00335     std::string name_;          
00336     StringBuffer help_;         
00337     bool do_builtins_;          
00338 
00339 
00343     enum type_t {
00344         BINDING_INVALID = -1,
00345         BINDING_INT = 1,
00346         BINDING_INT16,
00347         BINDING_DOUBLE, 
00348         BINDING_BOOL, 
00349         BINDING_STRING, 
00350         BINDING_ADDR
00351     };
00352     
00356     struct Binding {
00357         Binding(type_t type, void* val)
00358             : type_(type)
00359         {
00360             val_.voidval_ = val;
00361         }
00362 
00363         type_t type_;                   
00364         
00365         union {
00366             void*       voidval_;
00367             int*        intval_;
00368             int16_t*    int16val_;
00369             double*     doubleval_;
00370             bool*       boolval_;
00371             in_addr_t*  addrval_;
00372             std::string* stringval_;
00373         } val_;                         
00374     };
00375     
00379     typedef std::map<std::string, Binding*> BindingTable;
00380 
00384     BindingTable bindings_;
00385    
00389     void bind_i(const char* name, int* val, const char *help = NULL);
00390     void bind_i(const char* name, int* val, int initval,
00391                 const char* help = NULL);
00392 
00396     void bind_i(const char* name, int16_t* val, const char *help = NULL);
00397     void bind_i(const char* name, int16_t* val, int16_t initval,
00398                 const char* help = NULL);
00399     
00401 
00404     void bind_i(const char* name, unsigned int* val,
00405                 const char* help = NULL)
00406     {
00407         bind_i(name, (int*)val, help);
00408     }
00409 
00410     void bind_i(const char* name, unsigned int* val, unsigned int initval,
00411                 const char* help = NULL)
00412     {
00413         bind_i(name, (int*)val, initval, help);
00414     }
00415     
00416     void bind_i(const char* name, u_int16_t* val,
00417                 const char* help = NULL)
00418     {
00419         bind_i(name, (int16_t*)val, help);
00420     }
00421 
00422     void bind_i(const char* name, u_int16_t* val, u_int16_t initval,
00423                 const char* help = NULL)
00424     {
00425         bind_i(name, (int16_t*)val, initval, help);
00426     }
00427     
00429     
00433     void bind_d(const char* name, double* val, const char* help = NULL);
00434     void bind_d(const char* name, double* val, double initval,
00435                 const char* help = NULL);
00436 
00440     void bind_b(const char* name, bool* val, const char* help = NULL);
00441     void bind_b(const char* name, bool* val, bool initval,
00442                 const char* help = NULL);
00443     
00447     void bind_s(const char* name, std::string* str,
00448                 const char* initval, const char* help);
00449 
00450     void bind_s(const char* name, std::string* str,
00451                 const char* help = NULL)
00452     {
00453         return bind_s(name, str, NULL, help);
00454     }
00455 
00460     void bind_addr(const char* name, in_addr_t* addrp,
00461                    const char* help = NULL);
00462     void bind_addr(const char* name, in_addr_t* addrp,
00463                    in_addr_t initval, const char* help = NULL);
00464 
00468     void unbind(const char* name);
00469     
00473     void set_result(const char* result)
00474     {
00475         TclCommandInterp::instance()->set_result(result);
00476     }
00477 
00481     void set_objresult(Tcl_Obj* obj)
00482     {
00483         TclCommandInterp::instance()->set_objresult(obj);
00484     }
00485 
00489     void append_result(const char* result)
00490     {
00491         TclCommandInterp::instance()->append_result(result);
00492     }
00493 
00497     void resultf(const char* fmt, ...) PRINTFLIKE(2, 3);
00498 
00502     void append_resultf(const char* fmt, ...) PRINTFLIKE(2, 3);
00503 
00514     void wrong_num_args(int objc, const char** objv, int parsed,
00515                         int min, int max)
00516     {
00517         TclCommandInterp::instance()->
00518             wrong_num_args(objc, objv, parsed, min, max);
00519     }
00520 
00531     void wrong_num_args(int objc, Tcl_Obj** objv, int parsed,
00532                         int min, int max)
00533     {
00534         TclCommandInterp::instance()->
00535             wrong_num_args(objc, objv, parsed, min, max);
00536     }
00537     
00542     void add_to_help(const char* subcmd, const char* help_str)
00543     {
00544         help_.appendf("%s %s\n", name(), subcmd);
00545         if (help_str) {
00546             help_.appendf("\t%s\n", help_str);
00547         }
00548         help_.append("\n");
00549     }
00550 };
00551 
00555 class AutoTclCommand : public TclCommand {
00556 public:
00557     AutoTclCommand(const char* name, const char* theNamespace = 0)
00558         : TclCommand(name, theNamespace)
00559     {
00560         TclCommandInterp::auto_reg(this);
00561     }
00562 };
00563 
00564 } // namespace oasys
00565 
00566 #endif /* _OASYS_TCL_COMMAND_H_ */

Generated on Fri Dec 22 14:48:01 2006 for DTN Reference Implementation by  doxygen 1.5.1