source: EcnlProtoTool/trunk/mruby-1.3.0/mrbgems/mruby-array-ext/src/array.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 5.9 KB
Line 
1#include <mruby.h>
2#include <mruby/value.h>
3#include <mruby/array.h>
4#include <mruby/range.h>
5#include <mruby/hash.h>
6
7/*
8 * call-seq:
9 * ary.assoc(obj) -> new_ary or nil
10 *
11 * Searches through an array whose elements are also arrays
12 * comparing _obj_ with the first element of each contained array
13 * using obj.==.
14 * Returns the first contained array that matches (that
15 * is, the first associated array),
16 * or +nil+ if no match is found.
17 * See also <code>Array#rassoc</code>.
18 *
19 * s1 = [ "colors", "red", "blue", "green" ]
20 * s2 = [ "letters", "a", "b", "c" ]
21 * s3 = "foo"
22 * a = [ s1, s2, s3 ]
23 * a.assoc("letters") #=> [ "letters", "a", "b", "c" ]
24 * a.assoc("foo") #=> nil
25 */
26
27static mrb_value
28mrb_ary_assoc(mrb_state *mrb, mrb_value ary)
29{
30 mrb_int i;
31 mrb_value v, k;
32
33 mrb_get_args(mrb, "o", &k);
34
35 for (i = 0; i < RARRAY_LEN(ary); ++i) {
36 v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);
37 if (!mrb_nil_p(v) && RARRAY_LEN(v) > 0 &&
38 mrb_equal(mrb, RARRAY_PTR(v)[0], k))
39 return v;
40 }
41 return mrb_nil_value();
42}
43
44/*
45 * call-seq:
46 * ary.rassoc(obj) -> new_ary or nil
47 *
48 * Searches through the array whose elements are also arrays. Compares
49 * _obj_ with the second element of each contained array using
50 * <code>==</code>. Returns the first contained array that matches. See
51 * also <code>Array#assoc</code>.
52 *
53 * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ]
54 * a.rassoc("two") #=> [2, "two"]
55 * a.rassoc("four") #=> nil
56 */
57
58static mrb_value
59mrb_ary_rassoc(mrb_state *mrb, mrb_value ary)
60{
61 mrb_int i;
62 mrb_value v, value;
63
64 mrb_get_args(mrb, "o", &value);
65
66 for (i = 0; i < RARRAY_LEN(ary); ++i) {
67 v = RARRAY_PTR(ary)[i];
68 if (mrb_type(v) == MRB_TT_ARRAY &&
69 RARRAY_LEN(v) > 1 &&
70 mrb_equal(mrb, RARRAY_PTR(v)[1], value))
71 return v;
72 }
73 return mrb_nil_value();
74}
75
76/*
77 * call-seq:
78 * ary.at(index) -> obj or nil
79 *
80 * Returns the element at _index_. A
81 * negative index counts from the end of +self+. Returns +nil+
82 * if the index is out of range. See also <code>Array#[]</code>.
83 *
84 * a = [ "a", "b", "c", "d", "e" ]
85 * a.at(0) #=> "a"
86 * a.at(-1) #=> "e"
87 */
88
89static mrb_value
90mrb_ary_at(mrb_state *mrb, mrb_value ary)
91{
92 mrb_int pos;
93 mrb_get_args(mrb, "i", &pos);
94
95 return mrb_ary_entry(ary, pos);
96}
97
98static mrb_value
99mrb_ary_values_at(mrb_state *mrb, mrb_value self)
100{
101 mrb_int argc;
102 mrb_value *argv;
103
104 mrb_get_args(mrb, "*", &argv, &argc);
105
106 return mrb_get_values_at(mrb, self, RARRAY_LEN(self), argc, argv, mrb_ary_ref);
107}
108
109/*
110 * call-seq:
111 * ary.to_h -> Hash
112 *
113 * Returns the result of interpreting <i>aray</i> as an array of
114 * <tt>[key, value]</tt> paris.
115 *
116 * [[:foo, :bar], [1, 2]].to_h
117 * # => {:foo => :bar, 1 => 2}
118 *
119 */
120
121static mrb_value
122mrb_ary_to_h(mrb_state *mrb, mrb_value ary)
123{
124 mrb_int i;
125 mrb_value v, hash;
126
127 hash = mrb_hash_new_capa(mrb, 0);
128
129 for (i = 0; i < RARRAY_LEN(ary); ++i) {
130 v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]);
131
132 if (mrb_nil_p(v)) {
133 mrb_raisef(mrb, E_TYPE_ERROR, "wrong element type %S at %S (expected array)",
134 mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, ary_elt(ary, i))),
135 mrb_fixnum_value(i)
136 );
137 }
138
139 if (RARRAY_LEN(v) != 2) {
140 mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong array length at %S (expected 2, was %S)",
141 mrb_fixnum_value(i),
142 mrb_fixnum_value(RARRAY_LEN(v))
143 );
144 }
145
146 mrb_hash_set(mrb, hash, RARRAY_PTR(v)[0], RARRAY_PTR(v)[1]);
147 }
148
149 return hash;
150}
151
152/*
153 * call-seq:
154 * ary.slice!(index) -> obj or nil
155 * ary.slice!(start, length) -> new_ary or nil
156 * ary.slice!(range) -> new_ary or nil
157 *
158 * Deletes the element(s) given by an +index+ (optionally up to +length+
159 * elements) or by a +range+.
160 *
161 * Returns the deleted object (or objects), or +nil+ if the +index+ is out of
162 * range.
163 *
164 * a = [ "a", "b", "c" ]
165 * a.slice!(1) #=> "b"
166 * a #=> ["a", "c"]
167 * a.slice!(-1) #=> "c"
168 * a #=> ["a"]
169 * a.slice!(100) #=> nil
170 * a #=> ["a"]
171 */
172
173static mrb_value
174mrb_ary_slice_bang(mrb_state *mrb, mrb_value self)
175{
176 struct RArray *a = mrb_ary_ptr(self);
177 mrb_int i, j, k, len;
178 mrb_value index;
179 mrb_value val;
180 mrb_value *ptr;
181 mrb_value ary;
182
183 mrb_ary_modify(mrb, a);
184
185 if (mrb_get_args(mrb, "o|i", &index, &len) == 1) {
186 switch (mrb_type(index)) {
187 case MRB_TT_RANGE:
188 if (mrb_range_beg_len(mrb, index, &i, &len, a->len, TRUE) == 1) {
189 goto delete_pos_len;
190 }
191 else {
192 return mrb_nil_value();
193 }
194 case MRB_TT_FIXNUM:
195 val = mrb_funcall(mrb, self, "delete_at", 1, index);
196 return val;
197 default:
198 val = mrb_funcall(mrb, self, "delete_at", 1, index);
199 return val;
200 }
201 }
202
203 i = mrb_fixnum(index);
204 delete_pos_len:
205 if (i < 0) i += a->len;
206 if (i < 0 || a->len < i) return mrb_nil_value();
207 if (len < 0) return mrb_nil_value();
208 if (a->len == i) return mrb_ary_new(mrb);
209 if (len > a->len - i) len = a->len - i;
210
211 ary = mrb_ary_new_capa(mrb, len);
212
213 for (j = i, k = 0; k < len; ++j, ++k) {
214 mrb_ary_push(mrb, ary, a->ptr[j]);
215 }
216
217 ptr = a->ptr + i;
218 for (j = i; j < a->len - len; ++j) {
219 *ptr = *(ptr+len);
220 ++ptr;
221 }
222
223 mrb_ary_resize(mrb, self, a->len - len);
224 return ary;
225}
226
227void
228mrb_mruby_array_ext_gem_init(mrb_state* mrb)
229{
230 struct RClass * a = mrb->array_class;
231
232 mrb_define_method(mrb, a, "assoc", mrb_ary_assoc, MRB_ARGS_REQ(1));
233 mrb_define_method(mrb, a, "at", mrb_ary_at, MRB_ARGS_REQ(1));
234 mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, MRB_ARGS_REQ(1));
235 mrb_define_method(mrb, a, "values_at", mrb_ary_values_at, MRB_ARGS_ANY());
236 mrb_define_method(mrb, a, "to_h", mrb_ary_to_h, MRB_ARGS_REQ(0));
237 mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang, MRB_ARGS_ANY());
238}
239
240void
241mrb_mruby_array_ext_gem_final(mrb_state* mrb)
242{
243}
Note: See TracBrowser for help on using the repository browser.