This routine implements Posix command line argument parsing. Notice
that returning values through global variables means that
is not reentrant.
Obedience to Posix format for the
getopt calls sows confusion.
Passing argc and argv as arguments while referencing
optind as a global variable leads to strange behavior,
especially when the calls to
getopt are buried in other
Even in C, argc can be derived from argv; what purpose
does it serve beyond providing an opportunity for
argv/argc mismatch? Just such a mismatch existed for
years in a SLIB
I have removed the argc and argv arguments to getopt procedures; and replaced them with a global variable:
Define *argv* with a list of arguments before calling getopt procedures. If you don’t want the first (0th) element to be ignored, set *optind* to 0 (after requiring getopt).
Is the index of the current element of the command line. It is initially one. In order to parse a new command line or reparse an old one, *optind* must be reset.
Is set by getopt to the (string) option-argument of the current option.
Returns the next option letter in *argv* (starting from
(vector-ref argv *optind*)) that matches a letter in
optstring. *argv* is a vector or list of strings, the 0th
of which getopt usually ignores. optstring is a string of
recognized option characters; if a character is followed by a colon,
the option takes an argument which may be immediately following it in
the string or in the next element of *argv*.
*optind* is the index of the next element of the *argv* vector
to be processed. It is initialized to 1 by getopt.scm, and
getopt updates it when it finishes with each element of
getopt returns the next option character from *argv* that
matches a character in optstring, if there is one that matches.
If the option takes an argument,
getopt sets the variable
*optarg* to the option-argument as follows:
(length *argv*), this indicates a missing option argument, and
getoptreturns an error indication.
getopt is called, the string
*optind*) either does not begin with the character
#\- or is
#f without changing
(vector-ref argv *optind*) is the string
#f after incrementing
getopt encounters an option character that is not contained in
optstring, it returns the question-mark
#\? character. If
it detects a missing option argument, it returns the colon character
#\: if the first character of optstring was a colon, or a
question-mark character otherwise. In either case,
the variable getopt:opt to the option character that caused the
The special option
"--" can be used to delimit the end of the
#f is returned, and
"--" is skipped.
getopt returns the next option character specified on the command
line. A colon
#\: is returned if
getopt detects a missing
argument and the first character of optstring was a colon
#\? is returned if
getopt encounters an
option character not in optstring or detects a missing argument
and the first character of optstring was not a colon
#f when all command line options
have been parsed.
#! /usr/local/bin/scm (require 'program-arguments) (require 'getopt) (define argv (program-arguments)) (define opts ":a:b:cd") (let loop ((opt (getopt (length argv) argv opts))) (case opt ((#\a) (print "option a: " *optarg*)) ((#\b) (print "option b: " *optarg*)) ((#\c) (print "option c")) ((#\d) (print "option d")) ((#\?) (print "error" getopt:opt)) ((#\:) (print "missing arg" getopt:opt)) ((#f) (if (< *optind* (length argv)) (print "argv[" *optind* "]=" (list-ref argv *optind*))) (set! *optind* (+ *optind* 1)))) (if (< *optind* (length argv)) (loop (getopt (length argv) argv opts)))) (slib:exit)
getopt-- is an extended version of
which parses long option names of the form
‘--hold-the-onions’ and ‘--verbosity-level=extreme’.
Getopt-- behaves as
getopt except for non-empty
options beginning with ‘--’.
Options beginning with ‘--’ are returned as strings rather than
characters. If a value is assigned (using ‘=’) to a long option,
*optarg* is set to the value. The ‘=’ and value are
not returned as part of the option string.
No information is passed to
getopt-- concerning which long
options should be accepted or whether such options can take arguments.
If a long option did not have an argument,
*optarg* will be set
#f. The caller is responsible for detecting and reporting
(define opts ":-:b:") (define *argv* '("foo" "-b9" "--f1" "--2=" "--g3=35234.342" "--")) (define *optind* 1) (define *optarg* #f) (require 'qp) (do ((i 5 (+ -1 i))) ((zero? i)) (let ((opt (getopt-- opts))) (print *optind* opt *optarg*))) -| 2 #\b "9" 3 "f1" #f 4 "2" "" 5 "g3" "35234.342" 5 #f "35234.342"