ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/OpenMD/branches/development/src/utils/getopt.cpp
Revision: 1767
Committed: Fri Jul 6 22:01:58 2012 UTC (12 years, 9 months ago) by gezelter
File size: 13738 byte(s)
Log Message:
Various fixes required to compile OpenMD with the MS Visual C++ compiler

File Contents

# Content
1 /* 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 *