'''command options''' presents information about working with command options in Tcl. ** See Also ** [category Argument Processing]: [Syntax parsing in Tcl]: [Tcl syntax]: [Argument Parsing, a discussion]: ** Description ** suggests several distinct topics: * tclsh and wish arguments * command-line options (as seen through $::argv) of Tcl-coded applications * idioms for parsing variable (args) arguments seen by pure-Tcl [proc]s. Certain considerations are common to all these, and are convenient to treat here in a unified way. ** Option Parsing for Tcl Commands ** [http://openacs.org/api-doc/proc-view?proc=ad_proc%|%ad_proc]: [argument parsing with defaults (Wagner)]: Only available by contacting the author directly. see [theObjects] for a C version, which is available for download [aqtools]: includes an ... [[?]] package for argument parsing [argp]: simple and flexible arg parsing for Tcl [http://wi-fizzle.com/clig/%|%clig]: written in Tcl, generates interpreters for both standalone programs and Tcl commands [cmdline] in [tcllib]: probably the most standard and widely-used of these packages [http://core.tcl.tk/akupries/cmdr/index%|%cmdr] ,by [AK]: a framework for command-line parsing and dispatch. Presented at the [Twentieth Annual Tcl/Tk Conference (2013)] [[`[dict with] $args {}`]: provides extremely simple parsing. [ftp://ftp.lehigh.edu/pub/evap/Announce%|%Evaluate Parameters 2.4]: for [C] , [Perl], and [Tcl] [Extral]'s args_parse, cmd_parse, and so on: [getopt], by [RS]: light-weight, of course [GetOpt-ish] by [FF]: getopt-like tool [http://groups.google.com/d/msg/comp.lang.tcl/4YPkcMyFgy4/KcrGjaFviD0J%|%groom: a simple getopt: calling Tcl procs with options], Doug Simpson, 2001-09-04: [init], by [Larry Smith]: parses a command's arguments and also initialises local variables. [Matthias Hoffmann - Tcl-Code-Snippets - misc routines - command line parsing]: another simple command line parsing routine in a few lines of tcl, with integrated help support [mkextensions], by [Michael Kraus]: includes mkGeneric::options, a simple but efficient option-processing routine. [Octopus package for parsing command line options for procedures/scripts]: [opt]: deprecated [optparse], by [Laurent Demailly]: deprecated ''optional arguments'', in [Tcl Gems]: illustrates the use of [Arrays / Hash Maps%|%arrays] to do simple argument parsing [Options and Arguments], by [aspect]: [option parsing using ensemble], by [Lars H]: uses the [namespace ensemble] mechanism to to handle options [ParseArgs], circa 1996: Utility library for parsing command line arguments in various languages (including Tcl) and on various hardware platforms [procargs], by [JBR]: [http://jazimmer.com/tclbook/tcl/examples/html/zproc_usage.html%|%Procedure for Extracting Options and Switches], by J Adrian Zimmer, 1988: [Simple way to parse command options], by [FabricioRocha%|%Fabricio Rocha]: provides '''optionscheck''', which verifies the formatting of a traditional options list like `-option1 value1 -option2 value2 ...`. Intended for being used in megawidgets and customized commands, the procedure finds unknown options, values without preceding options, options without a value assigned to them. It returns a dict containing all those cases above along with the valid option/value pairs, and can generate errors in such cases or work silently. [SNTL], by [Sam Shen]: contains code for command line argument processing as well as many other items. [ftp://ftp.tcl.tk/pub/tcl/all/t/tclGetOpts/1.1/tclGetOpts1.1.tar.gz%|%TclGetOpts]: mildly buggy Tcl_ParseArgsObjv: parsing of C implemented Tcl commands using the object interface. (See example below.) [tepam], or ''Tcl's Enhanced Procedure Argument Manager'': a component of [tcllib] [Option Parsing for Tcl Commands - tgetopt] [TWAPI]: provides [http://twapi.sourceforge.net/misc.html#parseargs%|%parseargs] for flexible argument parsing. This is implemented in C and is therefore fast enough to be used for argument parsing in any proc. Some of the Tcl based parsers are slow enough that they impose a significant performance penalty if used for general proc arg processing as opposed to just dealing with command line options where performance of course does not matter. [yaap - Yet Another Argument Parsing utility]: [The Simple Development Library]: includes both [http://simpledevlib.sourceforge.net/SimpleProc.html%|%SimpleProc], a package for command arguments handling including typed arguments, with optional run-time checking, and options [http://simpledevlib.sourceforge.net/SimpleOption.html%|%SimpleOption], a very powerful command options parser with too many features to list here [yaap - Yet Another Argument Parsing utility]: a template-based argument parsing utility inspired by `XtGetApplicationResources()` [ycl]::checkargs: somewhat like [tepam], but weaves documentation and code together in a [Literate Programming] style, providing a versatile argument specification system as well as argument validation and inter-argument validation ** System Command Line ** [ftp://ftp.lehigh.edu/pub/evap/Announce%|%Evaluate Parameters 2.4]: for [C] , [Perl], and [Tcl] ** Discussion ** Question: In C, for Tcl, using the newer objc, objv API, how do I parse options? I would have thought people would need to do this all the time, but I can't find anything. Needs to handle args, options, required optional etc. Speed is high on the priority list... If you can use the Tk library, try `Tk_SetOptions` and its assorted support functions. It would be nice if something like this were in the Tcl library, for those times when one doesn't have Tk around. A pure-Tcl solution might be to do the option handling in Tcl, passing a fixed number of arguments to the C code, but that might not meet your speed requirements. [SPB]: I've modified the `Tk_ParseArgv()` routine in tkArg.[[hc] to handle this case. Also, to make it even more useful, I added a `Tcl_ParseArgsObjv` for parsing a bunch of arguments passed to a C-implemented Tcl command. For example, you can do something like: ======c #include #include #include #include #include int mycoolcommand(ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { int mytoggle=0; int myint=-2; Tcl_ArgvInfo argTable[] = { {"-toggle",TCL_ARGV_CONSTANT,(void*)1,&mytoggle,"turn toggle on"}, {"-theint",TCL_ARGV_INT,NULL,&myint,"set myint"}, {(char*)NULL,TCL_ARGV_END,NULL,NULL,(char*)NULL} }; Tcl_Obj **private_objv=(Tcl_Obj**)calloc(objc+1,sizeof(Tcl_Obj*)); int i; for (i=0;i 0 } { set flag [lindex $argv 0] switch -- $flag { -bool { set bool 1 set argv [lrange $argv 1 end] } -option { set value [lindex $argv 1] set argv [lrange $argv 2 end] } default break } } } foreach file $argv { puts "[format "file: %s" $file]" } ====== ---- PT writes: I like to use code similar to the above example for option processing. However, we want to avoid 'shimmering' the args list into a string and back into a list. Plus I find it repatative to keep writing the same two lines for setting the option value. Here is my current example: ====== # ------------------------------------------------------------------------- # Description: # Pop the nth element off a list. Used in options processing. # proc dns::Pop {varname {nth 0}} { upvar $varname args set r [lindex $args $nth] set args [lreplace $args $nth $nth] return $r } # --------------------------------------------------------------------- # Now the option processing loop. Eats the arguments once handled and stops at '--' # setup the defaults. array set opts {-a 1 -b 0} while {[string match -* [lindex $args 0]]} { switch -glob -- [lindex $args 0] { -A* -a* { set opts(-a) [Pop args 1] } -b* { set opts(-b) [Pop args 1] } -- { Pop args ; break } default { set opts [join [lsort [array names state -*]] ", "] return -code error "bad option [lindex $args 0]: \ must be one of $opts" } } Pop args } puts "Options now [array get opts] and the remaining args: $args" ====== ----- A quick and dirty way uses one-liners like this: ====== if [regexp { -x} $::argv] {# do the X thing} ;# RS ====== ---- If your values come in pairs (like -option value), I usually use the following code for parsing them: ====== foreach {option value} $argument_list { switch -glob -- $option { -opt* {set opt $value} -otheropt* {set otheropt $value} default {error "Unknown option $option!"} } } ====== ---- A classical and elegant solution to this task is from the Welch book: ====== proc foo {args} { # first assign default values... array set options {-bar 1 -grill 2 -verbose 0 ...} # ...then possibly override them with user choices array set options $args .... } ====== It does not check for undefined switches, though. ([RS]) ---- [troym72] 2009-12-22: For passing arguments to a Tcl script from the UNIX command line in the form of a keyed list, it can be a little tricky. Here's an example proc that I created to help illustrate how Tcl handles arguments from the command line in keyed list form. ====== #!/usr/bin/tcl # Script Name: argstest.tcl # Date Created: 12/22/2009 # Author: Troy Morton # Purpose: Test command line arguments package require tclx proc parseargs {args} { echo $args ;# args as passed from the “parseargs $argv procedure call” set args [lindex $args 0] ;# pull my args keyed list from the argv single element list keylget args KEY1 value ;# now do my keylget from the args which is now a properly formatted keyed list. echo $value ;# echo value of the key “KEY1”. } echo $argv ;# args from command line arrive as keyed list parseargs $argv ;# argv is passed to pareargs as a list ====== When run from the UNIX command line the above script looks like this: ====== />argstest.tcl "KEY ValueKey1" "KEY2 ValueKey2" ;# typed on command line {KEY1 ValueKey1} {KEY2 ValueKey2} ;# argv as received by the tcl script {{KEY1 ValueKey1} {KEY2 ValueKey2}} ;# argv as received by proc parseargs ValueKey1 ;# value of the key KEY1 ====== ---- [SB] 2003-05-21: For many of my tcl utilities I have only vanilla tclsh but still need to parse command line options. As I mostly use the tools myself I don't need too much fancy error detection. For a small application, I need a couple of switches, one with an argument and then the file to process. Nothing fancy, but it is written in a matter of seconds, and it is fairly easy to extend with more switches. ====== set arglen [llength $argv] set index 0 while {$index < $arglen} { set arg [lindex $argv $index] switch -exact -- $arg { {-s} {set args($arg) [lindex $argv [incr index]]} {-l} {set args($arg) .} default {set filename [lindex $argv $index]} } incr index } if {[info exists args(-l)]} { puts "-l switch set" ... code what happens for -l } if {[info exists args(-s)]} { puts "-s switch set with arg $args(-s)" ... code what happens for -s and its arg } ====== <> Argument Processing | Arts and crafts of Tcl-Tk programming