Next: HTML, Previous: Standard Formatted I/O, Up: Textual Conversion Packages [Contents][Index]
Next: Command Line, Previous: Program and Arguments, Up: Program and Arguments [Contents][Index]
(require 'getopt)
This routine implements Posix command line argument parsing. Notice
that returning values through global variables means that getopt
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
procedures.
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 getopt--
example.
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
*argv*.
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 getopt
returns an error indication.
If, when getopt
is called, the string (vector-ref argv
*optind*)
either does not begin with the character #\-
or is
just "-"
, getopt
returns #f
without changing
*optind*. If (vector-ref argv *optind*)
is the string
"--"
, getopt
returns #f
after incrementing
*optind*.
If 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, getopt
sets
the variable getopt:opt to the option character that caused the
error.
The special option "--"
can be used to delimit the end of the
options; #f
is returned, and "--"
is skipped.
RETURN VALUE
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
#\:
.
A question-mark #\?
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 #\:
.
Otherwise, getopt
returns #f
when all command line options
have been parsed.
Example:
#! /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--
optstring ¶The procedure getopt--
is an extended version of getopt
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
to #f
. The caller is responsible for detecting and reporting
errors.
(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"
Next: Parameter lists, Previous: Getopt, Up: Program and Arguments [Contents][Index]
(require 'read-command)
read-command
converts a command line into a list of strings
suitable for parsing by getopt
. The syntax of command lines
supported resembles that of popular shells. read-command
updates port to point to the first character past the command
delimiter.
If an end of file is encountered in the input before any characters are found that can begin an object or comment, then an end of file object is returned.
The port argument may be omitted, in which case it defaults to the
value returned by current-input-port
.
The fields into which the command line is split are delimited by
whitespace as defined by char-whitespace?
. The end of a command
is delimited by end-of-file or unescaped semicolon (;) or
newline. Any character can be literally included in a field by
escaping it with a backslach (\).
The initial character and types of fields recognized are:
The next character has is taken literally and not interpreted as a field delimiter. If \ is the last character before a newline, that newline is just ignored. Processing continues from the characters after the newline as though the backslash and newline were not there.
The characters up to the next unescaped " are taken literally, according to [R4RS] rules for literal strings (see Strings in Revised(4) Scheme).
One scheme expression is read
starting with this character. The
read
expression is evaluated, converted to a string
(using display
), and replaces the expression in the returned
field.
Semicolon delimits a command. Using semicolons more than one command can appear on a line. Escaped semicolons and semicolons inside strings do not delimit commands.
The comment field differs from the previous fields in that it must be
the first character of a command or appear after whitespace in order to
be recognized. # can be part of fields if these conditions are
not met. For instance, ab#c
is just the field ab#c.
Introduces a comment. The comment continues to the end of the line on
which the semicolon appears. Comments are treated as whitespace by
read-dommand-line
and backslashes before newlines in
comments are also ignored.
read-options-file
converts an options file into a list of
strings suitable for parsing by getopt
. The syntax of options
files is the same as the syntax for command
lines, except that newlines do not terminate reading (only ;
or end of file).
If an end of file is encountered before any characters are found that can begin an object or comment, then an end of file object is returned.
Next: Getopt Parameter lists, Previous: Command Line, Up: Program and Arguments [Contents][Index]
(require 'parameters)
Arguments to procedures in scheme are distinguished from each other by their position in the procedure call. This can be confusing when a procedure takes many arguments, many of which are not often used.
A parameter-list is a way of passing named information to a procedure. Procedures are also defined to set unused parameters to default values, check parameters, and combine parameter lists.
A parameter has the form (parameter-name value1
…)
. This format allows for more than one value per
parameter-name.
A parameter-list is a list of parameters, each with a different parameter-name.
Returns an empty parameter-list with slots for parameter-names.
parameter-name must name a valid slot of parameter-list.
parameter-list-ref
returns the value of parameter
parameter-name of parameter-list.
Removes the parameter parameter-name from parameter-list.
remove-parameter
does not alter the argument
parameter-list.
If there are more than one parameter-name parameters, an error is signaled.
Returns parameter-list with parameter1 … merged in.
expanders is a list of procedures whose order matches the order of
the parameter-names in the call to make-parameter-list
which created parameter-list. For each non-false element of
expanders that procedure is mapped over the corresponding
parameter value and the returned parameter lists are merged into
parameter-list.
This process is repeated until parameter-list stops growing. The
value returned from parameter-list-expand
is unspecified.
defaulters is a list of procedures whose order matches the order
of the parameter-names in the call to make-parameter-list
which created parameter-list. fill-empty-parameters
returns a new parameter-list with each empty parameter replaced with the
list returned by calling the corresponding defaulter with
parameter-list as its argument.
checks is a list of procedures whose order matches the order of
the parameter-names in the call to make-parameter-list
which created parameter-list.
check-parameters
returns parameter-list if each check
of the corresponding parameter-list returns non-false. If some
check returns #f
a warning is signaled.
In the following procedures arities is a list of symbols. The
elements of arities
can be:
single
Requires a single parameter.
optional
A single parameter or no parameter is acceptable.
boolean
A single boolean parameter or zero parameters is acceptable.
nary
Any number of parameters are acceptable.
nary1
One or more of parameters are acceptable.
Returns parameter-list converted to an argument list. Parameters
of arity type single
and boolean
are converted to
the single value associated with them. The other arity types are
converted to lists of the value(s).
positions is a list of positive integers whose order matches the
order of the parameter-names in the call to
make-parameter-list
which created parameter-list. The
integers specify in which argument position the corresponding parameter
should appear.
Next: Filenames, Previous: Parameter lists, Up: Program and Arguments [Contents][Index]
(require 'getopt-parameters)
Returns *argv* converted to a parameter-list. optnames are the parameter-names. arities and types are lists of symbols corresponding to optnames.
aliases is a list of lists of strings or integers paired with
elements of optnames. Each one-character string will be treated
as a single ‘-’ option by getopt
. Longer strings will be
treated as long-named options (see getopt–).
If the aliases association list has only strings as its
car
s, then all the option-arguments after an option (and before
the next option) are adjoined to that option.
If the aliases association list has integers, then each (string) option will take at most one option-argument. Unoptioned arguments are collected in a list. A ‘-1’ alias will take the last argument in this list; ‘+1’ will take the first argument in the list. The aliases -2 then +2; -3 then +3; … are tried so long as a positive or negative consecutive alias is found and arguments remain in the list. Finally a ‘0’ alias, if found, absorbs any remaining arguments.
In all cases, if unclaimed arguments remain after processing, a warning is signaled and #f is returned.
Like getopt->parameter-list
, but converts *argv* to an
argument-list as specified by optnames, positions,
arities, types, defaulters, checks, and
aliases. If the options supplied violate the arities or
checks constraints, then a warning is signaled and #f is returned.
These getopt
functions can be used with SLIB relational
databases. For an example, See make-command-server.
If errors are encountered while processing options, directions for using
the options (and argument strings desc …) are printed to
current-error-port
.
(begin (set! *optind* 1) (set! *argv* '("cmd" "-?") (getopt->parameter-list '(flag number symbols symbols string flag2 flag3 num2 num3) '(boolean optional nary1 nary single boolean boolean nary nary) '(boolean integer symbol symbol string boolean boolean integer integer) '(("flag" flag) ("f" flag) ("Flag" flag2) ("B" flag3) ("optional" number) ("o" number) ("nary1" symbols) ("N" symbols) ("nary" symbols) ("n" symbols) ("single" string) ("s" string) ("a" num2) ("Abs" num3)))) -| Usage: cmd [OPTION ARGUMENT ...] ... -f, --flag -o, --optional=<number> -n, --nary=<symbols> ... -N, --nary1=<symbols> ... -s, --single=<string> --Flag -B -a <num2> ... --Abs=<num3> ... ERROR: getopt->parameter-list "unrecognized option" "-?"
Next: Batch, Previous: Getopt Parameter lists, Up: Program and Arguments [Contents][Index]
(require 'filename)
Returns a predicate which returns a non-false value if its string argument matches (the string) pattern, false otherwise. Filename matching is like glob expansion described the bash manpage, except that names beginning with ‘.’ are matched and ‘/’ characters are not treated specially.
These functions interpret the following characters specially in pattern strings:
Matches any string, including the null string.
Matches any single character.
Matches any one of the enclosed characters. A pair of characters separated by a minus sign (-) denotes a range; any character lexically between those two characters, inclusive, is matched. If the first character following the ‘[’ is a ‘!’ or a ‘^’ then any character not enclosed is matched. A ‘-’ or ‘]’ may be matched by including it as the first or last character in the set.
Returns a function transforming a single string argument according to
glob patterns pattern and template. pattern and
template must have the same number of wildcard specifications,
which need not be identical. pattern and template may have
a different number of literal sections. If an argument to the function
matches pattern in the sense of filename:match??
then it
returns a copy of template in which each wildcard specification is
replaced by the part of the argument matched by the corresponding
wildcard specification in pattern. A *
wildcard matches
the longest leftmost string possible. If the argument does not match
pattern then false is returned.
template may be a function accepting the same number of string
arguments as there are wildcard specifications in pattern. In
the case of a match the result of applying template to a list
of the substrings matched by wildcard specifications will be returned,
otherwise template will not be called and #f
will be returned.
((filename:substitute?? "scm_[0-9]*.html" "scm5c4_??.htm") "scm_10.html") ⇒ "scm5c4_10.htm" ((filename:substitute?? "??" "beg?mid?end") "AZ") ⇒ "begAmidZend" ((filename:substitute?? "*na*" "?NA?") "banana") ⇒ "banaNA" ((filename:substitute?? "?*?" (lambda (s1 s2 s3) (string-append s3 s1))) "ABZ") ⇒ "ZA"
str can be a string or a list of strings. Returns a new string
(or strings) similar to str
but with the suffix string old
removed and the suffix string new appended. If the end of
str does not match old, an error is signaled.
(replace-suffix "/usr/local/lib/slib/batch.scm" ".scm" ".c") ⇒ "/usr/local/lib/slib/batch.c"
Calls proc with k arguments, strings returned by successive calls to
tmpnam
.
If proc returns, then any files named by the arguments to proc are
deleted automatically and the value(s) yielded by the proc is(are)
returned. k may be ommited, in which case it defaults to 1
.
Calls proc with strings returned by successive calls to tmpnam
,
each with the corresponding suffix string appended.
If proc returns, then any files named by the arguments to proc are
deleted automatically and the value(s) yielded by the proc is(are)
returned.
Previous: Filenames, Up: Program and Arguments [Contents][Index]
(require 'batch)
The batch procedures provide a way to write and execute portable scripts
for a variety of operating systems. Each batch:
procedure takes
as its first argument a parameter-list (see Parameter lists). This
parameter-list argument parms contains named associations. Batch
currently uses 2 of these:
batch-port
The port on which to write lines of the batch file.
batch-dialect
The syntax of batch file to generate. Currently supported are:
The ‘batch’ module uses 2 enhanced relational tables
(see Using Databases) to store information linking the names of
operating-system
s to batch-dialect
es.
Defines operating-system
and batch-dialect
tables and adds
the domain operating-system
to the enhanced relational database
database.
Is batch’s best guess as to which operating-system it is running under.
*operating-system*
is set to (software-type)
(see Configuration) unless (software-type)
is unix
,
in which case finer distinctions are made.
proc should be a procedure of one argument. If file is an
output-port, batch:call-with-output-script
writes an appropriate
header to file and then calls proc with file as the
only argument. If file is a string,
batch:call-with-output-script
opens a output-file of name
file, writes an appropriate header to file, and then calls
proc with the newly opened port as the only argument. Otherwise,
batch:call-with-output-script
acts as if it was called with the
result of (current-output-port)
as its third argument.
The rest of the batch:
procedures write (or execute if
batch-dialect
is system
) commands to the batch port which
has been added to parms or (copy-tree parms)
by the
code:
(adjoin-parameters! parms (list 'batch-port port))
Calls batch:try-command
(below) with arguments, but signals an
error if batch:try-command
returns #f
.
These functions return a non-false value if the command was successfully
translated into the batch dialect and #f
if not. In the case of
the system
dialect, the value is non-false if the operation
suceeded.
Writes a command to the batch-port
in parms which executes
the program named string1 with arguments string2 ….
breaks the last argument list into chunks small enough so that the command:
arg1 arg2 … chunk
fits withing the platform’s maximum command-line length.
batch:try-chopped-command
calls batch:try-command
with the
command and returns non-false only if the commands all fit and
batch:try-command
of each command line returned non-false.
Writes a command to the batch-port
in parms which executes
the batch script named string1 with arguments string2
….
Note: batch:run-script
and batch:try-command
are not the
same for some operating systems (VMS).
Writes comment lines line1 … to the batch-port
in
parms.
Writes commands to the batch-port
in parms which create a
file named file with contents line1 ….
Writes a command to the batch-port
in parms which deletes
the file named file.
Writes a command to the batch-port
in parms which renames
the file old-name to new-name.
In addition, batch provides some small utilities very useful for writing scripts:
path can be a string or a list of strings. Returns path sans any prefixes ending with a character of the second argument. This can be used to derive a filename moved locally from elsewhere.
(truncate-up-to "/usr/local/lib/slib/batch.scm" "/") ⇒ "batch.scm"
Returns a new string consisting of all the strings string1 … in order appended together with the string joiner between each adjacent pair.
Returns a new list consisting of the elements of list2 ordered so
that if some elements of list1 are equal?
to elements of
list2, then those elements will appear first and in the order of
list1.
Returns a new list consisting of the elements of list1 ordered so
that if some elements of list2 are equal?
to elements of
list1, then those elements will appear last and in the order of
list2.
Returns its best guess for the batch-dialect
to be used for the
operating-system named osname. os->batch-dialect
uses the
tables added to database by batch:initialize!
.
Here is an example of the use of most of batch’s procedures:
(require 'databases) (require 'parameters) (require 'batch) (require 'filename) (define batch (create-database #f 'alist-table)) (batch:initialize! batch) (define my-parameters (list (list 'batch-dialect (os->batch-dialect *operating-system*)) (list 'operating-system *operating-system*) (list 'batch-port (current-output-port)))) ;gets filled in later (batch:call-with-output-script my-parameters "my-batch" (lambda (batch-port) (adjoin-parameters! my-parameters (list 'batch-port batch-port)) (and (batch:comment my-parameters "================ Write file with C program.") (batch:rename-file my-parameters "hello.c" "hello.c~") (batch:lines->file my-parameters "hello.c" "#include <stdio.h>" "int main(int argc, char **argv)" "{" " printf(\"hello world\\n\");" " return 0;" "}" ) (batch:command my-parameters "cc" "-c" "hello.c") (batch:command my-parameters "cc" "-o" "hello" (replace-suffix "hello.c" ".c" ".o")) (batch:command my-parameters "hello") (batch:delete-file my-parameters "hello") (batch:delete-file my-parameters "hello.c") (batch:delete-file my-parameters "hello.o") (batch:delete-file my-parameters "my-batch") )))
Produces the file my-batch:
#! /bin/sh # "my-batch" script created by SLIB/batch Sun Oct 31 18:24:10 1999 # ================ Write file with C program. mv -f hello.c hello.c~ rm -f hello.c echo '#include <stdio.h>'>>hello.c echo 'int main(int argc, char **argv)'>>hello.c echo '{'>>hello.c echo ' printf("hello world\n");'>>hello.c echo ' return 0;'>>hello.c echo '}'>>hello.c cc -c hello.c cc -o hello hello.o hello rm -f hello rm -f hello.c rm -f hello.o rm -f my-batch
When run, my-batch prints:
bash$ my-batch mv: hello.c: No such file or directory hello world
Next: HTML, Previous: Standard Formatted I/O, Up: Textual Conversion Packages [Contents][Index]