You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

199 lines
5.3 KiB

15 years ago
19 years ago
19 years ago
19 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2011 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Author: Marcus Boerger <helly@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. /* $Id$ */
  19. #include <stdio.h>
  20. #include <string.h>
  21. #include <assert.h>
  22. #include <stdlib.h>
  23. #include "php_getopt.h"
  24. #define OPTERRCOLON (1)
  25. #define OPTERRNF (2)
  26. #define OPTERRARG (3)
  27. static int php_opt_error(int argc, char * const *argv, int oint, int optchr, int err, int show_err) /* {{{ */
  28. {
  29. if (show_err)
  30. {
  31. fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
  32. switch(err)
  33. {
  34. case OPTERRCOLON:
  35. fprintf(stderr, ": in flags\n");
  36. break;
  37. case OPTERRNF:
  38. fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
  39. break;
  40. case OPTERRARG:
  41. fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
  42. break;
  43. default:
  44. fprintf(stderr, "unknown\n");
  45. break;
  46. }
  47. }
  48. return('?');
  49. }
  50. /* }}} */
  51. PHPAPI int php_optidx = -1;
  52. PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err, int arg_start) /* {{{ */
  53. {
  54. static int optchr = 0;
  55. static int dash = 0; /* have already seen the - */
  56. php_optidx = -1;
  57. if (*optind >= argc) {
  58. return(EOF);
  59. }
  60. if (!dash) {
  61. if ((argv[*optind][0] != '-')) {
  62. return(EOF);
  63. } else {
  64. if (!argv[*optind][1])
  65. {
  66. /*
  67. * use to specify stdin. Need to let pgm process this and
  68. * the following args
  69. */
  70. return(EOF);
  71. }
  72. }
  73. }
  74. if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
  75. char *pos;
  76. int arg_end = strlen(argv[*optind])-1;
  77. /* '--' indicates end of args if not followed by a known long option name */
  78. if (argv[*optind][2] == '\0') {
  79. (*optind)++;
  80. return(EOF);
  81. }
  82. arg_start = 2;
  83. /* Check for <arg>=<val> */
  84. if ((pos = php_memnstr(&argv[*optind][arg_start], "=", 1, argv[*optind]+arg_end)) != NULL) {
  85. arg_end = pos-&argv[*optind][arg_start];
  86. arg_start++;
  87. } else {
  88. arg_end--;
  89. }
  90. while (1) {
  91. php_optidx++;
  92. if (opts[php_optidx].opt_char == '-') {
  93. (*optind)++;
  94. return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
  95. } else if (opts[php_optidx].opt_name && !strncmp(&argv[*optind][2], opts[php_optidx].opt_name, arg_end) && arg_end == strlen(opts[php_optidx].opt_name)) {
  96. break;
  97. }
  98. }
  99. optchr = 0;
  100. dash = 0;
  101. arg_start += strlen(opts[php_optidx].opt_name);
  102. } else {
  103. if (!dash) {
  104. dash = 1;
  105. optchr = 1;
  106. }
  107. /* Check if the guy tries to do a -: kind of flag */
  108. if (argv[*optind][optchr] == ':') {
  109. dash = 0;
  110. (*optind)++;
  111. return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
  112. }
  113. arg_start = 1 + optchr;
  114. }
  115. if (php_optidx < 0) {
  116. while (1) {
  117. php_optidx++;
  118. if (opts[php_optidx].opt_char == '-') {
  119. int errind = *optind;
  120. int errchr = optchr;
  121. if (!argv[*optind][optchr+1]) {
  122. dash = 0;
  123. (*optind)++;
  124. } else {
  125. optchr++;
  126. arg_start++;
  127. }
  128. return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
  129. } else if (argv[*optind][optchr] == opts[php_optidx].opt_char) {
  130. break;
  131. }
  132. }
  133. }
  134. if (opts[php_optidx].need_param) {
  135. /* Check for cases where the value of the argument
  136. is in the form -<arg> <val>, -<arg>=<varl> or -<arg><val> */
  137. dash = 0;
  138. if (!argv[*optind][arg_start]) {
  139. (*optind)++;
  140. if (*optind == argc) {
  141. /* Was the value required or is it optional? */
  142. if (opts[php_optidx].need_param == 1) {
  143. return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
  144. }
  145. /* Optional value is not supported with -<arg> <val> style */
  146. } else if (opts[php_optidx].need_param == 1) {
  147. *optarg = argv[(*optind)++];
  148. }
  149. } else if (argv[*optind][arg_start] == '=') {
  150. arg_start++;
  151. *optarg = &argv[*optind][arg_start];
  152. (*optind)++;
  153. } else {
  154. *optarg = &argv[*optind][arg_start];
  155. (*optind)++;
  156. }
  157. return opts[php_optidx].opt_char;
  158. } else {
  159. /* multiple options specified as one (exclude long opts) */
  160. if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))) {
  161. if (!argv[*optind][optchr+1])
  162. {
  163. dash = 0;
  164. (*optind)++;
  165. } else {
  166. optchr++;
  167. }
  168. } else {
  169. (*optind)++;
  170. }
  171. return opts[php_optidx].opt_char;
  172. }
  173. assert(0);
  174. return(0); /* never reached */
  175. }
  176. /* }}} */
  177. /*
  178. * Local variables:
  179. * tab-width: 4
  180. * c-basic-offset: 4
  181. * End:
  182. * vim600: sw=4 ts=4 fdm=marker
  183. * vim<600: sw=4 ts=4
  184. */