PageRenderTime 26ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/sapi/cgi/getopt.c

http://php52-backports.googlecode.com/
C | 164 lines | 128 code | 9 blank | 27 comment | 46 complexity | c516e0dcc6171cd726ec559620332436 MD5 | raw file
Possible License(s): MPL-2.0-no-copyleft-exception, LGPL-2.1, BSD-3-Clause
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2010 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: getopt.c 293036 2010-01-03 09:23:27Z sebastian $ */
  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. if (argv[*optind][2] == '\0') {
  76. (*optind)++;
  77. return(EOF);
  78. }
  79. while (1) {
  80. opts_idx++;
  81. if (opts[opts_idx].opt_char == '-') {
  82. (*optind)++;
  83. return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
  84. } else if (opts[opts_idx].opt_name && !strcmp(&argv[*optind][2], opts[opts_idx].opt_name)) {
  85. break;
  86. }
  87. }
  88. optchr = 0;
  89. dash = 0;
  90. arg_start = 2 + strlen(opts[opts_idx].opt_name);
  91. } else {
  92. if (!dash) {
  93. dash = 1;
  94. optchr = 1;
  95. }
  96. /* Check if the guy tries to do a -: kind of flag */
  97. if (argv[*optind][optchr] == ':') {
  98. dash = 0;
  99. (*optind)++;
  100. return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
  101. }
  102. arg_start = 1 + optchr;
  103. }
  104. if (opts_idx < 0) {
  105. while (1) {
  106. opts_idx++;
  107. if (opts[opts_idx].opt_char == '-') {
  108. int errind = *optind;
  109. int errchr = optchr;
  110. if (!argv[*optind][optchr+1]) {
  111. dash = 0;
  112. (*optind)++;
  113. } else {
  114. optchr++;
  115. arg_start++;
  116. }
  117. return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
  118. } else if (argv[*optind][optchr] == opts[opts_idx].opt_char) {
  119. break;
  120. }
  121. }
  122. }
  123. if (opts[opts_idx].need_param) {
  124. /* Check for cases where the value of the argument
  125. is in the form -<arg> <val> or in the form -<arg><val> */
  126. dash = 0;
  127. if(!argv[*optind][arg_start]) {
  128. (*optind)++;
  129. if (*optind == argc) {
  130. return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
  131. }
  132. *optarg = argv[(*optind)++];
  133. } else {
  134. *optarg = &argv[*optind][arg_start];
  135. (*optind)++;
  136. }
  137. return opts[opts_idx].opt_char;
  138. } else {
  139. /* multiple options specified as one (exclude long opts) */
  140. if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))) {
  141. if (!argv[*optind][optchr+1])
  142. {
  143. dash = 0;
  144. (*optind)++;
  145. } else {
  146. optchr++;
  147. }
  148. } else {
  149. (*optind)++;
  150. }
  151. return opts[opts_idx].opt_char;
  152. }
  153. assert(0);
  154. return(0); /* never reached */
  155. }