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.

156 lines
4.1 KiB

  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2006 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. int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err)
  51. {
  52. static int optchr = 0;
  53. static int dash = 0; /* have already seen the - */
  54. int arg_start = 2;
  55. int opts_idx = -1;
  56. if (*optind >= argc) {
  57. return(EOF);
  58. }
  59. if (!dash) {
  60. if ((argv[*optind][0] != '-')) {
  61. return(EOF);
  62. } else {
  63. if (!argv[*optind][1])
  64. {
  65. /*
  66. * use to specify stdin. Need to let pgm process this and
  67. * the following args
  68. */
  69. return(EOF);
  70. }
  71. }
  72. }
  73. if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
  74. /* '--' indicates end of args if not followed by a known long option name */
  75. while (1) {
  76. opts_idx++;
  77. if (opts[opts_idx].opt_char == '-') {
  78. (*optind)++;
  79. return(EOF);
  80. } else if (opts[opts_idx].opt_name && !strcmp(&argv[*optind][2], opts[opts_idx].opt_name)) {
  81. break;
  82. }
  83. }
  84. optchr = 0;
  85. dash = 1;
  86. arg_start = 2 + strlen(opts[opts_idx].opt_name);
  87. }
  88. if (!dash) {
  89. dash = 1;
  90. optchr = 1;
  91. }
  92. /* Check if the guy tries to do a -: kind of flag */
  93. if (argv[*optind][optchr] == ':') {
  94. dash = 0;
  95. (*optind)++;
  96. return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
  97. }
  98. if (opts_idx < 0) {
  99. while (1) {
  100. opts_idx++;
  101. if (opts[opts_idx].opt_char == '-') {
  102. int errind = *optind;
  103. int errchr = optchr;
  104. if (!argv[*optind][optchr+1]) {
  105. dash = 0;
  106. (*optind)++;
  107. } else {
  108. optchr++;
  109. }
  110. return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
  111. } else if (argv[*optind][optchr] == opts[opts_idx].opt_char) {
  112. break;
  113. }
  114. }
  115. }
  116. if (opts[opts_idx].need_param) {
  117. /* Check for cases where the value of the argument
  118. is in the form -<arg> <val> or in the form -<arg><val> */
  119. dash = 0;
  120. if(!argv[*optind][arg_start]) {
  121. (*optind)++;
  122. if (*optind == argc) {
  123. return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
  124. }
  125. *optarg = argv[(*optind)++];
  126. } else {
  127. *optarg = &argv[*optind][arg_start];
  128. (*optind)++;
  129. }
  130. return opts[opts_idx].opt_char;
  131. } else {
  132. if (arg_start == 2) {
  133. if (!argv[*optind][optchr+1])
  134. {
  135. dash = 0;
  136. (*optind)++;
  137. } else {
  138. optchr++;
  139. }
  140. } else {
  141. (*optind)++;
  142. }
  143. return opts[opts_idx].opt_char;
  144. }
  145. assert(0);
  146. return(0); /* never reached */
  147. }