getopt.c 3.8 KB

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