getopt.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  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. int opterr __attribute__ ((__weak__)) = 1; /* error => print message */
  21. int optind __attribute__ ((__weak__)) = 1; /* next argv[] index */
  22. int optopt __attribute__ ((__weak__)) = 1; /* Set for unknown arguments */
  23. char *optarg __attribute__ ((__weak__)) = NULL; /* 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. if (sp == 1) { /* fresh argument */
  48. if (optind >= argc /* no more arguments */
  49. || argv[optind][0] != '-' /* no more options */
  50. || argv[optind][1] == '\0' /* not option; stdin */
  51. )
  52. return EOF;
  53. else if (strcmp(argv[optind], "--") == 0) {
  54. ++optind; /* skip over "--" */
  55. return EOF; /* "--" marks end of options */
  56. }
  57. }
  58. c = argv[optind][sp]; /* option letter */
  59. osp = sp++; /* get ready for next letter */
  60. #ifndef STRICT
  61. oind = optind; /* save optind for param test */
  62. #endif
  63. if (argv[optind][sp] == '\0') { /* end of argument */
  64. ++optind; /* get ready for next try */
  65. sp = 1; /* beginning of next argument */
  66. }
  67. if (c == ':' || c == '?' /* optstring syntax conflict */
  68. || (cp = strchr(optstring, c)) == NULL /* not found */ ) {
  69. return Err(argv[0], "illegal option", c);
  70. }
  71. if (cp[1] == ':') { /* option takes parameter */
  72. #ifdef STRICT
  73. if (osp != 1) {
  74. return Err(argv[0], "option must not be clustered", c);
  75. }
  76. /* reset by end of argument */
  77. if (sp != 1) {
  78. return Err(argv[0], "option must be followed by white space",
  79. c);
  80. }
  81. #else
  82. if (oind == optind) { /* argument w/o whitespace */
  83. optarg = &argv[optind][sp];
  84. sp = 1; /* beginning of next argument */
  85. }
  86. else
  87. #endif
  88. if (optind >= argc) {
  89. return Err(argv[0], "option requires an argument", c);
  90. }
  91. else /* argument w/ whitespace */
  92. optarg = argv[optind];
  93. ++optind; /* skip over parameter */
  94. }
  95. return c;
  96. }