Skip to content

Commit 024fc2c

Browse files
committed
MFH: - Add support for optional values
MFH: - Add support for = as seperator
1 parent 45f6b4c commit 024fc2c

File tree

4 files changed

+92
-6
lines changed

4 files changed

+92
-6
lines changed

ext/standard/basic_functions.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4532,6 +4532,10 @@ static int parse_opts(char * opts, opt_struct ** result)
45324532
paras->opt_name = NULL;
45334533
if (paras->need_param == 1) {
45344534
opts++;
4535+
if (*opts == ':') {
4536+
paras->need_param++;
4537+
opts++;
4538+
}
45354539
}
45364540
paras++;
45374541
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
getopt#004 (Optional values)
3+
--ARGS--
4+
-v -v1 -v=10 --v --v=100
5+
--INI--
6+
register_argc_argv=On
7+
variables_order=GPS
8+
--FILE--
9+
<?php
10+
var_dump(getopt("v::", array("v::")));
11+
?>
12+
--EXPECT--
13+
array(1) {
14+
["v"]=>
15+
array(5) {
16+
[0]=>
17+
bool(false)
18+
[1]=>
19+
string(1) "1"
20+
[2]=>
21+
string(2) "10"
22+
[3]=>
23+
bool(false)
24+
[4]=>
25+
string(3) "100"
26+
}
27+
}
28+
29+
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
getopt#005 (Required values)
3+
--ARGS--
4+
--arg value --arg=value -avalue -a=value -a value
5+
--INI--
6+
register_argc_argv=On
7+
variables_order=GPS
8+
--FILE--
9+
<?php
10+
var_dump(getopt("a:", array("arg:")));
11+
?>
12+
--EXPECT--
13+
array(2) {
14+
["arg"]=>
15+
array(2) {
16+
[0]=>
17+
string(5) "value"
18+
[1]=>
19+
string(5) "value"
20+
}
21+
["a"]=>
22+
array(3) {
23+
[0]=>
24+
string(5) "value"
25+
[1]=>
26+
string(5) "value"
27+
[2]=>
28+
string(5) "value"
29+
}
30+
}
31+
32+

main/getopt.c

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,24 +80,36 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char
8080
}
8181
}
8282
if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
83+
char *pos;
84+
int arg_end = strlen(argv[*optind])-1;
85+
8386
/* '--' indicates end of args if not followed by a known long option name */
8487
if (argv[*optind][2] == '\0') {
8588
(*optind)++;
8689
return(EOF);
8790
}
8891

92+
arg_start = 2;
93+
94+
/* Check for <arg>=<val> */
95+
if ((pos = php_memnstr(&argv[*optind][arg_start], "=", 1, argv[*optind]+arg_end)) != NULL) {
96+
arg_end = pos-&argv[*optind][arg_start];
97+
arg_start++;
98+
}
99+
100+
89101
while (1) {
90102
php_optidx++;
91103
if (opts[php_optidx].opt_char == '-') {
92104
(*optind)++;
93105
return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
94-
} else if (opts[php_optidx].opt_name && !strcmp(&argv[*optind][2], opts[php_optidx].opt_name)) {
106+
} else if (opts[php_optidx].opt_name && !strncmp(&argv[*optind][2], opts[php_optidx].opt_name, arg_end)) {
95107
break;
96108
}
97109
}
98110
optchr = 0;
99111
dash = 0;
100-
arg_start = 2 + strlen(opts[php_optidx].opt_name);
112+
arg_start += strlen(opts[php_optidx].opt_name);
101113
} else {
102114
if (!dash) {
103115
dash = 1;
@@ -133,14 +145,23 @@ PHPAPI int php_getopt(int argc, char* const *argv, const opt_struct opts[], char
133145
}
134146
if (opts[php_optidx].need_param) {
135147
/* Check for cases where the value of the argument
136-
is in the form -<arg> <val> or in the form -<arg><val> */
148+
is in the form -<arg> <val>, -<arg>=<varl> or -<arg><val> */
137149
dash = 0;
138150
if (!argv[*optind][arg_start]) {
139151
(*optind)++;
140152
if (*optind == argc) {
141-
return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
142-
}
143-
*optarg = argv[(*optind)++];
153+
/* Was the value required or is it optional? */
154+
if (opts[php_optidx].need_param == 1) {
155+
return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
156+
}
157+
/* Optional value is not supported with -<arg> <val> style */
158+
} else if (opts[php_optidx].need_param == 1) {
159+
*optarg = argv[(*optind)++];
160+
}
161+
} else if (argv[*optind][arg_start] == '=') {
162+
arg_start++;
163+
*optarg = &argv[*optind][arg_start];
164+
(*optind)++;
144165
} else {
145166
*optarg = &argv[*optind][arg_start];
146167
(*optind)++;

0 commit comments

Comments
 (0)