1 : /*
2 : +----------------------------------------------------------------------+
3 : | PHP Version 5 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 1997-2007 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 :
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 :
28 :
29 : static int php_opt_error(int argc, char * const *argv, int oint, int optchr, int err, int show_err)
30 2 : {
31 2 : if (show_err)
32 : {
33 1 : fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
34 1 : switch(err)
35 : {
36 : case OPTERRCOLON:
37 0 : fprintf(stderr, ": in flags\n");
38 0 : break;
39 : case OPTERRNF:
40 1 : fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
41 1 : break;
42 : case OPTERRARG:
43 0 : fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
44 0 : break;
45 : default:
46 0 : fprintf(stderr, "unknown\n");
47 : break;
48 : }
49 : }
50 2 : return('?');
51 : }
52 :
53 : int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err)
54 12013 : {
55 : static int optchr = 0;
56 : static int dash = 0; /* have already seen the - */
57 12013 : int arg_start = 2;
58 :
59 12013 : int opts_idx = -1;
60 :
61 12013 : if (*optind >= argc) {
62 216 : return(EOF);
63 : }
64 11797 : if (!dash) {
65 11797 : if ((argv[*optind][0] != '-')) {
66 331 : return(EOF);
67 : } else {
68 11466 : if (!argv[*optind][1])
69 : {
70 : /*
71 : * use to specify stdin. Need to let pgm process this and
72 : * the following args
73 : */
74 0 : return(EOF);
75 : }
76 : }
77 : }
78 11466 : if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
79 : /* '--' indicates end of args if not followed by a known long option name */
80 : while (1) {
81 0 : opts_idx++;
82 0 : if (opts[opts_idx].opt_char == '-') {
83 0 : (*optind)++;
84 0 : return(EOF);
85 0 : } else if (opts[opts_idx].opt_name && !strcmp(&argv[*optind][2], opts[opts_idx].opt_name)) {
86 0 : break;
87 : }
88 0 : }
89 0 : optchr = 0;
90 0 : dash = 1;
91 0 : arg_start = 2 + strlen(opts[opts_idx].opt_name);
92 : }
93 11466 : if (!dash) {
94 11466 : dash = 1;
95 11466 : optchr = 1;
96 : }
97 :
98 : /* Check if the guy tries to do a -: kind of flag */
99 11466 : if (argv[*optind][optchr] == ':') {
100 0 : dash = 0;
101 0 : (*optind)++;
102 0 : return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
103 : }
104 11466 : if (opts_idx < 0) {
105 : while (1) {
106 60384 : opts_idx++;
107 60384 : if (opts[opts_idx].opt_char == '-') {
108 2 : int errind = *optind;
109 2 : int errchr = optchr;
110 :
111 2 : if (!argv[*optind][optchr+1]) {
112 2 : dash = 0;
113 2 : (*optind)++;
114 : } else {
115 0 : optchr++;
116 : }
117 2 : return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
118 60382 : } else if (argv[*optind][optchr] == opts[opts_idx].opt_char) {
119 11464 : break;
120 : }
121 48918 : }
122 : }
123 11464 : 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 11140 : dash = 0;
127 11140 : if(!argv[*optind][arg_start]) {
128 11140 : (*optind)++;
129 11140 : if (*optind == argc) {
130 0 : return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
131 : }
132 11140 : *optarg = argv[(*optind)++];
133 : } else {
134 0 : *optarg = &argv[*optind][arg_start];
135 0 : (*optind)++;
136 : }
137 11140 : return opts[opts_idx].opt_char;
138 : } else {
139 324 : if (arg_start == 2) {
140 324 : if (!argv[*optind][optchr+1])
141 : {
142 324 : dash = 0;
143 324 : (*optind)++;
144 : } else {
145 0 : optchr++;
146 : }
147 : } else {
148 0 : (*optind)++;
149 : }
150 324 : return opts[opts_idx].opt_char;
151 : }
152 : assert(0);
153 : return(0); /* never reached */
154 : }
|