commit - e6eae0468089573a77abb012145073dd8d1c4402
commit + 19d28f97177c183d78bbce4642857db2ea27541f
blob - 7e552eddfecbe0b782dec4fa11b58fe32d9d2124
blob + fcbd49da45d37f494b7475ce90749039c3ab4052
--- exercise
+++ exercise
proc getopt {argvvar optstring optvar argvar} {
upvar $argvvar argv $optvar opt $argvar arg
- set hd [lindex $argv 0]
- set opt [string index $hd 1]
- if {$opt eq "" || [string index $hd 0] ne "-"} { ;# no option argument
- return 0
+ set arg [lindex $argv 0] ;# "" if argv empty
+ set opt [string index $arg 1] ;# "" if arg empty
+ if {$opt eq "" || [string index $arg 0] ne "-"} {
+ return 0 ;# no option
}
- if {$hd eq "--"} {
- set argv [lreplace $argv 0 0] ;# remove hd
- return 0
+ set argv [lreplace $argv 0 0] ;# tentative consumption
+ if {$arg eq "--"} {
+ return 0 ;# end of options
}
# consume option character
- set hd [string replace $hd 1 1]
- if {$hd ne "-"} {
- set argv [lreplace $argv 0 0 $hd] ;# replace hd
- } else {
- set argv [lreplace $argv 0 0] ;# consume exhausted hd
+ set arg [string replace $arg 1 1]
+ if {$arg ne "-"} { ;# not yet exhausted?
+ set argv [linsert $argv 0 $arg] ;# put it back for now
}
+ # check if option is valid
set idx [string first $opt $optstring]
if {$idx == -1 || $opt eq ":"} {
- puts stderr "$::argv0: unknown option -- $opt"
+ puts stderr "[file tail $::argv0]: unknown option -$opt"
set opt "?"
- return 1
+ return 1 ;# could come back for more
}
# handle option arguments
- if {[string index $optstring [expr $idx + 1]] ne ":"} {
- return 1 ;# no argument expected
- }
- if {$hd ne "-"} {
- set arg [string replace $hd 0 0] ;# rest of hd -> optarg
- set argv [lreplace $argv 0 0] ;# consume hd
- } elseif {[llength $argv] > 0} {
- set arg [lindex $argv 0] ;# next arg -> optarg
+ if {[string index $optstring [expr $idx + 1]] eq ":"} {
+ if {$arg ne "-"} {
+ set arg [string range $arg 1 end] ;# use the rest of arg
+ } elseif {[llength $argv] > 0} {
+ set arg [lindex $argv 0] ;# use the next arg
+ } else {
+ puts stderr "[file tail $::argv0]: -$opt requires an argument"
+ set opt [expr {[string index $optstring 0] eq ":" ? ":" : "?"}]
+ }
set argv [lreplace $argv 0 0] ;# consume arg
- } else {
- puts stderr "$::argv0: option requires an argument -- $opt"
- if {[string index $optstring 0] eq ":"} {
- set opt ":"
- } else {
- set opt "?"
- }
}
return 1