summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2014-03-09 00:25:59 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2014-03-09 00:25:59 +0900
commitbd4b59cd043fcff8095a5c474330d66ccaf69524 (patch)
tree4a9eb6c1608f4a9e32fd877f74a1f24e8b558aae /src
parent058bb18f280dddb53ac40c838b371e9469024274 (diff)
downloadmruby-bd4b59cd043fcff8095a5c474330d66ccaf69524.tar.gz
mruby-bd4b59cd043fcff8095a5c474330d66ccaf69524.zip
add "?" specifier to check if preceding optional argument is given
Diffstat (limited to 'src')
-rw-r--r--src/class.c23
1 files changed, 19 insertions, 4 deletions
diff --git a/src/class.c b/src/class.c
index 9880a82fa..5a084b016 100644
--- a/src/class.c
+++ b/src/class.c
@@ -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 '*':
{