getopt.c 3.0 KB

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