source: trunk/gui/scripts/getopts.tcl

Last change on this file was 5659, checked in by ldelgass, 9 years ago

whitespace

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