Apply PIE to nghttpx
[platform/upstream/nghttp2.git] / third-party / mruby / mrbgems / mruby-kernel-ext / src / kernel.c
1 #include <mruby.h>
2 #include <mruby/error.h>
3 #include <mruby/array.h>
4 #include <mruby/hash.h>
5 #include <mruby/range.h>
6
7 static mrb_value
8 mrb_f_caller(mrb_state *mrb, mrb_value self)
9 {
10   mrb_value bt, v, length;
11   mrb_int bt_len, argc, lev, n;
12
13   bt = mrb_get_backtrace(mrb);
14   bt_len = RARRAY_LEN(bt);
15   argc = mrb_get_args(mrb, "|oo", &v, &length);
16
17   switch (argc) {
18     case 0:
19       lev = 1;
20       n = bt_len - lev;
21       break;
22     case 1:
23       if (mrb_type(v) == MRB_TT_RANGE) {
24         mrb_int beg, len;
25         if (mrb_range_beg_len(mrb, v, &beg, &len, bt_len, TRUE) == 1) {
26           lev = beg;
27           n = len;
28         }
29         else {
30           return mrb_nil_value();
31         }
32       }
33       else {
34         v = mrb_to_int(mrb, v);
35         lev = mrb_fixnum(v);
36         if (lev < 0) {
37           mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v);
38         }
39         n = bt_len - lev;
40       }
41       break;
42     case 2:
43       lev = mrb_fixnum(mrb_to_int(mrb, v));
44       n = mrb_fixnum(mrb_to_int(mrb, length));
45       if (lev < 0) {
46         mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative level (%S)", v);
47       }
48       if (n < 0) {
49         mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative size (%S)", length);
50       }
51       break;
52     default:
53       lev = n = 0;
54       break;
55   }
56
57   if (n == 0) {
58     return mrb_ary_new(mrb);
59   }
60
61   return mrb_funcall(mrb, bt, "[]", 2, mrb_fixnum_value(lev), mrb_fixnum_value(n));
62 }
63
64 /*
65  *  call-seq:
66  *     __method__         -> symbol
67  *
68  *  Returns the name at the definition of the current method as a
69  *  Symbol.
70  *  If called outside of a method, it returns <code>nil</code>.
71  *
72  */
73 static mrb_value
74 mrb_f_method(mrb_state *mrb, mrb_value self)
75 {
76   mrb_callinfo *ci = mrb->c->ci;
77   ci--;
78   if (ci->mid)
79     return mrb_symbol_value(ci->mid);
80   else
81     return mrb_nil_value();
82 }
83
84 /*
85  *  call-seq:
86  *     Integer(arg,base=0)    -> integer
87  *
88  *  Converts <i>arg</i> to a <code>Fixnum</code>.
89  *  Numeric types are converted directly (with floating point numbers
90  *  being truncated).    <i>base</i> (0, or between 2 and 36) is a base for
91  *  integer string representation.  If <i>arg</i> is a <code>String</code>,
92  *  when <i>base</i> is omitted or equals to zero, radix indicators
93  *  (<code>0</code>, <code>0b</code>, and <code>0x</code>) are honored.
94  *  In any case, strings should be strictly conformed to numeric
95  *  representation. This behavior is different from that of
96  *  <code>String#to_i</code>.  Non string values will be treated as integers.
97  *  Passing <code>nil</code> raises a TypeError.
98  *
99  *     Integer(123.999)    #=> 123
100  *     Integer("0x1a")     #=> 26
101  *     Integer(Time.new)   #=> 1204973019
102  *     Integer("0930", 10) #=> 930
103  *     Integer("111", 2)   #=> 7
104  *     Integer(nil)        #=> TypeError
105  */
106 static mrb_value
107 mrb_f_integer(mrb_state *mrb, mrb_value self)
108 {
109   mrb_value arg;
110   mrb_int base = 0;
111
112   mrb_get_args(mrb, "o|i", &arg, &base);
113   return mrb_convert_to_integer(mrb, arg, base);
114 }
115
116 #ifndef MRB_WITHOUT_FLOAT
117 /*
118  *  call-seq:
119  *     Float(arg)    -> float
120  *
121  *  Returns <i>arg</i> converted to a float. Numeric types are converted
122  *  directly, the rest are converted using <i>arg</i>.to_f.
123  *
124  *     Float(1)           #=> 1.0
125  *     Float(123.456)     #=> 123.456
126  *     Float("123.456")   #=> 123.456
127  *     Float(nil)         #=> TypeError
128  */
129 static mrb_value
130 mrb_f_float(mrb_state *mrb, mrb_value self)
131 {
132   mrb_value arg;
133
134   mrb_get_args(mrb, "o", &arg);
135   return mrb_Float(mrb, arg);
136 }
137 #endif
138
139 /*
140  *  call-seq:
141  *     String(arg)   -> string
142  *
143  *  Returns <i>arg</i> as an <code>String</code>.
144  *  converted using <code>to_s</code> method.
145  *
146  *     String(self)        #=> "main"
147  *     String(self.class)  #=> "Object"
148  *     String(123456)      #=> "123456"
149  */
150 static mrb_value
151 mrb_f_string(mrb_state *mrb, mrb_value self)
152 {
153   mrb_value arg, tmp;
154
155   mrb_get_args(mrb, "o", &arg);
156   tmp = mrb_convert_type(mrb, arg, MRB_TT_STRING, "String", "to_s");
157   return tmp;
158 }
159
160 /*
161  *  call-seq:
162  *     Array(arg)    -> array
163  *
164  *  Returns +arg+ as an Array using to_a method.
165  *
166  *     Array(1..5)   #=> [1, 2, 3, 4, 5]
167  *
168  */
169 static mrb_value
170 mrb_f_array(mrb_state *mrb, mrb_value self)
171 {
172   mrb_value arg, tmp;
173
174   mrb_get_args(mrb, "o", &arg);
175   tmp = mrb_check_convert_type(mrb, arg, MRB_TT_ARRAY, "Array", "to_a");
176   if (mrb_nil_p(tmp)) {
177     return mrb_ary_new_from_values(mrb, 1, &arg);
178   }
179
180   return tmp;
181 }
182
183 /*
184  *  call-seq:
185  *     Hash(arg)    -> hash
186  *
187  *  Returns a <code>Hash</code> if <i>arg</i> is a <code>Hash</code>.
188  *  Returns an empty <code>Hash</code> when <i>arg</i> is <tt>nil</tt>
189  *  or <tt>[]</tt>.
190  *
191  *      Hash([])          #=> {}
192  *      Hash(nil)         #=> {}
193  *      Hash(key: :value) #=> {:key => :value}
194  *      Hash([1, 2, 3])   #=> TypeError
195  *
196  */
197 static mrb_value
198 mrb_f_hash(mrb_state *mrb, mrb_value self)
199 {
200   mrb_value arg;
201
202   mrb_get_args(mrb, "o", &arg);
203   if (mrb_nil_p(arg) || (mrb_array_p(arg) && RARRAY_LEN(arg) == 0)) {
204     return mrb_hash_new(mrb);
205   }
206   return mrb_ensure_hash_type(mrb, arg);
207 }
208
209 /*
210  *  call-seq:
211  *     obj.itself -> an_object
212  *
213  *  Returns <i>obj</i>.
214  *
215  *      string = 'my string' #=> "my string"
216  *      string.itself.object_id == string.object_id #=> true
217  *
218  */
219 static mrb_value
220 mrb_f_itself(mrb_state *mrb, mrb_value self)
221 {
222   return self;
223 }
224
225 void
226 mrb_mruby_kernel_ext_gem_init(mrb_state *mrb)
227 {
228   struct RClass *krn = mrb->kernel_module;
229
230   mrb_define_module_function(mrb, krn, "fail", mrb_f_raise, MRB_ARGS_OPT(2));
231   mrb_define_module_function(mrb, krn, "caller", mrb_f_caller, MRB_ARGS_OPT(2));
232   mrb_define_method(mrb, krn, "__method__", mrb_f_method, MRB_ARGS_NONE());
233   mrb_define_module_function(mrb, krn, "Integer", mrb_f_integer, MRB_ARGS_ANY());
234 #ifndef MRB_WITHOUT_FLOAT
235   mrb_define_module_function(mrb, krn, "Float", mrb_f_float, MRB_ARGS_REQ(1));
236 #endif
237   mrb_define_module_function(mrb, krn, "String", mrb_f_string, MRB_ARGS_REQ(1));
238   mrb_define_module_function(mrb, krn, "Array", mrb_f_array, MRB_ARGS_REQ(1));
239   mrb_define_module_function(mrb, krn, "Hash", mrb_f_hash, MRB_ARGS_REQ(1));
240   mrb_define_module_function(mrb, krn, "itself", mrb_f_itself, MRB_ARGS_NONE());
241 }
242
243 void
244 mrb_mruby_kernel_ext_gem_final(mrb_state *mrb)
245 {
246 }