Updated 2015-03-21 07:16:56 by Lorry

Package cmdline is a part of Tcllib. Documentation can be read online at http://core.tcl.tk/tcllib/doc/trunk/embedded/www/tcllib/files/modules/cmdline/cmdline.html, and examples of cmdline usage appear in ftpd, htmlparse, and pop3.

Glenn Jackman offers [1] and [2] as "examples of cmdline in action". (AMG: 404)

The cmdline package can be used for both programs which accept arguments via the argv list as well as procs which have specific needs for argument processing.

12 Jun 2003: Here is an example of its use (http://groups.google.com/groups?th=89144039acd5554b):
    package require cmdline

    proc test {args} {

        # A list of lists where each element specifies an option in the form: flag default comment.
        # If flag ends in ".arg" then the value is taken from the command line otherwise it is a boolean.
        # If flag is of type boolean then second element in the list element is assumed as comment 
        # and third argument is ignored if present.
        # If the flag is non boolean(i.e followed by .arg) then its default value is blank string "" if not given.
        # If boolean flag is present in command line then its value is set as 1 else 0 
        set options {
            {first.arg  1 "1st arg"}
            {second.arg 2 "2nd arg"}
            {third.arg  3 "3rd arg"}
            {fourth.arg 4 "4th arg"}
        }
         
        # cmdline::getoptions will throw an error for unknown option
        array set params [::cmdline::getoptions args $options]

        # do other stuff...
        parray params
    }                
     
    test -fourth last -first one

Here's a portion of another example, this one by [Eric Varsanyi]:
 proc sc_dump {args} {
        set ::argv0 "sc_dump"
        array set arg [::cmdline::getoptions args {
                {v "Verbose"}
                {t "Only dump top 10 LRU"}
                {hit "Sort by hit count"}
                {top.arg end "Dump top N LRU"}
                {main "Dump main cache"}
                {unrunnable "Dump unrunnable cache"}
                {i "Case insensitive expression match"}
                {all "Search entire entry (otherwise SQL only)"}
        }]
        if {$arg(t)} {
                set arg(top) 10
        }

        # Pick cache groups to dump
        set clist {}
        if {$arg(main)} {
                lappend clist main
        }
        if {$arg(unrunnable)} {
                lappend clist unrunnable
        }
        if {[llength $clist] == 0} {
                set clist {main unrunnable}
        }
        ...

cmdline::getoptions args $optlist has a nasty side effect: it removes all of the elements from args.

So, if you want to do anything with the original args after calling getoptions, save args or do it before calling getoptions.

HaO This is by design. If there are any non-flag options, they are left in args. The special flag -- may be used to signal end of flags to.

Example Code:
proc printdata args {
        array set param [::cmdline::getoptions args {\
                        {page.arg  1 "current page"}
                        {pages.arg 1 "number of pages"}
                        } "printdata ?options? Data"]
        if {1 != [llength $args]} {
                return -code error "No data given"
        }
        set param(data) [lindex $args 0]
        # processing here
        parray param
}

which might be called with:
% printdata -pages 2 -- "--Head data to print--"
param(data)  = --Head data to print--
param(page)  = 1
param(pages) = 2

and shows the help message:
% printdata -?
printdata ?options? Data
 -page value          current page <1>
 -pages value         number of pages <1>
 -help                Print this message
 -?                   Print this message