getopt.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  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. #include <stdio.h>
  15. #include <string.h>
  16. int opterr = 1; /* error => print message */
  17. int optind = 1; /* next argv[] index */
  18. int optopt = 1; /* Set for unknown arguments */
  19. char *optarg = NULL; /* option parameter if any */
  20. static int Err(name, mess, c) /* returns '?' */
  21. char *name; /* program name argv[0] */
  22. char *mess; /* specific message */
  23. int c; /* defective option letter */
  24. {
  25. optopt = c;
  26. if (opterr) {
  27. (void) fprintf(stderr, "%s: %s -- %c\n", name, mess, c);
  28. }
  29. return '?'; /* erroneous-option marker */
  30. }
  31. int getopt (int argc, char *const *argv, const char *optstring)
  32. {
  33. static int sp = 1; /* position within argument */
  34. register int osp; /* saved `sp' for param test */
  35. #ifndef STRICT
  36. register int oind; /* saved `optind' for param test */
  37. #endif
  38. register int c; /* option letter */
  39. register char *cp; /* -> option in `optstring' */
  40. optarg = NULL;
  41. if (sp == 1) { /* fresh argument */
  42. if (optind >= argc /* no more arguments */
  43. || argv[optind][0] != '-' /* no more options */
  44. || argv[optind][1] == '\0' /* not option; stdin */
  45. )
  46. return EOF;
  47. else if (strcmp(argv[optind], "--") == 0) {
  48. ++optind; /* skip over "--" */
  49. return EOF; /* "--" marks end of options */
  50. }
  51. }
  52. c = argv[optind][sp]; /* option letter */
  53. osp = sp++; /* get ready for next letter */
  54. #ifndef STRICT
  55. oind = optind; /* save optind for param test */
  56. #endif
  57. if (argv[optind][sp] == '\0') { /* end of argument */
  58. ++optind; /* get ready for next try */
  59. sp = 1; /* beginning of next argument */
  60. }
  61. if (c == ':' || c == '?' /* optstring syntax conflict */
  62. || (cp = strchr(optstring, c)) == NULL /* not found */ ) {
  63. return Err(argv[0], "illegal option", c);
  64. }
  65. if (cp[1] == ':') { /* option takes parameter */
  66. #ifdef STRICT
  67. if (osp != 1) {
  68. return Err(argv[0], "option must not be clustered", c);
  69. }
  70. /* reset by end of argument */
  71. if (sp != 1) {
  72. return Err(argv[0], "option must be followed by white space",
  73. c);
  74. }
  75. #else
  76. if (oind == optind) { /* argument w/o whitespace */
  77. optarg = &argv[optind][sp];
  78. sp = 1; /* beginning of next argument */
  79. }
  80. else
  81. #endif
  82. if (optind >= argc) {
  83. return Err(argv[0], "option requires an argument", c);
  84. }
  85. else /* argument w/ whitespace */
  86. optarg = argv[optind];
  87. ++optind; /* skip over parameter */
  88. }
  89. return c;
  90. }