summaryrefslogtreecommitdiffhomepage
path: root/src/class.c
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2021-08-30 07:38:45 +0900
committerGitHub <[email protected]>2021-08-30 07:38:45 +0900
commit64d5a40cde6fe1e33ebe3287bc6abdba9b68fb20 (patch)
tree71633ea2f686a28979f74047dbf8ef66bb1a1d45 /src/class.c
parent84e36d748ca6d2681aab9d548c225e601aa4cc30 (diff)
parentf99620436d2cb09046a99d330ffa7ca1c622538d (diff)
downloadmruby-64d5a40cde6fe1e33ebe3287bc6abdba9b68fb20.tar.gz
mruby-64d5a40cde6fe1e33ebe3287bc6abdba9b68fb20.zip
Merge pull request #5542 from dearblue/mrb_get_args-cI
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 a4a2f90e3..855a7715c 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
@@ -1042,8 +1042,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;
@@ -1116,13 +1121,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;