136 lines
4.1 KiB
C++
136 lines
4.1 KiB
C++
|
/*
|
||
|
getopt.c -- Turbo C
|
||
|
|
||
|
Copyright (c) 1986,1987 by Borland International Inc.
|
||
|
All Rights Reserved.
|
||
|
*/
|
||
|
|
||
|
#include <errno.h>
|
||
|
#include <string.h>
|
||
|
#include <dos.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
int optind = 1; /* index of which argument is next */
|
||
|
char *optarg; /* pointer to argument of current option */
|
||
|
int opterr = 1; /* allow error message */
|
||
|
|
||
|
static char *letP = NULL; /* remember next option char's location */
|
||
|
static char SW = 0; /* DOS switch character, either '-' or '/' */
|
||
|
|
||
|
/*
|
||
|
Parse the command line options, System V style.
|
||
|
|
||
|
Standard option syntax is:
|
||
|
|
||
|
option ::= SW [optLetter]* [argLetter space* argument]
|
||
|
|
||
|
where
|
||
|
- SW is either '/' or '-', according to the current setting
|
||
|
of the MSDOS switchar (int 21h function 37h).
|
||
|
- there is no space before any optLetter or argLetter.
|
||
|
- opt/arg letters are alphabetic, not punctuation characters.
|
||
|
- optLetters, if present, must be matched in optionS.
|
||
|
- argLetters, if present, are found in optionS followed by ':'.
|
||
|
- argument is any white-space delimited string. Note that it
|
||
|
can include the SW character.
|
||
|
- upper and lower case letters are distinct.
|
||
|
|
||
|
There may be multiple option clusters on a command line, each
|
||
|
beginning with a SW, but all must appear before any non-option
|
||
|
arguments (arguments not introduced by SW). Opt/arg letters may
|
||
|
be repeated: it is up to the caller to decide if that is an error.
|
||
|
|
||
|
The character SW appearing alone as the last argument is an error.
|
||
|
The lead-in sequence SWSW ("--" or "//") causes itself and all the
|
||
|
rest of the line to be ignored (allowing non-options which begin
|
||
|
with the switch char).
|
||
|
|
||
|
The string *optionS allows valid opt/arg letters to be recognized.
|
||
|
argLetters are followed with ':'. Getopt () returns the value of
|
||
|
the option character found, or EOF if no more options are in the
|
||
|
command line. If option is an argLetter then the global optarg is
|
||
|
set to point to the argument string (having skipped any white-space).
|
||
|
|
||
|
The global optind is initially 1 and is always left as the index
|
||
|
of the next argument of argv[] which getopt has not taken. Note
|
||
|
that if "--" or "//" are used then optind is stepped to the next
|
||
|
argument before getopt() returns EOF.
|
||
|
|
||
|
If an error occurs, that is an SW char precedes an unknown letter,
|
||
|
then getopt() will return a '?' character and normally prints an
|
||
|
error message via perror(). If the global variable opterr is set
|
||
|
to false (zero) before calling getopt() then the error message is
|
||
|
not printed.
|
||
|
|
||
|
For example, if the MSDOS switch char is '/' (the MSDOS norm) and
|
||
|
|
||
|
*optionS == "A:F:PuU:wXZ:"
|
||
|
|
||
|
then 'P', 'u', 'w', and 'X' are option letters and 'F', 'U', 'Z'
|
||
|
are followed by arguments. A valid command line may be:
|
||
|
|
||
|
aCommand /uPFPi /X /A L someFile
|
||
|
|
||
|
where:
|
||
|
- 'u' and 'P' will be returned as isolated option letters.
|
||
|
- 'F' will return with "Pi" as its argument string.
|
||
|
- 'X' is an isolated option.
|
||
|
- 'A' will return with "L" as its argument.
|
||
|
- "someFile" is not an option, and terminates getOpt. The
|
||
|
caller may collect remaining arguments using argv pointers.
|
||
|
*/
|
||
|
|
||
|
int getopt(int argc, char *argv[], char *optionS)
|
||
|
{
|
||
|
unsigned char ch;
|
||
|
char *optP;
|
||
|
|
||
|
if (SW == 0) {
|
||
|
/* get SW using dos call 0x37 */
|
||
|
_AX = 0x3700;
|
||
|
geninterrupt(0x21);
|
||
|
SW = _DL;
|
||
|
}
|
||
|
|
||
|
if (argc > optind) {
|
||
|
if (letP == NULL) {
|
||
|
if ((letP = argv[optind]) == NULL ||
|
||
|
*(letP++) != SW) goto gopEOF;
|
||
|
if (*letP == SW) {
|
||
|
optind++; goto gopEOF;
|
||
|
}
|
||
|
}
|
||
|
if (0 == (ch = *(letP++))) {
|
||
|
optind++; goto gopEOF;
|
||
|
}
|
||
|
if (':' == ch || (optP = strchr(optionS, ch)) == NULL)
|
||
|
goto gopError;
|
||
|
if (':' == *(++optP)) {
|
||
|
optind++;
|
||
|
if (0 == *letP) {
|
||
|
if (argc <= optind) goto gopError;
|
||
|
letP = argv[optind++];
|
||
|
}
|
||
|
optarg = letP;
|
||
|
letP = NULL;
|
||
|
} else {
|
||
|
if (0 == *letP) {
|
||
|
optind++;
|
||
|
letP = NULL;
|
||
|
}
|
||
|
optarg = NULL;
|
||
|
}
|
||
|
return ch;
|
||
|
}
|
||
|
gopEOF:
|
||
|
optarg = letP = NULL;
|
||
|
return EOF;
|
||
|
|
||
|
gopError:
|
||
|
optarg = NULL;
|
||
|
errno = EINVAL;
|
||
|
if (opterr)
|
||
|
perror ("get command line option");
|
||
|
return ('?');
|
||
|
}
|