summaryrefslogtreecommitdiffhomepage
path: root/src/class.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2017-08-25 09:00:58 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2017-08-26 02:03:21 +0900
commit1b545a6b635a40218a6977caede8616655de3d86 (patch)
treef6c8ab8e638c9f202330bcebd31efea52ef9848e /src/class.c
parent60104ce41d503ed0c405d2488954f223798d9201 (diff)
downloadmruby-1b545a6b635a40218a6977caede8616655de3d86.tar.gz
mruby-1b545a6b635a40218a6977caede8616655de3d86.zip
Check for ability to skip optional argument parsing.
Diffstat (limited to 'src/class.c')
-rw-r--r--src/class.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/src/class.c b/src/class.c
index 861c3a8f2..41f617c37 100644
--- a/src/class.c
+++ b/src/class.c
@@ -562,6 +562,7 @@ to_sym(mrb_state *mrb, mrb_value ss)
MRB_API mrb_int
mrb_get_args(mrb_state *mrb, const char *format, ...)
{
+ const char *fmt = format;
char c;
int i = 0;
va_list ap;
@@ -569,6 +570,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
int arg_i = 0;
mrb_value *array_argv;
mrb_bool opt = FALSE;
+ mrb_bool opt_skip = TRUE;
mrb_bool given = TRUE;
va_start(ap, format);
@@ -585,6 +587,27 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
#define ARGV \
(array_argv ? array_argv : (mrb->c->stack + 1))
+ while ((c = *fmt++)) {
+ switch (c) {
+ case '|':
+ opt = TRUE;
+ break;
+ case '*':
+ opt_skip = FALSE;
+ goto check_exit;
+ case '!':
+ break;
+ case '&': case '?':
+ if (opt) opt_skip = FALSE;
+ break;
+ default:
+ break;
+ }
+ }
+
+ check_exit:
+ opt = FALSE;
+ i = 0;
while ((c = *format++)) {
switch (c) {
case '|': case '*': case '&': case '?':
@@ -884,6 +907,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
break;
case '|':
+ if (opt_skip && i == argc) return argc;
opt = TRUE;
break;
case '?':