From be1c7e50e1e8809ea56f2c9d472eccd8ffd73a97 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 04:57:58 +0200 Subject: Adding upstream version 1.44.3. Signed-off-by: Daniel Baumann --- .../deps/mruby/mrbgems/mruby-array-ext/src/array.c | 244 +++++++++++++++++++++ 1 file changed, 244 insertions(+) create mode 100644 web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/src/array.c (limited to 'web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/src/array.c') diff --git a/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/src/array.c b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/src/array.c new file mode 100644 index 00000000..e99599b0 --- /dev/null +++ b/web/server/h2o/libh2o/deps/mruby/mrbgems/mruby-array-ext/src/array.c @@ -0,0 +1,244 @@ +#include +#include +#include +#include +#include + +/* + * call-seq: + * ary.assoc(obj) -> new_ary or nil + * + * Searches through an array whose elements are also arrays + * comparing _obj_ with the first element of each contained array + * using obj.==. + * Returns the first contained array that matches (that + * is, the first associated array), + * or +nil+ if no match is found. + * See also Array#rassoc. + * + * s1 = [ "colors", "red", "blue", "green" ] + * s2 = [ "letters", "a", "b", "c" ] + * s3 = "foo" + * a = [ s1, s2, s3 ] + * a.assoc("letters") #=> [ "letters", "a", "b", "c" ] + * a.assoc("foo") #=> nil + */ + +static mrb_value +mrb_ary_assoc(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mrb_value v, k; + + mrb_get_args(mrb, "o", &k); + + for (i = 0; i < RARRAY_LEN(ary); ++i) { + v = mrb_check_array_type(mrb, RARRAY_PTR(ary)[i]); + if (!mrb_nil_p(v) && RARRAY_LEN(v) > 0 && + mrb_equal(mrb, RARRAY_PTR(v)[0], k)) + return v; + } + return mrb_nil_value(); +} + +/* + * call-seq: + * ary.rassoc(obj) -> new_ary or nil + * + * Searches through the array whose elements are also arrays. Compares + * _obj_ with the second element of each contained array using + * ==. Returns the first contained array that matches. See + * also Array#assoc. + * + * a = [ [ 1, "one"], [2, "two"], [3, "three"], ["ii", "two"] ] + * a.rassoc("two") #=> [2, "two"] + * a.rassoc("four") #=> nil + */ + +static mrb_value +mrb_ary_rassoc(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mrb_value v, value; + + mrb_get_args(mrb, "o", &value); + + for (i = 0; i < RARRAY_LEN(ary); ++i) { + v = RARRAY_PTR(ary)[i]; + if (mrb_type(v) == MRB_TT_ARRAY && + RARRAY_LEN(v) > 1 && + mrb_equal(mrb, RARRAY_PTR(v)[1], value)) + return v; + } + return mrb_nil_value(); +} + +/* + * call-seq: + * ary.at(index) -> obj or nil + * + * Returns the element at _index_. A + * negative index counts from the end of +self+. Returns +nil+ + * if the index is out of range. See also Array#[]. + * + * a = [ "a", "b", "c", "d", "e" ] + * a.at(0) #=> "a" + * a.at(-1) #=> "e" + */ + +static mrb_value +mrb_ary_at(mrb_state *mrb, mrb_value ary) +{ + mrb_int pos; + mrb_get_args(mrb, "i", &pos); + + return mrb_ary_entry(ary, pos); +} + +static mrb_value +mrb_ary_values_at(mrb_state *mrb, mrb_value self) +{ + mrb_int argc; + mrb_value *argv; + + mrb_get_args(mrb, "*", &argv, &argc); + + return mrb_get_values_at(mrb, self, RARRAY_LEN(self), argc, argv, mrb_ary_ref); +} + +/* + * call-seq: + * ary.to_h -> Hash + * + * Returns the result of interpreting aray as an array of + * [key, value] paris. + * + * [[:foo, :bar], [1, 2]].to_h + * # => {:foo => :bar, 1 => 2} + * + */ + +static mrb_value +mrb_ary_to_h(mrb_state *mrb, mrb_value ary) +{ + mrb_int i; + mrb_value v, hash; + + hash = mrb_hash_new_capa(mrb, 0); + + for (i = 0; i < RARRAY_LEN(ary); ++i) { + mrb_value elt = RARRAY_PTR(ary)[i]; + v = mrb_check_array_type(mrb, elt); + + if (mrb_nil_p(v)) { + mrb_raisef(mrb, E_TYPE_ERROR, "wrong element type %S at %S (expected array)", + mrb_str_new_cstr(mrb, mrb_obj_classname(mrb, elt)), + mrb_fixnum_value(i) + ); + } + + if (RARRAY_LEN(v) != 2) { + mrb_raisef(mrb, E_ARGUMENT_ERROR, "wrong array length at %S (expected 2, was %S)", + mrb_fixnum_value(i), + mrb_fixnum_value(RARRAY_LEN(v)) + ); + } + + mrb_hash_set(mrb, hash, RARRAY_PTR(v)[0], RARRAY_PTR(v)[1]); + } + + return hash; +} + +/* + * call-seq: + * ary.slice!(index) -> obj or nil + * ary.slice!(start, length) -> new_ary or nil + * ary.slice!(range) -> new_ary or nil + * + * Deletes the element(s) given by an +index+ (optionally up to +length+ + * elements) or by a +range+. + * + * Returns the deleted object (or objects), or +nil+ if the +index+ is out of + * range. + * + * a = [ "a", "b", "c" ] + * a.slice!(1) #=> "b" + * a #=> ["a", "c"] + * a.slice!(-1) #=> "c" + * a #=> ["a"] + * a.slice!(100) #=> nil + * a #=> ["a"] + */ + +static mrb_value +mrb_ary_slice_bang(mrb_state *mrb, mrb_value self) +{ + struct RArray *a = mrb_ary_ptr(self); + mrb_int i, j, k, len, alen = ARY_LEN(a); + mrb_value index; + mrb_value val; + mrb_value *ptr; + mrb_value ary; + + mrb_ary_modify(mrb, a); + + if (mrb_get_args(mrb, "o|i", &index, &len) == 1) { + switch (mrb_type(index)) { + case MRB_TT_RANGE: + if (mrb_range_beg_len(mrb, index, &i, &len, alen, TRUE) == 1) { + goto delete_pos_len; + } + else { + return mrb_nil_value(); + } + case MRB_TT_FIXNUM: + val = mrb_funcall(mrb, self, "delete_at", 1, index); + return val; + default: + val = mrb_funcall(mrb, self, "delete_at", 1, index); + return val; + } + } + + i = mrb_fixnum(index); + delete_pos_len: + if (i < 0) i += alen; + if (i < 0 || alen < i) return mrb_nil_value(); + if (len < 0) return mrb_nil_value(); + if (alen == i) return mrb_ary_new(mrb); + if (len > alen - i) len = alen - i; + + ary = mrb_ary_new_capa(mrb, len); + ptr = ARY_PTR(a); + for (j = i, k = 0; k < len; ++j, ++k) { + mrb_ary_push(mrb, ary, ptr[j]); + } + + ptr += i; + for (j = i; j < alen - len; ++j) { + *ptr = *(ptr+len); + ++ptr; + } + + mrb_ary_resize(mrb, self, alen - len); + return ary; +} + +void +mrb_mruby_array_ext_gem_init(mrb_state* mrb) +{ + struct RClass * a = mrb->array_class; + + mrb_define_method(mrb, a, "assoc", mrb_ary_assoc, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "at", mrb_ary_at, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "rassoc", mrb_ary_rassoc, MRB_ARGS_REQ(1)); + mrb_define_method(mrb, a, "values_at", mrb_ary_values_at, MRB_ARGS_ANY()); + mrb_define_method(mrb, a, "to_h", mrb_ary_to_h, MRB_ARGS_REQ(0)); + mrb_define_method(mrb, a, "slice!", mrb_ary_slice_bang, MRB_ARGS_ANY()); +} + +void +mrb_mruby_array_ext_gem_final(mrb_state* mrb) +{ +} -- cgit v1.2.3