% $Id: GETOPT.TEX 1.1 2000/01/24 10:18:51 ska Exp ska $
\section{\label{ssgetopt}\subsys{getopt}}

The functions of this subsystem do base upon the implementation
of function \fct{getopt()} by Morgan \quote{Hannibal} Toal, which
already was a \freedos adaption of the original source made by James Hall.

The internals of \fct{getopt()} were compacted and additional variants of
\quote{a-function-that-parses-options} has been implemented on top of
the base source code. This function also co-works with the associated
functions of \msglib.

\subsection{Design}

\fct{getopt()} is a command line parser for options, that means it
can be used to extract any number of options, where each of the
four variants supports additional features superceeding the traditional
scan-options-only parsers, however, no \fct{getopt()} variant accepts
longname options, but scans single letters only, insofar the implementation
conflicts with the behaviour of later DOS utilities, such as {\sc Xcopy},
where the options are single letters themselves, but cannot be joined
together, as usual in tradition Unix utilities.

\begin{example}
For instance:\newline\noindent
\verb|C:\> CMD /Garfield|\newline\noindent
The argument \verb|/Garfield| is detected, most probably, as an option
argument and \fct{getopt()} would return seven options, one each turn:
\verb|G|, \verb|a|, \verb|r|, \verb|f|, \verb|i|, \verb|e|, \verb|l|,
and at last \verb|d|. The DOS tools often would require to call the
command \verb|CMD| like that:\newline\noindent
\verb|C:\> CMD /G/a/r/f/i/e/l/d|
\end{example}

\paragraphe{The parameters of option arguments} includes a not so
wide range of variables in order to detect and scan options; they
will be explained at this example: \verb|CMD /Odo/Jon=Arbuckle/TV= arg/o|:
\begin{description}
\item[Switch character:] The forward slash \verb|/| in the example;
this character immediately preceeds an argument, that is to be interpreted
as an option by the command. The argument is therefore called {\em option
argument} within this document. In total, there are four different switch
characters. The one that:
\begin{enumerate}
\item preceeds an option argument, as the first slash does.
\item is embedded within an option argument, as the second one is.
\item delimits an option from its argument, as the third slash.
\item delimits an option from an non-option argument, as the fourth slash
is.
\end{enumerate}

\item[Argument seperator:] The equal sign \verb|=| in the example;
this character delimits an option from its argument, as the first
sign in the example. The second one is a special case, because
assigns an empty argument to an option.

\item[Option:] All the letters, except the words \verb|Arbuckle| and
\verb|arg|. Because \fct{getopt()} does {\em not} support longname
options, each individual letter represants one option, so \verb|O|,
\verb|d|, \verb|o|, \verb|J|, and \verb|n| are real individual, seperate
options. Conditionally, \verb|T|, \verb|V|, and \verb|l| are options,
too.

Letters are upcased before returning them as a valid option, because
usually there are no case-sensitive options in DOS programs.

Options are not limited to letters, but must not use characters
used otherwise, such as the switch or argument character themselves or
a whitespace.

\item[Argument of an option:] The word \verb|Arbuckle| in the example;
when an {\em argument seperator} follows an option, the right portion
forms an argument of the option immediately preceeding the argument
seperator.

\end{description}

The different variants of \fct{getopt()} differ themselves, what they
support, how customizable they are, and what parameters are hard-coded.
Though, their basic functioning is the same, as show below.

\paragraphe{\fct{getopt()} recieves the values} passed by the startup
code to the function \fct{main()}, usually called \tok{int argc} and
\tok{char *argv[]}, and some argument specifying what options are
supported.

\fct{getopt()} internally maintains two global variables, \tok{int
optchar} and \tok{int optind}, which point to the currently processed
character within the argument: \tok{argv[optind][optchar]}. So, if both
variables are resetted purposefully prior calling \fct{getopt()}, any
array of strings can be pressed easily. The variables are statically
initialized so that they begin to scan argument \tok{optind == 1},
which correct for the parameters of \fct{main()}.

If \tok{optchar} is less than two, \fct{getopt()} assumes that the
argument is processed the first time, thus, it requires an
switch character at its front; otherwise this argument would be
treated as a non-option argument and \fct{getopt()} fails.
That means that \fct{getopt()} does neither automatically skip
non-option arguments nor does it every option on command line, but
only those at the beginning of it.

When \fct{getopt()} found an option, that is enumerated in one of
the option strings, and all the other rules are satisfied, too, the
option is returned to the caller; otherwise \tok{EOF} is returned.

\subsection{Implementation}

\subsubsection{Macros}

The same source code is used to compile all four variants of
\fct{getopt()}, the following three macros control, which function
is generated:
\begin{tabTS}

\fct{GETOPT1} &			to generate getopt1() \\
\fct{GETOPT2} &			to generate getopt2() \\
\fct{GETOPTG} &			to generate getoptG() \\
none & 	to generate getopt() \\

\end{tabTS}


\subsubsection{Variants of \fct{getopt()}}

\begin{description}

\item[\fct{getopt}] The traditional one. It gets passed four arguments:
\tok{int argc}, \tok{char *argv[]}, \tok{char opt1st[]} and \tok{char opt2nd[]}.
\newline\noindent
\tok{argc} and \tok{argv} are the usual string array.\newline\noindent
\tok{opt1st} enumerates options that must not have an argument, and \tok{opt2nd}
enumerates options that must have an argument. Letters must be upcased.

Only one hard-coded switch character and one hard-coded argument seperator
are supported. The switch character can be configured at compiled time
by changing the macro \tok{SWCHAR}, which defaults to the forward
slash \verb/|. The argument seperator is configurable, too, by modifying
the macro \tok{ARGCHAR}, which defaults to the equal sign \verb|=|.

An switch character embedded within options (case \#2 in above list) is
ignored. Switch characters embedded within arguments (cases \#3 and \#4)
are not supported natively, but they can be simulated, when the user
manually patched the variables \tok{optchar} and \tok{optind}.

Empty arguments are not excepted and options must not appear in both
\tok{opt1st} and \tok{opt2nd}. On error, an \fct{Esuppl\_} function
of \subsys{error} is invoked; in conjunction with \msglib  they
are overriden by the appropriate error function of \msglib, otherwise
the internal and in \suppl  hard-coded language is used.

The option \verb|?|, question mark, is processed special, by invoking
the function \tok{void hlpScreen(void)}, which should display a
help screen to the user and then terminate the program. If the
function returns to \fct{getopt()} nonetheless, the option \verb|?|
is returned to the user.

All parameters can be changed upon the next call to \fct{getopt()},
though, the caller must take care that the two global variables
\tok{optchar} and \tok{optind} are resetted to valid values, if
\tok{argc} or \tok{argv} change.

\item[\fct{getopt1()}] The first enhancement. Basically this function
works the same as the plain function \fct{getopt()}, but
\begin{itemize}
\item it supports two hard-coded switch characters, \tok{SWCHAR}
(\verb|/|) and \tok{SWCHAR1} (\verb|-|), and two hard-coded argument
seperators, \tok{ARGCHAR} (\verb|=|) and \tok{ARGCHAR1} (\verb|:|),
\item the same option may appear in both \tok{opt1st} and \tok{opt2nd},
\item arguments may be empty,
\item a boolean state character, either a plus (\verb|+|) or minus
(\verb|-|) sign, hard-coded, can immediately follow the switch character
and applies to all non-argument options, the boolean character is returned
to the caller in addition to the option.
\end{itemize}

\item[\fct{getopt2()}] The second enhancement. Basically this function
works the same as function \fct{getopt1()}, but
\begin{itemize}
\item it recieves a fifth parameter \tok{opt3rd}, which enumerates
argumented options that can be written without an argument seperator,
for instance: instead of placing \verb|P| into \tok{opt2nd} and
passing the command line option as \verb|/P=izza|, one can place \verb|P|
into \tok{opt3rd} and write \verb|Pizza|. But if the first character
of the argument is an argument seperator, the option is considered a
normal argumented option and is validated from \tok{opt2nd}.
\end{itemize}

\item[\fct{getoptG()}] The third, last free-standing and most
generic enhancement.
This function bases upon \fct{getopt2()}, but recieves only two arguments
directly by the call, the \tok{argc} and \tok{argv}. The other parameters
are outsourced into global variables of the same name, \tok{opt1st},
\tok{opt2nd} and \tok{opt3rd}.

Although, these changes discard the reentranebility of \fct{getoptG()},
most DOS programs won't care at all, but by reducing the overhead
while invoking the function, the code becomes more compact and can
be configured statically in many cases.

There are the following additional changes:
\begin{itemize}
\item The switch characters are enumerated by the string contained
in the global variable \tok{char *optSWITCHAR} and default to \tok{"/-"}.
\item The argument seperators are enumerated by the string contained
in the global variable \tok{char *optARGCHAR} and default to \tok{":="}.
\item The boolean state characters are enumerated by the string contained
in the global variable \tok{char *optBOOL} and default to \tok{"+-"}.
\item The global variable \tok{int optFlags} modifies some default
activities:
\begin{description}
\item[\tok{GETOPT\_MARKEMPTY}] When an option argument has been used up, it
is marked as empty, thus, the second character is overwritten by a \tok{'\0'}
byte.
\item[\tok{GETOPT\_IGNORE}] When the scan process hits a non-option argument,
it is skipped until either the end of the argument array is reached or
an option argument is discovered.
\item[\tok{GETOPT\_NOHELPSCREEN]} The option \verb|?| no longer invokes
the function \fct{helpScreen()}.
\item[\tok{optFlags \& GETOPT\_ADVANCE}] The resulting number specifies how
many arguments are to skip when the current option argument has been
used up; this allows to used \verb|tar|-like option for instance:
\verb|tar -cBf 512 dummy.tar files|. Where \verb|512| is an argument of
option \verb|B| and \verb|dummy.tar| of \verb|f|. One can increment
\tok{optFlags} a maximum of \tok{GETOPT\_ADVANCE} times; then the 
behaviour becomes undefined.
\end{description}
\end{itemize}
\end{description}
