[go: up one dir, main page]

File: getopt.c

package info (click to toggle)
t1utils 1.2-3
  • links: PTS
  • area: main
  • in suites: potato
  • size: 148 kB
  • ctags: 173
  • sloc: ansic: 1,558; makefile: 78; sh: 10
file content (119 lines) | stat: -rw-r--r-- 3,849 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/* getopt.c - get command line options
 *
 * Parse the command line options, System V style.
 *
 * Standard option syntax is:
 *
 *         option = -[optLetter,...][argLetter argument]
 *
 * where
 *    - there is no space between the '-' and optLetters or argLetters.
 *    - optLetters and argLetters 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 '-'.
 *    - upper and lower case letters are distinct.
 *
 * There may be multiple option clusters on a command line, each
 * beginning with a '-', but all must appear before any non-option
 * arguments (arguments not introduced by a '-'). optLetters and
 * argLetters may be repeated, it is up to the caller to decide
 * if that is an error.
 *
 * The character '-' appearing alone as the last argument is an error.
 * The lead-in sequence '--' causes itself and all the rest of the
 * line to be ignored (allowing non-options which begin with '-'.
 *
 * The string *options allows valid optLetters and argLetters 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 '--' is used then optind is stepped to the next argument
 * before getopt() returns EOF.
 *
 * If an error occurs, that is '-' 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
 *
 *         *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:
 *
 *     command  -uPFPi -X -A L otherparameters
 *
 * 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.
 *    - "otherparameters" is not an option, and terminates getOpt.  The
 *      caller may collect remaining arguments using argv pointers.
*/

#include <errno.h>
#include <stdio.h>
#include <string.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 */


int        getopt(int argc, char *argv[], char *options)
{
	  unsigned char ch;
	 char *optP;

	  if (argc > optind) {
		 if (letP == NULL) {
			 if ((letP = argv[optind]) == NULL ||
				 *(letP++) != '-')  goto gopEOF;
			 if (*letP == '-') {
				 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 ("getopt()");
	 return ('?');
}