aboutsummaryrefslogtreecommitdiffstats
path: root/lib/getopt.c
diff options
context:
space:
mode:
authorPaul Eggert2015-02-20 23:31:17 -0800
committerPaul Eggert2015-02-20 23:32:45 -0800
commit066b17df681fabb40108d719086669957aebbc51 (patch)
tree27f9362ed6a6e68ef6b61925932f84bb1afb37b8 /lib/getopt.c
parent43fb42da8bd6851b5b22d2bbb5d2cd8ceede9c09 (diff)
downloademacs-066b17df681fabb40108d719086669957aebbc51.tar.gz
emacs-066b17df681fabb40108d719086669957aebbc51.zip
Merge from gnulib
* doc/misc/texinfo.tex: Update from gnulib. * lib/getdtablesize.c, lib/getopt.c, lib/signal.in.h, lib/tempname.c: * lib/tempname.h, m4/dup2.m4, m4/fcntl.m4, m4/getdtablesize.m4: Update from gnulib, incorporating: 2015-02-20 getdtablesize: port better for Android 2015-02-19 fcntl: Fix cross compiling 2015-02-18 dup2, fcntl: cross-compile better for Android 2015-02-18 getopt: don't crash on memory exhaustion 2015-02-17 tempname: allow compilation with C++ (trivial) 2015-02-17 dup2, fcntl: port to AIX 2015-02-16 getdtablesize, dup2, fcntl: port to Android 2015-02-11 getdtablesize, signal_h: Fix Android build 2015-02-11 maint: various whitespace cleanups in tempname
Diffstat (limited to 'lib/getopt.c')
-rw-r--r--lib/getopt.c52
1 files changed, 41 insertions, 11 deletions
diff --git a/lib/getopt.c b/lib/getopt.c
index 3b9c585a28c..212cbf73410 100644
--- a/lib/getopt.c
+++ b/lib/getopt.c
@@ -487,7 +487,20 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
487 const struct option *p; 487 const struct option *p;
488 struct option_list *next; 488 struct option_list *next;
489 } *ambig_list = NULL; 489 } *ambig_list = NULL;
490#ifdef _LIBC
491/* malloc() not used for _LIBC to simplify failure messages. */
492# define free_option_list(l)
493#else
494# define free_option_list(l) \
495 while (l != NULL) \
496 { \
497 struct option_list *pn = l->next; \
498 free (l); \
499 l = pn; \
500 }
501#endif
490 int exact = 0; 502 int exact = 0;
503 int ambig = 0;
491 int indfound = -1; 504 int indfound = -1;
492 int option_index; 505 int option_index;
493 506
@@ -514,22 +527,37 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
514 pfound = p; 527 pfound = p;
515 indfound = option_index; 528 indfound = option_index;
516 } 529 }
530 else if (ambig)
531 ; /* Taking simpler path to handling ambiguities. */
517 else if (long_only 532 else if (long_only
518 || pfound->has_arg != p->has_arg 533 || pfound->has_arg != p->has_arg
519 || pfound->flag != p->flag 534 || pfound->flag != p->flag
520 || pfound->val != p->val) 535 || pfound->val != p->val)
521 { 536 {
522 /* Second or later nonexact match found. */ 537 /* Second or later nonexact match found. */
538#ifdef _LIBC
539 struct option_list *newp = alloca (sizeof (*newp));
540#else
523 struct option_list *newp = malloc (sizeof (*newp)); 541 struct option_list *newp = malloc (sizeof (*newp));
524 newp->p = p; 542 if (newp == NULL)
525 newp->next = ambig_list; 543 {
526 ambig_list = newp; 544 free_option_list (ambig_list);
545 ambig_list = NULL;
546 ambig = 1; /* Use simpler fallback message. */
547 }
548 else
549#endif
550 {
551 newp->p = p;
552 newp->next = ambig_list;
553 ambig_list = newp;
554 }
527 } 555 }
528 } 556 }
529 557
530 if (ambig_list != NULL && !exact) 558 if ((ambig || ambig_list) && !exact)
531 { 559 {
532 if (print_errors) 560 if (print_errors && ambig_list)
533 { 561 {
534 struct option_list first; 562 struct option_list first;
535 first.p = pfound; 563 first.p = pfound;
@@ -585,18 +613,20 @@ _getopt_internal_r (int argc, char **argv, const char *optstring,
585 fputc ('\n', stderr); 613 fputc ('\n', stderr);
586#endif 614#endif
587 } 615 }
616 else if (print_errors && ambig)
617 {
618 fprintf (stderr,
619 _("%s: option '%s' is ambiguous\n"),
620 argv[0], argv[d->optind]);
621 }
588 d->__nextchar += strlen (d->__nextchar); 622 d->__nextchar += strlen (d->__nextchar);
589 d->optind++; 623 d->optind++;
590 d->optopt = 0; 624 d->optopt = 0;
625 free_option_list (ambig_list);
591 return '?'; 626 return '?';
592 } 627 }
593 628
594 while (ambig_list != NULL) 629 free_option_list (ambig_list);
595 {
596 struct option_list *pn = ambig_list->next;
597 free (ambig_list);
598 ambig_list = pn;
599 }
600 630
601 if (pfound != NULL) 631 if (pfound != NULL)
602 { 632 {