ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/trunk/src/utils/getopt.cpp
Revision: 1782
Committed: Wed Aug 22 02:28:28 2012 UTC (12 years, 8 months ago) by gezelter
File size: 13738 byte(s)
Log Message:
MERGE OpenMD development branch 1465:1781 into trunk

File Contents

# User Rev Content
1 gezelter 1767 /* Getopt for Microsoft C
2     This code is a modification of the Free Software Foundation, Inc.
3     Getopt library for parsing command line argument the purpose was
4     to provide a Microsoft Visual C friendly derivative. This code
5     provides functionality for both Unicode and Multibyte builds.
6    
7     Date: 02/03/2011 - Ludvik Jerabek - Initial Release
8     Version: 1.0
9     Comment: Supports getopt, getopt_long, and getopt_long_only
10     and POSIXLY_CORRECT environment flag
11     License: LGPL
12    
13     Revisions:
14    
15     02/03/2011 - Ludvik Jerabek - Initial Release
16     02/20/2011 - Ludvik Jerabek - Fixed compiler warnings at Level 4
17     07/05/2011 - Ludvik Jerabek - Added no_argument, required_argument, optional_argument defs
18     08/03/2011 - Ludvik Jerabek - Fixed non-argument runtime bug which caused runtime exception
19     08/09/2011 - Ludvik Jerabek - Added code to export functions for DLL and LIB
20     02/15/2012 - Ludvik Jerabek - Fixed _GETOPT_THROW definition missing in implementation file
21    
22     **DISCLAIMER**
23     THIS MATERIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
24     EITHER EXPRESS OR IMPLIED, INCLUDING, BUT Not LIMITED TO, THE
25     IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
26     PURPOSE, OR NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE
27     EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT
28     APPLY TO YOU. IN NO EVENT WILL I BE LIABLE TO ANY PARTY FOR ANY
29     DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY
30     USE OF THIS MATERIAL INCLUDING, WITHOUT LIMITATION, ANY LOST
31     PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON
32     YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN If WE ARE
33     EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
34     */
35    
36     #define _CRT_SECURE_NO_WARNINGS
37     #include <stdlib.h>
38     #include <stdio.h>
39     #include "getopt.h"
40    
41     #ifdef __cplusplus
42     #define _GETOPT_THROW throw()
43     #else
44     #define _GETOPT_THROW
45     #endif
46    
47     enum ENUM_ORDERING { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER };
48    
49     struct _getopt_data
50     {
51     int optind;
52     int opterr;
53     int optopt;
54     TCHAR *optarg;
55     int __initialized;
56     TCHAR *__nextchar;
57     int __ordering;
58     int __posixly_correct;
59     int __first_nonopt;
60     int __last_nonopt;
61     };
62    
63     static struct _getopt_data getopt_data;
64    
65     TCHAR *optarg;
66     int optind = 1;
67     int opterr = 1;
68     int optopt = _T('?');
69    
70     static void exchange(TCHAR **argv, struct _getopt_data *d)
71     {
72     int bottom = d->__first_nonopt;
73     int middle = d->__last_nonopt;
74     int top = d->optind;
75     TCHAR *tem;
76     while (top > middle && middle > bottom)
77     {
78     if (top - middle > middle - bottom)
79     {
80     int len = middle - bottom;
81     register int i;
82     for (i = 0; i < len; i++)
83     {
84     tem = argv[bottom + i];
85     argv[bottom + i] = argv[top - (middle - bottom) + i];
86     argv[top - (middle - bottom) + i] = tem;
87     }
88     top -= len;
89     }
90     else
91     {
92     int len = top - middle;
93     register int i;
94     for (i = 0; i < len; i++)
95     {
96     tem = argv[bottom + i];
97     argv[bottom + i] = argv[middle + i];
98     argv[middle + i] = tem;
99     }
100     bottom += len;
101     }
102     }
103     d->__first_nonopt += (d->optind - d->__last_nonopt);
104     d->__last_nonopt = d->optind;
105     }
106    
107    
108     static const TCHAR *_getopt_initialize (const TCHAR *optstring, struct _getopt_data *d, int posixly_correct)
109     {
110     d->__first_nonopt = d->__last_nonopt = d->optind;
111     d->__nextchar = NULL;
112     d->__posixly_correct = posixly_correct | !!_tgetenv(_T("POSIXLY_CORRECT"));
113    
114    
115     if (optstring[0] == _T('-'))
116     {
117     d->__ordering = RETURN_IN_ORDER;
118     ++optstring;
119     }
120     else if (optstring[0] == _T('+'))
121     {
122     d->__ordering = REQUIRE_ORDER;
123     ++optstring;
124     }
125     else if (d->__posixly_correct)
126     d->__ordering = REQUIRE_ORDER;
127     else
128     d->__ordering = PERMUTE;
129     return optstring;
130     }
131    
132     int _getopt_internal_r (int argc, TCHAR *const *argv, const TCHAR *optstring, const struct option *longopts, int *longind, int long_only, struct _getopt_data *d, int posixly_correct)
133     {
134     int print_errors = d->opterr;
135    
136     if (argc < 1)
137     return -1;
138    
139     d->optarg = NULL;
140    
141     if (d->optind == 0 || !d->__initialized)
142     {
143     if (d->optind == 0)
144     d->optind = 1;
145     optstring = _getopt_initialize (optstring, d, posixly_correct);
146     d->__initialized = 1;
147     }
148     else if (optstring[0] == _T('-') || optstring[0] == _T('+'))
149     optstring++;
150     if (optstring[0] == _T(':'))
151     print_errors = 0;
152    
153     if (d->__nextchar == NULL || *d->__nextchar == _T('\0'))
154     {
155     if (d->__last_nonopt > d->optind)
156     d->__last_nonopt = d->optind;
157     if (d->__first_nonopt > d->optind)
158     d->__first_nonopt = d->optind;
159    
160     if (d->__ordering == PERMUTE)
161     {
162     if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
163     exchange ((TCHAR **) argv, d);
164     else if (d->__last_nonopt != d->optind)
165     d->__first_nonopt = d->optind;
166    
167     while (d->optind < argc && (argv[d->optind][0] != _T('-') || argv[d->optind][1] == _T('\0')))
168     d->optind++;
169     d->__last_nonopt = d->optind;
170     }
171    
172     if (d->optind != argc && !_tcscmp(argv[d->optind], _T("--")))
173     {
174     d->optind++;
175    
176     if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
177     exchange ((TCHAR **) argv, d);
178     else if (d->__first_nonopt == d->__last_nonopt)
179     d->__first_nonopt = d->optind;
180     d->__last_nonopt = argc;
181    
182     d->optind = argc;
183     }
184    
185     if (d->optind == argc)
186     {
187     if (d->__first_nonopt != d->__last_nonopt)
188     d->optind = d->__first_nonopt;
189     return -1;
190     }
191    
192     if ((argv[d->optind][0] != _T('-') || argv[d->optind][1] == _T('\0')))
193     {
194     if (d->__ordering == REQUIRE_ORDER)
195     return -1;
196     d->optarg = argv[d->optind++];
197     return 1;
198     }
199    
200     d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == _T('-')));
201     }
202    
203     if (longopts != NULL && (argv[d->optind][1] == _T('-') || (long_only && (argv[d->optind][2] || !_tcschr(optstring, argv[d->optind][1])))))
204     {
205     TCHAR *nameend;
206     const struct option *p;
207     const struct option *pfound = NULL;
208     int exact = 0;
209     int ambig = 0;
210     int indfound = -1;
211     int option_index;
212    
213     for (nameend = d->__nextchar; *nameend && *nameend != _T('='); nameend++);
214    
215     for (p = longopts, option_index = 0; p->name; p++, option_index++)
216     if (!_tcsncmp(p->name, d->__nextchar, nameend - d->__nextchar))
217     {
218     if ((unsigned int)(nameend - d->__nextchar) == (unsigned int)_tcslen(p->name))
219     {
220     pfound = p;
221     indfound = option_index;
222     exact = 1;
223     break;
224     }
225     else if (pfound == NULL)
226     {
227     pfound = p;
228     indfound = option_index;
229     }
230     else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
231     ambig = 1;
232     }
233    
234     if (ambig && !exact)
235     {
236     if (print_errors)
237     {
238     _ftprintf(stderr, _T("%s: option '%s' is ambiguous\n"),
239     argv[0], argv[d->optind]);
240     }
241     d->__nextchar += _tcslen(d->__nextchar);
242     d->optind++;
243     d->optopt = 0;
244     return _T('?');
245     }
246    
247     if (pfound != NULL)
248     {
249     option_index = indfound;
250     d->optind++;
251     if (*nameend)
252     {
253     if (pfound->has_arg)
254     d->optarg = nameend + 1;
255     else
256     {
257     if (print_errors)
258     {
259     if (argv[d->optind - 1][1] == _T('-'))
260     {
261     _ftprintf(stderr, _T("%s: option '--%s' doesn't allow an argument\n"),argv[0], pfound->name);
262     }
263     else
264     {
265     _ftprintf(stderr, _T("%s: option '%c%s' doesn't allow an argument\n"),argv[0], argv[d->optind - 1][0],pfound->name);
266     }
267    
268     }
269    
270     d->__nextchar += _tcslen(d->__nextchar);
271    
272     d->optopt = pfound->val;
273     return _T('?');
274     }
275     }
276     else if (pfound->has_arg == 1)
277     {
278     if (d->optind < argc)
279     d->optarg = argv[d->optind++];
280     else
281     {
282     if (print_errors)
283     {
284     _ftprintf(stderr,_T("%s: option '--%s' requires an argument\n"),argv[0], pfound->name);
285     }
286     d->__nextchar += _tcslen(d->__nextchar);
287     d->optopt = pfound->val;
288     return optstring[0] == _T(':') ? _T(':') : _T('?');
289     }
290     }
291     d->__nextchar += _tcslen(d->__nextchar);
292     if (longind != NULL)
293     *longind = option_index;
294     if (pfound->flag)
295     {
296     *(pfound->flag) = pfound->val;
297     return 0;
298     }
299     return pfound->val;
300     }
301    
302     if (!long_only || argv[d->optind][1] == _T('-') || _tcschr(optstring, *d->__nextchar) == NULL)
303     {
304     if (print_errors)
305     {
306     if (argv[d->optind][1] == _T('-'))
307     {
308     /* --option */
309     _ftprintf(stderr, _T("%s: unrecognized option '--%s'\n"),argv[0], d->__nextchar);
310     }
311     else
312     {
313     /* +option or -option */
314     _ftprintf(stderr, _T("%s: unrecognized option '%c%s'\n"),argv[0], argv[d->optind][0], d->__nextchar);
315     }
316     }
317     d->__nextchar = (TCHAR *)_T("");
318     d->optind++;
319     d->optopt = 0;
320     return _T('?');
321     }
322     }
323    
324     {
325     TCHAR c = *d->__nextchar++;
326     TCHAR *temp = (TCHAR*)_tcschr(optstring, c);
327    
328     if (*d->__nextchar == _T('\0'))
329     ++d->optind;
330    
331     if (temp == NULL || c == _T(':') || c == _T(';'))
332     {
333     if (print_errors)
334     {
335     _ftprintf(stderr, _T("%s: invalid option -- '%c'\n"), argv[0], c);
336     }
337     d->optopt = c;
338     return _T('?');
339     }
340     if (temp[0] == _T('W') && temp[1] == _T(';'))
341     {
342     TCHAR *nameend;
343     const struct option *p;
344     const struct option *pfound = NULL;
345     int exact = 0;
346     int ambig = 0;
347     int indfound = 0;
348     int option_index;
349    
350     if (*d->__nextchar != _T('\0'))
351     {
352     d->optarg = d->__nextchar;
353     d->optind++;
354     }
355     else if (d->optind == argc)
356     {
357     if (print_errors)
358     {
359     _ftprintf(stderr,
360     _T("%s: option requires an argument -- '%c'\n"),
361     argv[0], c);
362     }
363     d->optopt = c;
364     if (optstring[0] == _T(':'))
365     c = _T(':');
366     else
367     c = _T('?');
368     return c;
369     }
370     else
371     d->optarg = argv[d->optind++];
372    
373     for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != _T('='); nameend++);
374    
375     for (p = longopts, option_index = 0; p->name; p++, option_index++)
376     if (!_tcsncmp(p->name, d->__nextchar, nameend - d->__nextchar))
377     {
378     if ((unsigned int) (nameend - d->__nextchar) == _tcslen(p->name))
379     {
380     pfound = p;
381     indfound = option_index;
382     exact = 1;
383     break;
384     }
385     else if (pfound == NULL)
386     {
387     pfound = p;
388     indfound = option_index;
389     }
390     else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
391     ambig = 1;
392     }
393     if (ambig && !exact)
394     {
395     if (print_errors)
396     {
397     _ftprintf(stderr, _T("%s: option '-W %s' is ambiguous\n"),
398     argv[0], d->optarg);
399     }
400     d->__nextchar += _tcslen(d->__nextchar);
401     d->optind++;
402     return _T('?');
403     }
404     if (pfound != NULL)
405     {
406     option_index = indfound;
407     if (*nameend)
408     {
409     if (pfound->has_arg)
410     d->optarg = nameend + 1;
411     else
412     {
413     if (print_errors)
414     {
415     _ftprintf(stderr, _T("\
416     %s: option '-W %s' doesn't allow an argument\n"),
417     argv[0], pfound->name);
418     }
419    
420     d->__nextchar += _tcslen(d->__nextchar);
421     return _T('?');
422     }
423     }
424     else if (pfound->has_arg == 1)
425     {
426     if (d->optind < argc)
427     d->optarg = argv[d->optind++];
428     else
429     {
430     if (print_errors)
431     {
432     _ftprintf(stderr, _T("\
433     %s: option '-W %s' requires an argument\n"),
434     argv[0], pfound->name);
435     }
436     d->__nextchar += _tcslen(d->__nextchar);
437     return optstring[0] == _T(':') ? _T(':') : _T('?');
438     }
439     }
440     else
441     d->optarg = NULL;
442     d->__nextchar += _tcslen(d->__nextchar);
443     if (longind != NULL)
444     *longind = option_index;
445     if (pfound->flag)
446     {
447     *(pfound->flag) = pfound->val;
448     return 0;
449     }
450     return pfound->val;
451     }
452     d->__nextchar = NULL;
453     return _T('W');
454     }
455     if (temp[1] == _T(':'))
456     {
457     if (temp[2] == _T(':'))
458     {
459     if (*d->__nextchar != _T('\0'))
460     {
461     d->optarg = d->__nextchar;
462     d->optind++;
463     }
464     else
465     d->optarg = NULL;
466     d->__nextchar = NULL;
467     }
468     else
469     {
470     if (*d->__nextchar != _T('\0'))
471     {
472     d->optarg = d->__nextchar;
473     d->optind++;
474     }
475     else if (d->optind == argc)
476     {
477     if (print_errors)
478     {
479     _ftprintf(stderr,
480     _T("%s: option requires an argument -- '%c'\n"),
481     argv[0], c);
482     }
483     d->optopt = c;
484     if (optstring[0] == _T(':'))
485     c = _T(':');
486     else
487     c = _T('?');
488     }
489     else
490     d->optarg = argv[d->optind++];
491     d->__nextchar = NULL;
492     }
493     }
494     return c;
495     }
496     }
497    
498     int _getopt_internal (int argc, TCHAR *const *argv, const TCHAR *optstring, const struct option *longopts, int *longind, int long_only, int posixly_correct)
499     {
500     int result;
501     getopt_data.optind = optind;
502     getopt_data.opterr = opterr;
503     result = _getopt_internal_r (argc, argv, optstring, longopts,longind, long_only, &getopt_data,posixly_correct);
504     optind = getopt_data.optind;
505     optarg = getopt_data.optarg;
506     optopt = getopt_data.optopt;
507     return result;
508     }
509    
510     int getopt (int argc, TCHAR *const *argv, const TCHAR *optstring) _GETOPT_THROW
511     {
512     return _getopt_internal (argc, argv, optstring, (const struct option *) 0, (int *) 0, 0, 0);
513     }
514    
515     int getopt_long (int argc, TCHAR *const *argv, const TCHAR *options, const struct option *long_options, int *opt_index) _GETOPT_THROW
516     {
517     return _getopt_internal (argc, argv, options, long_options, opt_index, 0, 0);
518     }
519    
520     int _getopt_long_r (int argc, TCHAR *const *argv, const TCHAR *options, const struct option *long_options, int *opt_index, struct _getopt_data *d)
521     {
522     return _getopt_internal_r (argc, argv, options, long_options, opt_index,0, d, 0);
523     }
524    
525     int getopt_long_only (int argc, TCHAR *const *argv, const TCHAR *options, const struct option *long_options, int *opt_index) _GETOPT_THROW
526     {
527     return _getopt_internal (argc, argv, options, long_options, opt_index, 1, 0);
528     }
529    
530     int _getopt_long_only_r (int argc, TCHAR *const *argv, const TCHAR *options, const struct option *long_options, int *opt_index, struct _getopt_data *d)
531     {
532     return _getopt_internal_r (argc, argv, options, long_options, opt_index, 1, d, 0);
533     }

Properties

Name Value
svn:eol-style native
svn:executable *