getopt.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  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. extern int getopt (int argc, char *const *argv, const char *optstring)
  36. __attribute__ ((__weak__));
  37. int getopt (int argc, char *const *argv, const char *optstring)
  38. {
  39. static int sp = 1; /* position within argument */
  40. register int osp; /* saved `sp' for param test */
  41. #ifndef STRICT
  42. register int oind; /* saved `optind' for param test */
  43. #endif
  44. register int c; /* option letter */
  45. register char *cp; /* -> option in `optstring' */
  46. optarg = NULL;
  47. /* initialise getopt vars */
  48. if (optind == 0)
  49. {
  50. optind = 1;
  51. opterr = 1;
  52. optopt = 1;
  53. optarg = NULL;
  54. }
  55. if (sp == 1) { /* fresh argument */
  56. if (optind >= argc /* no more arguments */
  57. || argv[optind][0] != '-' /* no more options */
  58. || argv[optind][1] == '\0' /* not option; stdin */
  59. )
  60. return EOF;
  61. else if (strcmp(argv[optind], "--") == 0) {
  62. ++optind; /* skip over "--" */
  63. return EOF; /* "--" marks end of options */
  64. }
  65. }
  66. c = argv[optind][sp]; /* option letter */
  67. osp = sp++; /* get ready for next letter */
  68. #ifndef STRICT
  69. oind = optind; /* save optind for param test */
  70. #endif
  71. if (argv[optind][sp] == '\0') { /* end of argument */
  72. ++optind; /* get ready for next try */
  73. sp = 1; /* beginning of next argument */
  74. }
  75. if (c == ':' || c == '?' /* optstring syntax conflict */
  76. || (cp = strchr(optstring, c)) == NULL /* not found */ ) {
  77. return Err(argv[0], "illegal option", c);
  78. }
  79. if (cp[1] == ':') { /* option takes parameter */
  80. #ifdef STRICT
  81. if (osp != 1) {
  82. return Err(argv[0], "option must not be clustered", c);
  83. }
  84. /* reset by end of argument */
  85. if (sp != 1) {
  86. return Err(argv[0], "option must be followed by white space",
  87. c);
  88. }
  89. #else
  90. if (oind == optind) { /* argument w/o whitespace */
  91. optarg = &argv[optind][sp];
  92. sp = 1; /* beginning of next argument */
  93. }
  94. else
  95. #endif
  96. if (optind >= argc) {
  97. return Err(argv[0], "option requires an argument", c);
  98. }
  99. else /* argument w/ whitespace */
  100. optarg = argv[optind];
  101. ++optind; /* skip over parameter */
  102. }
  103. return c;
  104. }