GnuCOBOL  2.0
A free COBOL compiler
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
cobgetopt.h File Reference
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  option
 

Macros

#define no_argument   0
 
#define required_argument   1
 
#define optional_argument   2
 

Functions

COB_EXPIMP int cob_getopt_long_long (const int, char *const *, const char *, const struct option *, int *, const int)
 

Variables

COB_EXPIMP char * cob_optarg
 
COB_EXPIMP int cob_optind
 
COB_EXPIMP int cob_opterr
 
COB_EXPIMP int cob_optopt
 

Macro Definition Documentation

#define no_argument   0
#define optional_argument   2
#define required_argument   1

Function Documentation

COB_EXPIMP int cob_getopt_long_long ( const int  ,
char *const *  ,
const char *  ,
const struct option ,
int *  ,
const int   
)

References _, _getopt_initialize(), cob_getopt_initialized, cob_optarg, cob_opterr, cob_optind, cob_optopt, exchange(), first_nonopt, option::flag, option::has_arg, last_nonopt, option::name, nextchar, NONOPTION_P, NULL, ordering, p, PERMUTE, REQUIRE_ORDER, seen_short, and option::val.

Referenced by cob_sys_getopt_long_long(), and process_command_line().

323 {
324  if (argc < 1)
325  return -1;
326 
327  cob_optarg = NULL;
328 
329  if (cob_optind == 0 || !cob_getopt_initialized)
330  {
331  if (cob_optind == 0)
332  cob_optind = 1; /* Don't scan ARGV[0], the program name. */
333  optstring = _getopt_initialize (optstring);
335  }
336 
337  /* Test whether ARGV[optind] points to a non-option argument.
338  Either it does not have option syntax, or there is an environment flag
339  from the shell indicating it is not an option. The later information
340  is only used when the used in the GNU libc. */
341 
342  if (nextchar == NULL || *nextchar == '\0')
343  {
344  /* Advance to the next ARGV-element. */
345 
346  seen_short = 0;
347  /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
348  moved back by the user (who may also have changed the arguments). */
349  if (last_nonopt > cob_optind)
351  if (first_nonopt > cob_optind)
353 
354  if (ordering == PERMUTE)
355  {
356  /* If we have just processed some options following some non-options,
357  exchange them so that the options come first. */
358 
360  exchange ((char **) argv);
361  else if (last_nonopt != cob_optind)
363 
364  /* Skip any additional non-options
365  and extend the range of non-options previously skipped. */
366 
367  while (cob_optind < argc && NONOPTION_P)
368  cob_optind++;
370  }
371 
372  /* The special ARGV-element `--' means premature end of options.
373  Skip it like a null option,
374  then exchange with previous non-options as if it were an option,
375  then skip everything else like a non-option. */
376 
377  if (cob_optind != argc && !strcmp (argv[cob_optind], "--"))
378  {
379  cob_optind++;
380 
381  if (first_nonopt != last_nonopt && last_nonopt != cob_optind)
382  exchange ((char **) argv);
383  else if (first_nonopt == last_nonopt)
385  last_nonopt = argc;
386 
387  cob_optind = argc;
388  }
389 
390  /* If we have done all the ARGV-elements, stop the scan
391  and back over any non-options that we skipped and permuted. */
392 
393  if (cob_optind == argc)
394  {
395  /* Set the next-arg-index to point at the non-options
396  that we previously skipped, so the caller will digest them. */
397  if (first_nonopt != last_nonopt)
398  cob_optind = first_nonopt;
399  return -1;
400  }
401 
402  /* If we have come to a non-option and did not permute it,
403  either stop the scan or describe it to the caller and pass it by. */
404 
405  if (NONOPTION_P)
406  {
407  if (ordering == REQUIRE_ORDER)
408  return -1;
409  cob_optarg = argv[cob_optind++];
410  return 1;
411  }
412 
413  /* We have found another option-ARGV-element.
414  Skip the initial punctuation. */
415 
416  nextchar = (argv[cob_optind] + 1
417  + (longopts != NULL && argv[cob_optind][1] == '-'));
418  }
419 
420  /* Decode the current option-ARGV-element. */
421 
422  /* Check whether the ARGV-element is a long option.
423 
424  If long_only and the ARGV-element has the form "-f", where f is
425  a valid short option, don't consider it an abbreviated form of
426  a long option that starts with f. Otherwise there would be no
427  way to give the -f short option.
428 
429  On the other hand, if there's a long option "fubar" and
430  the ARGV-element is "-fu", do consider that an abbreviation of
431  the long option, just like "--fu", and not "-f" with arg "u".
432 
433  This distinction seems to be the most useful approach. */
434 
435  if (longopts != NULL && (argv[cob_optind][1] == '-'
436  || (long_only && !seen_short && (argv[cob_optind][2] || !strchr (optstring, argv[cob_optind][1])))))
437  {
438  char *nameend;
439  const struct option *p;
440  const struct option *pfound = NULL;
441  int exact = 0;
442  int ambig = 0;
443  int indfound = -1;
444  int option_index;
445 
446  for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
447  /* Do nothing. */ ;
448 
449  /* Test all long options for either exact match
450  or abbreviated matches. */
451  for (p = longopts, option_index = 0; p->name; p++, option_index++)
452  if (!strncmp (p->name, nextchar, (size_t)(nameend - nextchar)))
453  {
454  if ((unsigned int) (nameend - nextchar)
455  == (unsigned int) strlen (p->name))
456  {
457  /* Exact match found. */
458  pfound = p;
459  indfound = option_index;
460  exact = 1;
461  break;
462  }
463  else if (pfound == NULL)
464  {
465  /* First nonexact match found. */
466  pfound = p;
467  indfound = option_index;
468  }
469 #if 0 /* RXWRXW - ambig */
470  else if (long_only
471  || pfound->has_arg != p->has_arg
472  || pfound->flag != p->flag
473  || pfound->val != p->val)
474 #else
475  else
476 #endif
477  /* Second or later nonexact match found. */
478  ambig = 1;
479  }
480 
481  if (ambig && !exact)
482  {
483  if (cob_opterr)
484  {
485  fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
486  argv[0], argv[cob_optind]);
487  }
488  nextchar += strlen (nextchar);
489  cob_optind++;
490  cob_optopt = 0;
491  return '?';
492  }
493 
494  if (pfound != NULL)
495  {
496  option_index = indfound;
497  cob_optind++;
498  if (*nameend)
499  {
500  /* Don't test has_arg with >, because some C compilers don't
501  allow it to be used on enums. */
502  if (pfound->has_arg)
503  cob_optarg = nameend + 1;
504  else
505  {
506  if (cob_opterr)
507  {
508  if (argv[cob_optind - 1][1] == '-')
509  {
510  /* --option */
511  fprintf (stderr,
512  _("%s: option `--%s' doesn't allow an argument\n"),
513  argv[0], pfound->name);
514  }
515  else
516  {
517  /* +option or -option */
518  fprintf (stderr,
519  _("%s: option `%c%s' doesn't allow an argument\n"),
520  argv[0], argv[cob_optind - 1][0], pfound->name);
521  }
522  }
523 
524  nextchar += strlen (nextchar);
525 
526  cob_optopt = pfound->val;
527  return '?';
528  }
529  }
530  else if (pfound->has_arg == 1)
531  {
532  if (cob_optind < argc)
533  cob_optarg = argv[cob_optind++];
534  else
535  {
536  if (cob_opterr)
537  {
538  fprintf (stderr,
539  _("%s: option `%s' requires an argument\n"),
540  argv[0], argv[cob_optind - 1]);
541  }
542  nextchar += strlen (nextchar);
543  cob_optopt = pfound->val;
544  return optstring[0] == ':' ? ':' : '?';
545  }
546  }
547  nextchar += strlen (nextchar);
548  if (longind != NULL)
549  *longind = option_index;
550  if (pfound->flag)
551  {
552  *(pfound->flag) = pfound->val;
553  return 0;
554  }
555  return pfound->val;
556  }
557 
558  /* Can't find it as a long option. If this is not getopt_long_only,
559  or the option starts with '--' or is not a valid short
560  option, then it's an error.
561  Otherwise interpret it as a short option. */
562  if (!long_only || argv[cob_optind][1] == '-'
563  || strchr (optstring, *nextchar) == NULL)
564  {
565  if (cob_opterr)
566  {
567  if (argv[cob_optind][1] == '-')
568  {
569  /* --option */
570  fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
571  argv[0], nextchar);
572  }
573  else
574  {
575  /* +option or -option */
576  fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
577  argv[0], argv[cob_optind][0], nextchar);
578  }
579  }
580  nextchar = (char *) "";
581  cob_optind++;
582  cob_optopt = 0;
583  return '?';
584  }
585  }
586 
587  /* Look at and handle the next short option-character. */
588 
589  {
590  char c = *nextchar++;
591  char *temp = strchr (optstring, c);
592 
593  /* Increment `cob_optind' when we start to process its last character. */
594  if (*nextchar == '\0')
595  {
596  ++cob_optind;
597  seen_short = 0;
598  }
599 
600  if (temp == NULL || c == ':')
601  {
602  if (cob_opterr)
603  {
604  fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
605  }
606  cob_optopt = c;
607  seen_short = 0;
608  return '?';
609  }
610  /* Convenience. Treat POSIX -W foo same as long option --foo */
611  if (temp[0] == 'W' && temp[1] == ';')
612  {
613  char *nameend;
614  const struct option *p;
615  const struct option *pfound = NULL;
616  int exact = 0;
617  int ambig = 0;
618  int indfound = 0;
619  int option_index;
620 
621  /* This is an option that requires an argument. */
622  if (*nextchar != '\0')
623  {
625  /* If we end this ARGV-element by taking the rest as an arg,
626  we must advance to the next element now. */
627  cob_optind++;
628  }
629  else if (cob_optind == argc)
630  {
631  if (cob_opterr)
632  {
633  /* 1003.2 specifies the format of this message. */
634  fprintf (stderr, _("%s: option requires an argument -- %c\n"),
635  argv[0], c);
636  }
637  cob_optopt = c;
638  if (optstring[0] == ':')
639  c = ':';
640  else
641  c = '?';
642  seen_short = 0;
643  return c;
644  }
645  else
646  /* We already incremented `cob_optind' once;
647  increment it again when taking next ARGV-elt as argument. */
648  cob_optarg = argv[cob_optind++];
649 
650  /* cob_optarg is now the argument, see if it's in the
651  table of longopts. */
652 
653  for (nextchar = nameend = cob_optarg; *nameend && *nameend != '='; nameend++)
654  /* Do nothing. */ ;
655 
656  /* Test all long options for either exact match
657  or abbreviated matches. */
658  for (p = longopts, option_index = 0; p->name; p++, option_index++)
659  if (!strncmp (p->name, nextchar, (size_t)(nameend - nextchar)))
660  {
661  if ((unsigned int) (nameend - nextchar) == strlen (p->name))
662  {
663  /* Exact match found. */
664  pfound = p;
665  indfound = option_index;
666  exact = 1;
667  break;
668  }
669  else if (pfound == NULL)
670  {
671  /* First nonexact match found. */
672  pfound = p;
673  indfound = option_index;
674  }
675  else
676  /* Second or later nonexact match found. */
677  ambig = 1;
678  }
679  if (ambig && !exact)
680  {
681  if (cob_opterr)
682  {
683  fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
684  argv[0], argv[cob_optind]);
685  }
686  nextchar += strlen (nextchar);
687  cob_optind++;
688  seen_short = 0;
689  return '?';
690  }
691  if (pfound != NULL)
692  {
693  option_index = indfound;
694  if (*nameend)
695  {
696  /* Don't test has_arg with >, because some C compilers don't
697  allow it to be used on enums. */
698  if (pfound->has_arg)
699  cob_optarg = nameend + 1;
700  else
701  {
702  if (cob_opterr)
703  {
704  fprintf (stderr, _("\
705 %s: option `-W %s' doesn't allow an argument\n"),
706  argv[0], pfound->name);
707  }
708 
709  nextchar += strlen (nextchar);
710  seen_short = 0;
711  return '?';
712  }
713  }
714  else if (pfound->has_arg == 1)
715  {
716  if (cob_optind < argc)
717  cob_optarg = argv[cob_optind++];
718  else
719  {
720  if (cob_opterr)
721  {
722  fprintf (stderr,
723  _("%s: option `%s' requires an argument\n"),
724  argv[0], argv[cob_optind - 1]);
725  }
726  nextchar += strlen (nextchar);
727  seen_short = 0;
728  return optstring[0] == ':' ? ':' : '?';
729  }
730  }
731  nextchar += strlen (nextchar);
732  if (longind != NULL)
733  *longind = option_index;
734  if (pfound->flag)
735  {
736  *(pfound->flag) = pfound->val;
737  return 0;
738  }
739  return pfound->val;
740  }
741  nextchar = NULL;
742  return 'W'; /* Let the application handle it. */
743  }
744  if (temp[1] == ':')
745  {
746  if (temp[2] == ':')
747  {
748  /* This is an option that accepts an argument optionally. */
749  if (*nextchar != '\0')
750  {
752  cob_optind++;
753  }
754  else
755  cob_optarg = NULL;
756  nextchar = NULL;
757  }
758  else
759  {
760  /* This is an option that requires an argument. */
761  if (*nextchar != '\0')
762  {
764  /* If we end this ARGV-element by taking the rest as an arg,
765  we must advance to the next element now. */
766  cob_optind++;
767  }
768  else if (cob_optind == argc)
769  {
770  if (cob_opterr)
771  {
772  /* 1003.2 specifies the format of this message. */
773  fprintf (stderr,
774  _("%s: option requires an argument -- %c\n"),
775  argv[0], c);
776  }
777  cob_optopt = c;
778  seen_short = 0;
779  if (optstring[0] == ':')
780  c = ':';
781  else
782  c = '?';
783  }
784  else
785  /* We already incremented `cob_optind' once;
786  increment it again when taking next ARGV-elt as argument. */
787  cob_optarg = argv[cob_optind++];
788  nextchar = NULL;
789  }
790  }
791  seen_short = 1;
792  return c;
793  }
794 }

Variable Documentation

COB_EXPIMP char* cob_optarg
COB_EXPIMP int cob_opterr
COB_EXPIMP int cob_optind
COB_EXPIMP int cob_optopt