Programming Corner from Icon Newsletter 42


July 15, 1993; Icon Version 8

When Icon is run from the command line, arguments are passed to the main procedure in the form of a list of strings, one for each argument. This is the main way in which information is passed to a program that is run from the command line. For example, if a program that is named tabulate begins with
procedure main(arglist)
   limit := integer(arglist[1])
   bound := integer(arglist[2])
and tabulate is called as
tabulate 15 30
limit is set to 15 and bound is set to 30. A more sophisticated program might issue an error message for a non-integer value and provide defaults for omitted arguments.

Command-line arguments can be used in any way you like. If you use a standard format that is supported by the Icon program library procedure options(), other Icon programmers will know how to specify options without special documentation and you can take advantage of the powerful features provided by options().

options() was originally written by Bob Alexander. Gregg Townsend and Bob subsequently made a number of improvements. The description of options() that follows is based on the documentation in their program. There are more features than described here. See the program for complete documentation.

options(arglist, optstring) separates and interprets options given in arglist. Option names and values are removed from arglist and returned in a table.

Options are introduced by the character -. An option name is either a single printable character, as in -n, or a string of letters, as in -geometry. Valueless single-character options may appear in combination, for example as -qtv.

Some options require values. Generally, the option name is one argument and the value appears as the next argument, as in -F file.txt. However, with a single-character argument name (as in this example), the value may be concatenated: -Ffile.txt is equivalent to the form above.

Options may be freely interspersed with non-option arguments. An argument of - is treated as a non-option. The special argument -- terminates option processing. Non-option arguments are retained in the original argument list for interpretation by the caller.

The argument optstring is a string specifying the allowable options. This is a concatenation, with optional spaces between one or more option specifications of the form -name% where - introduces the option name and is either a string of letters or any single printable character. % is one of the following flags:
!	  no value is required or allowed
:	  a string value is required
+	  an integer value is required
.	  a real value is required
The leading - may be omitted for a single-character option. The ! flag may be omitted except when needed to terminate a multi-character name. Thus, the following optstrings are equivalent:
"-n+ -t -v -q -F: -geometry: -silent"
"n+tvqF:-geometry:-silent"
"-silent!n+tvqF:-geometry:"
If optstring is omitted or null, any single letter is assumed to be valid and to require no data.

options() returns a table that contains the options that were specified. The keys are the specified option names. The assigned values are the data values following the options, converted to the specified type. A value of 1 is stored for options that accept no values. The table's default value is &null.

Upon return, the option arguments are removed from arglist, leaving only the non-option arguments.

Obviously, options() is a very capable procedure. The question is how to use it. Here's an example from the Icon program library.

The program rsg.icn generates randomly constructed sentences from a context-free grammar. It has three options:
-s   i   set the seed for random numbers to i
-l   i   limit sentences to at most i characters,
 	          default 1,000
-t       enable tracing
The portion of rsg.icn that handles these options is
link options

procedure main(args)
	
   opts := options(args, "s+l+t")
   &random := \opts["s"]
   limit := \opts["l"] | 1000
   trace := \opts["t"]
Strings from the command line are passed to main() in the list args, which in turn is passed to options(). The second argument to options() specifies that only three command-line options are allowed, and that -s and -l must have integer arguments. Thus, options() returns a table with entries for "s", "l", and "t". These entries are used in setting variables, as shown.

The non-null test succeeds if the option is present on the command line. Thus, &random is assigned a value only if -s appears on the command line. Similarly, limit is set to the value given on the command line, if -l appears, or to 1000, the default, if it doesn't. Finally, trace is assigned the value 1, provided by options(), if -t appears on the command line.

Obviously, there's some overhead in setting up a program to use options(). The investment usually is well worth the effort. We suggest you try it.

Icon home page