Version 1 of command dispatcher

Updated 2014-11-16 20:27:41 by MHo

Simple mechanism to dispatch procs corresponding to given commands and subcommands. Commands and subcommands can be abbreviated. Command 'help errorlevel' is mapped to a procedure '.help.errorlevel', e.g. 'he err' does the job, too.

# Example

proc .help {} {
}

proc .help.errorlevel {} {
}

proc dispatch {allowed cmdwords} {
     if {[llength $cmdwords] == 0} {
        puts stderr "command missing!"
        puts stderr "Possible commands are:"
        lmap l $allowed {puts stderr [lindex $l 0]}
        exit 250
     }
     foreach word $cmdwords {
          set cmdword [lsearch -glob -nocase -index 0 -inline $allowed $word*]
          if {[llength $cmdword]} {
             append p .  [lindex $cmdword 0]; # expanded command name
             set allowed [lindex $cmdword 1]; # subcommands
          } else {
             puts stderr "Unknown (sub-)command: $word"
             puts stderr "Possible (sub-)commands are:"
             lmap l $allowed {puts stderr [lindex $l 0]}
             exit 250
          }
     }
     if {[catch {tailcall $p} rc]} {
        puts stderr "cmd '$cmdwords' noch implemented yet!"
        exit 250
     }
}

# Give the list of allowed commands and subcommands, and the current commandwords. The format of the list is:
#  each element of the list is one command
#  each element can in turn be a list; element #1 of the list is the command itself, element #2 is a list of possible subcommands
#  and so on
dispatch {
   {help {errorlevel inifile examples}}
   list
} $argv

All that's to do to implement a new command is to add it to the list given to dispatch and implement the corresponding proc. I found that simpler than namespace ensemble which confuses me still.