zscan 2.0.8 → 2.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/pack/pack-27.c +1 -0
- data/ext/pack/pack.c +1 -0
- data/ext/pack/ruby/backward/2/assume.h +43 -0
- data/ext/pack/ruby/backward/2/attributes.h +157 -0
- data/ext/pack/ruby/backward/2/bool.h +37 -0
- data/ext/pack/ruby/backward/2/extern.h +46 -0
- data/ext/pack/ruby/backward/2/gcc_version_since.h +38 -0
- data/ext/pack/ruby/backward/2/inttypes.h +132 -0
- data/ext/pack/ruby/backward/2/limits.h +100 -0
- data/ext/pack/ruby/backward/2/long_long.h +65 -0
- data/ext/pack/ruby/backward/2/r_cast.h +27 -0
- data/ext/pack/ruby/backward/2/rmodule.h +31 -0
- data/ext/pack/ruby/backward/2/stdalign.h +30 -0
- data/ext/pack/ruby/backward/2/stdarg.h +47 -0
- data/ext/pack/ruby/backward/classext.h +25 -0
- data/ext/pack/ruby/backward/rubyio.h +18 -0
- data/ext/pack/ruby/backward/rubysig.h +26 -0
- data/ext/pack/ruby/backward/st.h +18 -0
- data/ext/pack/ruby/backward/util.h +18 -0
- data/ext/pack/ruby/internal/anyargs.h +375 -0
- data/ext/pack/ruby/internal/arithmetic.h +38 -0
- data/ext/pack/ruby/internal/arithmetic/char.h +58 -0
- data/ext/pack/ruby/internal/arithmetic/double.h +39 -0
- data/ext/pack/ruby/internal/arithmetic/fixnum.h +44 -0
- data/ext/pack/ruby/internal/arithmetic/gid_t.h +34 -0
- data/ext/pack/ruby/internal/arithmetic/int.h +163 -0
- data/ext/pack/ruby/internal/arithmetic/intptr_t.h +42 -0
- data/ext/pack/ruby/internal/arithmetic/long.h +244 -0
- data/ext/pack/ruby/internal/arithmetic/long_long.h +53 -0
- data/ext/pack/ruby/internal/arithmetic/mode_t.h +34 -0
- data/ext/pack/ruby/internal/arithmetic/off_t.h +49 -0
- data/ext/pack/ruby/internal/arithmetic/pid_t.h +34 -0
- data/ext/pack/ruby/internal/arithmetic/short.h +54 -0
- data/ext/pack/ruby/internal/arithmetic/size_t.h +51 -0
- data/ext/pack/ruby/internal/arithmetic/st_data_t.h +59 -0
- data/ext/pack/ruby/internal/arithmetic/uid_t.h +34 -0
- data/ext/pack/ruby/internal/assume.h +90 -0
- data/ext/pack/ruby/internal/attr/alloc_size.h +32 -0
- data/ext/pack/ruby/internal/attr/artificial.h +46 -0
- data/ext/pack/ruby/internal/attr/cold.h +37 -0
- data/ext/pack/ruby/internal/attr/const.h +46 -0
- data/ext/pack/ruby/internal/attr/constexpr.h +85 -0
- data/ext/pack/ruby/internal/attr/deprecated.h +59 -0
- data/ext/pack/ruby/internal/attr/diagnose_if.h +42 -0
- data/ext/pack/ruby/internal/attr/enum_extensibility.h +32 -0
- data/ext/pack/ruby/internal/attr/error.h +32 -0
- data/ext/pack/ruby/internal/attr/flag_enum.h +33 -0
- data/ext/pack/ruby/internal/attr/forceinline.h +40 -0
- data/ext/pack/ruby/internal/attr/format.h +38 -0
- data/ext/pack/ruby/internal/attr/maybe_unused.h +38 -0
- data/ext/pack/ruby/internal/attr/noalias.h +58 -0
- data/ext/pack/ruby/internal/attr/nodiscard.h +45 -0
- data/ext/pack/ruby/internal/attr/noexcept.h +91 -0
- data/ext/pack/ruby/internal/attr/noinline.h +35 -0
- data/ext/pack/ruby/internal/attr/nonnull.h +32 -0
- data/ext/pack/ruby/internal/attr/noreturn.h +48 -0
- data/ext/pack/ruby/internal/attr/pure.h +43 -0
- data/ext/pack/ruby/internal/attr/restrict.h +45 -0
- data/ext/pack/ruby/internal/attr/returns_nonnull.h +37 -0
- data/ext/pack/ruby/internal/attr/warning.h +32 -0
- data/ext/pack/ruby/internal/attr/weakref.h +32 -0
- data/ext/pack/ruby/internal/cast.h +53 -0
- data/ext/pack/ruby/internal/compiler_is.h +45 -0
- data/ext/pack/ruby/internal/compiler_is/apple.h +41 -0
- data/ext/pack/ruby/internal/compiler_is/clang.h +38 -0
- data/ext/pack/ruby/internal/compiler_is/gcc.h +46 -0
- data/ext/pack/ruby/internal/compiler_is/intel.h +41 -0
- data/ext/pack/ruby/internal/compiler_is/msvc.h +57 -0
- data/ext/pack/ruby/internal/compiler_is/sunpro.h +55 -0
- data/ext/pack/ruby/internal/compiler_since.h +61 -0
- data/ext/pack/ruby/internal/config.h +131 -0
- data/ext/pack/ruby/internal/constant_p.h +37 -0
- data/ext/pack/ruby/internal/core.h +35 -0
- data/ext/pack/ruby/internal/core/rarray.h +275 -0
- data/ext/pack/ruby/internal/core/rbasic.h +85 -0
- data/ext/pack/ruby/internal/core/rbignum.h +51 -0
- data/ext/pack/ruby/internal/core/rclass.h +47 -0
- data/ext/pack/ruby/internal/core/rdata.h +174 -0
- data/ext/pack/ruby/internal/core/rfile.h +36 -0
- data/ext/pack/ruby/internal/core/rhash.h +62 -0
- data/ext/pack/ruby/internal/core/rmatch.h +73 -0
- data/ext/pack/ruby/internal/core/robject.h +97 -0
- data/ext/pack/ruby/internal/core/rregexp.h +84 -0
- data/ext/pack/ruby/internal/core/rstring.h +215 -0
- data/ext/pack/ruby/internal/core/rstruct.h +73 -0
- data/ext/pack/ruby/internal/core/rtypeddata.h +184 -0
- data/ext/pack/ruby/internal/ctype.h +203 -0
- data/ext/pack/ruby/internal/dllexport.h +92 -0
- data/ext/pack/ruby/internal/dosish.h +63 -0
- data/ext/pack/ruby/internal/error.h +74 -0
- data/ext/pack/ruby/internal/eval.h +50 -0
- data/ext/pack/ruby/internal/event.h +75 -0
- data/ext/pack/ruby/internal/fl_type.h +469 -0
- data/ext/pack/ruby/internal/gc.h +35 -0
- data/ext/pack/ruby/internal/glob.h +35 -0
- data/ext/pack/ruby/internal/globals.h +159 -0
- data/ext/pack/ruby/internal/has/attribute.h +164 -0
- data/ext/pack/ruby/internal/has/builtin.h +105 -0
- data/ext/pack/ruby/internal/has/c_attribute.h +38 -0
- data/ext/pack/ruby/internal/has/cpp_attribute.h +79 -0
- data/ext/pack/ruby/internal/has/declspec_attribute.h +48 -0
- data/ext/pack/ruby/internal/has/extension.h +33 -0
- data/ext/pack/ruby/internal/has/feature.h +31 -0
- data/ext/pack/ruby/internal/has/warning.h +31 -0
- data/ext/pack/ruby/internal/intern/array.h +78 -0
- data/ext/pack/ruby/internal/intern/bignum.h +105 -0
- data/ext/pack/ruby/internal/intern/class.h +57 -0
- data/ext/pack/ruby/internal/intern/compar.h +34 -0
- data/ext/pack/ruby/internal/intern/complex.h +60 -0
- data/ext/pack/ruby/internal/intern/cont.h +40 -0
- data/ext/pack/ruby/internal/intern/dir.h +33 -0
- data/ext/pack/ruby/internal/intern/enum.h +33 -0
- data/ext/pack/ruby/internal/intern/enumerator.h +79 -0
- data/ext/pack/ruby/internal/intern/error.h +82 -0
- data/ext/pack/ruby/internal/intern/eval.h +59 -0
- data/ext/pack/ruby/internal/intern/file.h +44 -0
- data/ext/pack/ruby/internal/intern/gc.h +57 -0
- data/ext/pack/ruby/internal/intern/hash.h +59 -0
- data/ext/pack/ruby/internal/intern/io.h +70 -0
- data/ext/pack/ruby/internal/intern/load.h +39 -0
- data/ext/pack/ruby/internal/intern/marshal.h +35 -0
- data/ext/pack/ruby/internal/intern/numeric.h +42 -0
- data/ext/pack/ruby/internal/intern/object.h +90 -0
- data/ext/pack/ruby/internal/intern/parse.h +64 -0
- data/ext/pack/ruby/internal/intern/proc.h +53 -0
- data/ext/pack/ruby/internal/intern/process.h +46 -0
- data/ext/pack/ruby/internal/intern/random.h +45 -0
- data/ext/pack/ruby/internal/intern/range.h +35 -0
- data/ext/pack/ruby/internal/intern/rational.h +46 -0
- data/ext/pack/ruby/internal/intern/re.h +50 -0
- data/ext/pack/ruby/internal/intern/ruby.h +37 -0
- data/ext/pack/ruby/internal/intern/select.h +52 -0
- data/ext/pack/ruby/internal/intern/select/largesize.h +103 -0
- data/ext/pack/ruby/internal/intern/select/posix.h +82 -0
- data/ext/pack/ruby/internal/intern/select/win32.h +124 -0
- data/ext/pack/ruby/internal/intern/signal.h +40 -0
- data/ext/pack/ruby/internal/intern/sprintf.h +43 -0
- data/ext/pack/ruby/internal/intern/string.h +290 -0
- data/ext/pack/ruby/internal/intern/struct.h +47 -0
- data/ext/pack/ruby/internal/intern/thread.h +76 -0
- data/ext/pack/ruby/internal/intern/time.h +52 -0
- data/ext/pack/ruby/internal/intern/variable.h +83 -0
- data/ext/pack/ruby/internal/intern/vm.h +77 -0
- data/ext/pack/ruby/internal/interpreter.h +94 -0
- data/ext/pack/ruby/internal/iterator.h +65 -0
- data/ext/pack/ruby/internal/memory.h +286 -0
- data/ext/pack/ruby/internal/method.h +39 -0
- data/ext/pack/ruby/internal/module.h +39 -0
- data/ext/pack/ruby/internal/newobj.h +73 -0
- data/ext/pack/ruby/internal/rgengc.h +199 -0
- data/ext/pack/ruby/internal/scan_args.h +394 -0
- data/ext/pack/ruby/internal/special_consts.h +204 -0
- data/ext/pack/ruby/internal/static_assert.h +77 -0
- data/ext/pack/ruby/internal/stdalign.h +124 -0
- data/ext/pack/ruby/internal/stdbool.h +51 -0
- data/ext/pack/ruby/internal/symbol.h +114 -0
- data/ext/pack/ruby/internal/token_paste.h +75 -0
- data/ext/pack/ruby/internal/value.h +66 -0
- data/ext/pack/ruby/internal/value_type.h +354 -0
- data/ext/pack/ruby/internal/variable.h +62 -0
- data/ext/pack/ruby/internal/warning_push.h +91 -0
- data/ext/pack/ruby/internal/xmalloc.h +201 -0
- data/lib/zscan.rb +1 -1
- data/readme.md +2 -0
- data/zscan.gemspec +1 -1
- metadata +162 -2
@@ -0,0 +1,394 @@
|
|
1
|
+
#ifndef RBIMPL_SCAN_ARGS_H /*-*-C++-*-vi:se ft=cpp:*/
|
2
|
+
#define RBIMPL_SCAN_ARGS_H
|
3
|
+
/**
|
4
|
+
* @file
|
5
|
+
* @author Ruby developers <ruby-core@ruby-lang.org>
|
6
|
+
* @copyright This file is a part of the programming language Ruby.
|
7
|
+
* Permission is hereby granted, to either redistribute and/or
|
8
|
+
* modify this file, provided that the conditions mentioned in the
|
9
|
+
* file COPYING are met. Consult the file for details.
|
10
|
+
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
|
11
|
+
* implementation details. Don't take them as canon. They could
|
12
|
+
* rapidly appear then vanish. The name (path) of this header file
|
13
|
+
* is also an implementation detail. Do not expect it to persist
|
14
|
+
* at the place it is now. Developers are free to move it anywhere
|
15
|
+
* anytime at will.
|
16
|
+
* @note To ruby-core: remember that this header can be possibly
|
17
|
+
* recursively included from extension libraries written in C++.
|
18
|
+
* Do not expect for instance `__VA_ARGS__` is always available.
|
19
|
+
* We assume C99 for ruby itself but we don't assume languages of
|
20
|
+
* extension libraries. They could be written in C++98.
|
21
|
+
* @brief Compile-time static implementation of ::rb_scan_args().
|
22
|
+
*
|
23
|
+
* This is a beast. It statically analyses the argument spec string, and
|
24
|
+
* expands the assignment of variables into dedicated codes.
|
25
|
+
*/
|
26
|
+
#include "ruby/internal/attr/diagnose_if.h"
|
27
|
+
#include "ruby/internal/attr/error.h"
|
28
|
+
#include "ruby/internal/attr/forceinline.h"
|
29
|
+
#include "ruby/internal/attr/noreturn.h"
|
30
|
+
#include "ruby/internal/config.h"
|
31
|
+
#include "ruby/internal/dllexport.h"
|
32
|
+
#include "ruby/internal/has/attribute.h"
|
33
|
+
#include "ruby/internal/intern/array.h" /* rb_ary_new_from_values */
|
34
|
+
#include "ruby/internal/intern/error.h" /* rb_error_arity */
|
35
|
+
#include "ruby/internal/intern/hash.h" /* rb_hash_dup */
|
36
|
+
#include "ruby/internal/intern/proc.h" /* rb_block_proc */
|
37
|
+
#include "ruby/internal/iterator.h" /* rb_block_given_p / rb_keyword_given_p */
|
38
|
+
#include "ruby/internal/static_assert.h"
|
39
|
+
#include "ruby/internal/stdbool.h"
|
40
|
+
#include "ruby/internal/value.h"
|
41
|
+
#include "ruby/assert.h"
|
42
|
+
|
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()
|
49
|
+
/* rb_scan_args() format allows ':' for optional hash */
|
50
|
+
#define HAVE_RB_SCAN_ARGS_OPTIONAL_HASH 1
|
51
|
+
|
52
|
+
RBIMPL_SYMBOL_EXPORT_BEGIN()
|
53
|
+
int rb_scan_args(int, const VALUE*, const char*, ...);
|
54
|
+
int rb_scan_args_kw(int, int, const VALUE*, const char*, ...);
|
55
|
+
|
56
|
+
RBIMPL_ATTR_ERROR(("bad scan arg format"))
|
57
|
+
void rb_scan_args_bad_format(const char*);
|
58
|
+
|
59
|
+
RBIMPL_ATTR_ERROR(("variable argument length doesn't match"))
|
60
|
+
void rb_scan_args_length_mismatch(const char*,int);
|
61
|
+
|
62
|
+
RBIMPL_SYMBOL_EXPORT_END()
|
63
|
+
|
64
|
+
/* If we could use constexpr the following macros could be inline functions
|
65
|
+
* ... but sadly we cannot. */
|
66
|
+
|
67
|
+
#define rb_scan_args_isdigit(c) (RBIMPL_CAST((unsigned char)((c)-'0'))<10)
|
68
|
+
|
69
|
+
#define rb_scan_args_count_end(fmt, ofs, vari) \
|
70
|
+
((fmt)[ofs] ? -1 : (vari))
|
71
|
+
|
72
|
+
#define rb_scan_args_count_block(fmt, ofs, vari) \
|
73
|
+
((fmt)[ofs]!='&' ? \
|
74
|
+
rb_scan_args_count_end(fmt, ofs, vari) : \
|
75
|
+
rb_scan_args_count_end(fmt, (ofs)+1, (vari)+1))
|
76
|
+
|
77
|
+
#define rb_scan_args_count_hash(fmt, ofs, vari) \
|
78
|
+
((fmt)[ofs]!=':' ? \
|
79
|
+
rb_scan_args_count_block(fmt, ofs, vari) : \
|
80
|
+
rb_scan_args_count_block(fmt, (ofs)+1, (vari)+1))
|
81
|
+
|
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')))
|
86
|
+
|
87
|
+
#define rb_scan_args_count_var(fmt, ofs, vari) \
|
88
|
+
((fmt)[ofs]!='*' ? \
|
89
|
+
rb_scan_args_count_trail(fmt, ofs, vari) : \
|
90
|
+
rb_scan_args_count_trail(fmt, (ofs)+1, (vari)+1))
|
91
|
+
|
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'))
|
96
|
+
|
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'))
|
101
|
+
|
102
|
+
#define rb_scan_args_count(fmt) rb_scan_args_count_lead(fmt, 0, 0)
|
103
|
+
|
104
|
+
#if RBIMPL_HAS_ATTRIBUTE(diagnose_if)
|
105
|
+
# /* Assertions done in the attribute. */
|
106
|
+
# define rb_scan_args_verify(fmt, varc) RBIMPL_ASSERT_NOTHING
|
107
|
+
#else
|
108
|
+
# /* At one sight it _seems_ the expressions below could be written using
|
109
|
+
# * static assrtions. The reality is no, they don't. Because fmt is a string
|
110
|
+
# * literal, any operations against fmt cannot produce the "integer constant
|
111
|
+
# * expression"s, as defined in ISO/IEC 9899:2018 section 6.6 paragraph #6.
|
112
|
+
# * Static assertions need such integer constant expressions as defined in
|
113
|
+
# * ISO/IEC 9899:2018 section 6.7.10 paragraph #3.
|
114
|
+
# *
|
115
|
+
# * GCC nonetheless constant-folds this into no-op, though. */
|
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)
|
122
|
+
#endif
|
123
|
+
|
124
|
+
static inline bool
|
125
|
+
rb_scan_args_keyword_p(int kw_flag, VALUE last)
|
126
|
+
{
|
127
|
+
switch (kw_flag) {
|
128
|
+
case RB_SCAN_ARGS_PASS_CALLED_KEYWORDS:
|
129
|
+
return !! rb_keyword_given_p();
|
130
|
+
case RB_SCAN_ARGS_KEYWORDS:
|
131
|
+
return true;
|
132
|
+
case RB_SCAN_ARGS_LAST_HASH_KEYWORDS:
|
133
|
+
return RB_TYPE_P(last, T_HASH);
|
134
|
+
default:
|
135
|
+
return false;
|
136
|
+
}
|
137
|
+
}
|
138
|
+
|
139
|
+
RBIMPL_ATTR_FORCEINLINE()
|
140
|
+
static bool
|
141
|
+
rb_scan_args_lead_p(const char *fmt)
|
142
|
+
{
|
143
|
+
return rb_scan_args_isdigit(fmt[0]);
|
144
|
+
}
|
145
|
+
|
146
|
+
RBIMPL_ATTR_FORCEINLINE()
|
147
|
+
static int
|
148
|
+
rb_scan_args_n_lead(const char *fmt)
|
149
|
+
{
|
150
|
+
return (rb_scan_args_lead_p(fmt) ? fmt[0]-'0' : 0);
|
151
|
+
}
|
152
|
+
|
153
|
+
RBIMPL_ATTR_FORCEINLINE()
|
154
|
+
static bool
|
155
|
+
rb_scan_args_opt_p(const char *fmt)
|
156
|
+
{
|
157
|
+
return (rb_scan_args_lead_p(fmt) && rb_scan_args_isdigit(fmt[1]));
|
158
|
+
}
|
159
|
+
|
160
|
+
RBIMPL_ATTR_FORCEINLINE()
|
161
|
+
static int
|
162
|
+
rb_scan_args_n_opt(const char *fmt)
|
163
|
+
{
|
164
|
+
return (rb_scan_args_opt_p(fmt) ? fmt[1]-'0' : 0);
|
165
|
+
}
|
166
|
+
|
167
|
+
RBIMPL_ATTR_FORCEINLINE()
|
168
|
+
static int
|
169
|
+
rb_scan_args_var_idx(const char *fmt)
|
170
|
+
{
|
171
|
+
return (!rb_scan_args_lead_p(fmt) ? 0 : !rb_scan_args_isdigit(fmt[1]) ? 1 : 2);
|
172
|
+
}
|
173
|
+
|
174
|
+
RBIMPL_ATTR_FORCEINLINE()
|
175
|
+
static bool
|
176
|
+
rb_scan_args_f_var(const char *fmt)
|
177
|
+
{
|
178
|
+
return (fmt[rb_scan_args_var_idx(fmt)]=='*');
|
179
|
+
}
|
180
|
+
|
181
|
+
RBIMPL_ATTR_FORCEINLINE()
|
182
|
+
static int
|
183
|
+
rb_scan_args_trail_idx(const char *fmt)
|
184
|
+
{
|
185
|
+
const int idx = rb_scan_args_var_idx(fmt);
|
186
|
+
return idx+(fmt[idx]=='*');
|
187
|
+
}
|
188
|
+
|
189
|
+
RBIMPL_ATTR_FORCEINLINE()
|
190
|
+
static int
|
191
|
+
rb_scan_args_n_trail(const char *fmt)
|
192
|
+
{
|
193
|
+
const int idx = rb_scan_args_trail_idx(fmt);
|
194
|
+
return (rb_scan_args_isdigit(fmt[idx]) ? fmt[idx]-'0' : 0);
|
195
|
+
}
|
196
|
+
|
197
|
+
RBIMPL_ATTR_FORCEINLINE()
|
198
|
+
static int
|
199
|
+
rb_scan_args_hash_idx(const char *fmt)
|
200
|
+
{
|
201
|
+
const int idx = rb_scan_args_trail_idx(fmt);
|
202
|
+
return idx+rb_scan_args_isdigit(fmt[idx]);
|
203
|
+
}
|
204
|
+
|
205
|
+
RBIMPL_ATTR_FORCEINLINE()
|
206
|
+
static bool
|
207
|
+
rb_scan_args_f_hash(const char *fmt)
|
208
|
+
{
|
209
|
+
return (fmt[rb_scan_args_hash_idx(fmt)]==':');
|
210
|
+
}
|
211
|
+
|
212
|
+
RBIMPL_ATTR_FORCEINLINE()
|
213
|
+
static int
|
214
|
+
rb_scan_args_block_idx(const char *fmt)
|
215
|
+
{
|
216
|
+
const int idx = rb_scan_args_hash_idx(fmt);
|
217
|
+
return idx+(fmt[idx]==':');
|
218
|
+
}
|
219
|
+
|
220
|
+
RBIMPL_ATTR_FORCEINLINE()
|
221
|
+
static bool
|
222
|
+
rb_scan_args_f_block(const char *fmt)
|
223
|
+
{
|
224
|
+
return (fmt[rb_scan_args_block_idx(fmt)]=='&');
|
225
|
+
}
|
226
|
+
|
227
|
+
# if 0
|
228
|
+
RBIMPL_ATTR_FORCEINLINE()
|
229
|
+
static int
|
230
|
+
rb_scan_args_end_idx(const char *fmt)
|
231
|
+
{
|
232
|
+
const int idx = rb_scan_args_block_idx(fmt);
|
233
|
+
return idx+(fmt[idx]=='&');
|
234
|
+
}
|
235
|
+
# endif
|
236
|
+
|
237
|
+
/* NOTE: Use `char *fmt` instead of `const char *fmt` because of clang's bug*/
|
238
|
+
/* https://bugs.llvm.org/show_bug.cgi?id=38095 */
|
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)
|
257
|
+
|
258
|
+
RBIMPL_ATTR_FORCEINLINE()
|
259
|
+
static int
|
260
|
+
rb_scan_args_set(int kw_flag, int argc, const VALUE *argv,
|
261
|
+
int n_lead, int n_opt, int n_trail,
|
262
|
+
bool f_var, bool f_hash, bool f_block,
|
263
|
+
VALUE *vars[], RB_UNUSED_VAR(const char *fmt), RB_UNUSED_VAR(int varc))
|
264
|
+
RBIMPL_ATTR_DIAGNOSE_IF(rb_scan_args_count(fmt) < 0, "bad scan arg format", "error")
|
265
|
+
RBIMPL_ATTR_DIAGNOSE_IF(rb_scan_args_count(fmt) != varc, "variable argument length doesn't match", "error")
|
266
|
+
{
|
267
|
+
int i, argi = 0, vari = 0;
|
268
|
+
VALUE *var, hash = Qnil;
|
269
|
+
#define rb_scan_args_next_param() vars[vari++]
|
270
|
+
const int n_mand = n_lead + n_trail;
|
271
|
+
|
272
|
+
if (f_hash && argc > 0) {
|
273
|
+
VALUE last = argv[argc - 1];
|
274
|
+
if (rb_scan_args_keyword_p(kw_flag, last)) {
|
275
|
+
hash = rb_hash_dup(last);
|
276
|
+
argc--;
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
if (argc < n_mand) {
|
281
|
+
goto argc_error;
|
282
|
+
}
|
283
|
+
|
284
|
+
/* capture leading mandatory arguments */
|
285
|
+
for (i = n_lead; i-- > 0; ) {
|
286
|
+
var = rb_scan_args_next_param();
|
287
|
+
if (var) *var = argv[argi];
|
288
|
+
argi++;
|
289
|
+
}
|
290
|
+
/* capture optional arguments */
|
291
|
+
for (i = n_opt; i-- > 0; ) {
|
292
|
+
var = rb_scan_args_next_param();
|
293
|
+
if (argi < argc - n_trail) {
|
294
|
+
if (var) *var = argv[argi];
|
295
|
+
argi++;
|
296
|
+
}
|
297
|
+
else {
|
298
|
+
if (var) *var = Qnil;
|
299
|
+
}
|
300
|
+
}
|
301
|
+
/* capture variable length arguments */
|
302
|
+
if (f_var) {
|
303
|
+
int n_var = argc - argi - n_trail;
|
304
|
+
|
305
|
+
var = rb_scan_args_next_param();
|
306
|
+
if (0 < n_var) {
|
307
|
+
if (var) *var = rb_ary_new_from_values(n_var, &argv[argi]);
|
308
|
+
argi += n_var;
|
309
|
+
}
|
310
|
+
else {
|
311
|
+
if (var) *var = rb_ary_new();
|
312
|
+
}
|
313
|
+
}
|
314
|
+
/* capture trailing mandatory arguments */
|
315
|
+
for (i = n_trail; i-- > 0; ) {
|
316
|
+
var = rb_scan_args_next_param();
|
317
|
+
if (var) *var = argv[argi];
|
318
|
+
argi++;
|
319
|
+
}
|
320
|
+
/* capture an option hash - phase 2: assignment */
|
321
|
+
if (f_hash) {
|
322
|
+
var = rb_scan_args_next_param();
|
323
|
+
if (var) *var = hash;
|
324
|
+
}
|
325
|
+
/* capture iterator block */
|
326
|
+
if (f_block) {
|
327
|
+
var = rb_scan_args_next_param();
|
328
|
+
if (rb_block_given_p()) {
|
329
|
+
*var = rb_block_proc();
|
330
|
+
}
|
331
|
+
else {
|
332
|
+
*var = Qnil;
|
333
|
+
}
|
334
|
+
}
|
335
|
+
|
336
|
+
if (argi < argc) {
|
337
|
+
argc_error:
|
338
|
+
rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt);
|
339
|
+
}
|
340
|
+
|
341
|
+
return argc;
|
342
|
+
#undef rb_scan_args_next_param
|
343
|
+
}
|
344
|
+
|
345
|
+
#if ! defined(HAVE_BUILTIN___BUILTIN_CHOOSE_EXPR_CONSTANT_P)
|
346
|
+
# /* skip */
|
347
|
+
|
348
|
+
#elif ! defined(HAVE_VA_ARGS_MACRO)
|
349
|
+
# /* skip */
|
350
|
+
|
351
|
+
#elif ! defined(__OPTIMIZE__)
|
352
|
+
# /* skip */
|
353
|
+
|
354
|
+
#elif defined(HAVE___VA_OPT__)
|
355
|
+
# define rb_scan_args(argc, argvp, fmt, ...) \
|
356
|
+
__builtin_choose_expr( \
|
357
|
+
__builtin_constant_p(fmt), \
|
358
|
+
rb_scan_args0( \
|
359
|
+
argc, argvp, fmt, \
|
360
|
+
(sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
|
361
|
+
((VALUE*[]){__VA_ARGS__})), \
|
362
|
+
(rb_scan_args)(argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
|
363
|
+
# define rb_scan_args_kw(kw_flag, argc, argvp, fmt, ...) \
|
364
|
+
__builtin_choose_expr( \
|
365
|
+
__builtin_constant_p(fmt), \
|
366
|
+
rb_scan_args_kw0( \
|
367
|
+
kw_flag, argc, argvp, fmt, \
|
368
|
+
(sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
|
369
|
+
((VALUE*[]){__VA_ARGS__})), \
|
370
|
+
(rb_scan_args_kw)(kw_flag, argc, argvp, fmt __VA_OPT__(, __VA_ARGS__)))
|
371
|
+
|
372
|
+
#elif defined(__STRICT_ANSI__)
|
373
|
+
# /* skip */
|
374
|
+
|
375
|
+
#elif defined(__GNUC__)
|
376
|
+
# define rb_scan_args(argc, argvp, fmt, ...) \
|
377
|
+
__builtin_choose_expr( \
|
378
|
+
__builtin_constant_p(fmt), \
|
379
|
+
rb_scan_args0( \
|
380
|
+
argc, argvp, fmt, \
|
381
|
+
(sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
|
382
|
+
((VALUE*[]){__VA_ARGS__})), \
|
383
|
+
(rb_scan_args)(argc, argvp, fmt, __VA_ARGS__))
|
384
|
+
# define rb_scan_args_kw(kw_flag, argc, argvp, fmt, ...) \
|
385
|
+
__builtin_choose_expr( \
|
386
|
+
__builtin_constant_p(fmt), \
|
387
|
+
rb_scan_args_kw0( \
|
388
|
+
kw_flag, argc, argvp, fmt, \
|
389
|
+
(sizeof((VALUE*[]){__VA_ARGS__})/sizeof(VALUE*)), \
|
390
|
+
((VALUE*[]){__VA_ARGS__})), \
|
391
|
+
(rb_scan_args_kw)(kw_flag, argc, argvp, fmt, __VA_ARGS__ /**/))
|
392
|
+
#endif
|
393
|
+
|
394
|
+
#endif /* RBIMPL_SCAN_ARGS_H */
|
@@ -0,0 +1,204 @@
|
|
1
|
+
#ifndef RBIMPL_SPECIAL_CONSTS_H /*-*-C++-*-vi:se ft=cpp:*/
|
2
|
+
#define RBIMPL_SPECIAL_CONSTS_H
|
3
|
+
/**
|
4
|
+
* @file
|
5
|
+
* @author Ruby developers <ruby-core@ruby-lang.org>
|
6
|
+
* @copyright This file is a part of the programming language Ruby.
|
7
|
+
* Permission is hereby granted, to either redistribute and/or
|
8
|
+
* modify this file, provided that the conditions mentioned in the
|
9
|
+
* file COPYING are met. Consult the file for details.
|
10
|
+
* @warning Symbols prefixed with either `RBIMPL` or `rbimpl` are
|
11
|
+
* implementation details. Don't take them as canon. They could
|
12
|
+
* rapidly appear then vanish. The name (path) of this header file
|
13
|
+
* is also an implementation detail. Do not expect it to persist
|
14
|
+
* at the place it is now. Developers are free to move it anywhere
|
15
|
+
* anytime at will.
|
16
|
+
* @note To ruby-core: remember that this header can be possibly
|
17
|
+
* recursively included from extension libraries written in C++.
|
18
|
+
* Do not expect for instance `__VA_ARGS__` is always available.
|
19
|
+
* We assume C99 for ruby itself but we don't assume languages of
|
20
|
+
* extension libraries. They could be written in C++98.
|
21
|
+
* @brief Defines enum ::ruby_special_consts.
|
22
|
+
* @see Sasada, K., "A Lighweight Representation of Floting-Point
|
23
|
+
* Numbers on Ruby Interpreter", in proceedings of 10th JSSST
|
24
|
+
* SIGPPL Workshop on Programming and Programming Languages
|
25
|
+
* (PPL2008), pp. 9-16, 2008.
|
26
|
+
*/
|
27
|
+
#include "ruby/internal/attr/artificial.h"
|
28
|
+
#include "ruby/internal/attr/const.h"
|
29
|
+
#include "ruby/internal/attr/constexpr.h"
|
30
|
+
#include "ruby/internal/attr/enum_extensibility.h"
|
31
|
+
#include "ruby/internal/stdbool.h"
|
32
|
+
#include "ruby/internal/value.h"
|
33
|
+
|
34
|
+
#if defined(USE_FLONUM)
|
35
|
+
# /* Take that. */
|
36
|
+
#elif SIZEOF_VALUE >= SIZEOF_DOUBLE
|
37
|
+
# define USE_FLONUM 1
|
38
|
+
#else
|
39
|
+
# define USE_FLONUM 0
|
40
|
+
#endif
|
41
|
+
|
42
|
+
#define RTEST RB_TEST
|
43
|
+
|
44
|
+
#define FIXNUM_P RB_FIXNUM_P
|
45
|
+
#define IMMEDIATE_P RB_IMMEDIATE_P
|
46
|
+
#define NIL_P RB_NIL_P
|
47
|
+
#define SPECIAL_CONST_P RB_SPECIAL_CONST_P
|
48
|
+
#define STATIC_SYM_P RB_STATIC_SYM_P
|
49
|
+
|
50
|
+
#define Qfalse RUBY_Qfalse
|
51
|
+
#define Qnil RUBY_Qnil
|
52
|
+
#define Qtrue RUBY_Qtrue
|
53
|
+
#define Qundef RUBY_Qundef
|
54
|
+
|
55
|
+
/** @cond INTERNAL_MACRO */
|
56
|
+
#define FIXNUM_FLAG RUBY_FIXNUM_FLAG
|
57
|
+
#define FLONUM_FLAG RUBY_FLONUM_FLAG
|
58
|
+
#define FLONUM_MASK RUBY_FLONUM_MASK
|
59
|
+
#define FLONUM_P RB_FLONUM_P
|
60
|
+
#define IMMEDIATE_MASK RUBY_IMMEDIATE_MASK
|
61
|
+
#define SYMBOL_FLAG RUBY_SYMBOL_FLAG
|
62
|
+
|
63
|
+
#define RB_FIXNUM_P RB_FIXNUM_P
|
64
|
+
#define RB_FLONUM_P RB_FLONUM_P
|
65
|
+
#define RB_IMMEDIATE_P RB_IMMEDIATE_P
|
66
|
+
#define RB_NIL_P RB_NIL_P
|
67
|
+
#define RB_SPECIAL_CONST_P RB_SPECIAL_CONST_P
|
68
|
+
#define RB_STATIC_SYM_P RB_STATIC_SYM_P
|
69
|
+
#define RB_TEST RB_TEST
|
70
|
+
/** @endcond */
|
71
|
+
|
72
|
+
/** special constants - i.e. non-zero and non-fixnum constants */
|
73
|
+
enum
|
74
|
+
RBIMPL_ATTR_ENUM_EXTENSIBILITY(closed)
|
75
|
+
ruby_special_consts {
|
76
|
+
#if USE_FLONUM
|
77
|
+
RUBY_Qfalse = 0x00, /* ...0000 0000 */
|
78
|
+
RUBY_Qtrue = 0x14, /* ...0001 0100 */
|
79
|
+
RUBY_Qnil = 0x08, /* ...0000 1000 */
|
80
|
+
RUBY_Qundef = 0x34, /* ...0011 0100 */
|
81
|
+
RUBY_IMMEDIATE_MASK = 0x07, /* ...0000 0111 */
|
82
|
+
RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
|
83
|
+
RUBY_FLONUM_MASK = 0x03, /* ...0000 0011 */
|
84
|
+
RUBY_FLONUM_FLAG = 0x02, /* ...xxxx xx10 */
|
85
|
+
RUBY_SYMBOL_FLAG = 0x0c, /* ...xxxx 1100 */
|
86
|
+
#else
|
87
|
+
RUBY_Qfalse = 0x00, /* ...0000 0000 */
|
88
|
+
RUBY_Qtrue = 0x02, /* ...0000 0010 */
|
89
|
+
RUBY_Qnil = 0x04, /* ...0000 0100 */
|
90
|
+
RUBY_Qundef = 0x06, /* ...0000 0110 */
|
91
|
+
RUBY_IMMEDIATE_MASK = 0x03, /* ...0000 0011 */
|
92
|
+
RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
|
93
|
+
RUBY_FLONUM_MASK = 0x00, /* any values ANDed with FLONUM_MASK cannot be FLONUM_FLAG */
|
94
|
+
RUBY_FLONUM_FLAG = 0x02, /* ...0000 0010 */
|
95
|
+
RUBY_SYMBOL_FLAG = 0x0e, /* ...0000 1110 */
|
96
|
+
#endif
|
97
|
+
|
98
|
+
RUBY_SPECIAL_SHIFT = 8 /** Least significant 8 bits are reserved. */
|
99
|
+
};
|
100
|
+
|
101
|
+
RBIMPL_ATTR_CONST()
|
102
|
+
RBIMPL_ATTR_CONSTEXPR(CXX11)
|
103
|
+
RBIMPL_ATTR_ARTIFICIAL()
|
104
|
+
/*
|
105
|
+
* :NOTE: rbimpl_test HAS to be `__attribute__((const))` in order for clang to
|
106
|
+
* properly deduce `__builtin_assume()`.
|
107
|
+
*/
|
108
|
+
static inline bool
|
109
|
+
RB_TEST(VALUE obj)
|
110
|
+
{
|
111
|
+
/*
|
112
|
+
* Qfalse: ....0000 0000
|
113
|
+
* Qnil: ....0000 1000
|
114
|
+
* ~Qnil: ....1111 0111
|
115
|
+
* v ....xxxx xxxx
|
116
|
+
* ----------------------------
|
117
|
+
* RTEST(v) ....xxxx 0xxx
|
118
|
+
*
|
119
|
+
* RTEST(v) can be 0 if and only if (v == Qfalse || v == Qnil).
|
120
|
+
*/
|
121
|
+
return obj & ~RUBY_Qnil;
|
122
|
+
}
|
123
|
+
|
124
|
+
RBIMPL_ATTR_CONST()
|
125
|
+
RBIMPL_ATTR_CONSTEXPR(CXX11)
|
126
|
+
RBIMPL_ATTR_ARTIFICIAL()
|
127
|
+
static inline bool
|
128
|
+
RB_NIL_P(VALUE obj)
|
129
|
+
{
|
130
|
+
return obj == RUBY_Qnil;
|
131
|
+
}
|
132
|
+
|
133
|
+
RBIMPL_ATTR_CONST()
|
134
|
+
RBIMPL_ATTR_CONSTEXPR(CXX11)
|
135
|
+
RBIMPL_ATTR_ARTIFICIAL()
|
136
|
+
static inline bool
|
137
|
+
RB_FIXNUM_P(VALUE obj)
|
138
|
+
{
|
139
|
+
return obj & RUBY_FIXNUM_FLAG;
|
140
|
+
}
|
141
|
+
|
142
|
+
RBIMPL_ATTR_CONST()
|
143
|
+
RBIMPL_ATTR_CONSTEXPR(CXX14)
|
144
|
+
RBIMPL_ATTR_ARTIFICIAL()
|
145
|
+
static inline bool
|
146
|
+
RB_STATIC_SYM_P(VALUE obj)
|
147
|
+
{
|
148
|
+
RBIMPL_ATTR_CONSTEXPR(CXX14)
|
149
|
+
const VALUE mask = ~(RBIMPL_VALUE_FULL << RUBY_SPECIAL_SHIFT);
|
150
|
+
return (obj & mask) == RUBY_SYMBOL_FLAG;
|
151
|
+
}
|
152
|
+
|
153
|
+
RBIMPL_ATTR_CONST()
|
154
|
+
RBIMPL_ATTR_CONSTEXPR(CXX11)
|
155
|
+
RBIMPL_ATTR_ARTIFICIAL()
|
156
|
+
static inline bool
|
157
|
+
RB_FLONUM_P(VALUE obj)
|
158
|
+
{
|
159
|
+
#if USE_FLONUM
|
160
|
+
return (obj & RUBY_FLONUM_MASK) == RUBY_FLONUM_FLAG;
|
161
|
+
#else
|
162
|
+
return false;
|
163
|
+
#endif
|
164
|
+
}
|
165
|
+
|
166
|
+
RBIMPL_ATTR_CONST()
|
167
|
+
RBIMPL_ATTR_CONSTEXPR(CXX11)
|
168
|
+
RBIMPL_ATTR_ARTIFICIAL()
|
169
|
+
static inline bool
|
170
|
+
RB_IMMEDIATE_P(VALUE obj)
|
171
|
+
{
|
172
|
+
return obj & RUBY_IMMEDIATE_MASK;
|
173
|
+
}
|
174
|
+
|
175
|
+
RBIMPL_ATTR_CONST()
|
176
|
+
RBIMPL_ATTR_CONSTEXPR(CXX11)
|
177
|
+
RBIMPL_ATTR_ARTIFICIAL()
|
178
|
+
static inline bool
|
179
|
+
RB_SPECIAL_CONST_P(VALUE obj)
|
180
|
+
{
|
181
|
+
return RB_IMMEDIATE_P(obj) || ! RB_TEST(obj);
|
182
|
+
}
|
183
|
+
|
184
|
+
RBIMPL_ATTR_CONST()
|
185
|
+
RBIMPL_ATTR_CONSTEXPR(CXX11)
|
186
|
+
/* This function is to mimic old rb_special_const_p macro but have anyone
|
187
|
+
* actually used its return value? Wasn't it just something no one needed? */
|
188
|
+
static inline VALUE
|
189
|
+
rb_special_const_p(VALUE obj)
|
190
|
+
{
|
191
|
+
return RB_SPECIAL_CONST_P(obj) * RUBY_Qtrue;
|
192
|
+
}
|
193
|
+
|
194
|
+
/**
|
195
|
+
* @cond INTERNAL_MACRO
|
196
|
+
* See [ruby-dev:27513] for the following macros.
|
197
|
+
*/
|
198
|
+
#define RUBY_Qfalse RBIMPL_CAST((VALUE)RUBY_Qfalse)
|
199
|
+
#define RUBY_Qtrue RBIMPL_CAST((VALUE)RUBY_Qtrue)
|
200
|
+
#define RUBY_Qnil RBIMPL_CAST((VALUE)RUBY_Qnil)
|
201
|
+
#define RUBY_Qundef RBIMPL_CAST((VALUE)RUBY_Qundef)
|
202
|
+
/** @endcond */
|
203
|
+
|
204
|
+
#endif /* RBIMPL_SPECIAL_CONSTS_H */
|