Windows 命令行解析工具(getopt)

  忘记了上次在哪里找到这个功能库,只有一个 .h 和 .c 文件,再次搜索的时候发现找不到了,结果只能在之前的代码中,两个文件提出使用,顾将这两个文件备份在这里。

  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 08/01/2012 - Ludvik Jerabek - Created separate functions for char and wchar_t characters so single dll can do both unicode and ansi
 22 10/15/2012 - Ludvik Jerabek - Modified to match latest GNU features
 23 06/19/2015 - Ludvik Jerabek - Fixed maximum option limitation caused by option_a (255) and option_w (65535) structure val variable
 24
 25 **DISCLAIMER**
 26 THIS MATERIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
 27 EITHER EXPRESS OR IMPLIED, INCLUDING, BUT Not LIMITED TO, THE
 28 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 29 PURPOSE, OR NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE
 30 EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT
 31 APPLY TO YOU. IN NO EVENT WILL I BE LIABLE TO ANY PARTY FOR ANY
 32 DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY
 33 USE OF THIS MATERIAL INCLUDING, WITHOUT LIMITATION, ANY LOST
 34 PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON
 35 YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN If WE ARE
 36 EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 37 */
 38 #ifndef __GETOPT_H_
 39     #define __GETOPT_H_
 40
 41     #ifdef _GETOPT_API
 42         #undef _GETOPT_API
 43     #endif
 44
 45     #if defined(EXPORTS_GETOPT) && defined(STATIC_GETOPT)
 46         #error "The preprocessor definitions of EXPORTS_GETOPT and STATIC_GETOPT can only be used individually"
 47     #elif defined(STATIC_GETOPT)
 48         #pragma message("Warning static builds of getopt violate the Lesser GNU Public License")
 49         #define _GETOPT_API
 50     #elif defined(EXPORTS_GETOPT)
 51         #pragma message("Exporting getopt library")
 52         #define _GETOPT_API __declspec(dllexport)
 53     #else
 54         #pragma message("Importing getopt library")
 55         #define _GETOPT_API __declspec(dllimport)
 56     #endif
 57
 58     // Change behavior for C\C++
 59     #ifdef __cplusplus
 60         #define _BEGIN_EXTERN_C extern "C" {
 61         #define _END_EXTERN_C }
 62         #define _GETOPT_THROW throw()
 63     #else
 64         #define _BEGIN_EXTERN_C
 65         #define _END_EXTERN_C
 66         #define _GETOPT_THROW
 67     #endif
 68
 69     // Standard GNU options
 70     #define    null_argument        0    /*Argument Null*/
 71     #define    no_argument            0    /*Argument Switch Only*/
 72     #define required_argument    1    /*Argument Required*/
 73     #define optional_argument    2    /*Argument Optional*/
 74
 75     // Shorter Options
 76     #define ARG_NULL    0    /*Argument Null*/
 77     #define ARG_NONE    0    /*Argument Switch Only*/
 78     #define ARG_REQ        1    /*Argument Required*/
 79     #define ARG_OPT        2    /*Argument Optional*/
 80
 81     #include <string.h>
 82     #include <wchar.h>
 83
 84 _BEGIN_EXTERN_C
 85
 86     extern _GETOPT_API int optind;
 87     extern _GETOPT_API int opterr;
 88     extern _GETOPT_API int optopt;
 89
 90     // Ansi
 91     struct option_a
 92     {
 93         const char* name;
 94         int has_arg;
 95         int *flag;
 96         int val;
 97     };
 98     extern _GETOPT_API char *optarg_a;
 99     extern _GETOPT_API int getopt_a(int argc, char *const *argv, const char *optstring) _GETOPT_THROW;
100     extern _GETOPT_API int getopt_long_a(int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW;
101     extern _GETOPT_API int getopt_long_only_a(int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW;
102
103     // Unicode
104     struct option_w
105     {
106         const wchar_t* name;
107         int has_arg;
108         int *flag;
109         int val;
110     };
111     extern _GETOPT_API wchar_t *optarg_w;
112     extern _GETOPT_API int getopt_w(int argc, wchar_t *const *argv, const wchar_t *optstring) _GETOPT_THROW;
113     extern _GETOPT_API int getopt_long_w(int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW;
114     extern _GETOPT_API int getopt_long_only_w(int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW;
115
116 _END_EXTERN_C
117
118     #undef _BEGIN_EXTERN_C
119     #undef _END_EXTERN_C
120     #undef _GETOPT_THROW
121     #undef _GETOPT_API
122
123     #ifdef _UNICODE
124         #define getopt getopt_w
125         #define getopt_long getopt_long_w
126         #define getopt_long_only getopt_long_only_w
127         #define option option_w
128         #define optarg optarg_w
129     #else
130         #define getopt getopt_a
131         #define getopt_long getopt_long_a
132         #define getopt_long_only getopt_long_only_a
133         #define option option_a
134         #define optarg optarg_a
135     #endif
136 #endif  // __GETOPT_H_
  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 08/01/2012 - Ludvik Jerabek - Created separate functions for char and wchar_t characters so single dll can do both unicode and ansi
 22 10/15/2012 - Ludvik Jerabek - Modified to match latest GNU features
 23 06/19/2015 - Ludvik Jerabek - Fixed maximum option limitation caused by option_a (255) and option_w (65535) structure val variable
 24
 25 **DISCLAIMER**
 26 THIS MATERIAL IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
 27 EITHER EXPRESS OR IMPLIED, INCLUDING, BUT Not LIMITED TO, THE
 28 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 29 PURPOSE, OR NON-INFRINGEMENT. SOME JURISDICTIONS DO NOT ALLOW THE
 30 EXCLUSION OF IMPLIED WARRANTIES, SO THE ABOVE EXCLUSION MAY NOT
 31 APPLY TO YOU. IN NO EVENT WILL I BE LIABLE TO ANY PARTY FOR ANY
 32 DIRECT, INDIRECT, SPECIAL OR OTHER CONSEQUENTIAL DAMAGES FOR ANY
 33 USE OF THIS MATERIAL INCLUDING, WITHOUT LIMITATION, ANY LOST
 34 PROFITS, BUSINESS INTERRUPTION, LOSS OF PROGRAMS OR OTHER DATA ON
 35 YOUR INFORMATION HANDLING SYSTEM OR OTHERWISE, EVEN If WE ARE
 36 EXPRESSLY ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
 37 */
 38 #define _CRT_SECURE_NO_WARNINGS
 39 #include <stdlib.h>
 40 #include <stdio.h>
 41 #include <malloc.h>
 42 #include "getopt.h"
 43
 44 #ifdef __cplusplus
 45     #define _GETOPT_THROW throw()
 46 #else
 47     #define _GETOPT_THROW
 48 #endif
 49
 50 int optind = 1;
 51 int opterr = 1;
 52 int optopt = ‘?‘;
 53 enum ENUM_ORDERING { REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER };
 54
 55 //
 56 //
 57 //        Ansi structures and functions follow
 58 //
 59 //
 60
 61 static struct _getopt_data_a
 62 {
 63     int optind;
 64     int opterr;
 65     int optopt;
 66     char *optarg;
 67     int __initialized;
 68     char *__nextchar;
 69     enum ENUM_ORDERING __ordering;
 70     int __posixly_correct;
 71     int __first_nonopt;
 72     int __last_nonopt;
 73 } getopt_data_a;
 74 char *optarg_a;
 75
 76 static void exchange_a(char **argv, struct _getopt_data_a *d)
 77 {
 78     int bottom = d->__first_nonopt;
 79     int middle = d->__last_nonopt;
 80     int top = d->optind;
 81     char *tem;
 82     while (top > middle && middle > bottom)
 83     {
 84         if (top - middle > middle - bottom)
 85         {
 86             int len = middle - bottom;
 87             register int i;
 88             for (i = 0; i < len; i++)
 89             {
 90                 tem = argv[bottom + i];
 91                 argv[bottom + i] = argv[top - (middle - bottom) + i];
 92                 argv[top - (middle - bottom) + i] = tem;
 93             }
 94             top -= len;
 95         }
 96         else
 97         {
 98             int len = top - middle;
 99             register int i;
100             for (i = 0; i < len; i++)
101             {
102                 tem = argv[bottom + i];
103                 argv[bottom + i] = argv[middle + i];
104                 argv[middle + i] = tem;
105             }
106             bottom += len;
107         }
108     }
109     d->__first_nonopt += (d->optind - d->__last_nonopt);
110     d->__last_nonopt = d->optind;
111 }
112 static const char *_getopt_initialize_a (const char *optstring, struct _getopt_data_a *d, int posixly_correct)
113 {
114     d->__first_nonopt = d->__last_nonopt = d->optind;
115     d->__nextchar = NULL;
116     d->__posixly_correct = posixly_correct | !!getenv("POSIXLY_CORRECT");
117     if (optstring[0] == ‘-‘)
118     {
119         d->__ordering = RETURN_IN_ORDER;
120         ++optstring;
121     }
122     else if (optstring[0] == ‘+‘)
123     {
124         d->__ordering = REQUIRE_ORDER;
125         ++optstring;
126     }
127     else if (d->__posixly_correct)
128         d->__ordering = REQUIRE_ORDER;
129     else
130         d->__ordering = PERMUTE;
131     return optstring;
132 }
133 int _getopt_internal_r_a (int argc, char *const *argv, const char *optstring, const struct option_a *longopts, int *longind, int long_only, struct _getopt_data_a *d, int posixly_correct)
134 {
135     int print_errors = d->opterr;
136     if (argc < 1)
137         return -1;
138     d->optarg = NULL;
139     if (d->optind == 0 || !d->__initialized)
140     {
141         if (d->optind == 0)
142             d->optind = 1;
143         optstring = _getopt_initialize_a (optstring, d, posixly_correct);
144         d->__initialized = 1;
145     }
146     else if (optstring[0] == ‘-‘ || optstring[0] == ‘+‘)
147         optstring++;
148     if (optstring[0] == ‘:‘)
149         print_errors = 0;
150     if (d->__nextchar == NULL || *d->__nextchar == ‘\0‘)
151     {
152         if (d->__last_nonopt > d->optind)
153             d->__last_nonopt = d->optind;
154         if (d->__first_nonopt > d->optind)
155             d->__first_nonopt = d->optind;
156         if (d->__ordering == PERMUTE)
157         {
158             if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
159                 exchange_a ((char **) argv, d);
160             else if (d->__last_nonopt != d->optind)
161                 d->__first_nonopt = d->optind;
162             while (d->optind < argc && (argv[d->optind][0] != ‘-‘ || argv[d->optind][1] == ‘\0‘))
163                 d->optind++;
164             d->__last_nonopt = d->optind;
165         }
166         if (d->optind != argc && !strcmp(argv[d->optind], "--"))
167         {
168             d->optind++;
169             if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
170                 exchange_a((char **) argv, d);
171             else if (d->__first_nonopt == d->__last_nonopt)
172                 d->__first_nonopt = d->optind;
173             d->__last_nonopt = argc;
174             d->optind = argc;
175         }
176         if (d->optind == argc)
177         {
178             if (d->__first_nonopt != d->__last_nonopt)
179                 d->optind = d->__first_nonopt;
180             return -1;
181         }
182         if ((argv[d->optind][0] != ‘-‘ || argv[d->optind][1] == ‘\0‘))
183         {
184             if (d->__ordering == REQUIRE_ORDER)
185                 return -1;
186             d->optarg = argv[d->optind++];
187             return 1;
188         }
189         d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == ‘-‘));
190     }
191     if (longopts != NULL && (argv[d->optind][1] == ‘-‘ || (long_only && (argv[d->optind][2] || !strchr(optstring, argv[d->optind][1])))))
192     {
193         char *nameend;
194         unsigned int namelen;
195         const struct option_a *p;
196         const struct option_a *pfound = NULL;
197         struct option_list
198         {
199             const struct option_a *p;
200             struct option_list *next;
201         } *ambig_list = NULL;
202         int exact = 0;
203         int indfound = -1;
204         int option_index;
205         for (nameend = d->__nextchar; *nameend && *nameend != ‘=‘; nameend++);
206         namelen = (unsigned int)(nameend - d->__nextchar);
207         for (p = longopts, option_index = 0; p->name; p++, option_index++)
208             if (!strncmp(p->name, d->__nextchar, namelen))
209             {
210                 if (namelen == (unsigned int)strlen(p->name))
211                 {
212                     pfound = p;
213                     indfound = option_index;
214                     exact = 1;
215                     break;
216                 }
217                 else if (pfound == NULL)
218                 {
219                     pfound = p;
220                     indfound = option_index;
221                 }
222                 else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
223                 {
224                     struct option_list *newp = (struct option_list*)alloca(sizeof(*newp));
225                     newp->p = p;
226                     newp->next = ambig_list;
227                     ambig_list = newp;
228                 }
229             }
230             if (ambig_list != NULL && !exact)
231             {
232                 if (print_errors)
233                 {
234                     struct option_list first;
235                     first.p = pfound;
236                     first.next = ambig_list;
237                     ambig_list = &first;
238                     fprintf (stderr, "%s: option ‘%s‘ is ambiguous; possibilities:", argv[0], argv[d->optind]);
239                     do
240                     {
241                         fprintf (stderr, " ‘--%s‘", ambig_list->p->name);
242                         ambig_list = ambig_list->next;
243                     }
244                     while (ambig_list != NULL);
245                     fputc (‘\n‘, stderr);
246                 }
247                 d->__nextchar += strlen(d->__nextchar);
248                 d->optind++;
249                 d->optopt = 0;
250                 return ‘?‘;
251             }
252             if (pfound != NULL)
253             {
254                 option_index = indfound;
255                 d->optind++;
256                 if (*nameend)
257                 {
258                     if (pfound->has_arg)
259                         d->optarg = nameend + 1;
260                     else
261                     {
262                         if (print_errors)
263                         {
264                             if (argv[d->optind - 1][1] == ‘-‘)
265                             {
266                                 fprintf(stderr, "%s: option ‘--%s‘ doesn‘t allow an argument\n",argv[0], pfound->name);
267                             }
268                             else
269                             {
270                                 fprintf(stderr, "%s: option ‘%c%s‘ doesn‘t allow an argument\n",argv[0], argv[d->optind - 1][0],pfound->name);
271                             }
272                         }
273                         d->__nextchar += strlen(d->__nextchar);
274                         d->optopt = pfound->val;
275                         return ‘?‘;
276                     }
277                 }
278                 else if (pfound->has_arg == 1)
279                 {
280                     if (d->optind < argc)
281                         d->optarg = argv[d->optind++];
282                     else
283                     {
284                         if (print_errors)
285                         {
286                             fprintf(stderr,"%s: option ‘--%s‘ requires an argument\n",argv[0], pfound->name);
287                         }
288                         d->__nextchar += strlen(d->__nextchar);
289                         d->optopt = pfound->val;
290                         return optstring[0] == ‘:‘ ? ‘:‘ : ‘?‘;
291                     }
292                 }
293                 d->__nextchar += strlen(d->__nextchar);
294                 if (longind != NULL)
295                     *longind = option_index;
296                 if (pfound->flag)
297                 {
298                     *(pfound->flag) = pfound->val;
299                     return 0;
300                 }
301                 return pfound->val;
302             }
303             if (!long_only || argv[d->optind][1] == ‘-‘ || strchr(optstring, *d->__nextchar) == NULL)
304             {
305                 if (print_errors)
306                 {
307                     if (argv[d->optind][1] == ‘-‘)
308                     {
309                         fprintf(stderr, "%s: unrecognized option ‘--%s‘\n",argv[0], d->__nextchar);
310                     }
311                     else
312                     {
313                         fprintf(stderr, "%s: unrecognized option ‘%c%s‘\n",argv[0], argv[d->optind][0], d->__nextchar);
314                     }
315                 }
316                 d->__nextchar = (char *)"";
317                 d->optind++;
318                 d->optopt = 0;
319                 return ‘?‘;
320             }
321     }
322     {
323         char c = *d->__nextchar++;
324         char *temp = (char*)strchr(optstring, c);
325         if (*d->__nextchar == ‘\0‘)
326             ++d->optind;
327         if (temp == NULL || c == ‘:‘ || c == ‘;‘)
328         {
329             if (print_errors)
330             {
331                 fprintf(stderr, "%s: invalid option -- ‘%c‘\n", argv[0], c);
332             }
333             d->optopt = c;
334             return ‘?‘;
335         }
336         if (temp[0] == ‘W‘ && temp[1] == ‘;‘)
337         {
338             char *nameend;
339             const struct option_a *p;
340             const struct option_a *pfound = NULL;
341             int exact = 0;
342             int ambig = 0;
343             int indfound = 0;
344             int option_index;
345             if (longopts == NULL)
346                 goto no_longs;
347             if (*d->__nextchar != ‘\0‘)
348             {
349                 d->optarg = d->__nextchar;
350                 d->optind++;
351             }
352             else if (d->optind == argc)
353             {
354                 if (print_errors)
355                 {
356                     fprintf(stderr,"%s: option requires an argument -- ‘%c‘\n",argv[0], c);
357                 }
358                 d->optopt = c;
359                 if (optstring[0] == ‘:‘)
360                     c = ‘:‘;
361                 else
362                     c = ‘?‘;
363                 return c;
364             }
365             else
366                 d->optarg = argv[d->optind++];
367             for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != ‘=‘; nameend++);
368             for (p = longopts, option_index = 0; p->name; p++, option_index++)
369                 if (!strncmp(p->name, d->__nextchar, nameend - d->__nextchar))
370                 {
371                     if ((unsigned int) (nameend - d->__nextchar) == strlen(p->name))
372                     {
373                         pfound = p;
374                         indfound = option_index;
375                         exact = 1;
376                         break;
377                     }
378                     else if (pfound == NULL)
379                     {
380                         pfound = p;
381                         indfound = option_index;
382                     }
383                     else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
384                         ambig = 1;
385                 }
386                 if (ambig && !exact)
387                 {
388                     if (print_errors)
389                     {
390                         fprintf(stderr, "%s: option ‘-W %s‘ is ambiguous\n",argv[0], d->optarg);
391                     }
392                     d->__nextchar += strlen(d->__nextchar);
393                     d->optind++;
394                     return ‘?‘;
395                 }
396                 if (pfound != NULL)
397                 {
398                     option_index = indfound;
399                     if (*nameend)
400                     {
401                         if (pfound->has_arg)
402                             d->optarg = nameend + 1;
403                         else
404                         {
405                             if (print_errors)
406                             {
407                                 fprintf(stderr, "%s: option ‘-W %s‘ doesn‘t allow an argument\n",argv[0], pfound->name);
408                             }
409                             d->__nextchar += strlen(d->__nextchar);
410                             return ‘?‘;
411                         }
412                     }
413                     else if (pfound->has_arg == 1)
414                     {
415                         if (d->optind < argc)
416                             d->optarg = argv[d->optind++];
417                         else
418                         {
419                             if (print_errors)
420                             {
421                                 fprintf(stderr, "%s: option ‘-W %s‘ requires an argument\n",argv[0], pfound->name);
422                             }
423                             d->__nextchar += strlen(d->__nextchar);
424                             return optstring[0] == ‘:‘ ? ‘:‘ : ‘?‘;
425                         }
426                     }
427                     else
428                         d->optarg = NULL;
429                     d->__nextchar += strlen(d->__nextchar);
430                     if (longind != NULL)
431                         *longind = option_index;
432                     if (pfound->flag)
433                     {
434                         *(pfound->flag) = pfound->val;
435                         return 0;
436                     }
437                     return pfound->val;
438                 }
439 no_longs:
440                 d->__nextchar = NULL;
441                 return ‘W‘;
442         }
443         if (temp[1] == ‘:‘)
444         {
445             if (temp[2] == ‘:‘)
446             {
447                 if (*d->__nextchar != ‘\0‘)
448                 {
449                     d->optarg = d->__nextchar;
450                     d->optind++;
451                 }
452                 else
453                     d->optarg = NULL;
454                 d->__nextchar = NULL;
455             }
456             else
457             {
458                 if (*d->__nextchar != ‘\0‘)
459                 {
460                     d->optarg = d->__nextchar;
461                     d->optind++;
462                 }
463                 else if (d->optind == argc)
464                 {
465                     if (print_errors)
466                     {
467                         fprintf(stderr,"%s: option requires an argument -- ‘%c‘\n",argv[0], c);
468                     }
469                     d->optopt = c;
470                     if (optstring[0] == ‘:‘)
471                         c = ‘:‘;
472                     else
473                         c = ‘?‘;
474                 }
475                 else
476                     d->optarg = argv[d->optind++];
477                 d->__nextchar = NULL;
478             }
479         }
480         return c;
481     }
482 }
483 int _getopt_internal_a (int argc, char *const *argv, const char *optstring, const struct option_a *longopts, int *longind, int long_only, int posixly_correct)
484 {
485     int result;
486     getopt_data_a.optind = optind;
487     getopt_data_a.opterr = opterr;
488     result = _getopt_internal_r_a (argc, argv, optstring, longopts,longind, long_only, &getopt_data_a,posixly_correct);
489     optind = getopt_data_a.optind;
490     optarg_a = getopt_data_a.optarg;
491     optopt = getopt_data_a.optopt;
492     return result;
493 }
494 int getopt_a (int argc, char *const *argv, const char *optstring) _GETOPT_THROW
495 {
496     return _getopt_internal_a (argc, argv, optstring, (const struct option_a *) 0, (int *) 0, 0, 0);
497 }
498 int getopt_long_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW
499 {
500     return _getopt_internal_a (argc, argv, options, long_options, opt_index, 0, 0);
501 }
502 int getopt_long_only_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index) _GETOPT_THROW
503 {
504     return _getopt_internal_a (argc, argv, options, long_options, opt_index, 1, 0);
505 }
506 int _getopt_long_r_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index, struct _getopt_data_a *d)
507 {
508     return _getopt_internal_r_a (argc, argv, options, long_options, opt_index,0, d, 0);
509 }
510 int _getopt_long_only_r_a (int argc, char *const *argv, const char *options, const struct option_a *long_options, int *opt_index, struct _getopt_data_a *d)
511 {
512     return _getopt_internal_r_a (argc, argv, options, long_options, opt_index, 1, d, 0);
513 }
514
515 //
516 //
517 //    Unicode Structures and Functions
518 //
519 //
520
521 static struct _getopt_data_w
522 {
523     int optind;
524     int opterr;
525     int optopt;
526     wchar_t *optarg;
527     int __initialized;
528     wchar_t *__nextchar;
529     enum ENUM_ORDERING __ordering;
530     int __posixly_correct;
531     int __first_nonopt;
532     int __last_nonopt;
533 } getopt_data_w;
534 wchar_t *optarg_w;
535
536 static void exchange_w(wchar_t **argv, struct _getopt_data_w *d)
537 {
538     int bottom = d->__first_nonopt;
539     int middle = d->__last_nonopt;
540     int top = d->optind;
541     wchar_t *tem;
542     while (top > middle && middle > bottom)
543     {
544         if (top - middle > middle - bottom)
545         {
546             int len = middle - bottom;
547             register int i;
548             for (i = 0; i < len; i++)
549             {
550                 tem = argv[bottom + i];
551                 argv[bottom + i] = argv[top - (middle - bottom) + i];
552                 argv[top - (middle - bottom) + i] = tem;
553             }
554             top -= len;
555         }
556         else
557         {
558             int len = top - middle;
559             register int i;
560             for (i = 0; i < len; i++)
561             {
562                 tem = argv[bottom + i];
563                 argv[bottom + i] = argv[middle + i];
564                 argv[middle + i] = tem;
565             }
566             bottom += len;
567         }
568     }
569     d->__first_nonopt += (d->optind - d->__last_nonopt);
570     d->__last_nonopt = d->optind;
571 }
572 static const wchar_t *_getopt_initialize_w (const wchar_t *optstring, struct _getopt_data_w *d, int posixly_correct)
573 {
574     d->__first_nonopt = d->__last_nonopt = d->optind;
575     d->__nextchar = NULL;
576     d->__posixly_correct = posixly_correct | !!_wgetenv(L"POSIXLY_CORRECT");
577     if (optstring[0] == L‘-‘)
578     {
579         d->__ordering = RETURN_IN_ORDER;
580         ++optstring;
581     }
582     else if (optstring[0] == L‘+‘)
583     {
584         d->__ordering = REQUIRE_ORDER;
585         ++optstring;
586     }
587     else if (d->__posixly_correct)
588         d->__ordering = REQUIRE_ORDER;
589     else
590         d->__ordering = PERMUTE;
591     return optstring;
592 }
593 int _getopt_internal_r_w (int argc, wchar_t *const *argv, const wchar_t *optstring, const struct option_w *longopts, int *longind, int long_only, struct _getopt_data_w *d, int posixly_correct)
594 {
595     int print_errors = d->opterr;
596     if (argc < 1)
597         return -1;
598     d->optarg = NULL;
599     if (d->optind == 0 || !d->__initialized)
600     {
601         if (d->optind == 0)
602             d->optind = 1;
603         optstring = _getopt_initialize_w (optstring, d, posixly_correct);
604         d->__initialized = 1;
605     }
606     else if (optstring[0] == L‘-‘ || optstring[0] == L‘+‘)
607         optstring++;
608     if (optstring[0] == L‘:‘)
609         print_errors = 0;
610     if (d->__nextchar == NULL || *d->__nextchar == L‘\0‘)
611     {
612         if (d->__last_nonopt > d->optind)
613             d->__last_nonopt = d->optind;
614         if (d->__first_nonopt > d->optind)
615             d->__first_nonopt = d->optind;
616         if (d->__ordering == PERMUTE)
617         {
618             if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
619                 exchange_w((wchar_t **) argv, d);
620             else if (d->__last_nonopt != d->optind)
621                 d->__first_nonopt = d->optind;
622             while (d->optind < argc && (argv[d->optind][0] != L‘-‘ || argv[d->optind][1] == L‘\0‘))
623                 d->optind++;
624             d->__last_nonopt = d->optind;
625         }
626         if (d->optind != argc && !wcscmp(argv[d->optind], L"--"))
627         {
628             d->optind++;
629             if (d->__first_nonopt != d->__last_nonopt && d->__last_nonopt != d->optind)
630                 exchange_w((wchar_t **) argv, d);
631             else if (d->__first_nonopt == d->__last_nonopt)
632                 d->__first_nonopt = d->optind;
633             d->__last_nonopt = argc;
634             d->optind = argc;
635         }
636         if (d->optind == argc)
637         {
638             if (d->__first_nonopt != d->__last_nonopt)
639                 d->optind = d->__first_nonopt;
640             return -1;
641         }
642         if ((argv[d->optind][0] != L‘-‘ || argv[d->optind][1] == L‘\0‘))
643         {
644             if (d->__ordering == REQUIRE_ORDER)
645                 return -1;
646             d->optarg = argv[d->optind++];
647             return 1;
648         }
649         d->__nextchar = (argv[d->optind] + 1 + (longopts != NULL && argv[d->optind][1] == L‘-‘));
650     }
651     if (longopts != NULL && (argv[d->optind][1] == L‘-‘ || (long_only && (argv[d->optind][2] || !wcschr(optstring, argv[d->optind][1])))))
652     {
653         wchar_t *nameend;
654         unsigned int namelen;
655         const struct option_w *p;
656         const struct option_w *pfound = NULL;
657         struct option_list
658         {
659             const struct option_w *p;
660             struct option_list *next;
661         } *ambig_list = NULL;
662         int exact = 0;
663         int indfound = -1;
664         int option_index;
665         for (nameend = d->__nextchar; *nameend && *nameend != L‘=‘; nameend++);
666         namelen = (unsigned int)(nameend - d->__nextchar);
667         for (p = longopts, option_index = 0; p->name; p++, option_index++)
668             if (!wcsncmp(p->name, d->__nextchar, namelen))
669             {
670                 if (namelen == (unsigned int)wcslen(p->name))
671                 {
672                     pfound = p;
673                     indfound = option_index;
674                     exact = 1;
675                     break;
676                 }
677                 else if (pfound == NULL)
678                 {
679                     pfound = p;
680                     indfound = option_index;
681                 }
682                 else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
683                 {
684                     struct option_list *newp = (struct option_list*)alloca(sizeof(*newp));
685                     newp->p = p;
686                     newp->next = ambig_list;
687                     ambig_list = newp;
688                 }
689             }
690             if (ambig_list != NULL && !exact)
691             {
692                 if (print_errors)
693                 {
694                     struct option_list first;
695                     first.p = pfound;
696                     first.next = ambig_list;
697                     ambig_list = &first;
698                     fwprintf(stderr, L"%s: option ‘%s‘ is ambiguous; possibilities:", argv[0], argv[d->optind]);
699                     do
700                     {
701                         fwprintf (stderr, L" ‘--%s‘", ambig_list->p->name);
702                         ambig_list = ambig_list->next;
703                     }
704                     while (ambig_list != NULL);
705                     fputwc (L‘\n‘, stderr);
706                 }
707                 d->__nextchar += wcslen(d->__nextchar);
708                 d->optind++;
709                 d->optopt = 0;
710                 return L‘?‘;
711             }
712             if (pfound != NULL)
713             {
714                 option_index = indfound;
715                 d->optind++;
716                 if (*nameend)
717                 {
718                     if (pfound->has_arg)
719                         d->optarg = nameend + 1;
720                     else
721                     {
722                         if (print_errors)
723                         {
724                             if (argv[d->optind - 1][1] == L‘-‘)
725                             {
726                                 fwprintf(stderr, L"%s: option ‘--%s‘ doesn‘t allow an argument\n",argv[0], pfound->name);
727                             }
728                             else
729                             {
730                                 fwprintf(stderr, L"%s: option ‘%c%s‘ doesn‘t allow an argument\n",argv[0], argv[d->optind - 1][0],pfound->name);
731                             }
732                         }
733                         d->__nextchar += wcslen(d->__nextchar);
734                         d->optopt = pfound->val;
735                         return L‘?‘;
736                     }
737                 }
738                 else if (pfound->has_arg == 1)
739                 {
740                     if (d->optind < argc)
741                         d->optarg = argv[d->optind++];
742                     else
743                     {
744                         if (print_errors)
745                         {
746                             fwprintf(stderr,L"%s: option ‘--%s‘ requires an argument\n",argv[0], pfound->name);
747                         }
748                         d->__nextchar += wcslen(d->__nextchar);
749                         d->optopt = pfound->val;
750                         return optstring[0] == L‘:‘ ? L‘:‘ : L‘?‘;
751                     }
752                 }
753                 d->__nextchar += wcslen(d->__nextchar);
754                 if (longind != NULL)
755                     *longind = option_index;
756                 if (pfound->flag)
757                 {
758                     *(pfound->flag) = pfound->val;
759                     return 0;
760                 }
761                 return pfound->val;
762             }
763             if (!long_only || argv[d->optind][1] == L‘-‘ || wcschr(optstring, *d->__nextchar) == NULL)
764             {
765                 if (print_errors)
766                 {
767                     if (argv[d->optind][1] == L‘-‘)
768                     {
769                         fwprintf(stderr, L"%s: unrecognized option ‘--%s‘\n",argv[0], d->__nextchar);
770                     }
771                     else
772                     {
773                         fwprintf(stderr, L"%s: unrecognized option ‘%c%s‘\n",argv[0], argv[d->optind][0], d->__nextchar);
774                     }
775                 }
776                 d->__nextchar = (wchar_t *)L"";
777                 d->optind++;
778                 d->optopt = 0;
779                 return L‘?‘;
780             }
781     }
782     {
783         wchar_t c = *d->__nextchar++;
784         wchar_t *temp = (wchar_t*)wcschr(optstring, c);
785         if (*d->__nextchar == L‘\0‘)
786             ++d->optind;
787         if (temp == NULL || c == L‘:‘ || c == L‘;‘)
788         {
789             if (print_errors)
790             {
791                 fwprintf(stderr, L"%s: invalid option -- ‘%c‘\n", argv[0], c);
792             }
793             d->optopt = c;
794             return L‘?‘;
795         }
796         if (temp[0] == L‘W‘ && temp[1] == L‘;‘)
797         {
798             wchar_t *nameend;
799             const struct option_w *p;
800             const struct option_w *pfound = NULL;
801             int exact = 0;
802             int ambig = 0;
803             int indfound = 0;
804             int option_index;
805             if (longopts == NULL)
806                 goto no_longs;
807             if (*d->__nextchar != L‘\0‘)
808             {
809                 d->optarg = d->__nextchar;
810                 d->optind++;
811             }
812             else if (d->optind == argc)
813             {
814                 if (print_errors)
815                 {
816                     fwprintf(stderr,L"%s: option requires an argument -- ‘%c‘\n",argv[0], c);
817                 }
818                 d->optopt = c;
819                 if (optstring[0] == L‘:‘)
820                     c = L‘:‘;
821                 else
822                     c = L‘?‘;
823                 return c;
824             }
825             else
826                 d->optarg = argv[d->optind++];
827             for (d->__nextchar = nameend = d->optarg; *nameend && *nameend != L‘=‘; nameend++);
828             for (p = longopts, option_index = 0; p->name; p++, option_index++)
829                 if (!wcsncmp(p->name, d->__nextchar, nameend - d->__nextchar))
830                 {
831                     if ((unsigned int) (nameend - d->__nextchar) == wcslen(p->name))
832                     {
833                         pfound = p;
834                         indfound = option_index;
835                         exact = 1;
836                         break;
837                     }
838                     else if (pfound == NULL)
839                     {
840                         pfound = p;
841                         indfound = option_index;
842                     }
843                     else if (long_only || pfound->has_arg != p->has_arg || pfound->flag != p->flag || pfound->val != p->val)
844                         ambig = 1;
845                 }
846                 if (ambig && !exact)
847                 {
848                     if (print_errors)
849                     {
850                         fwprintf(stderr, L"%s: option ‘-W %s‘ is ambiguous\n",argv[0], d->optarg);
851                     }
852                     d->__nextchar += wcslen(d->__nextchar);
853                     d->optind++;
854                     return L‘?‘;
855                 }
856                 if (pfound != NULL)
857                 {
858                     option_index = indfound;
859                     if (*nameend)
860                     {
861                         if (pfound->has_arg)
862                             d->optarg = nameend + 1;
863                         else
864                         {
865                             if (print_errors)
866                             {
867                                 fwprintf(stderr, L"%s: option ‘-W %s‘ doesn‘t allow an argument\n",argv[0], pfound->name);
868                             }
869                             d->__nextchar += wcslen(d->__nextchar);
870                             return L‘?‘;
871                         }
872                     }
873                     else if (pfound->has_arg == 1)
874                     {
875                         if (d->optind < argc)
876                             d->optarg = argv[d->optind++];
877                         else
878                         {
879                             if (print_errors)
880                             {
881                                 fwprintf(stderr, L"%s: option ‘-W %s‘ requires an argument\n",argv[0], pfound->name);
882                             }
883                             d->__nextchar += wcslen(d->__nextchar);
884                             return optstring[0] == L‘:‘ ? L‘:‘ : L‘?‘;
885                         }
886                     }
887                     else
888                         d->optarg = NULL;
889                     d->__nextchar += wcslen(d->__nextchar);
890                     if (longind != NULL)
891                         *longind = option_index;
892                     if (pfound->flag)
893                     {
894                         *(pfound->flag) = pfound->val;
895                         return 0;
896                     }
897                     return pfound->val;
898                 }
899 no_longs:
900                 d->__nextchar = NULL;
901                 return L‘W‘;
902         }
903         if (temp[1] == L‘:‘)
904         {
905             if (temp[2] == L‘:‘)
906             {
907                 if (*d->__nextchar != L‘\0‘)
908                 {
909                     d->optarg = d->__nextchar;
910                     d->optind++;
911                 }
912                 else
913                     d->optarg = NULL;
914                 d->__nextchar = NULL;
915             }
916             else
917             {
918                 if (*d->__nextchar != L‘\0‘)
919                 {
920                     d->optarg = d->__nextchar;
921                     d->optind++;
922                 }
923                 else if (d->optind == argc)
924                 {
925                     if (print_errors)
926                     {
927                         fwprintf(stderr,L"%s: option requires an argument -- ‘%c‘\n",argv[0], c);
928                     }
929                     d->optopt = c;
930                     if (optstring[0] == L‘:‘)
931                         c = L‘:‘;
932                     else
933                         c = L‘?‘;
934                 }
935                 else
936                     d->optarg = argv[d->optind++];
937                 d->__nextchar = NULL;
938             }
939         }
940         return c;
941     }
942 }
943 int _getopt_internal_w (int argc, wchar_t *const *argv, const wchar_t *optstring, const struct option_w *longopts, int *longind, int long_only, int posixly_correct)
944 {
945     int result;
946     getopt_data_w.optind = optind;
947     getopt_data_w.opterr = opterr;
948     result = _getopt_internal_r_w (argc, argv, optstring, longopts,longind, long_only, &getopt_data_w,posixly_correct);
949     optind = getopt_data_w.optind;
950     optarg_w = getopt_data_w.optarg;
951     optopt = getopt_data_w.optopt;
952     return result;
953 }
954 int getopt_w (int argc, wchar_t *const *argv, const wchar_t *optstring) _GETOPT_THROW
955 {
956     return _getopt_internal_w (argc, argv, optstring, (const struct option_w *) 0, (int *) 0, 0, 0);
957 }
958 int getopt_long_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW
959 {
960     return _getopt_internal_w (argc, argv, options, long_options, opt_index, 0, 0);
961 }
962 int getopt_long_only_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index) _GETOPT_THROW
963 {
964     return _getopt_internal_w (argc, argv, options, long_options, opt_index, 1, 0);
965 }
966 int _getopt_long_r_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index, struct _getopt_data_w *d)
967 {
968     return _getopt_internal_r_w (argc, argv, options, long_options, opt_index,0, d, 0);
969 }
970 int _getopt_long_only_r_w (int argc, wchar_t *const *argv, const wchar_t *options, const struct option_w *long_options, int *opt_index, struct _getopt_data_w *d)
971 {
972     return _getopt_internal_r_w (argc, argv, options, long_options, opt_index, 1, d, 0);
973 }
时间: 2024-10-20 08:52:11

Windows 命令行解析工具(getopt)的相关文章

python之命令行解析工具argparse

以前写python的时候都会自己在文件开头写一个usgae函数,用来加上各种注释,给用这个脚本的人提供帮助文档. 今天才知道原来python已经有一个自带的命令行解析工具argparse,用了一下,效果还不错. argparse的官方文档请看 https://docs.python.org/2/howto/argparse.html#id1 from argparse import ArgumentParser p = ArgumentParser(usage='it is usage tip'

转:python命令行解析工具Argparse

转自:http://www.cnblogs.com/jianboqi/archive/2013/01/10/2854726.html 最近在研究pathon的命令行解析工具,argparse,它是Python标准库中推荐使用的编写命令行程序的工具. 以前老是做UI程序,今天试了下命令行程序,感觉相当好,不用再花大把时间去研究界面问题,尤其是vc++中尤其繁琐. 现在用python来实现命令行,核心计算模块可以用c自己写扩展库,效果挺好. 学习了argparse,在官方文档中找到一篇toturia

python命令行解析工具argparse模块【1】

argpaser是python中很好用的一个命令行解析模块,使用它我们可以很方便的创建用户友好型命令行程序.而且argparse会自动生成帮助信息和错误信息. 一.示例 例如下面的例子,从命令行中获取几个整数,然后获取它们的和或者最大值. import argparse parser = argparse.ArgumentParser(description='Process some integers.') parser.add_argument('integers', metavar='N'

Python中最好用的命令行解析工具:argparse

Python 做为一个脚本语言,可以很方便地写各种工具.当你在服务端要运行一个工具或服务时,输入参数似乎是一种硬需(当然你也可以通过配置文件来实现). 如果要以命令行执行,那你需要解析一个命令行参数解析的模块来帮你做这个苦力活. Python 本身就提供了三个命令行参数解析模块,我这里罗列一下它们的大致情况供你了解. getopt,只能简单的处理命令行参数 optparse,功能强大,易于使用,可以方便地生成标准的.符合Unix/Posix 规范的命令行说明.(Python2.7以后弃用,不会继

Google开源命令行解析工具gflags

转自:https://blog.csdn.net/achelloworld/article/details/41959595# gflags是google开源的一套命令行参数解析工具,支持C++和Python语言,其使用方法: 1. 定义参数  使用gflags需要包含头文件#include <gflags/gflags.h>.将需要的命令行参数使用gflags的宏:DEFINE_xxxxx(变量名,默认值,help-string) 定义在文件当中,定义的参数是全局的,gflags支持的参数类

python命令行解析工具argparse模块【3】

上一节,我们讲解了ArgumentParser对象,这一节我们将学习这个对象的add_argument()方法. add_argument()方法的定义了如何解析一个命令行参数,每个参数都有各自独立的设置参数. 1.name or flags add_argument()必须知道参数是可选的还是必须的位置参数,第一个传递给add_arguments的参数必须是可选参数或者是位置参数,例如,下面是可选参数. >>> parser.add_argument('-f','--foo') 而位置

python命令行解析工具argparse模块【4】

上一节我们讲解了add_argument()方法,这一节我们将学习parse_args()方法. parse_args()方法的作用是解析命令行参数,并返回解析之后的命名空间.默认的,参数从sys.argv中获取.       1.参数值语法 parse_args()支持多种语法来解析参数,最简单的方式如下,参数与值分开传递 >>> parser = argparse.ArgumentParser(prog='PROG') >>> parser.add_argument

命令行解析工具argparse简单使用-1

1.基本使用#01.py import argparse parser = argparse.ArgumentParser()    parser.parse_args() $ python 01.py$$ python 01.py --helpusage: 01.py [-h] optional arguments:  -h, --help  show this help message and exit 2.位置参数#02.py import argparse parser = argpar

【解锁】Linenoise——C命令行处理工具

Linenoise 今天解锁一个开源的REPL工具--Linenoise.Linenoise是可以完全代替readline的,非常轻量级的命令行处理工具.Redis,MongoDB和Android都将Linenoise作为命令行解析工具,那么今天我们就来解锁这个开源的命令行处理工具,也许某一天在你的项目里会派上用场. 特性 支持单行和多行编辑模式,实现了常用的键绑定. 支持历史命令记录 支持命令不全 支持命令提示 超轻量级,大约1100行代码(readline大约30,000行代码) 非常方便的