1 /*
2  * Public Domain getopt - history below
3  *
4  */
5 
6 /*
7  * From: gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) Newsgroups: net.sources
8  * Subject: getopt library routine Date: 30 Mar 85 04:45:33 GMT
9  */
10 
11 /*
12  * getopt -- public domain version of standard System V routine
13  *
14  * Strictly enforces the System V Command Syntax Standard; provided by D A
15  * Gwyn of BRL for generic ANSI C implementations
16  *
17  * #define STRICT to prevent acceptance of clustered options with arguments
18  * and ommision of whitespace between option and arg.
19  */
20 
21 /*
22  * Modified by Manuel Novoa III on 1/5/01 to use weak symbols.
23  * Programs needing long options will link gnu_getopt instead.
24  */
25 
26 /*
27  * Last public domain version 1.5 downloaded from uclibc CVS:
28  * http://www.uclibc.org/cgi-bin/cvsweb/uClibc/libc/unistd/getopt.c
29  * on 2003-02-18 by Dave Beckett and tidied:
30  *   Ran through "indent getopt.c -gnu" then fixed up the mess
31  *   Removed register - compilers are smart these days
32  *   ANSI-fied the declarations
33  *   Prefixed with raptor_ so that it doesn't clash with any getopt
34  *   linked in later.
35  */
36 
37 
38 #include <stdio.h>
39 #include <string.h>
40 
41 #include <rasqal_getopt.h>
42 
43 int opterr;		/* error => print message */
44 int optind;		/* next argv[] index */
45 int optopt;		/* Set for unknown arguments */
46 char *optarg;		/* option parameter if any */
47 
48 /*
49  * Err:
50  * program name argv[0]
51  * specific message
52  * defective option letter
53  */
54 static int
Err(char * name,const char * mess,int c)55 Err (char *name, const char *mess, int c)		/* returns '?' */
56 {
57   optopt = c;
58   if (opterr)
59     {
60       (void) fprintf (stderr, "%s: %s -- %c\n", name, mess, c);
61     }
62 
63   return '?';			/* erroneous-option marker */
64 }
65 
66 
67 int
getopt(int argc,char * const argv[],const char * optstring)68 getopt (int argc, char * const argv[], const char *optstring)
69 {
70   static int sp = 1;		/* position within argument */
71   int osp;		/* saved `sp' for param test */
72 
73 #ifndef STRICT
74   int oind;		/* saved `optind' for param test */
75 #endif
76   int c;		/* option letter */
77   char *cp;		/* -> option in `optstring' */
78 
79   optarg = NULL;
80 
81   /* initialise getopt vars */
82   if (optind == 0)
83     {
84       optind = 1;
85       opterr = 1;
86       optopt = 1;
87       optarg = NULL;
88     }
89 
90   if (sp == 1)
91     {				/* fresh argument */
92       if (optind >= argc	/* no more arguments */
93 	  || argv[optind][0] != '-'	/* no more options */
94 	  || argv[optind][1] == '\0'	/* not option; stdin */
95 	)
96 	return EOF;
97       else if (strcmp (argv[optind], "--") == 0)
98 	{
99 	  ++optind;		/* skip over "--" */
100 	  return EOF;		/* "--" marks end of options */
101 	}
102     }
103 
104   c = argv[optind][sp];		/* option letter */
105   osp = sp++;			/* get ready for next letter */
106 
107 #ifndef STRICT
108   oind = optind;		/* save optind for param test */
109 #endif
110   if (argv[optind][sp] == '\0')
111     {				/* end of argument */
112       ++optind;			/* get ready for next try */
113       sp = 1;			/* beginning of next argument */
114     }
115 
116   if (c == ':'
117       || c == '?'	/* optstring syntax conflict */
118       || (cp = strchr (optstring, c)) == NULL) /* not found */
119     {
120       return Err (argv[0], "illegal option", c);
121     }
122 
123   if (cp[1] == ':')
124     {				/* option takes parameter */
125 #ifdef STRICT
126       if (osp != 1)
127 	{
128 	  return Err (argv[0], "option must not be clustered", c);
129 	}
130 
131       /* reset by end of argument */
132       if (sp != 1)
133 	{
134 	  return Err (argv[0], "option must be followed by white space", c);
135 	}
136 #else
137       if (oind == optind)
138 	{			/* argument w/o whitespace */
139 	  optarg = &argv[optind][sp];
140 	  sp = 1;		/* beginning of next argument */
141 	}
142 
143       else
144 #endif
145       if (optind >= argc)
146 	{
147 	  return Err (argv[0], "option requires an argument", c);
148 	}
149 
150       else			/* argument w/ whitespace */
151 	optarg = argv[optind];
152 
153       ++optind;			/* skip over parameter */
154     }
155 
156   return c;
157 }
158