groom: a simple getopt: calling Tcl procs with options

85 views
Skip to first unread message

Doug Simpson

unread,
Sep 4, 2001, 1:16:47 PM9/4/01
to
While convenient for the user of a proc, the variable number and
variable ordering of options is tough on the person who has to write
it. Since opt package was deprecated and I found no clear
alternative, I decided to try more of a macro approach to this
problem.

Got to thinking that I could have a vararg proc

proc cmd args groom

front end a fixed-arg proc which does the work

proc _cmd { opt1 - opt2 opt3 - opt4 | arga argb } {...}

where the "-" stands for a required parameter for the preceding option
and "|" stands for the end of the option list. Surprisingly, Tcl
cares not that the "-" arguments are duplicated. In this example opts
1 & 3 take paramters and have default value {}. Opts 2 & 4 are
logical switches with default value 0. An example call to cmd would
be

cmd -opt3 param3 -opt2 -- "-arg beginning with dash" "second arg"

So here is groom. There is also a proc auto_mkgroom which
automatically builds a file of the "proc <procname> args groom"
commands and then auto indexes them.

Please let me know if you find this approach useful. Have you found
another way to do this?

------------clip here-------------

proc cmd args groom ;# for completeness--auto_mkgroom will insert

proc _cmd {opt1 - opt2 opt3 - opt4 | arga argb} {
puts "opt1: $opt1"
puts "opt2: $opt2"
puts "opt3: $opt3"
puts "opt4: $opt4"
puts "arg1: $arg1"
puts "arg2: $arg2"
}

proc groom {} {
uplevel {
set this_level [info level]
set proc [lindex [info level $this_level] 0]

# execute _$proc with 0 arguments to force autoload.
set catch_status [catch _$proc catch_message]

if {$catch_status == 1
&& [regexp "no value given for parameter" $catch_message]} {
set argnames [info args _$proc]
set argnames_count [llength $argnames]

set i 0
set argname [lindex $argnames $i]
if {$argname == "-"} {
return -code error \
"_$proc must not have '-' as the first argument"
}
while {$i < $argnames_count && $argname != "|"} {
set next_argname [lindex $argnames [expr $i+1]]
if {$next_argname == "-"} {
set flag_takes_parameter(-$argname) 1
set option_value(-$argname) "" ;# default value
} else {
set flag_takes_parameter(-$argname) 0
set option_value(-$argname) 0 ;# default value
}
incr i
set argname [lindex $argnames $i]
}
if {$argname != "|"} {
return -code error "_$proc must have '|' as an argument"
}

set args_count [llength $args]

set i 0
set arg [lindex $args $i]
set dash_override 0
while {!$dash_override && $i < $args_count
&& [regexp "^-" $arg]} {
set next_arg [lindex $args [expr $i+1]]
if {$arg == "--"} {
set dash_override 1
incr i
} elseif {! [info exists flag_takes_parameter($arg)]} {
return -code error "'$arg': illegal option"
} elseif {$flag_takes_parameter($arg)} {
set option_value($arg) $next_arg
incr i 2
} else {
set option_value($arg) 1
incr i
}
set arg [lindex $args $i]
}
set nonoption_args [lrange $args $i end]

set option_values {}
set i 0
set argname [lindex $argnames $i]
while {$argname != "|"} {
lappend option_values $option_value(-$argname)
incr i
set argname [lindex $argnames $i]
}

eval _$proc $option_values | $nonoption_args
} elseif {$catch_status == 1} {
# _$proc must have been defined with zero args
# and also has an error in it: pass on the error.
return -code error $catch_message
}
}
}

proc auto_mkgroom {dir tcl_filetype} {
# Syntax differs slightly from auto_mkindex:
#
# auto_mkgroom /usr/local/bin tcl
#
# Second arg is the filetype "tcl" not the glob "*.tcl"
#
# First auto_mkindex finds the _* proc names; second auto_mkindex
# picks up the matching non-underscore names which auto_mkgroom
# has created.
#
set catch_code \
[catch {auto_mkindex $dir *.$tcl_filetype} catch_message]
if {$catch_code == 0} {
source [file join $dir tclIndex]
set fid [open [file join $dir groomIndex.$tcl_filetype] w]
foreach proc [array names auto_index] {
if {[string range $proc 0 0] == "_"} {
puts $fid "proc [string range $proc 1 end] args groom"
}
}
close $fid
catch {unset auto_index}
set catch_code \
[catch {auto_mkindex $dir *.$tcl_filetype} catch_message]
}
return -code $catch_code $catch_message
}

------------clip here-------------

Bastien Chevreux

unread,
Sep 5, 2001, 6:09:12 AM9/5/01
to
On 4 Sep 2001 10:16:47 -0700, Doug Simpson <dsim...@gta.ga.gov> wrote:
>While convenient for the user of a proc, the variable number and
>variable ordering of options is tough on the person who has to write
>it. Since opt package was deprecated and I found no clear
>alternative, I decided to try more of a macro approach to this
>problem.

http://mini.net/cgi-bin/wikit/1730.html lists a few, my small argp package
(http://www.chevreux.org/projects_tcl.html) amongst them.

Salut,
Bastien

--
Bastien Chevreux -- Life Science Information Manager
MWG Biotech AG -- Anzinger Strasse 7a -- D-85560 Ebersberg; Germany
Phone: +49 8092 8289 309 -- Fax: +49 8092 8289 310

lvi...@yahoo.com

unread,
Sep 5, 2001, 8:02:44 AM9/5/01
to

According to Doug Simpson <dsim...@gta.ga.gov>:
: Since opt package was deprecated and I found no clear
:alternative,

Is there something wrong with the options summarized in
http://mini.net/tcl/1730.html ?


--
--
"See, he's not just anyone ... he's my son." Mark Schultz
<URL: mailto:lvi...@cas.org> <URL: http://www.purl.org/NET/lvirden/>
Even if explicitly stated to the contrary, nothing in this posting

Andreas Kupries

unread,
Sep 24, 2001, 10:14:07 PM9/24/01
to

dsim...@gta.ga.gov (Doug Simpson) writes:

> While convenient for the user of a proc, the variable number and
> variable ordering of options is tough on the person who has to write
> it. Since opt package was deprecated and I found no clear
> alternative,

The 'cmdline' module in 'tcllib' would be one for example.

--
Sincerely,
Andreas Kupries <akup...@home.com>
Developer @ <http://www.activestate.com/>
Private <http://www.purl.org/NET/akupries/>
-------------------------------------------------------------------------------
}

Juan C. Gil

unread,
Sep 25, 2001, 5:53:07 AM9/25/01
to
dsim...@gta.ga.gov (Doug Simpson) wrote in message news:<893fe91f.01090...@posting.google.com>...

> While convenient for the user of a proc, the variable number and
> variable ordering of options is tough on the person who has to write
> it. Since opt package was deprecated and I found no clear
> alternative, I decided to try more of a macro approach to this
> problem.
>
You may have a look at The Simple Library at
http://simplelib.bobsville.com, in particular de SimpleProc package.

Juan Carlos---

Cameron Laird

unread,
Sep 25, 2001, 8:06:03 AM9/25/01
to
In article <82d7542c.01092...@posting.google.com>,

<URL: http://mini.net/tcl/command > tries to capture
pointers to *all* the alternatives.
--

Cameron Laird <cla...@NeoSoft.com>
Business: http://www.Phaseit.net
Personal: http://starbase.neosoft.com/~claird/home.html

Reply all
Reply to author
Forward
0 new messages