getopt.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: getopt
  5. *
  6. * Copyright (C) 2000 - 2018, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. /*
  10. * ACPICA getopt() implementation
  11. *
  12. * Option strings:
  13. * "f" - Option has no arguments
  14. * "f:" - Option requires an argument
  15. * "f+" - Option has an optional argument
  16. * "f^" - Option has optional single-char sub-options
  17. * "f|" - Option has required single-char sub-options
  18. */
  19. #include <acpi/acpi.h>
  20. #include "accommon.h"
  21. #include "acapps.h"
  22. #define ACPI_OPTION_ERROR(msg, badchar) \
  23. if (acpi_gbl_opterr) {fprintf (stderr, "%s%c\n", msg, badchar);}
  24. int acpi_gbl_opterr = 1;
  25. int acpi_gbl_optind = 1;
  26. int acpi_gbl_sub_opt_char = 0;
  27. char *acpi_gbl_optarg;
  28. static int current_char_ptr = 1;
  29. /*******************************************************************************
  30. *
  31. * FUNCTION: acpi_getopt_argument
  32. *
  33. * PARAMETERS: argc, argv - from main
  34. *
  35. * RETURN: 0 if an argument was found, -1 otherwise. Sets acpi_gbl_Optarg
  36. * to point to the next argument.
  37. *
  38. * DESCRIPTION: Get the next argument. Used to obtain arguments for the
  39. * two-character options after the original call to acpi_getopt.
  40. * Note: Either the argument starts at the next character after
  41. * the option, or it is pointed to by the next argv entry.
  42. * (After call to acpi_getopt, we need to backup to the previous
  43. * argv entry).
  44. *
  45. ******************************************************************************/
  46. int acpi_getopt_argument(int argc, char **argv)
  47. {
  48. acpi_gbl_optind--;
  49. current_char_ptr++;
  50. if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
  51. acpi_gbl_optarg =
  52. &argv[acpi_gbl_optind++][(int)(current_char_ptr + 1)];
  53. } else if (++acpi_gbl_optind >= argc) {
  54. ACPI_OPTION_ERROR("\nOption requires an argument", 0);
  55. current_char_ptr = 1;
  56. return (-1);
  57. } else {
  58. acpi_gbl_optarg = argv[acpi_gbl_optind++];
  59. }
  60. current_char_ptr = 1;
  61. return (0);
  62. }
  63. /*******************************************************************************
  64. *
  65. * FUNCTION: acpi_getopt
  66. *
  67. * PARAMETERS: argc, argv - from main
  68. * opts - options info list
  69. *
  70. * RETURN: Option character or ACPI_OPT_END
  71. *
  72. * DESCRIPTION: Get the next option
  73. *
  74. ******************************************************************************/
  75. int acpi_getopt(int argc, char **argv, char *opts)
  76. {
  77. int current_char;
  78. char *opts_ptr;
  79. if (current_char_ptr == 1) {
  80. if (acpi_gbl_optind >= argc ||
  81. argv[acpi_gbl_optind][0] != '-' ||
  82. argv[acpi_gbl_optind][1] == '\0') {
  83. return (ACPI_OPT_END);
  84. } else if (strcmp(argv[acpi_gbl_optind], "--") == 0) {
  85. acpi_gbl_optind++;
  86. return (ACPI_OPT_END);
  87. }
  88. }
  89. /* Get the option */
  90. current_char = argv[acpi_gbl_optind][current_char_ptr];
  91. /* Make sure that the option is legal */
  92. if (current_char == ':' ||
  93. (opts_ptr = strchr(opts, current_char)) == NULL) {
  94. ACPI_OPTION_ERROR("Illegal option: -", current_char);
  95. if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
  96. acpi_gbl_optind++;
  97. current_char_ptr = 1;
  98. }
  99. return ('?');
  100. }
  101. /* Option requires an argument? */
  102. if (*++opts_ptr == ':') {
  103. if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
  104. acpi_gbl_optarg =
  105. &argv[acpi_gbl_optind++][(int)
  106. (current_char_ptr + 1)];
  107. } else if (++acpi_gbl_optind >= argc) {
  108. ACPI_OPTION_ERROR("Option requires an argument: -",
  109. current_char);
  110. current_char_ptr = 1;
  111. return ('?');
  112. } else {
  113. acpi_gbl_optarg = argv[acpi_gbl_optind++];
  114. }
  115. current_char_ptr = 1;
  116. }
  117. /* Option has an optional argument? */
  118. else if (*opts_ptr == '+') {
  119. if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
  120. acpi_gbl_optarg =
  121. &argv[acpi_gbl_optind++][(int)
  122. (current_char_ptr + 1)];
  123. } else if (++acpi_gbl_optind >= argc) {
  124. acpi_gbl_optarg = NULL;
  125. } else {
  126. acpi_gbl_optarg = argv[acpi_gbl_optind++];
  127. }
  128. current_char_ptr = 1;
  129. }
  130. /* Option has optional single-char arguments? */
  131. else if (*opts_ptr == '^') {
  132. if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
  133. acpi_gbl_optarg =
  134. &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
  135. } else {
  136. acpi_gbl_optarg = "^";
  137. }
  138. acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
  139. acpi_gbl_optind++;
  140. current_char_ptr = 1;
  141. }
  142. /* Option has a required single-char argument? */
  143. else if (*opts_ptr == '|') {
  144. if (argv[acpi_gbl_optind][(int)(current_char_ptr + 1)] != '\0') {
  145. acpi_gbl_optarg =
  146. &argv[acpi_gbl_optind][(int)(current_char_ptr + 1)];
  147. } else {
  148. ACPI_OPTION_ERROR
  149. ("Option requires a single-character suboption: -",
  150. current_char);
  151. current_char_ptr = 1;
  152. return ('?');
  153. }
  154. acpi_gbl_sub_opt_char = acpi_gbl_optarg[0];
  155. acpi_gbl_optind++;
  156. current_char_ptr = 1;
  157. }
  158. /* Option with no arguments */
  159. else {
  160. if (argv[acpi_gbl_optind][++current_char_ptr] == '\0') {
  161. current_char_ptr = 1;
  162. acpi_gbl_optind++;
  163. }
  164. acpi_gbl_optarg = NULL;
  165. }
  166. return (current_char);
  167. }