ReactOS 0.4.15-dev-7934-g1dc8d80
getopt.c File Reference
#include "getopt.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "getopt_int.h"
Include dependency graph for getopt.c:

Go to the source code of this file.

Macros

#define _(msgid)   (msgid)
 
#define flockfile(fp)   /* nop */
 
#define funlockfile(fp)   /* nop */
 
#define __libc_use_alloca(size)   0
 
#define alloca(size)   (abort (), (void *)0)
 
#define NONOPTION_P   (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
 
#define GETOPT_ENTRY(NAME, POSIXLY_CORRECT)
 

Functions

static void exchange (char **argv, struct _getopt_data *d)
 
static int process_long_option (int argc, char **argv, const char *optstring, const struct option *longopts, int *longind, int long_only, struct _getopt_data *d, int print_errors, const char *prefix)
 
static const char_getopt_initialize (int argc, char **argv, const char *optstring, struct _getopt_data *d, int posixly_correct)
 
int _getopt_internal_r (int argc, char **argv, const char *optstring, const struct option *longopts, int *longind, int long_only, struct _getopt_data *d, int posixly_correct)
 
int _getopt_internal (int argc, char **argv, const char *optstring, const struct option *longopts, int *longind, int long_only, int posixly_correct)
 

Variables

charoptarg
 
int optind = 1
 
int opterr = 1
 
int optopt = '?'
 
static struct _getopt_data getopt_data
 

Macro Definition Documentation

◆ _

#define _ (   msgid)    (msgid)

Definition at line 43 of file getopt.c.

◆ __libc_use_alloca

#define __libc_use_alloca (   size)    0

Definition at line 51 of file getopt.c.

◆ alloca

#define alloca (   size)    (abort (), (void *)0)

Definition at line 53 of file getopt.c.

◆ flockfile

#define flockfile (   fp)    /* nop */

Definition at line 47 of file getopt.c.

◆ funlockfile

#define funlockfile (   fp)    /* nop */

Definition at line 48 of file getopt.c.

◆ GETOPT_ENTRY

#define GETOPT_ENTRY (   NAME,
  POSIXLY_CORRECT 
)
Value:
int \
NAME (int argc, char *const *argv, const char *optstring) \
{ \
return _getopt_internal (argc, (char **)argv, optstring, \
0, 0, 0, POSIXLY_CORRECT); \
}
static int argc
Definition: ServiceArgs.c:12
#define argv
Definition: mplay32.c:18
int _getopt_internal(int argc, char **argv, const char *optstring, const struct option *longopts, int *longind, int long_only, int posixly_correct)
Definition: getopt.c:700

Definition at line 724 of file getopt.c.

◆ NONOPTION_P

#define NONOPTION_P   (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')

Function Documentation

◆ _getopt_initialize()

static const char * _getopt_initialize ( int  argc,
char **  argv,
const char optstring,
struct _getopt_data d,
int  posixly_correct 
)
static

Definition at line 378 of file getopt.c.

381{
382 /* Start processing options with ARGV-element 1 (since ARGV-element 0
383 is the program name); the sequence of previously skipped
384 non-option ARGV-elements is empty. */
385 if (d->optind == 0)
386 d->optind = 1;
387
388 d->__first_nonopt = d->__last_nonopt = d->optind;
389 d->__nextchar = NULL;
390
391 /* Determine how to handle the ordering of options and nonoptions. */
392 if (optstring[0] == '-')
393 {
394 d->__ordering = RETURN_IN_ORDER;
395 ++optstring;
396 }
397 else if (optstring[0] == '+')
398 {
399 d->__ordering = REQUIRE_ORDER;
400 ++optstring;
401 }
402 else if (posixly_correct || !!getenv ("POSIXLY_CORRECT"))
403 d->__ordering = REQUIRE_ORDER;
404 else
405 d->__ordering = PERMUTE;
406
407 d->__initialized = 1;
408 return optstring;
409}
#define NULL
Definition: types.h:112
@ REQUIRE_ORDER
Definition: getopt.cpp:45
@ RETURN_IN_ORDER
Definition: getopt.cpp:45
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
#define d
Definition: ke_i.h:81
#define PERMUTE
Definition: getopt.c:41

Referenced by _getopt_internal_r().

◆ _getopt_internal()

int _getopt_internal ( int  argc,
char **  argv,
const char optstring,
const struct option longopts,
int longind,
int  long_only,
int  posixly_correct 
)

Definition at line 700 of file getopt.c.

703{
704 int result;
705
706 getopt_data.optind = optind;
707 getopt_data.opterr = opterr;
708
709 result = _getopt_internal_r (argc, argv, optstring, longopts,
710 longind, long_only, &getopt_data,
711 posixly_correct);
712
713 optind = getopt_data.optind;
714 optarg = getopt_data.optarg;
715 optopt = getopt_data.optopt;
716
717 return result;
718}
int optopt
Definition: getopt.c:48
const char * optarg
Definition: getopt.c:49
int optind
Definition: getopt.c:47
int opterr
Definition: getopt.c:46
GLuint64EXT * result
Definition: glext.h:11304
static struct _getopt_data getopt_data
Definition: getopt.c:116
int _getopt_internal_r(int argc, char **argv, const char *optstring, const struct option *longopts, int *longind, int long_only, struct _getopt_data *d, int posixly_correct)
Definition: getopt.c:468

◆ _getopt_internal_r()

int _getopt_internal_r ( int  argc,
char **  argv,
const char optstring,
const struct option longopts,
int longind,
int  long_only,
struct _getopt_data d,
int  posixly_correct 
)

Definition at line 468 of file getopt.c.

471{
472 int print_errors = d->opterr;
473
474 if (argc < 1)
475 return -1;
476
477 d->optarg = NULL;
478
479 if (d->optind == 0 || !d->__initialized)
480 optstring = _getopt_initialize (argc, argv, optstring, d, posixly_correct);
481 else if (optstring[0] == '-' || optstring[0] == '+')
482 optstring++;
483
484 if (optstring[0] == ':')
485 print_errors = 0;
486
487 /* Test whether ARGV[optind] points to a non-option argument. */
488#define NONOPTION_P (argv[d->optind][0] != '-' || argv[d->optind][1] == '\0')
489
490 if (d->__nextchar == NULL || *d->__nextchar == '\0')
491 {
492 /* Advance to the next ARGV-element. */
493
494 /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
495 moved back by the user (who may also have changed the arguments). */
496 if (d->__last_nonopt > d->optind)
497 d->__last_nonopt = d->optind;
498 if (d->__first_nonopt > d->optind)
499 d->__first_nonopt = d->optind;
500
501 if (d->__ordering == PERMUTE)
502 {
503 /* If we have just processed some options following some non-options,
504 exchange them so that the options come first. */
505
506 if (d->__first_nonopt != d->__last_nonopt
507 && d->__last_nonopt != d->optind)
508 exchange (argv, d);
509 else if (d->__last_nonopt != d->optind)
510 d->__first_nonopt = d->optind;
511
512 /* Skip any additional non-options
513 and extend the range of non-options previously skipped. */
514
515 while (d->optind < argc && NONOPTION_P)
516 d->optind++;
517 d->__last_nonopt = d->optind;
518 }
519
520 /* The special ARGV-element '--' means premature end of options.
521 Skip it like a null option,
522 then exchange with previous non-options as if it were an option,
523 then skip everything else like a non-option. */
524
525 if (d->optind != argc && !strcmp (argv[d->optind], "--"))
526 {
527 d->optind++;
528
529 if (d->__first_nonopt != d->__last_nonopt
530 && d->__last_nonopt != d->optind)
531 exchange (argv, d);
532 else if (d->__first_nonopt == d->__last_nonopt)
533 d->__first_nonopt = d->optind;
534 d->__last_nonopt = argc;
535
536 d->optind = argc;
537 }
538
539 /* If we have done all the ARGV-elements, stop the scan
540 and back over any non-options that we skipped and permuted. */
541
542 if (d->optind == argc)
543 {
544 /* Set the next-arg-index to point at the non-options
545 that we previously skipped, so the caller will digest them. */
546 if (d->__first_nonopt != d->__last_nonopt)
547 d->optind = d->__first_nonopt;
548 return -1;
549 }
550
551 /* If we have come to a non-option and did not permute it,
552 either stop the scan or describe it to the caller and pass it by. */
553
554 if (NONOPTION_P)
555 {
556 if (d->__ordering == REQUIRE_ORDER)
557 return -1;
558 d->optarg = argv[d->optind++];
559 return 1;
560 }
561
562 /* We have found another option-ARGV-element.
563 Check whether it might be a long option. */
564 if (longopts)
565 {
566 if (argv[d->optind][1] == '-')
567 {
568 /* "--foo" is always a long option. The special option
569 "--" was handled above. */
570 d->__nextchar = argv[d->optind] + 2;
571 return process_long_option (argc, argv, optstring, longopts,
572 longind, long_only, d,
573 print_errors, "--");
574 }
575
576 /* If long_only and the ARGV-element has the form "-f",
577 where f is a valid short option, don't consider it an
578 abbreviated form of a long option that starts with f.
579 Otherwise there would be no way to give the -f short
580 option.
581
582 On the other hand, if there's a long option "fubar" and
583 the ARGV-element is "-fu", do consider that an
584 abbreviation of the long option, just like "--fu", and
585 not "-f" with arg "u".
586
587 This distinction seems to be the most useful approach. */
588 if (long_only && (argv[d->optind][2]
589 || !strchr (optstring, argv[d->optind][1])))
590 {
591 int code;
592 d->__nextchar = argv[d->optind] + 1;
593 code = process_long_option (argc, argv, optstring, longopts,
594 longind, long_only, d,
595 print_errors, "-");
596 if (code != -1)
597 return code;
598 }
599 }
600
601 /* It is not a long option. Skip the initial punctuation. */
602 d->__nextchar = argv[d->optind] + 1;
603 }
604
605 /* Look at and handle the next short option-character. */
606
607 {
608 char c = *d->__nextchar++;
609 const char *temp = strchr (optstring, c);
610
611 /* Increment 'optind' when we start to process its last character. */
612 if (*d->__nextchar == '\0')
613 ++d->optind;
614
615 if (temp == NULL || c == ':' || c == ';')
616 {
617 if (print_errors)
618 fprintf (stderr, _("%s: invalid option -- '%c'\n"), argv[0], c);
619 d->optopt = c;
620 return '?';
621 }
622
623 /* Convenience. Treat POSIX -W foo same as long option --foo */
624 if (temp[0] == 'W' && temp[1] == ';' && longopts != NULL)
625 {
626 /* This is an option that requires an argument. */
627 if (*d->__nextchar != '\0')
628 d->optarg = d->__nextchar;
629 else if (d->optind == argc)
630 {
631 if (print_errors)
633 _("%s: option requires an argument -- '%c'\n"),
634 argv[0], c);
635
636 d->optopt = c;
637 if (optstring[0] == ':')
638 c = ':';
639 else
640 c = '?';
641 return c;
642 }
643 else
644 d->optarg = argv[d->optind];
645
646 d->__nextchar = d->optarg;
647 d->optarg = NULL;
648 return process_long_option (argc, argv, optstring, longopts, longind,
649 0 /* long_only */, d, print_errors, "-W ");
650 }
651 if (temp[1] == ':')
652 {
653 if (temp[2] == ':')
654 {
655 /* This is an option that accepts an argument optionally. */
656 if (*d->__nextchar != '\0')
657 {
658 d->optarg = d->__nextchar;
659 d->optind++;
660 }
661 else
662 d->optarg = NULL;
663 d->__nextchar = NULL;
664 }
665 else
666 {
667 /* This is an option that requires an argument. */
668 if (*d->__nextchar != '\0')
669 {
670 d->optarg = d->__nextchar;
671 /* If we end this ARGV-element by taking the rest as an arg,
672 we must advance to the next element now. */
673 d->optind++;
674 }
675 else if (d->optind == argc)
676 {
677 if (print_errors)
679 _("%s: option requires an argument -- '%c'\n"),
680 argv[0], c);
681
682 d->optopt = c;
683 if (optstring[0] == ':')
684 c = ':';
685 else
686 c = '?';
687 }
688 else
689 /* We already incremented 'optind' once;
690 increment it again when taking next ARGV-elt as argument. */
691 d->optarg = argv[d->optind++];
692 d->__nextchar = NULL;
693 }
694 }
695 return c;
696 }
697}
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
char * strchr(const char *String, int ch)
Definition: utclib.c:501
const GLubyte * c
Definition: glext.h:8905
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define c
Definition: ke_i.h:80
static calc_node_t temp
Definition: rpn_ieee.c:38
#define NONOPTION_P
static int process_long_option(int argc, char **argv, const char *optstring, const struct option *longopts, int *longind, int long_only, struct _getopt_data *d, int print_errors, const char *prefix)
Definition: getopt.c:191
#define _(msgid)
Definition: getopt.c:43
static const char * _getopt_initialize(int argc, char **argv, const char *optstring, struct _getopt_data *d, int posixly_correct)
Definition: getopt.c:378
static void exchange(char **argv, struct _getopt_data *d)
Definition: getopt.c:128
Definition: inflate.c:139

Referenced by _getopt_internal(), _getopt_long_only_r(), and _getopt_long_r().

◆ exchange()

static void exchange ( char **  argv,
struct _getopt_data d 
)
static

Definition at line 128 of file getopt.c.

129{
130 int bottom = d->__first_nonopt;
131 int middle = d->__last_nonopt;
132 int top = d->optind;
133 char *tem;
134
135 /* Exchange the shorter segment with the far end of the longer segment.
136 That puts the shorter segment into the right place.
137 It leaves the longer segment in the right place overall,
138 but it consists of two parts that need to be swapped next. */
139
140 while (top > middle && middle > bottom)
141 {
142 if (top - middle > middle - bottom)
143 {
144 /* Bottom segment is the short one. */
145 int len = middle - bottom;
146 int i;
147
148 /* Swap it with the top part of the top segment. */
149 for (i = 0; i < len; i++)
150 {
151 tem = argv[bottom + i];
152 argv[bottom + i] = argv[top - (middle - bottom) + i];
153 argv[top - (middle - bottom) + i] = tem;
154 }
155 /* Exclude the moved bottom segment from further swapping. */
156 top -= len;
157 }
158 else
159 {
160 /* Top segment is the short one. */
161 int len = top - middle;
162 int i;
163
164 /* Swap it with the bottom part of the bottom segment. */
165 for (i = 0; i < len; i++)
166 {
167 tem = argv[bottom + i];
168 argv[bottom + i] = argv[middle + i];
169 argv[middle + i] = tem;
170 }
171 /* Exclude the moved top segment from further swapping. */
172 bottom += len;
173 }
174 }
175
176 /* Update records for the slots the non-options now occupy. */
177
178 d->__first_nonopt += (d->optind - d->__last_nonopt);
179 d->__last_nonopt = d->optind;
180}
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLint GLint bottom
Definition: glext.h:7726
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248

Referenced by _getopt_internal_r().

◆ process_long_option()

static int process_long_option ( int  argc,
char **  argv,
const char optstring,
const struct option longopts,
int longind,
int  long_only,
struct _getopt_data d,
int  print_errors,
const char prefix 
)
static

Definition at line 191 of file getopt.c.

195{
196 char *nameend;
197 size_t namelen;
198 const struct option *p;
199 const struct option *pfound = NULL;
200 int n_options;
201 int option_index;
202
203 for (nameend = d->__nextchar; *nameend && *nameend != '='; nameend++)
204 /* Do nothing. */ ;
205 namelen = nameend - d->__nextchar;
206
207 /* First look for an exact match, counting the options as a side
208 effect. */
209 for (p = longopts, n_options = 0; p->name; p++, n_options++)
210 if (!strncmp (p->name, d->__nextchar, namelen)
211 && namelen == strlen (p->name))
212 {
213 /* Exact match found. */
214 pfound = p;
215 option_index = n_options;
216 break;
217 }
218
219 if (pfound == NULL)
220 {
221 /* Didn't find an exact match, so look for abbreviations. */
222 unsigned char *ambig_set = NULL;
223 int ambig_malloced = 0;
224 int ambig_fallback = 0;
225 int indfound = -1;
226
227 for (p = longopts, option_index = 0; p->name; p++, option_index++)
228 if (!strncmp (p->name, d->__nextchar, namelen))
229 {
230 if (pfound == NULL)
231 {
232 /* First nonexact match found. */
233 pfound = p;
234 indfound = option_index;
235 }
236 else if (long_only
237 || pfound->has_arg != p->has_arg
238 || pfound->flag != p->flag
239 || pfound->val != p->val)
240 {
241 /* Second or later nonexact match found. */
242 if (!ambig_fallback)
243 {
244 if (!print_errors)
245 /* Don't waste effort tracking the ambig set if
246 we're not going to print it anyway. */
247 ambig_fallback = 1;
248 else if (!ambig_set)
249 {
250 if (__libc_use_alloca (n_options))
251 ambig_set = alloca (n_options);
252 else if ((ambig_set = malloc (n_options)) == NULL)
253 /* Fall back to simpler error message. */
254 ambig_fallback = 1;
255 else
256 ambig_malloced = 1;
257
258 if (ambig_set)
259 {
260 memset (ambig_set, 0, n_options);
261 ambig_set[indfound] = 1;
262 }
263 }
264 if (ambig_set)
265 ambig_set[option_index] = 1;
266 }
267 }
268 }
269
270 if (ambig_set || ambig_fallback)
271 {
272 if (print_errors)
273 {
274 if (ambig_fallback)
275 fprintf (stderr, _("%s: option '%s%s' is ambiguous\n"),
276 argv[0], prefix, d->__nextchar);
277 else
278 {
281 _("%s: option '%s%s' is ambiguous; possibilities:"),
282 argv[0], prefix, d->__nextchar);
283
284 for (option_index = 0; option_index < n_options; option_index++)
285 if (ambig_set[option_index])
286 fprintf (stderr, " '%s%s'",
287 prefix, longopts[option_index].name);
288
289 /* This must use 'fprintf' even though it's only
290 printing a single character, so that it goes through
291 __fxprintf_nocancel when compiled as part of glibc. */
292 fprintf (stderr, "\n");
294 }
295 }
296 if (ambig_malloced)
297 free (ambig_set);
298 d->__nextchar += strlen (d->__nextchar);
299 d->optind++;
300 d->optopt = 0;
301 return '?';
302 }
303
304 option_index = indfound;
305 }
306
307 if (pfound == NULL)
308 {
309 /* Can't find it as a long option. If this is not getopt_long_only,
310 or the option starts with '--' or is not a valid short option,
311 then it's an error. */
312 if (!long_only || argv[d->optind][1] == '-'
313 || strchr (optstring, *d->__nextchar) == NULL)
314 {
315 if (print_errors)
316 fprintf (stderr, _("%s: unrecognized option '%s%s'\n"),
317 argv[0], prefix, d->__nextchar);
318
319 d->__nextchar = NULL;
320 d->optind++;
321 d->optopt = 0;
322 return '?';
323 }
324
325 /* Otherwise interpret it as a short option. */
326 return -1;
327 }
328
329 /* We have found a matching long option. Consume it. */
330 d->optind++;
331 d->__nextchar = NULL;
332 if (*nameend)
333 {
334 /* Don't test has_arg with >, because some C compilers don't
335 allow it to be used on enums. */
336 if (pfound->has_arg)
337 d->optarg = nameend + 1;
338 else
339 {
340 if (print_errors)
342 _("%s: option '%s%s' doesn't allow an argument\n"),
343 argv[0], prefix, pfound->name);
344
345 d->optopt = pfound->val;
346 return '?';
347 }
348 }
349 else if (pfound->has_arg == 1)
350 {
351 if (d->optind < argc)
352 d->optarg = argv[d->optind++];
353 else
354 {
355 if (print_errors)
357 _("%s: option '%s%s' requires an argument\n"),
358 argv[0], prefix, pfound->name);
359
360 d->optopt = pfound->val;
361 return optstring[0] == ':' ? ':' : '?';
362 }
363 }
364
365 if (longind != NULL)
366 *longind = option_index;
367 if (pfound->flag)
368 {
369 *(pfound->flag) = pfound->val;
370 return 0;
371 }
372 return pfound->val;
373}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
GLint namelen
Definition: glext.h:7232
GLfloat GLfloat p
Definition: glext.h:8902
#define memset(x, y, z)
Definition: compat.h:39
#define alloca(size)
Definition: getopt.c:53
#define __libc_use_alloca(size)
Definition: getopt.c:51
#define flockfile(fp)
Definition: getopt.c:47
#define funlockfile(fp)
Definition: getopt.c:48
Definition: name.c:39
Definition: getopt.h:109
int val
Definition: getopt.h:115
int * flag
Definition: getopt.h:114
int has_arg
Definition: getopt.h:113
WCHAR * name
Definition: getopt.h:110

Referenced by _getopt_internal_r().

Variable Documentation

◆ getopt_data

struct _getopt_data getopt_data
static

Definition at line 116 of file getopt.c.

Referenced by _getopt_internal().

◆ optarg

char* optarg

Definition at line 86 of file getopt.c.

◆ opterr

int opterr = 1

Definition at line 106 of file getopt.c.

Referenced by check_option().

◆ optind

int optind = 1

Definition at line 101 of file getopt.c.

◆ optopt

int optopt = '?'

Definition at line 112 of file getopt.c.