source: trunk/gui/scripts/getopts.tcl @ 154

Last change on this file since 154 was 115, checked in by mmc, 19 years ago

Updated all copyright notices.

File size: 4.2 KB
Line 
1# ----------------------------------------------------------------------
2#  COMPONENT: getopts - simple argument parser
3#
4#  This utility makes it easy to process arguments for various
5#  commands.  You give a description of arguments, and it will
6#  parse and return the values.
7#
8#    getopts args params {
9#        value -foo foo_default
10#        flag group -bar default
11#        flag group -baz
12#    }
13#
14#  Note that both args and params are passed by name, not by
15#  value (not $args or $params).  This function initializes the
16#  params variable according to the values in the spec list.
17#  It then loops through all args, matching as many as possible
18#  from the list.  It throws an error on the first error
19#  encountered.  If there are extra arguments that don't match
20#  the flags and don't start with -, they are left in args, and
21#  processing stops.
22#
23# ======================================================================
24#  AUTHOR:  Michael McLennan, Purdue University
25#  Copyright (c) 2004-2005  Purdue Research Foundation
26#
27#  See the file "license.terms" for information on usage and
28#  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
29# ======================================================================
30namespace eval Rappture { # forward declaration }
31
32# ----------------------------------------------------------------------
33# USAGE: getopts <listvar> <returnvar> <spec>
34#
35# Processes options in <listvar>, storing results in <returnvar>.
36# Throws an exception if an error is encountered.  Leaves any remaining
37# arguments (after flags) in <listvar>.
38# ----------------------------------------------------------------------
39proc Rappture::getopts {listVar returnVar spec} {
40    upvar $listVar args
41    upvar $returnVar params
42    catch {unset params}
43    set opts ""
44
45    #
46    # Pick apart the info in the <spec> and set up flags/params
47    #
48    foreach line [split $spec \n] {
49        if {[llength $line] == 0} {
50            continue  ;# ignore blank lines
51        }
52
53        set type [lindex $line 0]
54        switch -- $type {
55            value {
56                if {[llength $line] < 3} {
57                    error "bad value spec \"$line\": should be \"value -flag default\""
58                }
59                set name [lindex $line 1]
60                set flags($name) $type
61                set params($name) [lindex $line 2]
62                lappend opts $name
63            }
64            flag {
65                if {[llength $line] < 3 || [llength $line] > 4} {
66                    error "bad value spec \"$line\": should be \"flag group -flag ?default?\""
67                }
68                set group [lindex $line 1]
69                set name [lindex $line 2]
70                set flags($name) [list $type $group]
71                if {[llength $line] > 3} {
72                    set params($group) $name
73                    set params($name) 1
74                } else {
75                    if {![info exists params($group)]} {
76                        set params($group) ""
77                    }
78                    set params($name) 0
79                }
80                lappend opts $name
81            }
82            default {
83                error "bad arg type \"$type\": should be flag or value"
84            }
85        }
86    }
87
88    #
89    # Now, walk through the values in $args and extract parameters.
90    #
91    while {[llength $args] > 0} {
92        set first [lindex $args 0]
93        if {[string index $first 0] != "-"} {
94            break
95        }
96        if {"--" == $first} {
97            set args [lrange $args 1 end]
98            break
99        }
100        if {![info exists params($first)]} {
101            error "bad option \"$first\": should be [join [lsort $opts] {, }]"
102        }
103        switch -- [lindex $flags($first) 0] {
104            value {
105                if {[llength $args] < 2} {
106                    error "missing value for option $first"
107                }
108                set params($first) [lindex $args 1]
109                set args [lrange $args 2 end]
110            }
111            flag {
112                set group [lindex $flags($first) 1]
113                set params($group) $first
114                set params($first) 1
115                set args [lrange $args 1 end]
116            }
117        }
118    }
119    return ""
120}
Note: See TracBrowser for help on using the repository browser.