.TH CRACK 3carl CARL
.SH NAME
crack - scan command line for flags and files
.SH SYNOPSIS
.sp
.nf
.B #include <carl/carl.h>
.B char crack(argc, argv, flags, ign)
.B    int argc; char **argv; char *flags; int ign;
.B extern int arg_index;
.B extern char *arg_option;
.fi
.SH DESCRIPTION
The purpose of this routine is to make scanning the command line of
a program painless and consistent with UNIX usage.  Unfortunately,
many obscure issues arise in solving this problem.  
A practical, intuitive example of the simplicity of 
.B crack()
in use is in the demonstration program
.B commandline(1carl).
Readers who simply want quick implementations should look there.  What follows
is an exigesis of 
.B crack()
itself.
.PP
This routine takes four arguments, the variables 
.B argc 
and 
.B argv 
from
the program's main procedure, a list of flags to recognize, and an
indication whether to ignore unknown flags or not.  
.PP
The action of 
.B crack()
is to read a command line laid out in the format:
.RS .5i
% command [flags] [files]
.RE
where the flags are of the form 
.nf
.RS .5i
-x -y -z[option]
.RE
or alternatively,
.RS .5i
-xyz[option]
.RE
.fi
Provision is made for selected flags to have optional components attached to
the flag, or for flags that do not have optional components to be run
together, yet still be treated as separate flags.
.PP
A flag consists of a
leading minus sign followed by a character.
There is provision for a flag to have
a value, called here the 
.I option, 
butted up to the character.  No space may
appear between any flag and its option.  
.PP
The order of the command line expected by 
.B crack()
is as follows
.RS .5i
% command_name [flags] [filenames]
.RE
The first command line
argument not preceeded by '-' is taken as the end of the flags and the
beginning of file names.
.PP
If we want there to be flags a, b, c, and d,
the 
.B flags 
argument to 
.B crack 
will look like this: "a|b|cd".
In this example, a and b take (optional!) options, as specified
by the trailing vertical bar; flags c and d do not take options.  When 
.B crack()
scans a flag, it
does several things.
First, it
sets the integer variable
.B arg_index 
to the number of
the 
.B argv 
variable it is about to scan.  
Next, it reads the flag character.  If the flag takes an option,
then the variable
.B arg_option 
is set to point to the first character of
the option part.  
If the flag takes an option, and the flag is not present, 
.B arg_option 
is set to NULL.
If the flag does not take an option,
.B arg_option 
is likewise set to NULL.
If the flag does not take an option, but one is supplied, an error is
generated and
.B crack()
returns EOF.
Lastly, 
.B crack()
returns the flag character (or the error status).
.PP
When the next item 
.B crack()
scans is not a flag, it returns NULL.
The value of \fBarg_index\fR then points at the first 
argument after the last flag, which should be the first filename, if
any.  If there are no arguments, or no more arguments after reading 
the flags, 
.B arg_index == argc.
.PP
Flags that do not take options
may be concatenated, for instance, using the flags argument
given above: -cd will treat c and d as
flags.  -cda[option]
also works.  However, tacking what you think is
a flag after another flag that takes an option will cause the flag to
be lost.  I.e., -ac will treat c as an option, not a flag.
.PP
When the 
.B ignore 
argument to 
.B crack
is 0,  flags scanned that are not in the 
.B flags
variable generate an error message and 
.B crack 
returns EOF.  If 
.B ignore 
is
nonzero, unknown flags do not generate error messages.
The purpose of ignoring flags is so that more than one part of a
program can scan the command line without having to know about the
flags of all the other parts.  For instance, where a program calculates
a sampling rate by one flag and a value in seconds in another, it must
search for the sampling rate first, then the time value.  
Two sets of 
calls to
.B crack() 
would be required, one to scan just for the flag setting sampling
rate (since it could occur anywhere among the flags, all flags must
be read), 
another to ignore the rate flag, but to set the time value based
on the sampling rate.
.PP
NOTE: When making muitiple scans of the command line 
in a program, it
is necessary to reset 
.B arg_index 
to 0 to enable 
.B crack()
to rescan all arguments again.
.SH FILES
/usr/local/lib/libdgl.a, /usr/local/lib/libcarl.a, /usr/local/lib/libsf.a.
.SH AUTHOR
Gareth Loy
.SH SEE ALSO
commandline(1carl)
.SH BUGS
When ignoring unknown flags, if an unknown flag has an option
associated with it, the option is also ignored.  Care should be excercised
here because it may be possible that the associated "option" is really
more concatenated flags.  These, if any, are lost.  The rule is that,
when ignoring unknown flags, the first instance of an unknown flag
causes that flag and the rest of that argument to be discarded.  For
instance, if flags is set to "a|b|cd", and a command line:
"-zcda" is supplied, c d and a would be ignored because they come
after z in the same argument.  The point is there is no way to disambiguate
flags from unknown options when ignoring flags, so concatenating options,
while nice, is problematical.
.SH FILES
Demonstration program is: /mnt/carl/src/demo/commandline.c at CARL.
