getopt.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. /*
  2. * From: gwyn@brl-tgr.ARPA (Doug Gwyn <gwyn>) Newsgroups: net.sources
  3. * Subject: getopt library routine Date: 30 Mar 85 04:45:33 GMT
  4. */
  5. /*
  6. * getopt -- public domain version of standard System V routine
  7. *
  8. * Strictly enforces the System V Command Syntax Standard; provided by D A
  9. * Gwyn of BRL for generic ANSI C implementations
  10. *
  11. * #define STRICT to prevent acceptance of clustered options with arguments
  12. * and ommision of whitespace between option and arg.
  13. */
  14. /*
  15. * Modified by Manuel Novoa III on 1/5/01 to use weak symbols.
  16. * Programs needing long options will link gnu_getopt instead.
  17. */
  18. #include <stdio.h>
  19. #include <string.h>
  20. extern int opterr; /* error => print message */
  21. extern int optind; /* next argv[] index */
  22. extern int optopt; /* Set for unknown arguments */
  23. extern char *optarg; /* option parameter if any */
  24. static int Err(name, mess, c) /* returns '?' */
  25. char *name; /* program name argv[0] */
  26. char *mess; /* specific message */
  27. int c; /* defective option letter */
  28. {
  29. optopt = c;
  30. if (opterr) {
  31. (void) fprintf(stderr, "%s: %s -- %c\n", name, mess, c);
  32. }
  33. return '?'; /* erroneous-option marker */
  34. }
  35. int __attribute__ ((__weak__)) getopt (int argc, char *const *argv, const char *optstring)
  36. {
  37. static int sp = 1; /* position within argument */
  38. register int osp; /* saved `sp' for param test */
  39. #ifndef STRICT
  40. register int oind; /* saved `optind' for param test */
  41. #endif
  42. register int c; /* option letter */
  43. register char *cp; /* -> option in `optstring' */
  44. optarg = NULL;
  45. /* initialise getopt vars */
  46. if (optind == 0)
  47. {
  48. optind = 1;
  49. opterr = 1;
  50. optopt = 1;
  51. optarg = NULL;
  52. }
  53. if (sp == 1) { /* fresh argument */
  54. if (optind >= argc /* no more arguments */
  55. || argv[optind][0] != '-' /* no more options */
  56. || argv[optind][1] == '\0' /* not option; stdin */
  57. )
  58. return EOF;
  59. else if (strcmp(argv[optind], "--") == 0) {
  60. ++optind; /* skip over "--" */
  61. return EOF; /* "--" marks end of options */
  62. }
  63. }
  64. c = argv[optind][sp]; /* option letter */
  65. osp = sp++; /* get ready for next letter */
  66. #ifndef STRICT
  67. oind = optind; /* save optind for param test */
  68. #endif
  69. if (argv[optind][sp] == '\0') { /* end of argument */
  70. ++optind; /* get ready for next try */
  71. sp = 1; /* beginning of next argument */
  72. }
  73. if (c == ':' || c == '?' /* optstring syntax conflict */
  74. || (cp = strchr(optstring, c)) == NULL /* not found */ ) {
  75. return Err(argv[0], "illegal option", c);
  76. }
  77. if (cp[1] == ':') { /* option takes parameter */
  78. #ifdef STRICT
  79. if (osp != 1) {
  80. return Err(argv[0], "option must not be clustered", c);
  81. }
  82. /* reset by end of argument */
  83. if (sp != 1) {
  84. return Err(argv[0], "option must be followed by white space",
  85. c);
  86. }
  87. #else
  88. if (oind == optind) { /* argument w/o whitespace */
  89. optarg = &argv[optind][sp];
  90. sp = 1; /* beginning of next argument */
  91. }
  92. else
  93. #endif
  94. if (optind >= argc) {
  95. return Err(argv[0], "option requires an argument", c);
  96. }
  97. else /* argument w/ whitespace */
  98. optarg = argv[optind];
  99. ++optind; /* skip over parameter */
  100. }
  101. return c;
  102. }