Example #1
0
void ngx_mrb_raise_error(mrb_state *mrb, mrb_value obj, ngx_http_request_t *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->as.heap.ptr;
    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                  "mrb_run failed: return 500 HTTP status code to client: error: %s", err_out);
  }
}
void ngx_mrb_raise_conf_error(mrb_state *mrb, mrb_value obj, ngx_conf_t *cf)
{
  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->as.heap.ptr;
    ngx_conf_log_error(NGX_LOG_ERR, cf, 0, "mrb_run failed. error: %s",
                       err_out);
  }
}
Example #3
0
static void
printstr(mrb_state *mrb, mrb_value obj)
{
  struct RString *str;
  char *s;
  int len;

  if (mrb_string_p(obj)) {
    str = mrb_str_ptr(obj);
    s = str->ptr;
    len = str->len;
    fwrite(s, len, 1, stdout);
  }
}
Example #4
0
mrb_value
mrb_str_pool(mrb_state *mrb, mrb_value str)
{
  struct RString *s = mrb_str_ptr(str);
  struct RString *ns;
  char *ptr;
  mrb_int len;

  ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
  ns->tt = MRB_TT_STRING;
  ns->c = mrb->string_class;

  if (RSTR_NOFREE_P(s)) {
    ns->flags = MRB_STR_NOFREE;
    ns->as.heap.ptr = s->as.heap.ptr;
    ns->as.heap.len = s->as.heap.len;
    ns->as.heap.aux.capa = 0;
  }
  else {
    ns->flags = 0;
    if (RSTR_EMBED_P(s)) {
      ptr = s->as.ary;
      len = RSTR_EMBED_LEN(s);
    }
    else {
      ptr = s->as.heap.ptr;
      len = s->as.heap.len;
    }

    if (len < RSTRING_EMBED_LEN_MAX) {
      RSTR_SET_EMBED_FLAG(ns);
      RSTR_SET_EMBED_LEN(ns, len);
      if (ptr) {
        memcpy(ns->as.ary, ptr, len);
      }
      ns->as.ary[len] = '\0';
    }
    else {
      ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
      ns->as.heap.len = len;
      ns->as.heap.aux.capa = len;
      if (ptr) {
        memcpy(ns->as.heap.ptr, ptr, len);
      }
      ns->as.heap.ptr[len] = '\0';
    }
  }
  return mrb_obj_value(ns);
}
Example #5
0
void
mrb_print_error(mrb_state *mrb)
{
#ifdef ENABLE_STDIO
  mrb_value s;
  
  mrb_print_backtrace(mrb);
  s = mrb_funcall(mrb, mrb_obj_value(mrb->exc), "inspect", 0);
  if (mrb_string_p(s)) {
    struct RString *str = mrb_str_ptr(s);
    fwrite(str->ptr, str->len, 1, stderr);
    putc('\n', stderr);
  }
#endif
}
Example #6
0
mrb_value
mrb_any_to_s(mrb_state *mrb, mrb_value obj)
{
  const char *cname = mrb_obj_classname(mrb, obj);
  size_t len;
  mrb_value str;
  struct RString *s;

  len = strlen(cname)+6+16;
  str = mrb_str_new(mrb, 0, len); /* 6:tags 16:addr */
  s = mrb_str_ptr(str);
  s->len = sprintf(s->ptr, "#<%s:0x%lx>", cname, (unsigned long)(obj.value.p));

  return str;
}
Example #7
0
File: state.c Project: herumi/mruby
mrb_value
mrb_str_pool(mrb_state *mrb, mrb_value str)
{
  struct RString *s = mrb_str_ptr(str);
  struct RString *ns;
  char *ptr;
  mrb_int len;

  ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
  ns->tt = MRB_TT_STRING;
  ns->c = mrb->string_class;

  if (s->flags & MRB_STR_EMBED)
    len = (mrb_int)((s->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT);
  else
mrb_value
cfunc_pointer_to_s(mrb_state *mrb, mrb_value self)
{
    struct cfunc_type_data *data = DATA_PTR(self);
    size_t len;
    mrb_value str;
    struct RString *s;
    const char* p = (const char*)get_cfunc_pointer_data(data);
        
    len = strlen(p);
    str = mrb_str_new(mrb, 0, len);
    s = mrb_str_ptr(str);
    strcpy(s->ptr, p);
    s->len = strlen(s->ptr);
    return str;
}
Example #9
0
File: state.c Project: herumi/mruby
void
mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
{
  size_t i;

  if (!(irep->flags & MRB_ISEQ_NO_FREE))
    mrb_free(mrb, irep->iseq);
  for (i=0; i<irep->plen; i++) {
    if (mrb_type(irep->pool[i]) == MRB_TT_STRING) {
      if ((mrb_str_ptr(irep->pool[i])->flags & (MRB_STR_NOFREE|MRB_STR_EMBED)) == 0) {
        mrb_free(mrb, RSTRING_PTR(irep->pool[i]));
      }
      mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
    }
#ifdef MRB_WORD_BOXING
    else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) {
      mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
    }
#endif
  }
  mrb_free(mrb, irep->pool);
  mrb_free(mrb, irep->syms);
  for (i=0; i<irep->rlen; i++) {
    mrb_irep_decref(mrb, irep->reps[i]);
  }
  mrb_free(mrb, irep->reps);
  mrb_free(mrb, (void *)irep->filename);
  mrb_free(mrb, irep->lines);
  mrb_free(mrb, irep->prof_info);
  if (irep->jit_entry_tab) {
    int i;
    int j;

    for (i = 0; i < irep->ilen; i++) {
      for (j = 0; j < irep->jit_entry_tab[i].size; j++) {
	if (irep->jit_entry_tab[i].body[j].reginfo) {
	  mrb_free(mrb, irep->jit_entry_tab[i].body[j].reginfo);
	}
      }
    }
    mrb_free(mrb, irep->jit_entry_tab->body);
    mrb_free(mrb, irep->jit_entry_tab);
  }
  mrb_debug_info_free(mrb, irep->debug_info);
  mrb_free(mrb, irep);
}
Example #10
0
static mrb_value
mrb_str_setbyte(mrb_state *mrb, mrb_value str)
{
  mrb_int pos, byte;
  long len = RSTRING_LEN(str);

  mrb_get_args(mrb, "ii", &pos, &byte);

  if (pos < -len || len <= pos)
    mrb_raisef(mrb, E_INDEX_ERROR, "index %S is out of array", mrb_fixnum_value(pos));
  if (pos < 0)
    pos += len;

  mrb_str_modify(mrb, mrb_str_ptr(str));
  byte &= 0xff;
  RSTRING_PTR(str)[pos] = byte;
  return mrb_fixnum_value((unsigned char)byte);
}
Example #11
0
static void ngx_mrb_raise_file_error(mrb_state *mrb, mrb_value obj, ngx_http_request_t *r, char *code_file)
{  
    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;
        ngx_log_error(NGX_LOG_ERR
            , r->connection->log
            , 0
            , "mrb_run failed. file: %s error: %s"
            , code_file
            , err_out
        );
    }
}
Example #12
0
mrb_value
mrb_any_to_s(mrb_state *mrb, mrb_value obj)
{
  const char *cname = mrb_obj_classname(mrb, obj);
  size_t len;
  mrb_value str;
  struct RString *s;

  len = strlen(cname)+6+16;
  str = mrb_str_new(mrb, 0, len); /* 6:tags 16:addr */
  s = mrb_str_ptr(str);
  //  snprintf(RSTRING(str)->ptr, len+1, "#<%s:0x%lx>", cname, obj);
  sprintf(s->buf, "#<%s:0x%lx>", cname, (unsigned long)(obj.value.p));
  s->len = strlen(s->buf);
  /*if (OBJ_TAINTED(obj)) OBJ_TAINT(str);*/

  return str;
}
Example #13
0
mrb_value
printstr(mrb_state *mrb, mrb_value obj)
{
  struct RString *str;
  char *s;
  size_t len;

  if (mrb_type(obj) == MRB_TT_STRING) {
    str = mrb_str_ptr(obj);
    s = str->buf;
    len = str->len;
    while (len--) {
      putc(*s, stdout);
      s++;
    }
  }
  return obj;
}
Example #14
0
void
mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
{
  const struct types *type = builtin_types;
  struct RString *s;
  int xt;

  /*if (x == Qundef) {
    //mrb_bug("undef leaked to the Ruby space");
    printf ("undef leaked to the Ruby space\n");
  }*/

  xt = mrb_type(x);
  if ((xt != t) || (xt == MRB_TT_DATA)) {
    while (type->type < MRB_TT_MAXDEFINE) {
      if (type->type == t) {
        const char *etype;

        if (mrb_nil_p(x)) {
          etype = "nil";
        }
        else if (mrb_type(x) == MRB_TT_FIXNUM) {
          etype = "Fixnum";
        }
        else if (mrb_type(x) == MRB_TT_SYMBOL) {
          etype = "Symbol";
        }
        else if (mrb_special_const_p(x)) {
          s = mrb_str_ptr(mrb_obj_as_string(mrb, x));
          etype = s->buf;
        }
        else {
          etype = mrb_obj_classname(mrb, x);
        }
        mrb_raise(mrb, E_TYPE_ERROR, "wrong argument type %s (expected %s)",
          etype, type->name);
      }
      type++;
    }
    /*mrb_bug("unknown type 0x%x", t);*/
    printf ("unknown type 0x%x (0x%x given)", t, mrb_type(x));
  }
}
Example #15
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
       );
   }
}
Example #16
0
void
mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t)
{
  const struct types *type = builtin_types;
  struct RString *s;
  enum mrb_vtype xt;

  xt = mrb_type(x);
  if ((xt != t) || (xt == MRB_TT_DATA)) {
    while (type->type < MRB_TT_MAXDEFINE) {
      if (type->type == t) {
        const char *etype;

        if (mrb_nil_p(x)) {
          etype = "nil";
        }
        else if (mrb_fixnum_p(x)) {
          etype = "Fixnum";
        }
        else if (mrb_type(x) == MRB_TT_SYMBOL) {
          etype = "Symbol";
        }
        else if (mrb_special_const_p(x)) {
          s = mrb_str_ptr(mrb_obj_as_string(mrb, x));
          etype = s->ptr;
        }
        else {
          etype = mrb_obj_classname(mrb, x);
        }
        mrb_raisef(mrb, E_TYPE_ERROR, "wrong argument type %S (expected %S)",
                   mrb_str_new_cstr(mrb, etype), mrb_str_new_cstr(mrb, type->name));
      }
      type++;
    }
    mrb_raisef(mrb, E_TYPE_ERROR, "unknown type %S (%S given)",
               mrb_fixnum_value(t), mrb_fixnum_value(mrb_type(x)));
  }
}
Example #17
0
File: io.c Project: asfluido/mruby
int
mrb_cloexec_open(mrb_state *mrb, const char *pathname, mrb_int flags, mrb_int mode)
{
  mrb_value emsg;
  int fd, retry = FALSE;
  char* fname = mrb_locale_from_utf8(pathname, -1);

#ifdef O_CLOEXEC
  /* O_CLOEXEC is available since Linux 2.6.23.  Linux 2.6.18 silently ignore it. */
  flags |= O_CLOEXEC;
#elif defined O_NOINHERIT
  flags |= O_NOINHERIT;
#endif
reopen:
  fd = open(fname, (int)flags, (fmode_t)mode);
  if (fd == -1) {
    if (!retry) {
      switch (errno) {
        case ENFILE:
        case EMFILE:
        mrb_garbage_collect(mrb);
        retry = TRUE;
        goto reopen;
      }
    }

    emsg = mrb_format(mrb, "open %S", mrb_str_new_cstr(mrb, pathname));
    mrb_str_modify(mrb, mrb_str_ptr(emsg));
    mrb_sys_fail(mrb, RSTRING_PTR(emsg));
  }
  mrb_locale_free(fname);

  if (fd <= 2) {
    mrb_fd_cloexec(mrb, fd);
  }
  return fd;
}
Example #18
0
/*
  retrieve arguments from mrb_state.

  mrb_get_args(mrb, format, ...)
  
  returns number of arguments parsed.

  fortmat specifiers:

   o: Object [mrb_value]
   S: String [mrb_value]
   A: Array [mrb_value]
   H: Hash [mrb_value]
   s: String [char*,int]
   z: String [char*]
   a: Array [mrb_value*,int]
   f: Float [mrb_float]
   i: Integer [mrb_int]
   n: Symbol [mrb_sym]
   &: Block [mrb_value]
   *: rest argument [mrb_value*,int]
   |: optional
 */
int
mrb_get_args(mrb_state *mrb, const char *format, ...)
{
  char c;
  int i = 0;
  mrb_value *sp = mrb->stack + 1;
  va_list ap;
  int argc = mrb->ci->argc;
  int opt = 0;

  va_start(ap, format);
  if (argc < 0) {
    struct RArray *a = mrb_ary_ptr(mrb->stack[1]);

    argc = a->len;
    sp = a->ptr;
  }
  while ((c = *format++)) {
    switch (c) {
    case '|': case '*': case '&':
      break;
    default:
      if (argc <= i && !opt) {
	mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
      }
    }

    switch (c) {
    case 'o':
      {
        mrb_value *p;

        p = va_arg(ap, mrb_value*);
	if (i < argc) {
	  *p = *sp++;
	  i++;
	}
      }
      break;
    case 'S':
      {
        mrb_value *p;

        p = va_arg(ap, mrb_value*);
	if (i < argc) {
	  *p = to_str(mrb, *sp++);
	  i++;
	}
      }
      break;
    case 'A':
      {
        mrb_value *p;

        p = va_arg(ap, mrb_value*);
	if (i < argc) {
	  *p = to_ary(mrb, *sp++);
	  i++;
	}
      }
      break;
    case 'H':
      {
        mrb_value *p;

        p = va_arg(ap, mrb_value*);
	if (i < argc) {
	  *p = to_hash(mrb, *sp++);
	  i++;
	}
      }
      break;
    case 's':
      {
	mrb_value ss;
        struct RString *s;
        char **ps = 0;
        int *pl = 0;

	ps = va_arg(ap, char**);
	pl = va_arg(ap, int*);
	if (i < argc) {
	  ss = to_str(mrb, *sp++);
	  s = mrb_str_ptr(ss);
	  *ps = s->ptr;
	  *pl = s->len;
	  i++;
	}
      }
      break;
    case 'z':
      {
	mrb_value ss;
        struct RString *s;
        char **ps;

	ps = va_arg(ap, char**);
	if (i < argc) {
	  ss = to_str(mrb, *sp++);
	  s = mrb_str_ptr(ss);
	  if (strlen(s->ptr) != s->len) {
	    mrb_raise(mrb, E_ARGUMENT_ERROR, "String contains NUL");
	  }
	  *ps = s->ptr;
	  i++;
	}
      }
      break;
    case 'a':
      {
	mrb_value aa;
        struct RArray *a;
        mrb_value **pb;
        int *pl;

	pb = va_arg(ap, mrb_value**);
	pl = va_arg(ap, int*);
	if (i < argc) {
	  aa = to_ary(mrb, *sp++);
	  a = mrb_ary_ptr(aa);
	  *pb = a->ptr;
	  *pl = a->len;
	  i++;
	}
      }
      break;
    case 'f':
      {
        mrb_float *p;

        p = va_arg(ap, mrb_float*);
	if (i < argc) {
	  switch (mrb_type(*sp)) {
	  case MRB_TT_FLOAT:
	    *p = mrb_float(*sp);
	    break;
	  case MRB_TT_FIXNUM:
	    *p = (mrb_float)mrb_fixnum(*sp);
	    break;
	  case MRB_TT_STRING:
	    mrb_raise(mrb, E_TYPE_ERROR, "String can't be coerced into Float");
	    break;
	  default:
	    {
	      mrb_value tmp;

	      tmp = mrb_convert_type(mrb, *sp, MRB_TT_FLOAT, "Float", "to_f");
	      *p = mrb_float(tmp);
	    }
	    break;
	  }
	  sp++;
	  i++;
	}
      }
      break;
    case 'i':
      {
        mrb_int *p;

        p = va_arg(ap, mrb_int*);
	if (i < argc) {
	  switch (mrb_type(*sp)) {
	  case MRB_TT_FIXNUM:
	    *p = mrb_fixnum(*sp);
	    break;
	  case MRB_TT_FLOAT:
	    {
	      mrb_float f = mrb_float(*sp);

	      if (!FIXABLE(f)) {
		mrb_raise(mrb, E_RANGE_ERROR, "float too big for int");
	      }
	      *p = (mrb_int)f;
	    }
	    break;
	  case MRB_TT_FALSE:
	    *p = 0;
	    break;
	  default:
	    {
	      mrb_value tmp;

	      tmp = mrb_convert_type(mrb, *sp, MRB_TT_FIXNUM, "Integer", "to_int");
	      *p = mrb_fixnum(tmp);
	    }
	    break;
	  }
	  sp++;
	  i++;
	}
      }
      break;
    case 'n':
      {
	mrb_sym *symp;

	symp = va_arg(ap, mrb_sym*);
	if (i < argc) {
	  mrb_value ss;

	  ss = *sp++;
	  if (mrb_type(ss) == MRB_TT_SYMBOL) {
	    *symp = mrb_symbol(ss);
	  }
	  else {
	    *symp = mrb_intern_str(mrb, to_str(mrb, ss));
	  }
	  i++;
	}
      }
      break;

    case '&':
      {
        mrb_value *p, *bp;

        p = va_arg(ap, mrb_value*);
        if (mrb->ci->argc < 0) {
          bp = mrb->stack + 2;
        }
	else {
          bp = mrb->stack + mrb->ci->argc + 1;
	}
        *p = *bp;
      }
      break;
    case '|':
      opt = 1;
      break;

    case '*':
      {
        mrb_value **var;
	int *pl;

        var = va_arg(ap, mrb_value**);
        pl = va_arg(ap, int*);
        if (argc > i) {
          *pl = argc-i;
          if (*pl > 0) {
	    *var = sp;
            i = argc;
          }
	  i = argc;
	  sp += *pl;
        }
        else {
          *pl = 0;
          *var = NULL;
        }
      }
      break;
    default:
      mrb_raisef(mrb, E_ARGUMENT_ERROR, "invalid argument specifier %c", c);
      break;
    }
  }
  if (!c && argc > i) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
  }
  va_end(ap);
  return i;
}
Example #19
0
int
mrb_get_args(mrb_state *mrb, const char *format, ...)
{
  char c;
  int i=0;
  mrb_value *sp = mrb->stack + 1;
  va_list ap;
  int argc = mrb->ci->argc;
  int *argcp;

  va_start(ap, format);
  if (argc < 0) {
    struct RArray *a = mrb_ary_ptr(mrb->stack[1]);

    argc = a->len;
    sp = a->buf;
  }
  while ((c = *format++)) {
    switch (c) {
    case 'o':
      {
        mrb_value *p;
        p = va_arg(ap, mrb_value*);
        *p =  *sp;
        i++; sp++;
      }
      break;
    case 'i':
      {
        mrb_int *p;

        p = va_arg(ap, mrb_int*);
        switch (sp->tt) {
        case MRB_TT_FIXNUM:
          *p = mrb_fixnum(*sp);
          break;
        case MRB_TT_FLOAT:
          *p = (mrb_int)mrb_float(*sp);
          break;
        case MRB_TT_FALSE:
          *p = 0;
          break;
        default:
	  {
	    mrb_value tmp;

	    tmp = mrb_convert_type(mrb, *sp, MRB_TT_FIXNUM, "Integer", "to_int");
	    *p = mrb_fixnum(tmp);
	  }
          break;
        }
        i++; sp++;
      }
      break;
    case 'f':
      {
        mrb_float *p;

        p = va_arg(ap, mrb_float*);
        switch (sp->tt) {
        case MRB_TT_FLOAT:
          *p = mrb_float(*sp);
          break;
        case MRB_TT_FIXNUM:
          *p = (mrb_float)mrb_fixnum(*sp);
          break;
        case MRB_TT_FALSE:
          *p = 0.0;
          break;
        default:
	  {
	    mrb_value tmp;

	    tmp = mrb_convert_type(mrb, *sp, MRB_TT_FLOAT, "Float", "to_f");
	    *p = mrb_float(tmp);
	  }
          break;
        }
        i++; sp++;
      }
      break;
    case 's':
      {
        char **ps = 0;
        size_t *pl = 0;
        struct RString *s;

        if (argc > i) {
          s = mrb_str_ptr(*sp);
          ps = va_arg(ap, char**);
          *ps = s->buf;
          pl = va_arg(ap, size_t*);
          *pl = s->len;
        }
        i++; sp++;
      }
      break;
    case 'a':
      {
        mrb_value *var;
        var = va_arg(ap, mrb_value*);
        if (argc > i) {
          if (var) {
            memcpy(var, sp, sizeof(mrb_value)*(argc-i));
          }
          //i = mrb->argc;
        }
        else {
          if (var) *var = mrb_ary_new(mrb);
        }
        argcp = va_arg(ap, int*);
        *argcp = argc-i;
        goto last_var;
      }
      break;
    case 'b':
      {
        struct RProc **p;
        mrb_value *bp = mrb->stack + 1;

        p = va_arg(ap, struct RProc**);
        if (mrb->ci->argc > 0) {
          bp += mrb->ci->argc;
        }
        if (mrb_nil_p(*bp)) *p = 0;
        else *p = mrb_proc_ptr(*bp);
      }
      break;
    case '&':
      {
        mrb_value *p, *bp = mrb->stack + 1;

        p = va_arg(ap, mrb_value*);
        if (mrb->ci->argc > 0) {
          bp += mrb->ci->argc;
        }
        *p = *bp;
      }
      break;
    case '*':
      {
        mrb_value **var;
        var = va_arg(ap, mrb_value**);
        argcp = va_arg(ap, int*);
        if (argc > i) {
          *argcp = argc-i;
          if (*argcp > 0) {
            if (var) {
              *var = sp;
            }
            i += *argcp;
          }
        }
        else {
          *argcp = 0;
          *var = NULL;
        }
        goto last_var;
      }
      break;
    }
  }
Example #20
0
/*
  retrieve arguments from mrb_state.

  mrb_get_args(mrb, format, ...)
  
  returns number of arguments parsed.

  fortmat specifiers:

   o: Object [mrb_value]
   S: String [mrb_value]
   A: Array [mrb_value]
   H: Hash [mrb_value]
   s: String [char*,int]
   z: String [char*]
   a: Array [mrb_value*,int]
   f: Float [mrb_float]
   i: Integer [mrb_int]
   &: Block [mrb_value]
   *: rest argument [mrb_value*,int]
   |: optional
 */
int
mrb_get_args(mrb_state *mrb, const char *format, ...)
{
  char c;
  int i = 0;
  mrb_value *sp = mrb->stack + 1;
  va_list ap;
  int argc = mrb->ci->argc;
  int opt = 0;

  va_start(ap, format);
  if (argc < 0) {
    struct RArray *a = mrb_ary_ptr(mrb->stack[1]);

    argc = a->len;
    sp = a->buf;
  }
  while ((c = *format++)) {
    switch (c) {
    case '|': case '*': case '&':
      break;
    default:
      if (argc <= i) {
	if (opt) continue;
	mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
      }
    }

    switch (c) {
    case 'o':
      {
        mrb_value *p;

        p = va_arg(ap, mrb_value*);
        *p =  *sp;
        i++; sp++;
      }
      break;
    case 'S':
      {
        mrb_value *p;

        p = va_arg(ap, mrb_value*);
	*p = to_str(mrb, *sp);
        i++; sp++;
      }
      break;
    case 'A':
      {
        mrb_value *p;

        p = va_arg(ap, mrb_value*);
	*p = to_ary(mrb, *sp);
        i++; sp++;
      }
      break;
    case 'H':
      {
        mrb_value *p;

        p = va_arg(ap, mrb_value*);
	*p = to_hash(mrb, *sp);
        i++; sp++;
      }
      break;
    case 's':
      {
	mrb_value ss;
        struct RString *s;
        char **ps = 0;
        int *pl = 0;

	ss = to_str(mrb, *sp);
	s = mrb_str_ptr(ss);
	ps = va_arg(ap, char**);
	*ps = s->buf;
	pl = va_arg(ap, int*);
	*pl = s->len;
        i++; sp++;
      }
      break;
    case 'z':
      {
	mrb_value ss;
        struct RString *s;
        char **ps;

	ss = to_str(mrb, *sp);
	s = mrb_str_ptr(ss);
	if (strlen(s->buf) != s->len) {
	  mrb_raise(mrb, E_ARGUMENT_ERROR, "String contains NUL");
	}
	ps = va_arg(ap, char**);
	*ps = s->buf;
        i++; sp++;
      }
      break;
    case 'a':
      {
	mrb_value aa;
        struct RArray *a;
        mrb_value **pb;
        int *pl;

	aa = to_ary(mrb, *sp);
	a = mrb_ary_ptr(aa);
	pb = va_arg(ap, mrb_value**);
	*pb = a->buf;
	pl = va_arg(ap, int*);
	*pl = a->len;
        i++; sp++;
      }
      break;
    case 'f':
      {
        mrb_float *p;

        p = va_arg(ap, mrb_float*);
        switch (sp->tt) {
        case MRB_TT_FLOAT:
          *p = mrb_float(*sp);
          break;
        case MRB_TT_FIXNUM:
          *p = (mrb_float)mrb_fixnum(*sp);
          break;
        case MRB_TT_FALSE:
          *p = 0.0;
          break;
        default:
	  {
	    mrb_value tmp;

	    tmp = mrb_convert_type(mrb, *sp, MRB_TT_FLOAT, "Float", "to_f");
	    *p = mrb_float(tmp);
	  }
          break;
        }
        i++; sp++;
      }
      break;
    case 'i':
      {
        mrb_int *p;

        p = va_arg(ap, mrb_int*);
        switch (sp->tt) {
        case MRB_TT_FIXNUM:
          *p = mrb_fixnum(*sp);
          break;
        case MRB_TT_FLOAT:
          *p = (mrb_int)mrb_float(*sp);
          break;
        case MRB_TT_FALSE:
          *p = 0;
          break;
        default:
	  {
	    mrb_value tmp;

	    tmp = mrb_convert_type(mrb, *sp, MRB_TT_FIXNUM, "Integer", "to_int");
	    *p = mrb_fixnum(tmp);
	  }
          break;
        }
        i++; sp++;
      }
      break;

    case '&':
      {
        mrb_value *p, *bp = mrb->stack + 1;

        p = va_arg(ap, mrb_value*);
        if (mrb->ci->argc > 0) {
          bp += mrb->ci->argc;
        }
        *p = *bp;
      }
      break;
    case '|':
      opt = 1;
      break;

    case '*':
      {
        mrb_value **var;
	int *pl;

        var = va_arg(ap, mrb_value**);
        pl = va_arg(ap, int*);
        if (argc > i) {
          *pl = argc-i;
          if (*pl > 0) {
	    *var = sp;
            i = argc;
          }
	  i = argc;
	  sp += *pl;
        }
        else {
          *pl = 0;
          *var = NULL;
        }
      }
      break;
    }
  }
  if (!c && argc > i) {
    mrb_raise(mrb, E_ARGUMENT_ERROR, "wrong number of arguments");
  }
  va_end(ap);
  return i;
}
Example #21
0
/*
 *  call-seq:
 *     string.succ    ->  string
 *
 *  Returns next sequence of the string;
 *
 *     a = "abc"
 *     a.succ    #=> "abd"
 */
static mrb_value
mrb_str_succ_bang(mrb_state *mrb, mrb_value self)
{
  mrb_value result;
  unsigned char *p, *e, *b, *t;
  const char *prepend;
  struct RString *s = mrb_str_ptr(self);
  size_t l;

  if (RSTRING_LEN(self) == 0)
    return self;

  mrb_str_modify(mrb, s);
  l = RSTRING_LEN(self);
  b = p = (unsigned char*) RSTRING_PTR(self);
  t = e = p + l;
  *(e--) = 0;

  // find trailing ascii/number
  while (e >= b) {
    if (ISALNUM(*e))
      break;
    e--;
  }
  if (e < b) {
    e = p + l - 1;
    result = mrb_str_new_lit(mrb, "");
  } else {
    // find leading letter of the ascii/number
    b = e;
    while (b > p) {
      if (!ISALNUM(*b) || (ISALNUM(*b) && *b != '9' && *b != 'z' && *b != 'Z'))
        break;
      b--;
    }
    if (!ISALNUM(*b))
      b++;
    result = mrb_str_new(mrb, (char*) p, b - p);
  }

  while (e >= b) {
    if (!ISALNUM(*e)) {
      if (*e == 0xff) {
        mrb_str_cat_lit(mrb, result, "\x01");
        (*e) = 0;
      } else
        (*e)++;
      break;
    }
    prepend = NULL;
    if (*e == '9') {
      if (e == b) prepend = "1";
      *e = '0';
    } else if (*e == 'z') {
      if (e == b) prepend = "a";
      *e = 'a';
    } else if (*e == 'Z') {
      if (e == b) prepend = "A";
      *e = 'A';
    } else {
      (*e)++;
      break;
    }
    if (prepend) mrb_str_cat_cstr(mrb, result, prepend);
    e--;
  }
  result = mrb_str_cat(mrb, result, (char*) b, t - b);
  l = RSTRING_LEN(result);
  mrb_str_resize(mrb, self, l);
  memcpy(RSTRING_PTR(self), RSTRING_PTR(result), l);
  return self;
}