Added mrb_get_args_a() - an array version of mrb_get_args()

This commit is contained in:
Jonas Minnberg
2021-12-11 14:24:36 +01:00
parent 24939723d7
commit b1cf973186
2 changed files with 50 additions and 25 deletions
+7
View File
@@ -1009,6 +1009,13 @@ struct mrb_kwargs
*/
MRB_API mrb_int mrb_get_args(mrb_state *mrb, mrb_args_format format, ...);
/**
* Array version of mrb_get_args()
*
* @param ptr Array of void*, in the same order as the varargs version.
*/
MRB_API mrb_int mrb_get_args_a(mrb_state *mrb, mrb_args_format format, void** ptr);
MRB_INLINE mrb_sym
mrb_get_mid(mrb_state *mrb) /* get method symbol */
{
+43 -25
View File
@@ -869,6 +869,8 @@ mrb_block_given_p(mrb_state *mrb)
return !mrb_nil_p(b);
}
mrb_int mrb_get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list ap);
/*
retrieve arguments from mrb_state.
@@ -909,12 +911,31 @@ mrb_block_given_p(mrb_state *mrb)
+: Request a not frozen object; However, except nil value
*/
MRB_API mrb_int
mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_get_args(mrb_state *mrb, mrb_args_format format, ...)
{
va_list ap;
va_start(ap, format);
mrb_int rc = mrb_get_args_v(mrb, format, NULL, ap);
va_end(ap);
return rc;
}
MRB_API mrb_int
mrb_get_args_a(mrb_state *mrb, mrb_args_format format, void** args)
{
va_list ap;
mrb_int rc = mrb_get_args_v(mrb, format, args, ap);
return rc;
}
#define GET_ARG(_type) (ptr ? ((_type)(*ptr++)) : va_arg(ap, _type))
MRB_API mrb_int
mrb_get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list ap)
{
const char *fmt = format;
char c;
int i = 0;
va_list ap;
mrb_callinfo *ci = mrb->c->ci;
int argc = ci->n;
const mrb_value *argv = ci->stack+1;
@@ -926,8 +947,6 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_bool reqkarg = FALSE;
int argc_min = 0, argc_max = 0;
va_start(ap, format);
while ((c = *fmt++)) {
switch (c) {
case '|':
@@ -1051,7 +1070,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
{
mrb_value *p;
p = va_arg(ap, mrb_value*);
p = GET_ARG(mrb_value*);
if (pickarg) {
if (!(altmode && mrb_nil_p(*pickarg))) {
switch (c) {
@@ -1069,7 +1088,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
{
struct RClass **p;
p = va_arg(ap, struct RClass**);
p = GET_ARG(struct RClass**);
if (pickarg) {
if (altmode && mrb_nil_p(*pickarg)) {
*p = NULL;
@@ -1086,8 +1105,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
const char **ps = 0;
mrb_int *pl = 0;
ps = va_arg(ap, const char**);
pl = va_arg(ap, mrb_int*);
ps = GET_ARG(const char**);
pl = GET_ARG(mrb_int*);
if (needmodify) goto bad_needmodify;
if (pickarg) {
if (altmode && mrb_nil_p(*pickarg)) {
@@ -1106,7 +1125,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
{
const char **ps;
ps = va_arg(ap, const char**);
ps = GET_ARG(const char**);
if (needmodify) goto bad_needmodify;
if (pickarg) {
if (altmode && mrb_nil_p(*pickarg)) {
@@ -1125,8 +1144,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
const mrb_value **pb;
mrb_int *pl;
pb = va_arg(ap, const mrb_value**);
pl = va_arg(ap, mrb_int*);
pb = GET_ARG(const mrb_value**);
pl = GET_ARG(mrb_int*);
if (needmodify) goto bad_needmodify;
if (pickarg) {
if (altmode && mrb_nil_p(*pickarg)) {
@@ -1147,8 +1166,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
void* *p;
struct RClass *klass;
p = va_arg(ap, void**);
klass = va_arg(ap, struct RClass*);
p = GET_ARG(void**);
klass = GET_ARG(struct RClass*);
if (pickarg) {
if (altmode && mrb_nil_p(*pickarg)) {
*p = NULL;
@@ -1170,7 +1189,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
{
mrb_float *p;
p = va_arg(ap, mrb_float*);
p = GET_ARG(mrb_float*);
if (pickarg) {
*p = mrb_as_float(mrb, *pickarg);
}
@@ -1181,7 +1200,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
{
mrb_int *p;
p = va_arg(ap, mrb_int*);
p = GET_ARG(mrb_int*);
if (pickarg) {
*p = mrb_as_int(mrb, *pickarg);
}
@@ -1189,7 +1208,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
break;
case 'b':
{
mrb_bool *boolp = va_arg(ap, mrb_bool*);
mrb_bool *boolp = GET_ARG(mrb_bool*);
if (pickarg) {
*boolp = mrb_test(*pickarg);
@@ -1200,7 +1219,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
{
mrb_sym *symp;
symp = va_arg(ap, mrb_sym*);
symp = GET_ARG(mrb_sym*);
if (pickarg) {
*symp = to_sym(mrb, *pickarg);
}
@@ -1211,8 +1230,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
void** datap;
struct mrb_data_type const* type;
datap = va_arg(ap, void**);
type = va_arg(ap, struct mrb_data_type const*);
datap = GET_ARG(void**);
type = GET_ARG(struct mrb_data_type const*);
if (pickarg) {
if (altmode && mrb_nil_p(*pickarg)) {
*datap = 0;
@@ -1228,7 +1247,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
{
mrb_value *p, *bp;
p = va_arg(ap, mrb_value*);
p = GET_ARG(mrb_value*);
bp = ci->stack + mrb_ci_bidx(ci);
if (altmode && mrb_nil_p(*bp)) {
mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
@@ -1244,7 +1263,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
{
mrb_bool *p;
p = va_arg(ap, mrb_bool*);
p = GET_ARG(mrb_bool*);
*p = pickarg ? TRUE : FALSE;
}
break;
@@ -1255,8 +1274,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
mrb_int *pl;
mrb_bool nocopy = (altmode || !argv_on_stack) ? TRUE : FALSE;
var = va_arg(ap, const mrb_value**);
pl = va_arg(ap, mrb_int*);
var = GET_ARG(const mrb_value**);
pl = GET_ARG(mrb_int*);
if (argc > i) {
*pl = argc-i;
if (*pl > 0) {
@@ -1281,7 +1300,7 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
case ':':
{
mrb_value ksrc = mrb_hash_p(kdict) ? mrb_hash_dup(mrb, kdict) : mrb_hash_new(mrb);
const mrb_kwargs *kwargs = va_arg(ap, const mrb_kwargs*);
const mrb_kwargs *kwargs = GET_ARG(const mrb_kwargs*);
mrb_value *rest;
if (kwargs == NULL) {
@@ -1344,7 +1363,6 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
}
finish:
va_end(ap);
return i;
}