getopt.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. /*---------------------------------------------------------------------------*
  2. * <RCS keywords>
  3. *
  4. * C++ Library
  5. *
  6. * Copyright 1992-1994, David Gottner
  7. *
  8. * All Rights Reserved
  9. *
  10. * Permission to use, copy, modify, and distribute this software and its
  11. * documentation for any purpose and without fee is hereby granted,
  12. * provided that the above copyright notice, this permission notice and
  13. * the following disclaimer notice appear unmodified in all copies.
  14. *
  15. * I DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  16. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL I
  17. * BE LIABLE FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY
  18. * DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA, OR PROFITS, WHETHER
  19. * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
  20. * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21. *---------------------------------------------------------------------------*/
  22. /* Modified to support --help and --version, as well as /? on Windows
  23. * by Georg Brandl. */
  24. #include <Python.h>
  25. #include <stdio.h>
  26. #include <string.h>
  27. #include <wchar.h>
  28. #include "pycore_getopt.h"
  29. #ifdef __cplusplus
  30. extern "C" {
  31. #endif
  32. int _PyOS_opterr = 1; /* generate error messages */
  33. Py_ssize_t _PyOS_optind = 1; /* index into argv array */
  34. const wchar_t *_PyOS_optarg = NULL; /* optional argument */
  35. static const wchar_t *opt_ptr = L"";
  36. /* Python command line short and long options */
  37. #define SHORT_OPTS L"bBc:dEhiIJm:OPqRsStuvVW:xX:?"
  38. static const _PyOS_LongOption longopts[] = {
  39. /* name, has_arg, val (used in switch in initconfig.c) */
  40. {L"check-hash-based-pycs", 1, 0},
  41. {L"help-all", 0, 1},
  42. {L"help-env", 0, 2},
  43. {L"help-xoptions", 0, 3},
  44. {NULL, 0, -1}, /* sentinel */
  45. };
  46. void _PyOS_ResetGetOpt(void)
  47. {
  48. _PyOS_opterr = 1;
  49. _PyOS_optind = 1;
  50. _PyOS_optarg = NULL;
  51. opt_ptr = L"";
  52. }
  53. int _PyOS_GetOpt(Py_ssize_t argc, wchar_t * const *argv, int *longindex)
  54. {
  55. wchar_t *ptr;
  56. wchar_t option;
  57. if (*opt_ptr == '\0') {
  58. if (_PyOS_optind >= argc)
  59. return -1;
  60. #ifdef MS_WINDOWS
  61. else if (wcscmp(argv[_PyOS_optind], L"/?") == 0) {
  62. ++_PyOS_optind;
  63. return 'h';
  64. }
  65. #endif
  66. else if (argv[_PyOS_optind][0] != L'-' ||
  67. argv[_PyOS_optind][1] == L'\0' /* lone dash */ )
  68. return -1;
  69. else if (wcscmp(argv[_PyOS_optind], L"--") == 0) {
  70. ++_PyOS_optind;
  71. return -1;
  72. }
  73. else if (wcscmp(argv[_PyOS_optind], L"--help") == 0) {
  74. ++_PyOS_optind;
  75. return 'h';
  76. }
  77. else if (wcscmp(argv[_PyOS_optind], L"--version") == 0) {
  78. ++_PyOS_optind;
  79. return 'V';
  80. }
  81. opt_ptr = &argv[_PyOS_optind++][1];
  82. }
  83. if ((option = *opt_ptr++) == L'\0')
  84. return -1;
  85. if (option == L'-') {
  86. // Parse long option.
  87. if (*opt_ptr == L'\0') {
  88. if (_PyOS_opterr) {
  89. fprintf(stderr, "expected long option\n");
  90. }
  91. return -1;
  92. }
  93. *longindex = 0;
  94. const _PyOS_LongOption *opt;
  95. for (opt = &longopts[*longindex]; opt->name; opt = &longopts[++(*longindex)]) {
  96. if (!wcscmp(opt->name, opt_ptr))
  97. break;
  98. }
  99. if (!opt->name) {
  100. if (_PyOS_opterr) {
  101. fprintf(stderr, "unknown option %ls\n", argv[_PyOS_optind - 1]);
  102. }
  103. return '_';
  104. }
  105. opt_ptr = L"";
  106. if (!opt->has_arg) {
  107. return opt->val;
  108. }
  109. if (_PyOS_optind >= argc) {
  110. if (_PyOS_opterr) {
  111. fprintf(stderr, "Argument expected for the %ls options\n",
  112. argv[_PyOS_optind - 1]);
  113. }
  114. return '_';
  115. }
  116. _PyOS_optarg = argv[_PyOS_optind++];
  117. return opt->val;
  118. }
  119. if (option == 'J') {
  120. if (_PyOS_opterr) {
  121. fprintf(stderr, "-J is reserved for Jython\n");
  122. }
  123. return '_';
  124. }
  125. if ((ptr = wcschr(SHORT_OPTS, option)) == NULL) {
  126. if (_PyOS_opterr) {
  127. fprintf(stderr, "Unknown option: -%c\n", (char)option);
  128. }
  129. return '_';
  130. }
  131. if (*(ptr + 1) == L':') {
  132. if (*opt_ptr != L'\0') {
  133. _PyOS_optarg = opt_ptr;
  134. opt_ptr = L"";
  135. }
  136. else {
  137. if (_PyOS_optind >= argc) {
  138. if (_PyOS_opterr) {
  139. fprintf(stderr,
  140. "Argument expected for the -%c option\n", (char)option);
  141. }
  142. return '_';
  143. }
  144. _PyOS_optarg = argv[_PyOS_optind++];
  145. }
  146. }
  147. return option;
  148. }
  149. #ifdef __cplusplus
  150. }
  151. #endif