1#ifndef RBIMPL_SCAN_ARGS_H
2#define RBIMPL_SCAN_ARGS_H
43#define RB_SCAN_ARGS_PASS_CALLED_KEYWORDS 0
44#define RB_SCAN_ARGS_KEYWORDS 1
45#define RB_SCAN_ARGS_LAST_HASH_KEYWORDS 3
46#define RB_NO_KEYWORDS 0
47#define RB_PASS_KEYWORDS 1
48#define RB_PASS_CALLED_KEYWORDS rb_keyword_given_p()
50#define HAVE_RB_SCAN_ARGS_OPTIONAL_HASH 1
67#define rb_scan_args_isdigit(c) (RBIMPL_CAST((unsigned char)((c)-'0'))<10)
69#define rb_scan_args_count_end(fmt, ofs, vari) \
70 ((fmt)[ofs] ? -1 : (vari))
72#define rb_scan_args_count_block(fmt, ofs, vari) \
74 rb_scan_args_count_end(fmt, ofs, vari) : \
75 rb_scan_args_count_end(fmt, (ofs)+1, (vari)+1))
77#define rb_scan_args_count_hash(fmt, ofs, vari) \
79 rb_scan_args_count_block(fmt, ofs, vari) : \
80 rb_scan_args_count_block(fmt, (ofs)+1, (vari)+1))
82#define rb_scan_args_count_trail(fmt, ofs, vari) \
83 (!rb_scan_args_isdigit((fmt)[ofs]) ? \
84 rb_scan_args_count_hash(fmt, ofs, vari) : \
85 rb_scan_args_count_hash(fmt, (ofs)+1, (vari)+((fmt)[ofs]-'0')))
87#define rb_scan_args_count_var(fmt, ofs, vari) \
89 rb_scan_args_count_trail(fmt, ofs, vari) : \
90 rb_scan_args_count_trail(fmt, (ofs)+1, (vari)+1))
92#define rb_scan_args_count_opt(fmt, ofs, vari) \
93 (!rb_scan_args_isdigit((fmt)[ofs]) ? \
94 rb_scan_args_count_var(fmt, ofs, vari) : \
95 rb_scan_args_count_var(fmt, (ofs)+1, (vari)+(fmt)[ofs]-'0'))
97#define rb_scan_args_count_lead(fmt, ofs, vari) \
98 (!rb_scan_args_isdigit((fmt)[ofs]) ? \
99 rb_scan_args_count_var(fmt, ofs, vari) : \
100 rb_scan_args_count_opt(fmt, (ofs)+1, (vari)+(fmt)[ofs]-'0'))
102#define rb_scan_args_count(fmt) rb_scan_args_count_lead(fmt, 0, 0)
104#if RBIMPL_HAS_ATTRIBUTE(diagnose_if)
106# define rb_scan_args_verify(fmt, varc) RBIMPL_ASSERT_NOTHING
116# define rb_scan_args_verify(fmt, varc) \
117 (sizeof(char[1-2*(rb_scan_args_count(fmt)<0)])!=1 ? \
118 rb_scan_args_bad_format(fmt) : \
119 sizeof(char[1-2*(rb_scan_args_count(fmt)!=(varc))])!=1 ? \
120 rb_scan_args_length_mismatch(fmt, varc) : \
121 RBIMPL_ASSERT_NOTHING)
125rb_scan_args_keyword_p(
int kw_flag,
VALUE last)
141rb_scan_args_lead_p(
const char *fmt)
148rb_scan_args_n_lead(
const char *fmt)
150 return (rb_scan_args_lead_p(fmt) ? fmt[0]-
'0' : 0);
155rb_scan_args_opt_p(
const char *fmt)
162rb_scan_args_n_opt(
const char *fmt)
164 return (rb_scan_args_opt_p(fmt) ? fmt[1]-
'0' : 0);
169rb_scan_args_var_idx(
const char *fmt)
176rb_scan_args_f_var(
const char *fmt)
178 return (fmt[rb_scan_args_var_idx(fmt)]==
'*');
183rb_scan_args_trail_idx(
const char *fmt)
185 const int idx = rb_scan_args_var_idx(fmt);
186 return idx+(fmt[idx]==
'*');
191rb_scan_args_n_trail(
const char *fmt)
193 const int idx = rb_scan_args_trail_idx(fmt);
199rb_scan_args_hash_idx(
const char *fmt)
201 const int idx = rb_scan_args_trail_idx(fmt);
207rb_scan_args_f_hash(
const char *fmt)
209 return (fmt[rb_scan_args_hash_idx(fmt)]==
':');
214rb_scan_args_block_idx(
const char *fmt)
216 const int idx = rb_scan_args_hash_idx(fmt);
217 return idx+(fmt[idx]==
':');
222rb_scan_args_f_block(
const char *fmt)
224 return (fmt[rb_scan_args_block_idx(fmt)]==
'&');
230rb_scan_args_end_idx(
const char *fmt)
232 const int idx = rb_scan_args_block_idx(fmt);
233 return idx+(fmt[idx]==
'&');
239# define rb_scan_args0(argc, argv, fmt, varc, vars) \
240 rb_scan_args_set(RB_SCAN_ARGS_PASS_CALLED_KEYWORDS, argc, argv, \
241 rb_scan_args_n_lead(fmt), \
242 rb_scan_args_n_opt(fmt), \
243 rb_scan_args_n_trail(fmt), \
244 rb_scan_args_f_var(fmt), \
245 rb_scan_args_f_hash(fmt), \
246 rb_scan_args_f_block(fmt), \
247 (rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)
248# define rb_scan_args_kw0(kw_flag, argc, argv, fmt, varc, vars) \
249 rb_scan_args_set(kw_flag, argc, argv, \
250 rb_scan_args_n_lead(fmt), \
251 rb_scan_args_n_opt(fmt), \
252 rb_scan_args_n_trail(fmt), \
253 rb_scan_args_f_var(fmt), \
254 rb_scan_args_f_hash(fmt), \
255 rb_scan_args_f_block(fmt), \
256 (rb_scan_args_verify(fmt, varc), vars), (char *)fmt, varc)
261 int n_lead,
int n_opt,
int n_trail,
262 bool f_var,
bool f_hash,
bool f_block,
267 int i, argi = 0, vari = 0;
269#define rb_scan_args_next_param() vars[vari++]
270 const int n_mand = n_lead + n_trail;
273 if (f_hash &&
argc > 0) {
275 if (rb_scan_args_keyword_p(kw_flag,
last)) {
286 for (i = 0; i < n_lead; i++) {
288 if (var) *var =
argv[argi];
293 for (i = 0; i < n_opt; i++) {
295 if (argi <
argc - n_trail) {
296 if (var) *var =
argv[argi];
300 if (var) *var =
Qnil;
306 int n_var =
argc - argi - n_trail;
319 for (i = 0; i < n_trail; i++) {
321 if (var) *var =
argv[argi];
328 if (var) *var = hash;
349#undef rb_scan_args_next_param
352#if ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
355#elif ! defined(HAVE_VA_ARGS_MACRO)
358#elif ! defined(__OPTIMIZE__)
361#elif defined(HAVE___VA_OPT__)
362# define rb_scan_args(argc, argvp, fmt, ...) \
363 __builtin_choose_expr( \
364 __builtin_constant_p(fmt), \
367 (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
368 ((VALUE*[]){__VA_ARGS__})), \
369 (rb_scan_args)(argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
370# define rb_scan_args_kw(kw_flag, argc, argvp, fmt, ...) \
371 __builtin_choose_expr( \
372 __builtin_constant_p(fmt), \
374 kw_flag, argc, argvp, fmt, \
375 (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
376 ((VALUE*[]){__VA_ARGS__})), \
377 (rb_scan_args_kw)(kw_flag, argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
379#elif defined(__STRICT_ANSI__)
382#elif defined(__GNUC__)
383# define rb_scan_args(argc, argvp, fmt, ...) \
384 __builtin_choose_expr( \
385 __builtin_constant_p(fmt), \
388 (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
389 ((VALUE*[]){__VA_ARGS__})), \
390 (rb_scan_args)(argc, argvp, fmt, __VA_ARGS__))
391# define rb_scan_args_kw(kw_flag, argc, argvp, fmt, ...) \
392 __builtin_choose_expr( \
393 __builtin_constant_p(fmt), \
395 kw_flag, argc, argvp, fmt, \
396 (sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
397 ((VALUE*[]){__VA_ARGS__})), \
398 (rb_scan_args_kw)(kw_flag, argc, argvp, fmt, __VA_ARGS__ ))
VALUE rb_ary_new_from_values(long n, const VALUE *elts)
Defines RBIMPL_HAS_ATTRIBUTE.
#define UNREACHABLE_RETURN
Defines RBIMPL_ATTR_DIAGNOSE_IF.
#define RBIMPL_ATTR_DIAGNOSE_IF(_, __, ___)
Wraps (or simulates) __attribute__((diagnose_if))
Tewaking visibility of C variables/functions.
#define RBIMPL_SYMBOL_EXPORT_END()
Counterpart of RBIMPL_SYMBOL_EXPORT_BEGIN.
#define RBIMPL_SYMBOL_EXPORT_BEGIN()
Shortcut macro equivalent to RUBY_SYMBOL_EXPORT_BEGIN extern "C" {.
int rb_keyword_given_p(void)
Defines RBIMPL_ATTR_FORCEINLINE.
#define RBIMPL_ATTR_FORCEINLINE()
Wraps (or simulates) __forceinline.
int rb_scan_args_kw(int, int, const VALUE *, const char *,...)
int rb_scan_args(int, const VALUE *, const char *,...)
int rb_block_given_p(void)
Determines if the current method is given a block.
unsigned char match[65280+2]
VALUE rb_hash_dup(VALUE hash)
Defines RBIMPL_ATTR_ERROR.
#define RBIMPL_ATTR_ERROR(msg)
Wraps (or simulates) __attribute__((error))
Thin wrapper to ruby/config.h.
Public APIs related to rb_cArray.
Public APIs related to rb_eException.
#define UNLIMITED_ARGUMENTS
void rb_error_arity(int, int, int)
Public APIs related to rb_cHash.
Public APIs related to rb_cProc.
VALUE rb_block_proc(void)
Defines RBIMPL_STATIC_ASSERT.
typedef int(ZCALLBACK *close_file_func) OF((voidpf opaque
Defines RBIMPL_ATTR_NORETURN.
void rb_scan_args_length_mismatch(const char *, int)
#define RB_SCAN_ARGS_PASS_CALLED_KEYWORDS
#define RB_SCAN_ARGS_KEYWORDS
#define RB_SCAN_ARGS_LAST_HASH_KEYWORDS
void rb_scan_args_bad_format(const char *)
#define rb_scan_args_count(fmt)
#define rb_scan_args_isdigit(c)
#define rb_scan_args_next_param()
void error(const char *msg)