The argv library has been designed to handle the argument processing needs of most Unix software and to provide a consistent usage framework for user applications.
The library is reasonably portable having been run successfully on at least the following operating systems: AIX, BSDI, DG/UX, FreeBSD, HPUX, Irix, Linux, MS-DOG, NeXT, OSF, Solaris, SunOS, Ultrix, Unixware, and even Unicos on a Cray Y-MP.
The package includes the library, configuration scripts, shell-script utility application, test program, and extensive documentation (text, texi, info, ps). The library and its documentation are available online at URL http://256stuff.com/sources/argv/. See How To Get.
I can be reached via my web page http://256stuff.com/gray/ with any questions or feedback. Please include the version number of the library that you are using as well as your machine and operating system types.
Gray Watson.
Copyright 1992 to 2010 by Gray Watson.
Gray Watson makes no representations about the suitability of the software described herein for any purpose. It is provided “as is” without express or implied warranty. The name of Gray Watson cannot be used in advertising or publicity pertaining to distribution of the document or software without specific, written prior permission.
Permission to use, copy, modify, and distribute this software for any purpose and without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies, and that the name of Gray Watson not be used in advertising or publicity pertaining to distribution of the document or software without specific, written prior permission.
Gray Watson makes no representations about the suitability of the software described herein for any purpose. It is provided "as is" without express or implied warranty.
One thing that almost all Unix executables need to do is process the command line arguments. Whether this is to enable verbose mode or specify the files for a utility to work on, code has to be written to process these user specified options.
int main(int argc, char **argv) { ... }
As you must know, the command line arguments in most Unix systems are
passed in as arguments to main()
(seen above). The argc
integer argument contains the number of arguments specified. The
argv
variable holds the arguments themselves. It can be thought
of as a pointer to a list of character pointers – or an array of
character pointers.
To get a particular argument from argv
, you use argv[x]
where x
is an integer whose value is from 0 to argc - 1
.
In most Unix implementations, the zeroth argument is always the name the
program was executed with. For instance, if you typed `./ls -al',
argc
would equal 2 and the value of argv[0]
would be
`"./ls"'. The value for argv[1]
would be `"-al"'.
Currently, most programmers either write code on a per program basis to
process arguments or they use the getopt()
routine. Writing
argument processing code for each program results in improper and
inconsistent argument handling. Although better, getopt()
does
not provide the structure needed to ensure conformity in argument
processing and still requires significant code to be written by the
programmer.
The goal for this library was to achieve a standardized way of processing arguments – especially in terms of error and usage messages. Important consideration was also given to reducing the programming time necessary to enable the functionality.
The newest versions of the argv library are available on the web at http://256stuff.com/sources/argv/.
The versions in this repository also include such files as a postscript version of the manual and other large files which may not have been included in the distribution you received.
To configure, compile, and install the library, follow these steps carefully.
NOTE: It seems that some versions of tr (especially from HP-UX)
don't understand tr '[a-z]' '[A-Z]'
. Since configure uses tr
often, you may need to either get GNU's tr (in their textutils package)
or generate the Makefile and conf.h files by hand.
NOTE: The code is pretty dependent on a good ANSI-C compiler. If the configure script gives the `WARNING' that you do not have an ANSI-C compiler, you may still be able to add some sort of option to your compiler to make it ANSI. If there such is an option, please send it to the author so it can be added to the configure script.
You may have specified a `--prefix=PATH' option to configure in which can `/usr/local' will have been replaced with `PATH'.
See the Getting Started section to get up and running with the library. See Getting Started.
This section should give you a quick idea on how to get going.
argv_t
structure array to your main source file, you
need to compile and link your programs with the library.
The argv_t argument structure is as follows:
typedef struct { char ar_short_arg; /* short argument, 'd' if '-d' */ char *ar_long_arg; /* long version of arg, '--delete' */ short ar_type; /* type of variable */ void *ar_variable; /* address of associated variable */ char *ar_var_label; /* label for variable description */ char *ar_comment; /* comment for usage message */ } argv_t;
The ar_short_arg
element contains the character value of the
short option ('d' for `-d') or special codes such as ARGV_LAST
which identifies the last element in the array. See Special Short Args.
The ar_long_arg
element (if not-NULL) holds the string which is
the long version of ar_short_arg
. For instance, with `-d',
you might have "delete". This would mean that `-d' and
`--delete' would be equivalent. `--' is the long-option
prefix per POSIX specs.
You would define an array of these arguments at the top of the file with
main()
in it.
static char copy = ARGV_FALSE; static argv_t args[] = { { 'c', "copy", ARGV_BOOL, &cp_files, NULL, "copy-files flag" }, { 'g', "group", ARGV_CHAR_P, &group, "group", "name of group to set" }, ... { ARGV_LAST } }; ... int main(int argc, char ** argv) { argv_process(args, argc, argv); }
There are 3 types of arguments:
If the argument is a mandatory argument which has no -%c prefix then the
ar_short_arg
element should be assigned ARGV_MAND.
If this is a maybe argument then use ARGV_MAYBE in the
ar_short_arg
field.
To mark the last entry in the structure list use ARGV_LAST.
Ar_type holds the type of the argument whether an optional argument or mandatory. Below are the available values for this field.
ARGV_BOOL
ARGV_BOOL_NEG
ARGV_BOOL_ARG
ARGV_CHAR
ARGV_CHAR_P
ARGV_FLOAT
ARGV_SHORT
ARGV_INT
ARGV_U_INT
ARGV_LONG
ARGV_U_LONG
ARGV_BIN
ARGV_OCT
ARGV_HEX
ARGV_INCR
ARGV_SIZE
ARGV_U_SIZE
ARGV_BOOL_INT
ARGV_BOOL_INT_NEG
ARGV_BOOL_INT_ARG
For printing out of the type of the argument on the command line, use the `--argv-display' option which will display the argument, its type and value. It will display the variables' default values if no arguments specified before it on the command line otherwise it will show the values the variables are set to after processing the arguments.
Basically the argument processing routines, examine the type of the variable, absorb another argument (if necessary), and then translate the string argument (if necessary) and write the data into the address stored in the ar_variable field.
ARGV_BOOL, ARGV_BOOL_NEG, ARGV_INCR, ARGV_BOOL_INT, and ARGV_BOOL_INT_NEG are special in the above list in that they do not require another argument. With `ls -l', for example, the `-l' flag lives on its own. With `install -m 444 ...', on the other hand, `444' is an octal number argument associated with `-m' and will be translated and assigned to the `-m' mode variable.
Needs to be written. Sorry.
If a program `install' has the library compiled in you should be able to do a `install --usage-long' to get the long-format usage message.
Usage: install [-c] or --copy-files = copy file(s), don't move %t [-g group] or --group-id = group id name (default bin) %s [-m octal-mode] or --mode-value = permissions mode value %o [-o owner] or --owner-id = owner id name (default bin) %s [-s] or --strip = strip destination binary %t [file(s)] directory/destination = files to install or mkdir arg
In the above example, the program install's usage message is detailed. The `[-c]' line details the copy-files flag. You can either enable it with a `-c' or `--copy-files'. The description of the flag follows with lastly, a `%t' showing that it is a true/false flag.
The `[-g]' line shows the group-id flag. It is different from the `-c' flag since, if used, it takes a group string argument (notice the `%s' at the end of the line indicating it takes a string argument).
`install --usage-short' or just `--usage' will get you a condensed usage message:
Usage: install [-cs] [-g group] [-m octal-mode] [-o owner] [file(s)] directory/destination
Specifying arguments to a program which uses the library is quite straight-forward and standardized. Once you have learned how to do it once, you can use any program with it.
There are five basic types of arguments as defined by the library:
The `-c' in `install -c'.
The `-m' in `install -m 0644' will get the value `0644'.
The `from' and `to' arguments in `install from to'.
The `file' argument in `ls file' since `ls' does not require a file to be listed to work.
The values for the variable flags are assigned in a straight First-In-First-Out queue. In `install -m -g 0644 bin', the value `0644' is assigned to the `-m' flag and the value `bin' is assigned to `-g'.
Additional values that cannot be matched to variable flags will become mandatory or maybe arguments if the program is configured to accept them.
install from -c -m -g 0644 -o wheel -s jim to
In the previous convoluted example, `from' and `to' are mandatory arguments, `-c' and `-s' are true/false flags, `-m' gets assigned `0644', `-g' gets `wheel', and `-o' gets `jim'. It would be much easier to write it as:
install -cs -m 0644 -g wheel -o jim to from
Needs to be written. Sorry.
An environment variable is a variable that is part of the user's working environment and is shared by all the programs. The `GLOBAL_ARGV' variable is used by the argv library to customize its behavior at runtime. It can be set by hand and should probably be entered into your shell's runtime configuration or RC file.
To set the variable, C shell (csh or tcsh) users need to invoke:
setenv GLOBAL_ARGV value
Bourne shell (sh, bash, ksh, or zsh) users should use:
GLOBAL_ARGV=value export GLOBAL_ARGV
The value in the above example is a comma separated list of tokens each having a corresponding value. The tokens and their values are described below:
Enables the handling of arguments such as `-m=444' where `-m' is a flag and `444' is its value.
Values: disable, enable.
Enables the processing of the `ARGV_*' variables. If you have a set of options that you always use for `ls' for instance, you cat set the `ARGV_LS' environmental variable to hold these options. For instance: `setenv ARGV_LS "-sCF"'.
Values: none, before, after.
Whenever you do not use a command correctly, this token determines how the library reports errors to you.
Values: none, see, short, shortrem, long, all.
If you use am argument twice on the command line, this token determines if the library should say it is an error.
Values: accept, reject.
Determines what messages the library prints when you use the `--usage' option.
Values: short, shortrem, long, all.
Examples:
# accept -x=10, no env variables, long messages on errors, # accept multiple uses, and print all messages on --usage. setenv GLOBAL_ARGV close=accept,env=none,error=long,multi=accept,usage=all # process env variable options before command line, # and reject multiple argument uses setenv GLOBAL_ARGV env=before,error=long,multi=reject
Needs to be written. Sorry.