summaryrefslogtreecommitdiffhomepage
path: root/src/class.c
diff options
context:
space:
mode:
authordearblue <[email protected]>2021-08-28 15:54:30 +0900
committerdearblue <[email protected]>2021-08-28 15:54:30 +0900
commitf99620436d2cb09046a99d330ffa7ca1c622538d (patch)
treeec6f041a92652779ff909e0b656981448452de3d /src/class.c
parent07f12fe890738688da917cfdc75a95be2bea2e26 (diff)
downloadmruby-f99620436d2cb09046a99d330ffa7ca1c622538d.tar.gz
mruby-f99620436d2cb09046a99d330ffa7ca1c622538d.zip
Allow `nil` for `c!` and `I!` specifiers of `mrb_get_args()`
Diffstat (limited to 'src/class.c')
-rw-r--r--src/class.c28
1 files changed, 19 insertions, 9 deletions
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;