Imported from antiword-0.37.tar.gz.
[antiword.git] / DOS-only / getopt.c
blob0b1b67817ce4ea6346ecff390771cdc4a55c9d32
1 /*
2 getopt.c -- Turbo C
4 Copyright (c) 1986,87,88 by Borland International Inc.
5 All Rights Reserved.
6 */
8 #include <string.h>
9 #include <stdio.h>
11 int optind = 1; /* index of which argument is next */
12 char *optarg; /* pointer to argument of current option */
13 int opterr = 1; /* allow error message */
15 static char *letP = NULL; /* remember next option char's location */
18 Parse the command line options, System V style.
20 Standard option syntax is:
22 option ::= SW [optLetter]* [argLetter space* argument]
24 where
25 - SW is either '/' or '-', according to the current setting
26 of the MSDOS switchar (int 21h function 37h).
27 - there is no space before any optLetter or argLetter.
28 - opt/arg letters are alphabetic, not punctuation characters.
29 - optLetters, if present, must be matched in optionS.
30 - argLetters, if present, are found in optionS followed by ':'.
31 - argument is any white-space delimited string. Note that it
32 can include the SW character.
33 - upper and lower case letters are distinct.
35 There may be multiple option clusters on a command line, each
36 beginning with a SW, but all must appear before any non-option
37 arguments (arguments not introduced by SW). Opt/arg letters may
38 be repeated: it is up to the caller to decide if that is an error.
40 The character SW appearing alone as the last argument is an error.
41 The lead-in sequence SWSW ("--" or "//") causes itself and all the
42 rest of the line to be ignored (allowing non-options which begin
43 with the switch char).
45 The string *optionS allows valid opt/arg letters to be recognized.
46 argLetters are followed with ':'. Getopt () returns the value of
47 the option character found, or EOF if no more options are in the
48 command line. If option is an argLetter then the global optarg is
49 set to point to the argument string (having skipped any white-space).
51 The global optind is initially 1 and is always left as the index
52 of the next argument of argv[] which getopt has not taken. Note
53 that if "--" or "//" are used then optind is stepped to the next
54 argument before getopt() returns EOF.
56 If an error occurs, that is an SW char precedes an unknown letter,
57 then getopt() will return a '?' character and normally prints an
58 error message via perror(). If the global variable opterr is set
59 to false (zero) before calling getopt() then the error message is
60 not printed.
62 For example, if the MSDOS switch char is '/' (the MSDOS norm) and
64 *optionS == "A:F:PuU:wXZ:"
66 then 'P', 'u', 'w', and 'X' are option letters and 'F', 'U', 'Z'
67 are followed by arguments. A valid command line may be:
69 aCommand /uPFPi /X /A L someFile
71 where:
72 - 'u' and 'P' will be returned as isolated option letters.
73 - 'F' will return with "Pi" as its argument string.
74 - 'X' is an isolated option.
75 - 'A' will return with "L" as its argument.
76 - "someFile" is not an option, and terminates getOpt. The
77 caller may collect remaining arguments using argv pointers.
80 int
81 getopt(int argc, char **argv, const char *optionS)
83 char ch;
84 char *optP;
86 optarg = NULL;
87 if (optind >= argc) {
88 letP = NULL;
89 return EOF;
92 if (letP == NULL) {
93 letP = argv[optind];
94 if (letP == NULL) {
95 return EOF;
97 if (*letP != '-') {
98 letP = NULL;
99 return EOF;
101 letP++;
102 if (*letP == '-') {
103 optind++;
104 letP = NULL;
105 return EOF;
108 ch = *(letP++);
109 if ('\0' == ch) {
110 optind++;
111 letP = NULL;
112 return EOF;
114 if (':' == ch || (optP = strchr(optionS, ch)) == NULL) {
115 if (opterr) {
116 fprintf(stderr, "%s: illegal option -- %c\n",
117 argv[0], ch);
119 return '?';
121 if (':' != *(++optP)) {
122 /* Option without an argument */
123 if ('\0' == *letP) {
124 optind++;
125 letP = NULL;
127 return ch;
129 /* Option with an argument */
130 optind++;
131 if ('\0' == *letP) {
132 if (argc <= optind) {
133 if (opterr) {
134 fprintf(stderr,
135 "%s: option requires an argument -- %c\n",
136 argv[0], ch);
138 return '?';
140 letP = argv[optind++];
142 optarg = letP;
143 letP = NULL;
144 return ch;