getopt.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. //
  2. // Copyright (c) 1987, 1993, 1994
  3. // The Regents of the University of California. All rights reserved.
  4. //
  5. // Redistribution and use in source and binary forms, with or without
  6. // modification, are permitted provided that the following conditions
  7. // are met:
  8. //
  9. // 1. Redistributions of source code must retain the above copyright
  10. // notice, this list of conditions and the following disclaimer.
  11. // 2. Redistributions in binary form must reproduce the above copyright
  12. // notice, this list of conditions and the following disclaimer in the
  13. // documentation and/or other materials provided with the distribution.
  14. // 3. Neither the name of the University nor the names of its contributors
  15. // may be used to endorse or promote products derived from this software
  16. // without specific prior written permission.
  17. //
  18. // THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
  19. // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. // ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  22. // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. // SUCH DAMAGE.
  29. //
  30. #include <stdio.h>
  31. #include <stdlib.h>
  32. #include <string.h>
  33. #include "getopt.h"
  34. int opterr = 1; // if error message should be printed
  35. int optind = 1; // index into parent argv vector
  36. int optopt; // character checked for validity
  37. int optreset; // reset getopt
  38. char *optarg; // argument associated with option
  39. #define BADCH (int)'?'
  40. #define BADARG (int)':'
  41. #define EMSG ""
  42. //
  43. // getopt --
  44. // Parse argc/argv argument vector.
  45. //
  46. int
  47. getopt(
  48. int nargc,
  49. char * const *nargv,
  50. const char *ostr
  51. )
  52. {
  53. static char *place = EMSG; // option letter processing
  54. char *oli; // option letter list index
  55. if (optreset || !*place)
  56. {
  57. // update scanning pointer
  58. optreset = 0;
  59. if (optind >= nargc || *(place = nargv[optind]) != '-')
  60. {
  61. place = EMSG;
  62. return -1;
  63. }
  64. if (place[1] && *++place == '-')
  65. {
  66. // found "--"
  67. ++optind;
  68. place = EMSG;
  69. return -1;
  70. }
  71. }
  72. // option letter okay?
  73. if ((optopt = (int)*place++) == (int)':' ||
  74. !(oli = strchr(ostr, optopt)))
  75. {
  76. //
  77. // if the user didn't specify '-' as an option,
  78. // assume it means -1.
  79. //
  80. if (optopt == (int)'-')
  81. return -1;
  82. if (!*place)
  83. ++optind;
  84. if (opterr && *ostr != ':')
  85. fprintf(stderr, "%s: illegal option -- %c\n", nargv[0], optopt);
  86. return BADCH;
  87. }
  88. if (*++oli != ':')
  89. {
  90. // don't need argument
  91. optarg = NULL;
  92. if (!*place)
  93. ++optind;
  94. }
  95. else
  96. {
  97. // need an argument
  98. if (*place) // no white space
  99. optarg = place;
  100. else if (nargc <= ++optind)
  101. {
  102. // no arg
  103. place = EMSG;
  104. if (*ostr == ':')
  105. return BADARG;
  106. if (opterr)
  107. {
  108. fprintf(stderr, "%s: option requires an argument -- %c\n",
  109. nargv[0], optopt);
  110. }
  111. return BADCH;
  112. }
  113. else // white space
  114. optarg = nargv[optind];
  115. place = EMSG;
  116. ++optind;
  117. }
  118. return optopt; // dump back option letter
  119. }