diff options
| -rw-r--r-- | include/mruby.h | 3 | ||||
| -rw-r--r-- | src/class.c | 28 |
2 files changed, 21 insertions, 10 deletions
diff --git a/include/mruby.h b/include/mruby.h index 0563ab577..b32173c42 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -899,12 +899,13 @@ MRB_API struct RClass* mrb_define_module_under_id(mrb_state *mrb, struct RClass * | `s` | {String} | const char *, {mrb_int} | Receive two arguments; `s!` gives (`NULL`,`0`) for `nil` | * | `z` | {String} | const char * | `NULL` terminated string; `z!` gives `NULL` for `nil` | * | `a` | {Array} | const {mrb_value} *, {mrb_int} | Receive two arguments; `a!` gives (`NULL`,`0`) for `nil` | + * | `c` | {Class}/{Module} | strcut RClass * | `c!` gives `NULL` for `nil` | * | `f` | {Integer}/{Float} | {mrb_float} | | * | `i` | {Integer}/{Float} | {mrb_int} | | * | `b` | boolean | {mrb_bool} | | * | `n` | {String}/{Symbol} | {mrb_sym} | | * | `d` | data | void *, {mrb_data_type} const | 2nd argument will be used to check data type so it won't be modified; when `!` follows, the value may be `nil` | - * | `I` | inline struct | void *, struct RClass | | + * | `I` | inline struct | void *, struct RClass | `I!` gives `NULL` for `nil` | * | `&` | block | {mrb_value} | &! raises exception if no block given. | * | `*` | rest arguments | const {mrb_value} *, {mrb_int} | Receive the rest of arguments as an array; `*!` avoid copy of the stack. | * | <code>\|</code> | optional | | After this spec following specs would be optional. | diff --git a/src/class.c b/src/class.c index 316f61798..be94794ee 100644 --- a/src/class.c +++ b/src/class.c @@ -884,13 +884,13 @@ void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self); s: String [const char*,mrb_int] Receive two arguments; s! gives (NULL,0) for nil z: String [const char*] NUL terminated string; z! gives NULL for nil a: Array [const mrb_value*,mrb_int] Receive two arguments; a! gives (NULL,0) for nil - c: Class/Module [strcut RClass*] + c: Class/Module [strcut RClass*] c! gives NULL for nil f: Integer/Float [mrb_float] i: Integer/Float [mrb_int] b: boolean [mrb_bool] n: String/Symbol [mrb_sym] d: data [void*,mrb_data_type const] 2nd argument will be used to check data type so it won't be modified; when ! follows, the value may be nil - I: inline struct [void*,struct RClass] + I: inline struct [void*,struct RClass] I! gives NULL for nil &: block [mrb_value] &! raises exception if no block given *: rest argument [const mrb_value*,mrb_int] The rest of the arguments as an array; *! avoid copy of the stack |: optional Following arguments are optional @@ -1041,8 +1041,13 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) p = va_arg(ap, struct RClass**); if (pickarg) { - ensure_class_type(mrb, *pickarg); - *p = mrb_class_ptr(*pickarg); + if (altmode && mrb_nil_p(*pickarg)) { + *p = NULL; + } + else { + ensure_class_type(mrb, *pickarg); + *p = mrb_class_ptr(*pickarg); + } } } break; @@ -1154,13 +1159,18 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) p = va_arg(ap, void**); klass = va_arg(ap, struct RClass*); if (pickarg) { - if (!mrb_obj_is_kind_of(mrb, *pickarg, klass)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%v is not a %C", *pickarg, klass); + if (altmode && mrb_nil_p(*pickarg)) { + *p = NULL; } - if (!mrb_istruct_p(*pickarg)) { - mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", *pickarg); + else { + if (!mrb_obj_is_kind_of(mrb, *pickarg, klass)) { + mrb_raisef(mrb, E_TYPE_ERROR, "%v is not a %C", *pickarg, klass); + } + if (!mrb_istruct_p(*pickarg)) { + mrb_raisef(mrb, E_TYPE_ERROR, "%v is not inline struct", *pickarg); + } + *p = mrb_istruct_ptr(*pickarg); } - *p = mrb_istruct_ptr(*pickarg); } } break; |
