|
|
1.1 root 1: /******************************************************************************
2: * Copyright (c) 2004, 2008 IBM Corporation
3: * All rights reserved.
4: * This program and the accompanying materials
5: * are made available under the terms of the BSD License
6: * which accompanies this distribution, and is available at
7: * http://www.opensource.org/licenses/bsd-license.php
8: *
9: * Contributors:
10: * IBM Corporation - initial implementation
11: *****************************************************************************/
12:
13: /*
14: * includes
15: *******************************************************************************
16: */
17: #include <stdio.h>
18: #include <string.h>
19: #include <stdlib.h>
20: #include <getopt.h>
21:
22: /*
23: * global variables, types & constants
24: * may be removed if already defined
25: *******************************************************************************
26: */
27: int opterr = 1;
28: int optopt = 0;
29: int optind = 1;
30: char *optarg = NULL;
31:
32: /*
33: * internal values needed by getopt
34: * DO NOT CHANGE or REMOVE
35: */
36: enum {
37: OPTIONAL_ARG = 0,
38: MANDATORY_ARG = 1,
39: NO_ARG = 2
40: };
41:
42: /*
43: * variables needed by getopt & getopt_long!
44: * DO NOT REMOVE
45: */
46: static char *optstart = NULL;
47:
48: int
49: getopt(int argc, char **argv, const char *options)
50: {
51: char *optptr;
52: char *argptr;
53: int optman;
54: int idx;
55: int ret = 0;
56: int argpresent;
57:
58: /*
59: * reset used global values
60: */
61: optopt = 0;
62: optarg = NULL;
63:
64: /*
65: * reset getopt if a new argv pointer is passed
66: */
67: if (optstart != argv[0]) {
68: optopt = 0;
69: optind = 1;
70: optarg = NULL;
71: optstart = argv[0];
72: }
73:
74: /*
75: * return if no more arguments are available
76: */
77: if (optind >= argc) {
78: return -1;
79: }
80:
81: /*
82: * start parsing argv[optind]
83: */
84: idx = 0;
85:
86: /*
87: * return if the option does not begin with a '-' or has more than 2 characters
88: */
89: if (argv[optind][idx] != '-') {
90:
91: if (opterr != 0) {
92: printf("unknown option \'%s\', expecting \'-\'\n",
93: argv[optind]);
94: }
95:
96: optopt = (int) argv[optind][idx];
97: optind++;
98:
99: return '?';
100: }
101:
102: /*
103: * continue to the next character in argv[optind]
104: */
105: idx++;
106:
107: /*
108: * identify the option
109: * make sure if an option contains a ':' to invalidate the option
110: */
111: optptr = strchr(argv[optind], ':');
112:
113: if (optptr == NULL) {
114: optptr = strchr(options, (int) argv[optind][idx]);
115: } else {
116: optptr = NULL;
117: }
118:
119: /*
120: * check whether the option is present
121: */
122: if (optptr == NULL) {
123: /*
124: * unknown option detected
125: */
126: if (opterr != 0) {
127: printf("unknown option \'%s\'\n", argv[optind]);
128: }
129:
130: optopt = (int) argv[optind][idx];
131: optind++;
132:
133: return '?';
134: }
135:
136: /*
137: * the option is present in the option string
138: * setup return value
139: */
140: ret = (int) *optptr;
141:
142: /*
143: * get option argument if needed
144: */
145: optptr++;
146:
147: /*
148: * determine between mandatory and optional argument
149: */
150: optman = NO_ARG;
151:
152: if (*optptr == ':') {
153: optman--; // now set to MANDATORY_ARG
154: }
155:
156: if (optman == MANDATORY_ARG) {
157: optptr++;
158:
159: if (*optptr == ':') {
160: optman--; // now set to OPTIONAL_ARG
161: }
162:
163: }
164:
165: /*
166: * if strlen( argv[optind ) is greater than 2,
167: * the argument is in the same argv
168: */
169: if (strlen(argv[optind]) > 2) {
170: argptr = &argv[optind][2];
171:
172: /*
173: * do not allow '-' in an argument
174: */
175: if (strchr(argptr, '-') != NULL) {
176:
177: if (opterr != 0) {
178: printf
179: ("illegal argument value \'%s\' for option \'-%c\'\n",
180: argptr, ret);
181: }
182:
183: optopt = ret;
184:
185: return '?';
186: }
187:
188: } else {
189: /*
190: * move on to the next argv
191: * it now either contains an argument or the next option
192: */
193: optind++;
194:
195: /*
196: * make sure not to overflow
197: */
198: if (optind < argc) {
199: argptr = argv[optind];
200: } else {
201: argptr = NULL;
202: }
203:
204: }
205:
206: /*
207: * do the needed actions for the argument state
208: */
209: switch (optman) {
210: case OPTIONAL_ARG:
211:
212: if (argptr == NULL) {
213: break;
214: }
215:
216: if (*argptr != '-') {
217: /*
218: * argument present
219: */
220: optarg = argptr;
221: optind++;
222:
223: }
224:
225:
226: break;
227:
228: case MANDATORY_ARG:
229: argpresent = (argptr != NULL);
230:
231: if (argpresent) {
232: argpresent = (*argptr != '-');
233: }
234:
235: if (argpresent) {
236: /*
237: * argument present
238: */
239: optarg = argptr;
240: optind++;
241: } else {
242: /*
243: * mandatory argument missing
244: */
245: if (opterr != 0) {
246: printf
247: ("missing argument for option \'-%c\'\n",
248: ret);
249: }
250:
251: optopt = ret;
252:
253: /*
254: * if the first character of options is a ':'
255: * return a ':' instead of a '?' in case of
256: * a missing argument
257: */
258: if (*options == ':') {
259: ret = ':';
260: } else {
261: ret = '?';
262: }
263:
264: }
265:
266:
267: break;
268:
269: case NO_ARG:
270:
271: if (strlen(argv[optind - 1]) > 2) {
272:
273: if (opterr != 0) {
274: printf
275: ("too many arguments for option \'-%c\'\n",
276: ret);
277: }
278:
279: optopt = ret;
280: ret = '?';
281: }
282:
283:
284: break;
285:
286: }
287:
288: return ret;
289: }
290:
291: int
292: getopt_long(int argc, char **argv, const char *shortopts,
293: const struct option *longopts, int *indexptr)
294: {
295: struct option *optptr = (struct option *) longopts;
296: int optidx = 0;
297: int idx;
298: int ret = 0;
299: int argpresent;
300:
301: /*
302: * reset used global values
303: */
304: optopt = 0;
305: optarg = NULL;
306:
307: /*
308: * reset indexptr
309: */
310: *indexptr = -1;
311:
312: /*
313: * reset getopt if a new argv pointer is passed
314: */
315: if (optstart != argv[0]) {
316: optopt = 0;
317: optind = 1;
318: optarg = NULL;
319: optstart = argv[0];
320: }
321:
322: /*
323: * return if no more arguments are available
324: */
325: if (optind >= argc) {
326: return -1;
327: }
328:
329: /*
330: * start parsing argv[optind]
331: */
332: idx = 0;
333:
334: /*
335: * return if the option does not begin with a '-'
336: */
337: if (argv[optind][idx] != '-') {
338: printf("unknown option \'%s\', expecting \'-\'\n",
339: argv[optind]);
340:
341: optind++;
342:
343: return '?';
344: }
345:
346: /*
347: * move on to the next character in argv[optind]
348: */
349: idx++;
350:
351: /*
352: * return getopt() in case of a short option
353: */
354: if (argv[optind][idx] != '-') {
355: return getopt(argc, argv, shortopts);
356: }
357:
358: /*
359: * handle a long option
360: */
361: idx++;
362:
363: while (optptr->name != NULL) {
364:
365: if (strcmp(&argv[optind][idx], optptr->name) == 0) {
366: break;
367: }
368:
369: optptr++;
370: optidx++;
371: }
372:
373: /*
374: * no matching option found
375: */
376: if (optptr->name == NULL) {
377: printf("unknown option \'%s\'\n", argv[optind]);
378:
379: optind++;
380:
381: return '?';
382: }
383:
384: /*
385: * option was found, set up index pointer
386: */
387: *indexptr = optidx;
388:
389: /*
390: * get argument
391: */
392: optind++;
393:
394: switch (optptr->has_arg) {
395: case no_argument:
396: /*
397: * nothing to do
398: */
399:
400: break;
401:
402: case required_argument:
403: argpresent = (optind != argc);
404:
405: if (argpresent) {
406: argpresent = (argv[optind][0] != '-');
407: }
408:
409: if (argpresent) {
410: /*
411: * argument present
412: */
413: optarg = argv[optind];
414: optind++;
415: } else {
416: /*
417: * mandatory argument missing
418: */
419: printf("missing argument for option \'%s\'\n",
420: argv[optind - 1]);
421:
422: ret = '?';
423: }
424:
425:
426: break;
427:
428: case optional_argument:
429:
430: if (optind == argc) {
431: break;
432: }
433:
434: if (argv[optind][0] != '-') {
435: /*
436: * argument present
437: */
438: optarg = argv[optind];
439: optind++;
440: }
441:
442:
443: break;
444:
445: default:
446: printf("unknown argument option for option \'%s\'\n",
447: argv[optind - 1]);
448:
449: ret = '?';
450:
451: break;
452:
453: }
454:
455: /*
456: * setup return values
457: */
458: if (ret != '?') {
459:
460: if (optptr->flag == NULL) {
461: ret = optptr->val;
462: } else {
463: *optptr->flag = optptr->val;
464: ret = 0;
465: }
466:
467: }
468:
469: return ret;
470: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.