Beispiel #1
0
MRB_API mrb_value
mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base)
{
  mrb_value tmp;

  if (mrb_nil_p(val)) {
    if (base != 0) goto arg_error;
      mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Integer");
  }
  switch (mrb_type(val)) {
    case MRB_TT_FLOAT:
      if (base != 0) goto arg_error;
      if (FIXABLE(mrb_float(val))) {
        break;
      }
      return mrb_flo_to_fixnum(mrb, val);

    case MRB_TT_FIXNUM:
      if (base != 0) goto arg_error;
      return val;

    case MRB_TT_STRING:
    string_conv:
      return mrb_str_to_inum(mrb, val, base, TRUE);

    default:
      break;
  }
  if (base != 0) {
    tmp = mrb_check_string_type(mrb, val);
    if (!mrb_nil_p(tmp)) {
      goto string_conv;
    }
arg_error:
    mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value");
  }
  tmp = convert_type(mrb, val, "Integer", "to_int", FALSE);
  if (mrb_nil_p(tmp)) {
    return mrb_to_integer(mrb, val, "to_i");
  }
  return tmp;
}
static void
pcre_regexp_init(mrb_state *mrb, mrb_value self, mrb_value str, mrb_value flag) {
  mrb_value regexp;
  struct mrb_pcre_regexp *reg;
  int cflag = 0;
  int erroff = 0;
  const char *errstr = NULL;

  regexp = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@regexp"));
  if (mrb_nil_p(regexp)) {
    reg = malloc(sizeof(struct mrb_pcre_regexp));
    memset(reg, 0, sizeof(struct mrb_pcre_regexp));
    mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@regexp"), mrb_obj_value(
        Data_Wrap_Struct(mrb, mrb->object_class,
          &mrb_pcre_regexp_type, (void*) reg)));
  }else{
    Data_Get_Struct(mrb, regexp, &mrb_pcre_regexp_type, reg);
    pcre_free(reg->re);
  }

  if (mrb_nil_p(flag))
    cflag = 0;
  else if (mrb_fixnum_p(flag)) {
    int nflag = mrb_fixnum(flag);
    if (nflag & 1) cflag |= PCRE_CASELESS;
    if (nflag & 2) cflag |= PCRE_EXTENDED;
    if (nflag & 4) cflag |= PCRE_MULTILINE | PCRE_DOTALL;
  } else if (mrb_type(flag) == MRB_TT_TRUE)
    cflag |= PCRE_CASELESS;
  else if (mrb_string_p(flag)) {
    if (STRCHR(RSTRING_PTR(flag), 'i')) cflag |= PCRE_CASELESS;
    if (STRCHR(RSTRING_PTR(flag), 'x')) cflag |= PCRE_EXTENDED;
    if (STRCHR(RSTRING_PTR(flag), 'm')) cflag |= PCRE_MULTILINE | PCRE_DOTALL;
  }
  reg->flag = cflag;
  reg->re = pcre_compile(RSTRING_PTR(str), cflag, &errstr, &erroff, NULL);
  if (!reg->re) {
    mrb_raisef(mrb, E_ARGUMENT_ERROR, "'%S' is an invalid regular expression because %S.",
      mrb_str_new_cstr(mrb, RSTRING_PTR(str) + erroff), mrb_str_new_cstr(mrb, errstr));
  }
  mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "@source"), str);
}
Beispiel #3
0
mrb_value
mrb_Float(mrb_state *mrb, mrb_value val)
{
  if (mrb_nil_p(val)) {
    mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float");
  }
  switch (mrb_type(val)) {
    case MRB_TT_FIXNUM:
      return mrb_float_value(mrb, (mrb_float)mrb_fixnum(val));

    case MRB_TT_FLOAT:
      return val;

    case MRB_TT_STRING:
      return mrb_float_value(mrb, mrb_str_to_dbl(mrb, val, TRUE));

    default:
      return mrb_convert_type(mrb, val, MRB_TT_FLOAT, "Float", "to_f");
  }
}
Beispiel #4
0
/*
 *  call-seq:
 *     obj.inspect   -> string
 *
 *  Returns a string containing a human-readable representation of
 *  <i>obj</i>. If not overridden and no instance variables, uses the
 *  <code>to_s</code> method to generate the string.
 *  <i>obj</i>.  If not overridden, uses the <code>to_s</code> method to
 *  generate the string.
 *
 *     [ 1, 2, 3..4, 'five' ].inspect   #=> "[1, 2, 3..4, \"five\"]"
 *     Time.new.inspect                 #=> "2008-03-08 19:43:39 +0900"
 */
mrb_value
mrb_obj_inspect(mrb_state *mrb, mrb_value obj)
{
  if ((mrb_type(obj) == MRB_TT_OBJECT) && mrb_obj_basic_to_s_p(mrb, obj)) {
    long len = ROBJECT_NUMIV(obj);

    if (len > 0) {
      mrb_value str;
      const char *c = mrb_obj_classname(mrb, obj);

      str = mrb_sprintf(mrb, "-<%s:%p", c, (void*)&obj);
      return inspect_obj(mrb, obj, str, 0);
    }
    return mrb_any_to_s(mrb, obj);
  }
  else if (mrb_nil_p(obj)) {
    return mrb_str_new(mrb, "nil", 3);
  }
  return mrb_funcall(mrb, obj, "to_s", 0, 0);
}
Beispiel #5
0
static void
init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
{
    switch (mrb_type(obj)) {
    case MRB_TT_CLASS:
    case MRB_TT_MODULE:
        copy_class(mrb, dest, obj);
    /* fall through */
    case MRB_TT_OBJECT:
    case MRB_TT_SCLASS:
    case MRB_TT_HASH:
    case MRB_TT_DATA:
        mrb_iv_copy(mrb, dest, obj);
        break;

    default:
        break;
    }
    mrb_funcall(mrb, dest, "initialize_copy", 1, obj);
}
Beispiel #6
0
static mrb_value
hash_equal(mrb_state *mrb, mrb_value hash1, mrb_value hash2, int eql)
{
  khash_t(ht) *h1, *h2;

  if (mrb_obj_equal(mrb, hash1, hash2)) return mrb_true_value();
  if (mrb_type(hash2) != MRB_TT_HASH) {
      if (!mrb_respond_to(mrb, hash2, mrb_intern(mrb, "to_hash"))) {
          return mrb_false_value();
      }
      if (eql)
          return mrb_fixnum_value(mrb_eql(mrb, hash2, hash1));
      else
          return mrb_fixnum_value(mrb_equal(mrb, hash2, hash1));
  }
  h1 = RHASH_TBL(hash1);
  h2 = RHASH_TBL(hash2);
  if (!h2) {
    if (!h2)  return mrb_true_value();
    return mrb_false_value();
  }
  if (!h2) return mrb_false_value();
  if (kh_size(h1) != kh_size(h2)) return mrb_false_value();
  else {
    khiter_t k1, k2;
    mrb_value key;

    for (k1 = kh_begin(h1); k1 != kh_end(h1); k1++) {
      if (!kh_exist(h1, k1)) continue;
      key = kh_key(h1,k1);
      k2 = kh_get(ht, h2, key);
      if (k2 != kh_end(h2)) {
	if (mrb_equal(mrb, kh_value(h1,k1), kh_value(h2,k2))) {
	  continue; /* next key */
	}
      }
      return mrb_false_value();
    }
  }
  return mrb_true_value();
}
Beispiel #7
0
static mrb_value
mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value indx)
{
  mrb_int idx;

  regexp_check(mrb, indx);
  switch (mrb_type(indx)) {
    case MRB_TT_FIXNUM:
      idx = mrb_fixnum(indx);

num_index:
      str = str_substr(mrb, str, idx, 1);
      if (!mrb_nil_p(str) && RSTRING_LEN(str) == 0) return mrb_nil_value();
      return str;

    case MRB_TT_STRING:
      if (str_index(mrb, str, indx, 0) != -1)
        return mrb_str_dup(mrb, indx);
      return mrb_nil_value();

    case MRB_TT_RANGE:
      /* check if indx is Range */
      {
        mrb_int beg, len;
        mrb_value tmp;

        len = RSTRING_LEN_UTF8(str);
        if (mrb_range_beg_len(mrb, indx, &beg, &len, len)) {
          tmp = str_subseq(mrb, str, beg, len);
          return tmp;
        }
        else {
          return mrb_nil_value();
        }
      }
    default:
      idx = mrb_fixnum(indx);
      goto num_index;
    }
    return mrb_nil_value();    /* not reached */
}
Beispiel #8
0
static mrb_value
inspect_ary(mrb_state *mrb, mrb_value ary, mrb_value list)
{
  int i;
  mrb_value s, arystr;
  char head[] = { '[' };
  char sep[] = { ',', ' ' };
  char tail[] = { ']' };

  /* check recursive */
  for(i=0; i<RARRAY_LEN(list); i++) {
    if (mrb_obj_equal(mrb, ary, RARRAY_PTR(list)[i])) {
      return mrb_str_new(mrb, "[...]", 5);
    }
  }

  mrb_ary_push(mrb, list, ary);

  arystr = mrb_str_buf_new(mrb, 64);
  mrb_str_buf_cat(mrb, arystr, head, sizeof(head));

  for(i=0; i<RARRAY_LEN(ary); i++) {
    int ai = mrb_gc_arena_save(mrb);

    if (i > 0) {
      mrb_str_buf_cat(mrb, arystr, sep, sizeof(sep));
    }
    if (mrb_type(RARRAY_PTR(ary)[i]) == MRB_TT_ARRAY) {
      s = inspect_ary(mrb, RARRAY_PTR(ary)[i], list);
    } else {
      s = mrb_inspect(mrb, RARRAY_PTR(ary)[i]);
    }
    mrb_str_buf_cat(mrb, arystr, RSTRING_PTR(s), RSTRING_LEN(s));
    mrb_gc_arena_restore(mrb, ai);
  }

  mrb_str_buf_cat(mrb, arystr, tail, sizeof(tail));
  mrb_ary_pop(mrb, list);

  return arystr;
}
Beispiel #9
0
static mrb_value
flo_eq(mrb_state *mrb, mrb_value x)
{
  mrb_value y;
  volatile mrb_float a, b;

  mrb_get_args(mrb, "o", &y);

  switch (mrb_type(y)) {
  case MRB_TT_FIXNUM:
    b = (mrb_float)mrb_fixnum(y);
    break;
  case MRB_TT_FLOAT:
    b = mrb_float(y);
    break;
  default:
    return num_equal(mrb, x, y);
  }
  a = mrb_float(x);
  return (a == b)?mrb_true_value():mrb_false_value();
}
static mrb_value ngx_http_mruby_base64_encode(mrb_state *mrb, mrb_value self)
{
    mrb_value mrb_src;
    ngx_str_t src, dst;

    mrb_get_args(mrb, "o", &mrb_src);

    if (mrb_type(mrb_src) != MRB_TT_STRING) {
        mrb_src = mrb_funcall(mrb, mrb_src, "to_s", 0, NULL);
    }

    src.data = (u_char *)RSTRING_PTR(mrb_src);
    src.len  = RSTRING_LEN(mrb_src);

    dst.len  = ngx_base64_encoded_length(src.len);
    dst.data = mrb_malloc(mrb, dst.len + 1);

    ngx_encode_base64(&dst, &src);

    return mrb_str_new(mrb, (char *)dst.data, dst.len);
}
Beispiel #11
0
void ap_mrb_raise_error(mrb_state *mrb, mrb_value obj, request_rec *r)
{
   struct RString *str;
   char *err_out;

   obj = mrb_funcall(mrb, obj, "inspect", 0);

   if (mrb_type(obj) == MRB_TT_STRING) {
       str = mrb_str_ptr(obj);
       err_out = str->ptr;
       ap_log_rerror(APLOG_MARK
           , APLOG_ERR
           , 0
           , r
           , "%s ERROR %s: mrb_run failed. error: %s"
           , MODULE_NAME
           , __func__
           , err_out
       );
   }
}
Beispiel #12
0
static size_t
get_pool_block_size(mrb_state *mrb, mrb_irep *irep)
{
  size_t size = 0;
  size_t pool_no;
  int len;
  mrb_value str;
  char buf[32];

  size += sizeof(uint32_t); /* plen */
  size += irep->plen * (sizeof(uint8_t) + sizeof(uint16_t)); /* len(n) */

  for (pool_no = 0; pool_no < irep->plen; pool_no++) {
    int ai = mrb_gc_arena_save(mrb);

    switch (mrb_type(irep->pool[pool_no])) {
    case MRB_TT_FIXNUM:
      str = mrb_fix2str(mrb, irep->pool[pool_no], 10);
      size += RSTRING_LEN(str);
      break;

    case MRB_TT_FLOAT:
      len = mrb_float_to_str(buf, mrb_float(irep->pool[pool_no]));
      size += len;
      break;

    case MRB_TT_STRING:
      str = mrb_string_value(mrb, &irep->pool[pool_no]);
      size += RSTRING_LEN(str);
      break;

    default:
      break;
    }

    mrb_gc_arena_restore(mrb, ai);
  }

  return size;
}
Beispiel #13
0
static mrb_value
method_super_method(mrb_state *mrb, mrb_value self)
{
  mrb_value recv = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@recv"));
  mrb_value klass = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@klass"));
  mrb_value owner = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@owner"));
  mrb_value name = mrb_iv_get(mrb, self, mrb_intern_lit(mrb, "@name"));
  struct RClass *super, *rklass;
  struct RProc *proc;
  struct RObject *me;

  switch (mrb_type(klass)) {
    case MRB_TT_SCLASS:
      super = mrb_class_ptr(klass)->super->super;
      break;
    case MRB_TT_ICLASS:
      super = mrb_class_ptr(klass)->super;
      break;
    default:
      super = mrb_class_ptr(owner)->super;
      break;
  }

  proc = method_search_vm(mrb, &super, mrb_symbol(name));
  if (!proc)
    return mrb_nil_value();

  rklass = super;
  while (super->tt == MRB_TT_ICLASS)
    super = super->c;

  me = method_object_alloc(mrb, mrb_obj_class(mrb, self));
  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@owner"), mrb_obj_value(super));
  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@recv"), recv);
  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@name"), name);
  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "proc"), mrb_obj_value(proc));
  mrb_obj_iv_set(mrb, me, mrb_intern_lit(mrb, "@klass"), mrb_obj_value(rklass));

  return mrb_obj_value(me);
}
Beispiel #14
0
//convert rbObj in RVector (assumed to be possible!!!)
SEXP mrbArray2RVector(mrb_value rbobj)
{
  SEXP ans;
  mrb_value arr,elt,tmp;
  //char *name;
  int n,i;
  
  if(!mrb_obj_is_kind_of(mrb,rbobj,mrb->array_class)) {
    if(!(mrb_obj_is_kind_of(mrb,rbobj,mrb->fixnum_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->float_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->string_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->true_class) || mrb_obj_is_kind_of(mrb,rbobj,mrb->false_class))) 
      return R_NilValue;
    n=1;
    arr = mrb_ary_new_capa(mrb,1);
    mrb_ary_push(mrb,arr,rbobj);
  } else {
    arr=rbobj;
    n=RARRAY_LEN(rbobj);  
  }

  //Rprintf("n=%d\n",n);

  elt=mrb_ary_entry(arr,0);

  if(mrb_type(elt)==MRB_TT_FLOAT) {
    PROTECT(ans=allocVector(REALSXP,n));
    for(i=0;i<n;i++) {
      REAL(ans)[i]=mrb_float(mrb_ary_entry(arr,i));
    }
  } else if(mrb_type(elt)==MRB_TT_FIXNUM) {
    PROTECT(ans=allocVector(INTSXP,n));
    for(i=0;i<n;i++) {
      INTEGER(ans)[i]=mrb_int(mrb,mrb_ary_entry(arr,i));
    }
  } else if(mrb_type(elt)==MRB_TT_TRUE || mrb_type(elt)==MRB_TT_FALSE) {
    PROTECT(ans=allocVector(LGLSXP,n));
    for(i=0;i<n;i++) {
      LOGICAL(ans)[i]=(mrb_type(mrb_ary_entry(arr,i))==MRB_TT_FALSE ? FALSE : TRUE);
    }
  } else if(mrb_type(elt)==MRB_TT_STRING) {
    PROTECT(ans=allocVector(STRSXP,n));
    for(i=0;i<n;i++) {
      tmp=mrb_ary_entry(arr,i);
      SET_STRING_ELT(ans,i,mkChar(mrb_string_value_ptr(mrb,tmp)));
    }
  } else ans=R_NilValue;
  UNPROTECT(1);
  return ans; 
}
Beispiel #15
0
static mrb_value
mrb_obj_freeze(mrb_state *mrb, mrb_value self)
{
  struct RBasic *b;

  switch (mrb_type(self)) {
    case MRB_TT_FALSE:
    case MRB_TT_TRUE:
    case MRB_TT_FIXNUM:
    case MRB_TT_SYMBOL:
    case MRB_TT_FLOAT:
      return self;
    default:
      break;
  }

  b = mrb_basic_ptr(self);
  if (!MRB_FROZEN_P(b)) {
    MRB_SET_FROZEN_FLAG(b);
  }
  return self;
}
Beispiel #16
0
mrb_value
num_subi_1(int val, mrb_value a, mrb_int b)
{
  switch (mrb_type(a)) {
  case MRB_TT_FIXNUM:
    {
      mrb_int x, y, z;
      x = mrb_fixnum(a);
      y = b;
      z = x - y;
      if (((x < 0) ^ (y < 0)) != 0 && (x < 0) != (z < 0)) {
        /* integer overflow */
        return mrb_float_value((mrb_float)x - (mrb_float)y);
      }
      return mrb_fixnum_value(z);
    }
  case MRB_TT_FLOAT:
    return mrb_float_value(mrb_float(a) - (mrb_float)b);
  default:
    NOT_REACHABLE();
  }
}
Beispiel #17
0
static mrb_value
mrb_obj_frozen(mrb_state *mrb, mrb_value self)
{
  struct RBasic *b;

  switch (mrb_type(self)) {
    case MRB_TT_FALSE:
    case MRB_TT_TRUE:
    case MRB_TT_FIXNUM:
    case MRB_TT_SYMBOL:
    case MRB_TT_FLOAT:
      return mrb_true_value();
    default:
      break;
  }

  b = mrb_basic_ptr(self);
  if (!MRB_FROZEN_P(b)) {
    return mrb_false_value();
  }
  return mrb_true_value();
}
Beispiel #18
0
static mrb_value
mrb_sce_init(mrb_state *mrb, mrb_value self)
{
  mrb_value c, e2c, m, str;
  mrb_int n;
  int argc, no_errno = 0;
  char buf[20];

  argc = mrb_get_args(mrb, "o|i", &m, &n);
  if (argc == 1) {
    if (mrb_type(m) == MRB_TT_FIXNUM) {
      n = mrb_fixnum(m);
      m = mrb_nil_value();
    } else {
      no_errno = 1;
    }
  }
  if (!no_errno) {
    e2c = mrb_const_get(mrb, mrb_obj_value(mrb_module_get(mrb, "Errno")), mrb_intern_lit(mrb, "Errno2class"));
    c = mrb_hash_fetch(mrb, e2c, mrb_fixnum_value(n), mrb_nil_value());
    if (!mrb_nil_p(c)) {
      mrb_basic_ptr(self)->c = mrb_class_ptr(c);
      str = mrb_str_new_cstr(mrb, strerror(n));
    } else {
      mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "errno"), mrb_fixnum_value(n));
      str = mrb_str_new_cstr(mrb, "Unknown error: ");
      snprintf(buf, sizeof(buf), "%d", (int)n);
      mrb_str_cat2(mrb, str, buf);
    }
  } else {
    str = mrb_str_new_cstr(mrb, "unknown error");
  }
  if (!mrb_nil_p(m)) {
    mrb_str_cat2(mrb, str, " - ");
    mrb_str_append(mrb, str, m);
  }
  mrb_iv_set(mrb, self, mrb_intern_lit(mrb, "mesg"), str);
  return self;
}
Beispiel #19
0
static uint32_t
get_pool_block_size(mrb_state *mrb, mrb_irep *irep, int type)
{
  uint32_t size = 0;
  int pool_no;
  mrb_value str;
  char buf[32];

  size += MRB_DUMP_SIZE_OF_LONG; /* plen */
  size += irep->plen; /* tt(n) */
  size += irep->plen * MRB_DUMP_SIZE_OF_SHORT; /* len(n) */
  size += MRB_DUMP_SIZE_OF_SHORT; /* crc */
  size = DUMP_SIZE(size, type);

  for (pool_no = 0; pool_no < irep->plen; pool_no++) {
    uint16_t nlen =0;
    int len;

    switch (mrb_type(irep->pool[pool_no])) {
    case MRB_TT_FIXNUM:
      str = mrb_fix2str(mrb, irep->pool[pool_no], 10);
      size += (uint32_t)RSTRING_LEN(str);
      break;
    case MRB_TT_FLOAT:
      len = mrb_float_to_str( buf, mrb_float(irep->pool[pool_no]));
      size += (uint32_t)len;
      break;
    case MRB_TT_STRING:
      str = mrb_string_value( mrb, &irep->pool[pool_no]);
      nlen = str_dump_len(RSTRING_PTR(str), RSTRING_LEN(str), type);
      size += nlen;
      break;
    default:
      break;
    }
  }

  return size;
}
Beispiel #20
0
static struct timeval
time2timeval(mrb_state *mrb, mrb_value time)
{
  struct timeval t = { 0, 0 };

  switch (mrb_type(time)) {
    case MRB_TT_FIXNUM:
      t.tv_sec = mrb_fixnum(time);
      t.tv_usec = 0;
      break;

    case MRB_TT_FLOAT:
      t.tv_sec = mrb_float(time);
      t.tv_usec = (mrb_float(time) - t.tv_sec) * 1000000.0;
      break;

    default:
      mrb_raise(mrb, E_TYPE_ERROR, "wrong argument class");
  }

  return t;
}
Beispiel #21
0
static mrb_value mrb_vedis_append_s(mrb_state *mrb, mrb_value key_obj, mrb_value val_obj, vedis *vstore)
{
    int ret;
    const char *key = NULL;

    switch (mrb_type(key_obj)) {
        case MRB_TT_STRING:
            key = RSTRING_PTR(key_obj);
            break;
        case MRB_TT_SYMBOL:
            key = mrb_sym2name(mrb, mrb_obj_to_sym(mrb, key_obj));
            break;
        default:
            mrb_raise(mrb, E_RUNTIME_ERROR, "vedis key type is string or symbol");
    }
    val_obj = mrb_obj_as_string(mrb, val_obj);
    ret = vedis_kv_append(vstore, key, strlen(key), RSTRING_PTR(val_obj), RSTRING_LEN(val_obj));
    if (ret != VEDIS_OK) {
        mrb_vedis_error(mrb, vstore, 0);
    }
    return mrb_true_value();
}
Beispiel #22
0
static mrb_value
mrb_str_byteslice(mrb_state *mrb, mrb_value str)
{
  mrb_value a1;
  mrb_int len;
  int argc;

  argc = mrb_get_args(mrb, "o|i", &a1, &len);
  if (argc == 2) {
    return mrb_str_substr(mrb, str, mrb_fixnum(a1), len);
  }
  switch (mrb_type(a1)) {
  case MRB_TT_RANGE:
    {
      mrb_int beg;

      len = RSTRING_LEN(str);
      switch (mrb_range_beg_len(mrb, a1, &beg, &len, len, TRUE)) {
      case 0:                   /* not range */
        break;
      case 1:                   /* range */
        return mrb_str_substr(mrb, str, beg, len);
      case 2:                   /* out of range */
        mrb_raisef(mrb, E_RANGE_ERROR, "%S out of range", a1);
        break;
      }
      return mrb_nil_value();
    }
  case MRB_TT_FLOAT:
    a1 = mrb_fixnum_value((mrb_int)mrb_float(a1));
    /* fall through */
  case MRB_TT_FIXNUM:
    return mrb_str_substr(mrb, str, mrb_fixnum(a1), 1);
  default:
    mrb_raise(mrb, E_TYPE_ERROR, "wrong type of argument");
  }
  /* not reached */
  return mrb_nil_value();
}
Beispiel #23
0
/*
 *  call-seq:
 *     obj.instance_variables    -> array
 *
 *  Returns an array of instance variable names for the receiver. Note
 *  that simply defining an accessor does not create the corresponding
 *  instance variable.
 *
 *     class Fred
 *       attr_accessor :a1
 *       def initialize
 *         @iv = 3
 *       end
 *     end
 *     Fred.new.instance_variables   #=> [:@iv]
 */
mrb_value
mrb_obj_instance_variables(mrb_state *mrb, mrb_value self)
{
    mrb_value ary;
    kh_iv_t *h = RCLASS_IV_TBL(self);
    int i;
    const char* p;

    ary = mrb_ary_new(mrb);
    if (h) {
      for (i=0;i<kh_end(h);i++) {
        if (kh_exist(h, i)) {
          p = mrb_sym2name(mrb, kh_key(h,i));
          if (*p == '@') {
            if (mrb_type(kh_value(h, i)) != MRB_TT_UNDEF)
              mrb_ary_push(mrb, ary, mrb_str_new_cstr(mrb, p));
          }
        }
      }
    }
    return ary;
}
Beispiel #24
0
/*
 *  call-seq:
 *     obj.instance_eval {| | block }                       -> obj
 *
 *  Evaluates the given block,within  the context of the receiver (_obj_). 
 *  In order to set the context, the variable +self+ is set to _obj_ while
 *  the code is executing, giving the code access to _obj_'s
 *  instance variables. In the version of <code>instance_eval</code>
 *  that takes a +String+, the optional second and third
 *  parameters supply a filename and starting line number that are used
 *  when reporting compilation errors.
 *
 *     class KlassWithSecret
 *       def initialize
 *         @secret = 99
 *       end
 *     end
 *     k = KlassWithSecret.new
 *     k.instance_eval { @secret }   #=> 99
 */
mrb_value
mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
{
  mrb_value a, b;
  mrb_value cv;
  struct RClass *c;

  if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
    mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented");
  }
  switch (mrb_type(self)) {
  case MRB_TT_SYMBOL:
  case MRB_TT_FIXNUM:
  case MRB_TT_FLOAT:
    c = 0;
    break;
  default:
    cv = mrb_singleton_class(mrb, self);
    c = mrb_class_ptr(cv);
  }
  return mrb_yield_internal(mrb, b, 0, 0, self, c);
}
Beispiel #25
0
static mrb_value
mrb_struct_equal(mrb_state *mrb, mrb_value s)
{
  mrb_value s2;
  mrb_value *ptr, *ptr2;
  long i, len;

  mrb_get_args(mrb, "o", &s2);
  if (mrb_obj_equal(mrb, s, s2)) return mrb_true_value();
  if (mrb_type(s2) != MRB_TT_STRUCT) return mrb_false_value();
  if (mrb_obj_class(mrb, s) != mrb_obj_class(mrb, s2)) return mrb_false_value();
  if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
    mrb_bug("inconsistent struct"); /* should never happen */
  }
  ptr = RSTRUCT_PTR(s);
  ptr2 = RSTRUCT_PTR(s2);
  len = RSTRUCT_LEN(s);
  for (i=0; i<len; i++) {
    if (!mrb_equal(mrb, ptr[i], ptr2[i])) return mrb_false_value();
  }
  return mrb_true_value();
}
Beispiel #26
0
/* mrb_gc_unregister() removes the object from GC root. */
MRB_API void
mrb_gc_unregister(mrb_state *mrb, mrb_value obj)
{
  mrb_sym root = mrb_intern_lit(mrb, GC_ROOT_NAME);
  mrb_value table = mrb_gv_get(mrb, root);
  struct RArray *a;
  mrb_int i, j;

  if (mrb_nil_p(table)) return;
  if (mrb_type(table) != MRB_TT_ARRAY) {
    mrb_gv_set(mrb, root, mrb_nil_value());
    return;
  }
  a = mrb_ary_ptr(table);
  mrb_ary_modify(mrb, a);
  for (i=j=0; i<a->len; i++) {
    if (!mrb_obj_eq(mrb, a->ptr[i], obj)) {
      a->ptr[j++] = a->ptr[i];
    }
  }
  a->len = j;
}
Beispiel #27
0
/*
 * call-seq:
 *   lambda { |...| block }  -> a_proc
 *
 * Equivalent to <code>Proc.new</code>, except the resulting Proc objects
 * check the number of parameters passed when called.
 */
static mrb_value
proc_lambda(mrb_state *mrb, mrb_value self)
{
  mrb_value blk;
  struct RProc *p;

  mrb_get_args(mrb, "&", &blk);
  if (mrb_nil_p(blk)) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Proc object without a block");
  }
  if (mrb_type(blk) != MRB_TT_PROC) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "not a proc");
  }
  p = mrb_proc_ptr(blk);
  if (!MRB_PROC_STRICT_P(p)) {
    struct RProc *p2 = (struct RProc*)mrb_obj_alloc(mrb, MRB_TT_PROC, p->c);
    mrb_proc_copy(p2, p);
    p2->flags |= MRB_PROC_STRICT;
    return mrb_obj_value(p2);
  }
  return blk;
}
Beispiel #28
0
static void
mrb_wslay_event_on_msg_recv_callback(wslay_event_context_ptr ctx,
  const struct wslay_event_on_msg_recv_arg *arg, void *user_data)
{
  mrb_wslay_user_data *data = (mrb_wslay_user_data *) user_data;
  mrb_state *mrb = data->mrb;

  int ai = mrb_gc_arena_save(mrb);
  struct mrb_jmpbuf *prev_jmp = mrb->jmp;
  struct mrb_jmpbuf c_jmp;

  MRB_TRY(&c_jmp) {
    mrb->jmp = &c_jmp;

    mrb_value argv[4];
    argv[0] = mrb_fixnum_value(arg->rsv);
    argv[1] = MRB_GET_OPCODE(mrb_fixnum_value(arg->opcode));
    argv[2] = mrb_str_new(mrb, (const char *) arg->msg, arg->msg_length);
    argv[3] = MRB_GET_STATUSCODE(mrb_fixnum_value(arg->status_code));

    mrb_value on_msg_recv_arg = mrb_obj_new(mrb,
      mrb_class_get_under(mrb,
        mrb_module_get_under(mrb,
          mrb_module_get(mrb, "Wslay"), "Event"), "OnMsgRecvArg"), NELEMS(argv), argv);

    mrb_assert(mrb_type(data->on_msg_recv_callback) == MRB_TT_PROC);
    mrb_yield(mrb, data->on_msg_recv_callback, on_msg_recv_arg);

    mrb_gc_arena_restore(mrb, ai);

    mrb->jmp = prev_jmp;
  } MRB_CATCH(&c_jmp) {
    mrb->jmp = prev_jmp;
    wslay_event_set_error(ctx, WSLAY_ERR_CALLBACK_FAILURE);
    mrb_gc_arena_restore(mrb, ai);
    MRB_THROW(mrb->jmp);
  } MRB_END_EXC(&c_jmp);
}
Beispiel #29
0
/*
 *  call-seq:
 *     obj.remove_instance_variable(symbol)    -> obj
 *
 *  Removes the named instance variable from <i>obj</i>, returning that
 *  variable's value.
 *
 *     class Dummy
 *       attr_reader :var
 *       def initialize
 *         @var = 99
 *       end
 *       def remove
 *         remove_instance_variable(:@var)
 *       end
 *     end
 *     d = Dummy.new
 *     d.var      #=> 99
 *     d.remove   #=> 99
 *     d.var      #=> nil
 */
mrb_value
mrb_obj_remove_instance_variable(mrb_state *mrb, mrb_value self)
{
  mrb_sym sym;
  mrb_value name;
  khash_t(iv) *h;
  khiter_t k;
  mrb_value val;
  mrb_value Qundef = mrb_undef_value();

  mrb_get_args(mrb, "o", &name);
  sym = mrb_to_id(mrb, name);
  //if (OBJ_FROZEN(obj)) mrb_error_frozen("object");
  //if (!mrb_is_instance_id(id)) {
  //    mrb_name_error(mrb, id, "`%s' is not allowed as an instance variable name", mrb_sym2name(mrb, id));
  //}
  switch (mrb_type(self)) {
    case MRB_TT_OBJECT:
    case MRB_TT_CLASS:
    case MRB_TT_MODULE:
      if (!mrb_obj_ptr(self)->iv) break;
      h = mrb_obj_ptr(self)->iv;
      if (!h) break;
      k = kh_get(iv, h, sym);
      if (k != kh_end(h)) {
        val = kh_value(h, k);
        if (!mrb_obj_equal(mrb, val, Qundef)) {
          kh_value(h, k) = Qundef;
          return val;
        }
      }
      break;
    default:
      break;
  }
  mrb_name_error(mrb, sym, "instance variable %s not defined", mrb_sym2name(mrb, sym));
  return mrb_nil_value();            /* not reached */
}
Beispiel #30
0
ngx_int_t ngx_mrb_run_body_filter(ngx_http_request_t *r, ngx_mrb_state_t *state, ngx_mrb_code_t *code, ngx_flag_t cached, ngx_http_mruby_ctx_t *ctx)
{
    mrb_value ARGV, mrb_result;

    ARGV = mrb_ary_new_capa(state->mrb, 1);

    mrb_ary_push(state->mrb, ARGV, mrb_str_new(state->mrb, (char *)ctx->body, ctx->body_length));
    mrb_define_global_const(state->mrb, "ARGV", ARGV);

    mrb_result = mrb_run(state->mrb, mrb_proc_new(state->mrb, state->mrb->irep[code->n]), mrb_top_self(state->mrb));
    if (state->mrb->exc) {
        if (code->code_type == NGX_MRB_CODE_TYPE_FILE) {
            ngx_mrb_raise_file_error(state->mrb, mrb_obj_value(state->mrb->exc), r, code->code.file);
        } else {
            ngx_mrb_raise_error(state->mrb, mrb_obj_value(state->mrb->exc), r);
        }
        mrb_gc_arena_restore(state->mrb, state->ai);
        if (!cached) {
            ngx_mrb_irep_clean(r, state, code);
            ngx_mrb_state_clean(r, state);
        }
        return NGX_ERROR;
    }
    
    if (mrb_type(mrb_result) != MRB_TT_STRING) {
        mrb_result = mrb_funcall(state->mrb, mrb_result, "to_s", 0, NULL);
    }

    ctx->body        = (u_char *)RSTRING_PTR(mrb_result);
    ctx->body_length = ngx_strlen(ctx->body);

    mrb_gc_arena_restore(state->mrb, state->ai);
    if (!cached) {
        ngx_mrb_irep_clean(r, state, code);
        ngx_mrb_state_clean(r, state);
    }
    return NGX_OK;
}