package for parsing argument in TCL

后端 未结 3 1760
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-14 21:38

Does anyone know a standard package for tcl to easily parse the input arguments ? or a ready proc ? ( I have only 3 flags but something general is preferable ).

相关标签:
3条回答
  • 2021-01-14 22:12

    Here is a simple, native, no-package argument parser:

    #
    # arg_parse simple argument parser
    # Example `arg_parse {help version} {with-value} {-with-value 123 positional arguments}`
    # will return:
    # `positionals {positional arguments} with-value 123`
    #
    # @param boolean_flags flags which does not requires additional arguments (like help)
    # @param argument_flags flags which requires values (-with-value value)
    # @param args the got command line arguments
    #
    # @return stringified array of parsed arguments
    #
    proc arg_parse { boolean_flags argument_flags args } {
        set argsarr(positionals) {}
    
        for {set i 0} {$i < [llength $args]} {incr i} {
            set arg [lindex $args $i]
            if { [sstartswith $arg "-" ] } {
                set flag [string range $arg 1 end]
                if { [lsearch $boolean_flags $flag] >= 0 } {
                    set argsarr($flag) 1
                } elseif { [lsearch $argument_flags $flag] >= 0 } {
                    incr i
                    set argsarr($flag) [lindex $args $i]
                } else {
                    puts "ERROR: Unknown flag argument: $arg"
                    return
                }
            } else {
                lappend argsarr(positionals) $arg
            }
        }
        return [array get argsarr]
    }
    

    USE argument parser

    #
    # USE argument parser:
    #
    proc my_awesome_proc { args } {
        array set argsarr [arg_parse "help version" "with-value" {*}$args]
        parray argsarr
    }
    

    USE my_awesome_proc :

    % my_awesome_proc -help
    argsarr(help)        = 1
    argsarr(positionals) = 
    % my_awesome_proc -with-value 123
    argsarr(positionals) = 
    argsarr(with-value)  = 123
    % my_awesome_proc -wrong
    ERROR: Unknown flag argument: -wrong
    % my_awesome_proc positional arguments
    argsarr(positionals) = positional arguments
    % 
    
    0 讨论(0)
  • 2021-01-14 22:23

    The documentation includes an example. Here is a simple example:

    package require cmdline
    
    set parameters {
        {server.arg ""   "Which server to search"}
        {debug           "Turn on debugging, default=off"}
    }
    
    set usage "- A simple script to demo cmdline parsing"
    array set options [cmdline::getoptions ::argv $parameters $usage]
    parray options
    

    Sample runs:

    $ tclsh simple.tcl 
    options(debug)  = 0
    options(server) = 
    
    $ tclsh simple.tcl -server google.com
    options(debug)  = 0
    options(server) = google.com
    
    $ tclsh simple.tcl -server google.com -debug
    options(debug)  = 1
    options(server) = google.com
    
    $ tclsh simple.tcl -help
    simple - A simple script to demo cmdline parsing
     -server value        Which server to search <>
     -debug               Turn on debugging, default=off
     -help                Print this message
     -?                   Print this message
    
        while executing
    "error [usage $optlist $usage]"
        (procedure "cmdline::getoptions" line 15)
        invoked from within
    "cmdline::getoptions ::argv $parameters $usage"
        invoked from within
    "array set options [cmdline::getoptions ::argv $parameters $usage]"
        (file "simple.tcl" line 11)
    

    Discussion

    • Unlike most Linux utilities, TCL uses single dash instead of double dashes for command-line options
    • When a flags ends with .arg, then that flag expects an argument to follow, such as in the case of server.arg
    • The debug flag does not end with .arg, therefore it does not expect any argument
    • The user defines the command-line parameters by a list of lists. Each sub-list contains 2 or 3 parts:
      • The flag (e.g. debug)
      • The default value (e.g. 0), only if the parameter takes an argument (flag ends with .arg).
      • And the help message
    • Invoke usage/help with -help or -?, however, the output is not pretty, see the last sample run.

    Update: Help/Usage

    I have been thinking about the message output when the user invoke help (see the last sample run above). To get around that, you need to trap the error yourself:

    set usage "- A simple script to demo cmdline parsing"
    if {[catch {array set options [cmdline::getoptions ::argv $parameters $usage]}]} {
        puts [cmdline::usage $parameters $usage]
    } else {
        parray options
    }
    

    Sample run 2:

    $ tclsh simple.tcl -?
    simple - A simple script to demo cmdline parsing
     -server value        Which server to search <>
     -debug               Turn on debugging, default=off
     -help                Print this message
     -?                   Print this message
    
    0 讨论(0)
  • 2021-01-14 22:32

    Tcllib has such a package, cmdline. It's a bit underdocumented, but it works.

    0 讨论(0)
提交回复
热议问题