add "?" specifier to check if preceding optional argument is given

This commit is contained in:
Yukihiro "Matz" Matsumoto
2014-03-09 00:25:59 +09:00
parent 058bb18f28
commit bd4b59cd04
+19 -4
View File
@@ -411,6 +411,7 @@ to_hash(mrb_state *mrb, mrb_value val)
&: Block [mrb_value]
*: rest argument [mrb_value*,int] Receive the rest of the arguments as an array.
|: optional Next argument of '|' and later are optional.
?: optional given [mrb_bool] true if preceding argument (optional) is given.
*/
int
mrb_get_args(mrb_state *mrb, const char *format, ...)
@@ -420,7 +421,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_value *sp = mrb->c->stack + 1;
va_list ap;
int argc = mrb->c->ci->argc;
int opt = 0;
mrb_bool opt = 0;
mrb_bool given = 1;
va_start(ap, format);
if (argc < 0) {
@@ -431,11 +433,16 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
while ((c = *format++)) {
switch (c) {
case '|': case '*': case '&':
case '|': case '*': case '&': case '?':
break;
default:
if (argc <= i && !opt) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
if (argc <= i) {
if (opt) {
given = 0;
}
else {
mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
}
}
break;
}
@@ -689,6 +696,14 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
case '|':
opt = 1;
break;
case '?':
{
mrb_bool *p;
p = va_arg(ap, mrb_bool*);
*p = given;
}
break;
case '*':
{