mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Merge branch 'sasq64-get-args-array'
This commit is contained in:
@@ -1014,6 +1014,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 */
|
||||
{
|
||||
|
||||
+2
-1
@@ -48,7 +48,8 @@ typedef struct mrb_heap_page {
|
||||
struct mrb_heap_page *free_next;
|
||||
struct mrb_heap_page *free_prev;
|
||||
mrb_bool old:1;
|
||||
void *objects[];
|
||||
/* Flexible array members area a C99 feature, not C++ compatible */
|
||||
/* void* objects[]; */
|
||||
} mrb_heap_page;
|
||||
|
||||
#ifdef _MSC_VER
|
||||
|
||||
+76
-61
@@ -890,51 +890,14 @@ mrb_block_given_p(mrb_state *mrb)
|
||||
return !mrb_nil_p(b);
|
||||
}
|
||||
|
||||
/*
|
||||
retrieve arguments from mrb_state.
|
||||
#define GET_ARG(_type) (ptr ? ((_type)(*ptr++)) : va_arg(ap, _type))
|
||||
|
||||
mrb_get_args(mrb, format, ...)
|
||||
|
||||
returns number of arguments parsed.
|
||||
|
||||
format specifiers:
|
||||
|
||||
string mruby type C type note
|
||||
----------------------------------------------------------------------------------------------
|
||||
o: Object [mrb_value]
|
||||
C: Class/Module [mrb_value] when ! follows, the value may be nil
|
||||
S: String [mrb_value] when ! follows, the value may be nil
|
||||
A: Array [mrb_value] when ! follows, the value may be nil
|
||||
H: Hash [mrb_value] when ! follows, the value may be nil
|
||||
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! 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
|
||||
&: 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
|
||||
?: optional given [mrb_bool] true if preceding argument (optional) is given
|
||||
':': keyword args [mrb_kwargs const] Get keyword arguments
|
||||
|
||||
format modifiers:
|
||||
|
||||
string note
|
||||
----------------------------------------------------------------------------------------------
|
||||
!: Switch to the alternate mode; The behaviour changes depending on the specifier
|
||||
+: Request a not frozen object; However, except nil value
|
||||
*/
|
||||
MRB_API mrb_int
|
||||
mrb_get_args(mrb_state *mrb, const char *format, ...)
|
||||
static mrb_int
|
||||
get_args_v(mrb_state *mrb, mrb_args_format format, void** ptr, va_list ap)
|
||||
{
|
||||
const char *fmt = format;
|
||||
char c;
|
||||
mrb_int i = 0;
|
||||
va_list ap;
|
||||
mrb_callinfo *ci = mrb->c->ci;
|
||||
mrb_int argc = ci->n;
|
||||
const mrb_value *argv = ci->stack+1;
|
||||
@@ -946,8 +909,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 '|':
|
||||
@@ -1071,7 +1032,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) {
|
||||
@@ -1089,7 +1050,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;
|
||||
@@ -1106,8 +1067,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)) {
|
||||
@@ -1126,7 +1087,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)) {
|
||||
@@ -1145,8 +1106,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)) {
|
||||
@@ -1167,7 +1128,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);
|
||||
}
|
||||
@@ -1178,7 +1139,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);
|
||||
}
|
||||
@@ -1186,7 +1147,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);
|
||||
@@ -1197,7 +1158,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);
|
||||
}
|
||||
@@ -1208,8 +1169,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;
|
||||
@@ -1225,7 +1186,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");
|
||||
@@ -1241,7 +1202,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;
|
||||
@@ -1252,8 +1213,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) {
|
||||
@@ -1278,7 +1239,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) {
|
||||
@@ -1341,10 +1302,64 @@ mrb_get_args(mrb_state *mrb, const char *format, ...)
|
||||
}
|
||||
|
||||
finish:
|
||||
va_end(ap);
|
||||
return i;
|
||||
}
|
||||
|
||||
/*
|
||||
retrieve arguments from mrb_state.
|
||||
|
||||
mrb_get_args(mrb, format, ...)
|
||||
|
||||
returns number of arguments parsed.
|
||||
|
||||
format specifiers:
|
||||
|
||||
string mruby type C type note
|
||||
----------------------------------------------------------------------------------------------
|
||||
o: Object [mrb_value]
|
||||
C: Class/Module [mrb_value] when ! follows, the value may be nil
|
||||
S: String [mrb_value] when ! follows, the value may be nil
|
||||
A: Array [mrb_value] when ! follows, the value may be nil
|
||||
H: Hash [mrb_value] when ! follows, the value may be nil
|
||||
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! 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
|
||||
&: 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
|
||||
?: optional given [mrb_bool] true if preceding argument (optional) is given
|
||||
':': keyword args [mrb_kwargs const] Get keyword arguments
|
||||
|
||||
format modifiers:
|
||||
|
||||
string note
|
||||
----------------------------------------------------------------------------------------------
|
||||
!: Switch to the alternate mode; The behaviour changes depending on the specifier
|
||||
+: Request a not frozen object; However, except nil value
|
||||
*/
|
||||
MRB_API mrb_int
|
||||
mrb_get_args(mrb_state *mrb, mrb_args_format format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
mrb_int rc = 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;
|
||||
return get_args_v(mrb, format, args, ap);
|
||||
}
|
||||
|
||||
static struct RClass*
|
||||
boot_defclass(mrb_state *mrb, struct RClass *super)
|
||||
{
|
||||
|
||||
@@ -215,7 +215,11 @@ mrb_static_assert(MRB_GC_RED <= GC_COLOR_MASK);
|
||||
#define other_white_part(s) ((s)->current_white_part ^ GC_WHITES)
|
||||
#define is_dead(s, o) (((o)->color & other_white_part(s) & GC_WHITES) || (o)->tt == MRB_TT_FREE)
|
||||
|
||||
#define objects(p) ((RVALUE *)p->objects)
|
||||
/* We have removed `objects[]` from `mrb_heap_page` since it was not C++
|
||||
* compatible. Using array index to get pointer after structure instead. */
|
||||
|
||||
/* #define objects(p) ((RVALUE *)p->objects) */
|
||||
#define objects(p) ((RVALUE *)&p[1])
|
||||
|
||||
mrb_noreturn void mrb_raise_nomemory(mrb_state *mrb);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user