3.6 Class TclCommand

This class (TclCommand../Tcl/Tcl.h) provides just the mechanism for ns to export simple commands to the interpreter, that can then be executed within a global context by the interpreter. There are two functions defined in ~ns/misc.cc: ns-random and ns-version. These two functions are initialized by the function init_misc../ns-2/misc.cc::init_misc, defined in ~ns/misc.cc; init_misc is invoked by Tcl_AppInit../ns-2/ns_tclsh.cc::Tcl_AppInit during startup.

Note that, it is generally not advisable to construct top-level commands that are available to the user. We now describe how to define a new command using the example class say_hello. The example defines the command hi, to print the string ``hello world'', followed by any command line arguments specified by the user. For example,

            % hi this is ns [ns-version]
            hello world, this is ns 2.0a12
  1. The command must be defined within a class derived from the TclCommand../Tcl/Tcl.h. The class definition is:
            class say\_hello : public TclCommand {
            public:
                    say\_hello();
                    int command(int argc, const char*const* argv);
            };
    
  2. The constructor for the class must invoke the TclCommand constructor../Tcl/Tcl.ccTclCommand::TclCommand with the command as argument; ,
            say\_hello() : TclCommand("hi") {}
    
    The TclCommand constructor sets up "hi" as a global procedure that invokes []TclCommand::dispatch_cmd../ns-2/Tcl.ccTclCommand::dispatch_cmd.
  3. The method []command must perform the desired action.

    The method is passed two arguments. The first argument, argc, contains the number of actual arguments passed by the user.

    The actual arguments passed by the user are passed as an argument vector (argv) and contains the following:

    -- argv[0] contains the name of the command (hi).

    -- argv[1...(argc - 1)] contains additional arguments specified on the command line by the user.

    []command is invoked by []dispatch_cmd.

            #include \<streams.h\>        /* because we are using stream I/O /
            
            int say_hello::command(int argc, const char*const* argv) {
                    cout \<\< "hello world:";
                    for (int i = 1; i \< argc; i++)
                            cout \<\< ' ' \<\< argv[i];
                    cout \<\< '\bs n';
                    return TCL_OK;
            }
    
  4. Finally, we require an instance of this class. TclCommand instances are created in the routine init_misc../ns-2/misc.cc::init_misc.
            new say\_hello;
    
Note that there used to be more functions such as ns-at and ns-now that were accessible in this manner. Most of these functions have been subsumed into existing classes. In particular, ns-at and ns-now are accessible through the scheduler TclObject../ns-2/scheduler.ccScheduler::command. These functions are defined in ~ns/tcl/lib/ns-lib.tcl.
            % set ns [new Simulator]    # get new instance of simulator;
            _o1
            % $ns now                   # query simulator for current time;
            0
            % $ns at \ldots             # specify at operations for simulator;
            \ldots

Tom Henderson 2011-11-05