/** * call-seq: * search(*queries, ...) → an_array * * Search the database with POSIX regular expressions for packages. * === Parameters * [*queries (splat)] * A list of strings interpreted as POSIX regular expressions. * For a package to be found, it must match _all_ queries terms, * not just a single one. Each query is matched against both * the package name and the package description, where only * one needs to match for the package to be considered. * * Note that the match is not performed by Ruby or even Oniguruma/Onigmo, * but directly in libalpm via the +regexp+ library in C. * * === Return value * An array of Package instances whose names matched _all_ regular expressions. */ static VALUE search(int argc, VALUE argv[], VALUE self) { alpm_db_t* p_db = NULL; alpm_list_t* targets = NULL; alpm_list_t* packages = NULL; alpm_list_t* item = NULL; VALUE result = rb_ary_new(); int i; Data_Get_Struct(self, alpm_db_t, p_db); /* Convert our Ruby array to an alpm_list with C strings */ for(i=0; i < argc; i++) { VALUE term = rb_check_string_type(argv[i]); if (!RTEST(term)) { rb_raise(rb_eTypeError, "Argument is not a string (#to_str)"); return Qnil; } targets = alpm_list_add(targets, StringValuePtr(term)); } /* Perform the query */ packages = alpm_db_search(p_db, targets); if (!packages) return result; for(item=packages; item; item = alpm_list_next(item)) rb_ary_push(result, Data_Wrap_Struct(rb_cAlpm_Package, NULL, NULL, item->data)); alpm_list_free(targets); return result; }
/* Foo = Numo::Struct.new { int8 :byte float64 :float, [2,2] dcomplex :compl } */ static VALUE nst_s_new(int argc, VALUE *argv, VALUE klass) { VALUE name=Qnil, rest, size; VALUE st, members; ID id; rb_scan_args(argc, argv, "0*", &rest); if (RARRAY_LEN(rest)>0) { name = RARRAY_AREF(rest,0); if (!NIL_P(name)) { VALUE tmp = rb_check_string_type(name); if (!NIL_P(tmp)) { rb_ary_shift(rest); } else { name = Qnil; } } } if (NIL_P(name)) { st = rb_define_class_id(name, klass); rb_funcall(klass, rb_intern("inherited"), 1, st); } else { char *cname = StringValuePtr(name); id = rb_intern(cname); if (!rb_is_const_id(id)) { rb_name_error(id, "identifier %s needs to be constant", cname); } if (rb_const_defined_at(klass, id)) { rb_warn("redefining constant Struct::%s", cname); rb_mod_remove_const(klass, ID2SYM(id)); } st = rb_define_class_under(klass, rb_id2name(id), klass); } rb_iv_set(st, "__members__", rb_ary_new()); rb_iv_set(st, "__offset__", INT2FIX(0)); if (rb_block_given_p()) { rb_mod_module_eval(0, 0, st); } size = rb_iv_get(st, "__offset__"); members = rb_iv_get(st, "__members__"); //printf("size=%d\n",NUM2INT(size)); rb_define_const(st, CONTIGUOUS_STRIDE, size); rb_define_const(st, ELEMENT_BYTE_SIZE, size); rb_define_const(st, ELEMENT_BIT_SIZE, rb_funcall(size,'*',1,INT2FIX(8))); OBJ_FREEZE(members); rb_define_const(st, "DEFINITIONS", members); rb_define_singleton_method(st, "new", rb_class_new_instance, -1); //rb_define_singleton_method(st, "[]", rb_class_new_instance, -1); rb_define_method(st, "allocate", nst_allocate, 0); return st; }
static VALUE format_message(VALUE exc) { CFMutableStringRef result = CFStringCreateMutable(NULL, 0); VALUE message = rb_vm_call(exc, sel_registerName("message"), 0, NULL); VALUE bt = rb_vm_call(exc, sel_registerName("backtrace"), 0, NULL); message = rb_check_string_type(message); const char *msg = message == Qnil ? "" : RSTRING_PTR(message); const long count = (bt != Qnil ? RARRAY_LEN(bt) : 0); if (count > 0) { for (long i = 0; i < count; i++) { const char *bte = RSTRING_PTR(RARRAY_AT(bt, i)); if (i == 0) { CFStringAppendFormat(result, NULL, CFSTR("%s: %s (%s)\n"), bte, msg, rb_class2name(*(VALUE *)exc)); } else { CFStringAppendFormat(result, NULL, CFSTR("\tfrom %s\n"), bte); } } } else { CFStringAppendFormat(result, NULL, CFSTR("%s (%s)\n"), msg, rb_class2name(*(VALUE *)exc)); } CFMakeCollectable(result); return (VALUE)result; }
/* * call-seq: * context.find("xpath") -> true|false|number|string|XML::XPath::Object * * Executes the provided xpath function. The result depends on the execution * of the xpath statement. It may be true, false, a number, a string or * a node set. */ static VALUE rxml_xpath_context_find(VALUE self, VALUE xpath_expr) { xmlXPathContextPtr xctxt; xmlXPathObjectPtr xobject; xmlXPathCompExprPtr xcompexpr; Data_Get_Struct(self, xmlXPathContext, xctxt); if (TYPE(xpath_expr) == T_STRING) { VALUE expression = rb_check_string_type(xpath_expr); xobject = xmlXPathEval((xmlChar*) StringValueCStr(expression), xctxt); } else if (rb_obj_is_kind_of(xpath_expr, cXMLXPathExpression)) { Data_Get_Struct(xpath_expr, xmlXPathCompExpr, xcompexpr); xobject = xmlXPathCompiledEval(xcompexpr, xctxt); } else { rb_raise(rb_eTypeError, "Argument should be an intance of a String or XPath::Expression"); } return rxml_xpath_to_value(xctxt, xobject); }
static VALUE rbreg_get(VALUE, VALUE rname) { lwc::Registry *reg = lwc::Registry::Instance(); if (!reg) { rb_raise(rb_eRuntimeError, "lwc::Registry has not yet been initialized"); } VALUE sname = rb_check_string_type(rname); if (NIL_P(sname)) { rb_raise(rb_eTypeError, "RLWC::Registry.get expects a string as argument"); } char *name = RSTRING(sname)->ptr; lwc::Object *obj = reg->get(name); if (!obj) { return Qnil; } else { VALUE rv = Qnil; //if (!strcmp(obj->getLoaderName(), "rbloader")) { // rv = ((Object*)obj)->self(); // //} else { rv = rb_funcall2(cLWCObject, rb_intern("new"), 0, NULL); SetObjectPointer(rv, obj); //} return rv; } }
static sighandler_t trap_handler(VALUE *cmd, int sig) { sighandler_t func = sighandler; VALUE command; if (NIL_P(*cmd)) { func = SIG_IGN; } else { command = rb_check_string_type(*cmd); if (!NIL_P(command)) { SafeStringValue(command); /* taint check */ *cmd = command; switch (RSTRING_LEN(command)) { case 0: goto sig_ign; break; case 14: if (strncmp(RSTRING_PTR(command), "SYSTEM_DEFAULT", 14) == 0) { func = SIG_DFL; *cmd = 0; } break; case 7: if (strncmp(RSTRING_PTR(command), "SIG_IGN", 7) == 0) { sig_ign: func = SIG_IGN; *cmd = 0; } else if (strncmp(RSTRING_PTR(command), "SIG_DFL", 7) == 0) { sig_dfl: func = default_handler(sig); *cmd = 0; } else if (strncmp(RSTRING_PTR(command), "DEFAULT", 7) == 0) { goto sig_dfl; } break; case 6: if (strncmp(RSTRING_PTR(command), "IGNORE", 6) == 0) { goto sig_ign; } break; case 4: if (strncmp(RSTRING_PTR(command), "EXIT", 4) == 0) { *cmd = Qundef; } break; } } else { rb_proc_t *proc; GetProcPtr(*cmd, proc); } } return func; }
/* @overload rindex(pattern, offset = -1) * * Returns the maximal index of the receiver where PATTERN matches, equal to * or less than _i_, where _i_ = OFFSET if OFFSET ≥ 0, _i_ = {#length} - * abs(OFFSET) otherwise, or nil if there is no match. * * If PATTERN is a Regexp, the Regexp special variables `$&`, `$'`, * <code>$\`</code>, `$1`, `$2`, …, `$`_n_ are updated accordingly. * * If PATTERN responds to `#to_str`, the matching is performed by a byte * comparison. * * @param [Regexp, #to_str] pattern * @param [#to_int] offset * @return [Integer, nil] * @see #index */ VALUE rb_u_string_rindex_m(int argc, VALUE *argv, VALUE self) { const struct rb_u_string *string = RVAL2USTRING(self); VALUE sub, rboffset; long offset; if (rb_scan_args(argc, argv, "11", &sub, &rboffset) == 2) offset = NUM2LONG(rboffset); else /* TODO: Why not simply use -1? Benchmark which is faster. */ offset = u_n_chars_n(USTRING_STR(string), USTRING_LENGTH(string)); const char *begin = rb_u_string_begin_from_offset(string, offset); const char *end = USTRING_END(string); if (begin == NULL) { if (offset <= 0) { if (TYPE(sub) == T_REGEXP) rb_backref_set(Qnil); return Qnil; } begin = end; /* TODO: this converting back and forward can be optimized away * if rb_u_string_index_regexp() and rb_u_string_rindex() were split up * into two additional functions, adding * rb_u_string_index_regexp_pointer() and rb_u_string_rindex_pointer(), * so that one can pass a pointer to start at immediately * instead of an offset that gets calculated into a pointer. */ offset = u_n_chars_n(USTRING_STR(string), USTRING_LENGTH(string)); } switch (TYPE(sub)) { case T_REGEXP: /* TODO: What’s this first test for, exactly? */ if (RREGEXP(sub)->ptr == NULL || RREGEXP_SRC_LEN(sub) > 0) offset = rb_u_string_index_regexp(self, begin, sub, true); break; default: { VALUE tmp = rb_check_string_type(sub); if (NIL_P(tmp)) rb_u_raise(rb_eTypeError, "type mismatch: %s given", rb_obj_classname(sub)); sub = tmp; } /* fall through */ case T_STRING: offset = rb_u_string_rindex(self, sub, offset); break; } if (offset < 0) return Qnil; return LONG2NUM(offset); }
/* * call-seq: * context.find("xpath") -> true|false|number|string|XML::XPath::Object * * Executes the provided xpath function. The result depends on the execution * of the xpath statement. It may be true, false, a number, a string or * a node set. */ static VALUE rxml_xpath_context_find(VALUE self, VALUE xpath_expr) { xmlXPathContextPtr xctxt; xmlXPathObjectPtr xobject; xmlXPathCompExprPtr xcompexpr; VALUE result; Data_Get_Struct(self, xmlXPathContext, xctxt); if (TYPE(xpath_expr) == T_STRING) { VALUE expression = rb_check_string_type(xpath_expr); xobject = xmlXPathEval((xmlChar*) StringValueCStr(expression), xctxt); } else if (rb_obj_is_kind_of(xpath_expr, cXMLXPathExpression)) { Data_Get_Struct(xpath_expr, xmlXPathCompExpr, xcompexpr); xobject = xmlXPathCompiledEval(xcompexpr, xctxt); } else { rb_raise(rb_eTypeError, "Argument should be an intance of a String or XPath::Expression"); } if (xobject == NULL) { /* xmlLastError is different than xctxt->lastError. Use xmlLastError since it has the message set while xctxt->lastError does not. */ xmlErrorPtr xerror = xmlGetLastError(); rxml_raise(xerror); } switch (xobject->type) { case XPATH_NODESET: result = rxml_xpath_object_wrap(xctxt->doc, xobject); break; case XPATH_BOOLEAN: result = (xobject->boolval != 0) ? Qtrue : Qfalse; xmlXPathFreeObject(xobject); break; case XPATH_NUMBER: result = rb_float_new(xobject->floatval); xmlXPathFreeObject(xobject); break; case XPATH_STRING: result = rb_str_new2((const char*)xobject->stringval); xmlXPathFreeObject(xobject); break; default: result = Qnil; xmlXPathFreeObject(xobject); } return result; }
static VALUE rbreg_hasType(VALUE, VALUE rname) { lwc::Registry *reg = lwc::Registry::Instance(); if (!reg) { rb_raise(rb_eRuntimeError, "lwc::Registry has not yet been initialized"); } VALUE sname = rb_check_string_type(rname); if (NIL_P(sname)) { rb_raise(rb_eTypeError, "RLWC::Registry.hasType expects a string as argument"); } char *name = RSTRING(sname)->ptr; return (reg->hasType(name) ? Qtrue : Qfalse); }
static VALUE rbreg_getDesc(VALUE, VALUE rname) { lwc::Registry *reg = lwc::Registry::Instance(); if (!reg) { rb_raise(rb_eRuntimeError, "lwc::Registry has not yet been initialized"); } VALUE sname = rb_check_string_type(rname); if (NIL_P(sname)) { rb_raise(rb_eTypeError, "RLWC::Registry.getDescription expects a string as argument"); } char *name = RSTRING(sname)->ptr; const char *desc = reg->getDescription(name); return rb_str_new2(desc ? desc : ""); }
static VALUE rbreg_addModulePath(VALUE self, VALUE rpath) { lwc::Registry *reg = lwc::Registry::Instance(); if (!reg) { rb_raise(rb_eRuntimeError, "lwc::Registry has not yet been initialized"); } VALUE spath = rb_check_string_type(rpath); if (NIL_P(spath)) { rb_raise(rb_eTypeError, "RLWC::Registry.addModulePath expects a string as argument"); } char *path = RSTRING(spath)->ptr; reg->addModulePath(path); return self; }
static VALUE rbreg_docString(int argc, VALUE *argv, VALUE) { if (argc < 1 || argc > 2) { rb_raise(rb_eArgError, "RLWC::Registry.docString accepts 1 or 2 arguments"); } lwc::Registry *reg = lwc::Registry::Instance(); if (!reg) { rb_raise(rb_eRuntimeError, "lwc::Registry has not yet been initialized"); } VALUE sname = rb_check_string_type(argv[0]); if (NIL_P(sname)) { rb_raise(rb_eTypeError, "RLWC::Registry.docString expects a string as first argument"); } char *name = RSTRING(sname)->ptr; std::string indent = ""; if (argc == 2) { VALUE sindent = rb_check_string_type(argv[1]); if (NIL_P(sindent)) { rb_raise(rb_eTypeError, "RLWC::Registry.docString expects a string as second argument"); } indent = RSTRING(sindent)->ptr; } return rb_str_new2(reg->docString(name, indent).c_str()); }
/* * call-seq: * xc.medialib_entry_property_set(id, key, value, *source) -> result * * Write info to the medialib at _id_. _source_ is an optional argument that * describes where to write the mediainfo. If _source_ is omitted, the * mediainfo is written to "client/<yourclient>" where <yourclient> is the * name you specified in _Xmms::Client.new(name)_. */ static VALUE c_medialib_entry_property_set (int argc, VALUE *argv, VALUE self) { VALUE tmp, key, value, src = Qnil; RbXmmsClient *xmms = NULL; xmmsc_result_t *res; const char *ckey; bool is_str = false; uint32_t id; int32_t ivalue; Data_Get_Struct (self, RbXmmsClient, xmms); CHECK_DELETED (xmms); rb_scan_args (argc, argv, "31", &tmp, &key, &value, &src); id = check_int32 (tmp); Check_Type (key, T_SYMBOL); if (!NIL_P (rb_check_string_type (value))) is_str = true; else ivalue = check_int32 (value); ckey = rb_id2name (SYM2ID (key)); if (NIL_P (src) && is_str) res = xmmsc_medialib_entry_property_set_str (xmms->real, id, ckey, StringValuePtr (value)); else if (NIL_P (src)) res = xmmsc_medialib_entry_property_set_int (xmms->real, id, ckey, ivalue); else if (is_str) res = xmmsc_medialib_entry_property_set_str_with_source ( xmms->real, id, StringValuePtr (src), ckey, StringValuePtr (value)); else res = xmmsc_medialib_entry_property_set_int_with_source ( xmms->real, id, StringValuePtr (src), ckey, ivalue); return TO_XMMS_CLIENT_RESULT (self, res); }
static VALUE range_each(VALUE range, SEL sel) { VALUE beg, end; RETURN_ENUMERATOR(range, 0, 0); beg = RANGE_BEG(range); end = RANGE_END(range); if (FIXNUM_P(beg) && FIXNUM_P(end)) { /* fixnums are special */ long lim = FIX2LONG(end); long i; if (!EXCL(range)) lim += 1; for (i = FIX2LONG(beg); i < lim; i++) { rb_yield(LONG2FIX(i)); RETURN_IF_BROKEN(); } } else if (SYMBOL_P(beg) && SYMBOL_P(end)) { /* symbols are special */ VALUE args[2]; args[0] = rb_sym_to_s(end); args[1] = EXCL(range) ? Qtrue : Qfalse; rb_objc_block_call(rb_sym_to_s(beg), selUpto, 2, args, sym_each_i, 0); } else { VALUE tmp = rb_check_string_type(beg); if (!NIL_P(tmp)) { VALUE args[2]; args[0] = end; args[1] = EXCL(range) ? Qtrue : Qfalse; rb_objc_block_call(beg, selUpto, 2, args, rb_yield, 0); } else { if (!discrete_object_p(beg)) { rb_raise(rb_eTypeError, "can't iterate from %s", rb_obj_classname(beg)); } range_each_func(range, each_i, NULL); } } return range; }
/* * call-seq: * pl.add_entry(arg) -> result * * Adds an entry to the playlist. _arg_ can be either a URL or an id. */ static VALUE c_add_entry (VALUE self, VALUE arg) { int32_t id; PLAYLIST_METHOD_HANDLER_HEADER if (!NIL_P (rb_check_string_type (arg))) res = xmmsc_playlist_add_url (xmms->real, pl->name, StringValuePtr (arg)); else { id = check_int32 (arg); res = xmmsc_playlist_add_id (xmms->real, pl->name, id); } PLAYLIST_METHOD_HANDLER_FOOTER }
int rb_to_encoding_index(VALUE enc) { int idx; idx = enc_check_encoding(enc); if (idx >= 0) { return idx; } else if (NIL_P(enc = rb_check_string_type(enc))) { return -1; } if (!rb_enc_asciicompat(rb_enc_get(enc))) { return -1; } return rb_enc_find_index(StringValueCStr(enc)); }
static VALUE rbreg_getMethods(VALUE, VALUE rname) { lwc::Registry *reg = lwc::Registry::Instance(); if (!reg) { rb_raise(rb_eRuntimeError, "lwc::Registry has not yet been initialized"); } VALUE sname = rb_check_string_type(rname); if (NIL_P(sname)) { rb_raise(rb_eTypeError, "RLWC::Registry.getMethods expects a string as argument"); } char *name = RSTRING(sname)->ptr; const lwc::MethodsTable *mt = reg->getMethods(name); if (!mt) { return Qnil; } else { VALUE rv = rb_funcall2(cLWCMethodsTable, rb_intern("new"), 0, NULL); RDATA(rv)->data = (void*) mt; return rv; } }
void rb_threadptr_error_print(rb_thread_t *volatile th, volatile VALUE errinfo) { volatile VALUE errat = Qundef; volatile int raised_flag = th->raised_flag; volatile VALUE eclass = Qundef, emesg = Qundef; if (NIL_P(errinfo)) return; rb_thread_raised_clear(th); TH_PUSH_TAG(th); if (TH_EXEC_TAG() == 0) { errat = rb_get_backtrace(errinfo); } else if (errat == Qundef) { errat = Qnil; } else if (eclass == Qundef || emesg != Qundef) { goto error; } if ((eclass = CLASS_OF(errinfo)) != Qundef) { VALUE e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0); if (e != Qundef) { if (!RB_TYPE_P(e, T_STRING)) e = rb_check_string_type(e); emesg = e; } } if (rb_stderr_tty_p()) { if (0) warn_print("Traceback (most recent call last):\n"); print_backtrace(eclass, errat, TRUE); print_errinfo(eclass, errat, emesg); } else { print_errinfo(eclass, errat, emesg); print_backtrace(eclass, errat, FALSE); } error: TH_POP_TAG(); th->errinfo = errinfo; rb_thread_raised_set(th, raised_flag); }
int rb_to_encoding_index(VALUE enc) { if (CLASS_OF(enc) != rb_cEncoding && TYPE(enc) != T_STRING) { return -1; } else { int idx = index_of_encoding((rb_encoding_t *)enc); if (idx >= 0) { return idx; } else if (NIL_P(enc = rb_check_string_type(enc))) { return -1; } if (!rb_enc_asciicompat(rb_enc_get(enc))) { return -1; } return rb_enc_find_index(StringValueCStr(enc)); } }
/* @overload index(pattern, offset = 0) * * Returns the minimal index of the receiver where PATTERN matches, equal to or * greater than _i_, where _i_ = OFFSET if OFFSET ≥ 0, _i_ = {#length} - * abs(OFFSET) otherwise, or nil if there is no match. * * If PATTERN is a Regexp, the Regexp special variables `$&`, `$'`, * <code>$\`</code>, `$1`, `$2`, …, `$`_n_ are updated accordingly. * * If PATTERN responds to #to_str, the matching is performed by byte * comparison. * * @param [Regexp, #to_str] pattern * @param [#to_int] offset * @return [Integer, nil] * @see #rindex */ VALUE rb_u_string_index_m(int argc, VALUE *argv, VALUE self) { VALUE sub, rboffset; long offset = 0; if (rb_scan_args(argc, argv, "11", &sub, &rboffset) == 2) offset = NUM2LONG(rboffset); const struct rb_u_string *string = RVAL2USTRING(self); const char *begin = rb_u_string_begin_from_offset(string, offset); if (begin == NULL) { if (TYPE(sub) == T_REGEXP) rb_backref_set(Qnil); return Qnil; } switch (TYPE(sub)) { case T_REGEXP: offset = rb_u_string_index_regexp(self, begin, sub, false); break; default: { VALUE tmp = rb_check_string_type(sub); if (NIL_P(tmp)) rb_u_raise(rb_eTypeError, "type mismatch: %s given", rb_obj_classname(sub)); sub = tmp; } /* fall through */ case T_STRING: offset = rb_u_string_index(self, sub, offset); break; } if (offset < 0) return Qnil; return LONG2NUM(offset); }
/* * call-seq: * Groonga::Plugin.register(name, options=nil) * Groonga::Plugin.register({:path => path, :context => nil}) * * 既存のプラグインをデータベースに登録する。 * * _name_ を指定した場合はその名前のプラグインを登録する。 * * _path_ を指定した場合はそのパスのプラグインを登録する。 * * _options_ にはハッシュでオプションを指定する。指定できるオ * プションは以下の通り。 * @param options [::Hash] The name and value * pairs. Omitted names are initialized as the default value. * @option options :context (Groonga::Context.default) The context * * データベースを結びつけるコンテキスト。 */ static VALUE rb_grn_plugin_s_register (int argc, VALUE *argv, VALUE klass) { const char *name = NULL, *path = NULL; VALUE rb_options, rb_name = Qnil, rb_path, rb_context; grn_ctx *context; if (argc >= 1) { rb_name = rb_check_string_type(argv[0]); } if (NIL_P(rb_name)) { rb_scan_args(argc, argv, "01", &rb_options); rb_grn_scan_options(rb_options, "path", &rb_path, "context", &rb_context, NULL); path = StringValueCStr(rb_path); } else { rb_scan_args(argc, argv, "11", &rb_name, &rb_options); rb_grn_scan_options(rb_options, "context", &rb_context, NULL); name = StringValueCStr(rb_name); } if (NIL_P(rb_context)) { rb_context = rb_grn_context_get_default(); } context = RVAL2GRNCONTEXT(rb_context); if (name) { grn_plugin_register(context, name); } else { grn_plugin_register_by_path(context, path); } rb_grn_context_check(context, rb_ary_new4(argc, argv)); return Qnil; }
/* * call-seq: * context.find("xpath") -> XML::XPath::Object * * Find nodes matching the specified XPath expression */ static VALUE rxml_xpath_context_find(VALUE self, VALUE xpath_expr) { xmlXPathContextPtr xctxt; xmlXPathObjectPtr xobject; xmlXPathCompExprPtr xcompexpr; VALUE result; Data_Get_Struct(self, xmlXPathContext, xctxt); if (TYPE(xpath_expr) == T_STRING) { VALUE expression = rb_check_string_type(xpath_expr); xobject = xmlXPathEval((xmlChar*) StringValueCStr(expression), xctxt); } else if (rb_obj_is_kind_of(xpath_expr, cXMLXPathExpression)) { Data_Get_Struct(xpath_expr, xmlXPathCompExpr, xcompexpr); xobject = xmlXPathCompiledEval(xcompexpr, xctxt); } else { rb_raise(rb_eTypeError, "Argument should be an intance of a String or XPath::Expression"); } if (xobject == NULL) { /* xmlLastError is different than xctxt->lastError. Use xmlLastError since it has the message set while xctxt->lastError does not. */ xmlErrorPtr xerror = xmlGetLastError(); rxml_raise(xerror); } result = rxml_xpath_object_wrap(xobject); rb_iv_set(result, "@context", self); return result; }
static VALUE env_has_value(VALUE dmy, SEL sel, VALUE obj) { rb_secure(4); obj = rb_check_string_type(obj); if (NIL_P(obj)) { return Qnil; } char **env = GET_ENVIRON(); while (*env != NULL) { const char *s = strchr(*env, '='); if (s++ != NULL) { const long len = strlen(s); if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) { return Qtrue; } } env++; } return Qfalse; }
VALUE rb_get_expanded_load_path(void) { VALUE load_path = rb_get_load_path(); VALUE ary; long i; for (i = 0; i < RARRAY_LEN(load_path); ++i) { VALUE str = rb_check_string_type(RARRAY_PTR(load_path)[i]); if (NIL_P(str) || !rb_is_absolute_path(RSTRING_PTR(str))) goto relative_path_found; } return load_path; relative_path_found: ary = rb_ary_new2(RARRAY_LEN(load_path)); for (i = 0; i < RARRAY_LEN(load_path); ++i) { VALUE path = rb_file_expand_path(RARRAY_PTR(load_path)[i], Qnil); rb_str_freeze(path); rb_ary_push(ary, path); } rb_obj_freeze(ary); return ary; }
static sighandler_t trap_handler(VALUE *cmd, int sig) { sighandler_t func = sighandler; VALUE command; if (NIL_P(*cmd)) { func = SIG_IGN; } else { command = rb_check_string_type(*cmd); if (NIL_P(command) && SYMBOL_P(*cmd)) { command = rb_id2str(SYM2ID(*cmd)); if (!command) rb_raise(rb_eArgError, "bad handler"); } if (!NIL_P(command)) { SafeStringValue(command); /* taint check */ *cmd = command; for (int i = 0; gl_trap_handlers[i].command != NULL; i++) { if (strcmp(gl_trap_handlers[i].command, RSTRING_PTR(command)) == 0) { func = gl_trap_handlers[i].handler; if (func == USE_DEFAULT_HANDLER) { func = default_handler(sig); } *cmd = gl_trap_handlers[i].new_cmd_value; break; } } } else { /* func = sighandler; */ } } return func; }
/* * call-seq: * digest_obj == another_digest_obj -> boolean * digest_obj == string -> boolean * * If a string is given, checks whether it is equal to the hex-encoded * hash value of the digest object. If another digest instance is * given, checks whether they have the same hash value. Otherwise * returns false. */ static VALUE rb_digest_instance_equal(VALUE self, VALUE other) { VALUE str1, str2; if (rb_obj_is_kind_of(other, rb_mDigest_Instance) == Qtrue) { str1 = rb_digest_instance_digest(0, 0, self); str2 = rb_digest_instance_digest(0, 0, other); } else { str1 = rb_digest_instance_to_s(self); str2 = rb_check_string_type(other); if (NIL_P(str2)) return Qfalse; } /* never blindly assume that subclass methods return strings */ StringValue(str1); StringValue(str2); if (RSTRING_LEN(str1) == RSTRING_LEN(str2) && rb_str_cmp(str1, str2) == 0) { return Qtrue; } return Qfalse; }
static VALUE env_rassoc(VALUE dmy, SEL sel, VALUE obj) { rb_secure(4); obj = rb_check_string_type(obj); if (NIL_P(obj)) { return Qnil; } char **env = GET_ENVIRON(); while (*env != NULL) { const char *s = strchr(*env, '='); if (s++ != NULL) { const long len = strlen(s); if (RSTRING_LEN(obj) == len && strncmp(s, RSTRING_PTR(obj), len) == 0) { return rb_assoc_new(rb_tainted_str_new(*env, s - *env - 1), obj); } } env++; } return Qnil; }
void rb_threadptr_error_print(rb_thread_t *th, VALUE errinfo) { volatile VALUE errat = Qundef; int raised_flag = th->raised_flag; volatile VALUE eclass = Qundef, e = Qundef; const char *volatile einfo; volatile long elen; VALUE mesg; if (NIL_P(errinfo)) return; rb_thread_raised_clear(th); TH_PUSH_TAG(th); if (TH_EXEC_TAG() == 0) { errat = rb_get_backtrace(errinfo); } else if (errat == Qundef) { errat = Qnil; } else if (eclass == Qundef || e != Qundef) { goto error; } else { goto no_message; } if (NIL_P(errat) || RARRAY_LEN(errat) == 0 || NIL_P(mesg = RARRAY_AREF(errat, 0))) { error_pos(); } else { warn_print_str(mesg); warn_print(": "); } eclass = CLASS_OF(errinfo); if (eclass != Qundef && (e = rb_check_funcall(errinfo, rb_intern("message"), 0, 0)) != Qundef && (RB_TYPE_P(e, T_STRING) || !NIL_P(e = rb_check_string_type(e)))) { einfo = RSTRING_PTR(e); elen = RSTRING_LEN(e); } else { no_message: einfo = ""; elen = 0; } if (eclass == rb_eRuntimeError && elen == 0) { warn_print("unhandled exception\n"); } else { VALUE epath; epath = rb_class_name(eclass); if (elen == 0) { warn_print_str(epath); warn_print("\n"); } else { const char *tail = 0; long len = elen; if (RSTRING_PTR(epath)[0] == '#') epath = 0; if ((tail = memchr(einfo, '\n', elen)) != 0) { len = tail - einfo; tail++; /* skip newline */ } warn_print_str(tail ? rb_str_subseq(e, 0, len) : e); if (epath) { warn_print(" ("); warn_print_str(epath); warn_print(")\n"); } if (tail) { warn_print_str(rb_str_subseq(e, tail - einfo, elen - len - 1)); } if (tail ? einfo[elen-1] != '\n' : !epath) warn_print2("\n", 1); } } if (!NIL_P(errat)) { long i; long len = RARRAY_LEN(errat); int skip = eclass == rb_eSysStackError; #define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5) #define TRACE_HEAD 8 #define TRACE_TAIL 5 for (i = 1; i < len; i++) { VALUE line = RARRAY_AREF(errat, i); if (RB_TYPE_P(line, T_STRING)) { warn_print_str(rb_sprintf("\tfrom %"PRIsVALUE"\n", line)); } if (skip && i == TRACE_HEAD && len > TRACE_MAX) { warn_print_str(rb_sprintf("\t ... %ld levels...\n", len - TRACE_HEAD - TRACE_TAIL)); i = len - TRACE_TAIL; } } } error: TH_POP_TAG(); th->errinfo = errinfo; rb_thread_raised_set(th, raised_flag); }
VALUE rb_grn_check_convert_to_string (VALUE object) { return rb_check_string_type(object); }
VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt) { enum {default_float_precision = 6}; rb_encoding *enc; const char *p, *end; char *buf; long blen, bsiz; VALUE result; long scanned = 0; int coderange = ENC_CODERANGE_7BIT; int width, prec, flags = FNONE; int nextarg = 1; int posarg = 0; int tainted = 0; VALUE nextvalue; VALUE tmp; VALUE str; volatile VALUE hash = Qundef; #define CHECK_FOR_WIDTH(f) \ if ((f) & FWIDTH) { \ rb_raise(rb_eArgError, "width given twice"); \ } \ if ((f) & FPREC0) { \ rb_raise(rb_eArgError, "width after precision"); \ } #define CHECK_FOR_FLAGS(f) \ if ((f) & FWIDTH) { \ rb_raise(rb_eArgError, "flag after width"); \ } \ if ((f) & FPREC0) { \ rb_raise(rb_eArgError, "flag after precision"); \ } ++argc; --argv; if (OBJ_TAINTED(fmt)) tainted = 1; StringValue(fmt); enc = rb_enc_get(fmt); fmt = rb_str_new4(fmt); p = RSTRING_PTR(fmt); end = p + RSTRING_LEN(fmt); blen = 0; bsiz = 120; result = rb_str_buf_new(bsiz); rb_enc_copy(result, fmt); buf = RSTRING_PTR(result); memset(buf, 0, bsiz); ENC_CODERANGE_SET(result, coderange); for (; p < end; p++) { const char *t; int n; VALUE sym = Qnil; for (t = p; t < end && *t != '%'; t++) ; PUSH(p, t - p); if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) { scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &coderange); ENC_CODERANGE_SET(result, coderange); } if (t >= end) { /* end of fmt string */ goto sprint_exit; } p = t + 1; /* skip `%' */ width = prec = -1; nextvalue = Qundef; retry: switch (*p) { default: if (rb_enc_isprint(*p, enc)) rb_raise(rb_eArgError, "malformed format string - %%%c", *p); else rb_raise(rb_eArgError, "malformed format string"); break; case ' ': CHECK_FOR_FLAGS(flags); flags |= FSPACE; p++; goto retry; case '#': CHECK_FOR_FLAGS(flags); flags |= FSHARP; p++; goto retry; case '+': CHECK_FOR_FLAGS(flags); flags |= FPLUS; p++; goto retry; case '-': CHECK_FOR_FLAGS(flags); flags |= FMINUS; p++; goto retry; case '0': CHECK_FOR_FLAGS(flags); flags |= FZERO; p++; goto retry; case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': n = 0; GETNUM(n, width); if (*p == '$') { if (nextvalue != Qundef) { rb_raise(rb_eArgError, "value given twice - %d$", n); } nextvalue = GETPOSARG(n); p++; goto retry; } CHECK_FOR_WIDTH(flags); width = n; flags |= FWIDTH; goto retry; case '<': case '{': { const char *start = p; char term = (*p == '<') ? '>' : '}'; int len; for (; p < end && *p != term; ) { p += rb_enc_mbclen(p, end, enc); } if (p >= end) { rb_raise(rb_eArgError, "malformed name - unmatched parenthesis"); } #if SIZEOF_INT < SIZEOF_SIZE_T if ((size_t)(p - start) >= INT_MAX) { const int message_limit = 20; len = (int)(rb_enc_right_char_head(start, start + message_limit, p, enc) - start); rb_enc_raise(enc, rb_eArgError, "too long name (%"PRIdSIZE" bytes) - %.*s...%c", (size_t)(p - start - 2), len, start, term); } #endif len = (int)(p - start + 1); /* including parenthesis */ if (sym != Qnil) { rb_enc_raise(enc, rb_eArgError, "named%.*s after <%"PRIsVALUE">", len, start, rb_sym2str(sym)); } CHECKNAMEARG(start, len, enc); get_hash(&hash, argc, argv); sym = rb_check_symbol_cstr(start + 1, len - 2 /* without parenthesis */, enc); if (sym != Qnil) nextvalue = rb_hash_lookup2(hash, sym, Qundef); if (nextvalue == Qundef) { rb_enc_raise(enc, rb_eKeyError, "key%.*s not found", len, start); } if (term == '}') goto format_s; p++; goto retry; } case '*': CHECK_FOR_WIDTH(flags); flags |= FWIDTH; GETASTER(width); if (width < 0) { flags |= FMINUS; width = -width; } p++; goto retry; case '.': if (flags & FPREC0) { rb_raise(rb_eArgError, "precision given twice"); } flags |= FPREC|FPREC0; prec = 0; p++; if (*p == '*') { GETASTER(prec); if (prec < 0) { /* ignore negative precision */ flags &= ~FPREC; } p++; goto retry; } GETNUM(prec, precision); goto retry; case '\n': case '\0': p--; case '%': if (flags != FNONE) { rb_raise(rb_eArgError, "invalid format character - %%"); } PUSH("%", 1); break; case 'c': { VALUE val = GETARG(); VALUE tmp; unsigned int c; int n; tmp = rb_check_string_type(val); if (!NIL_P(tmp)) { if (rb_enc_strlen(RSTRING_PTR(tmp),RSTRING_END(tmp),enc) != 1) { rb_raise(rb_eArgError, "%%c requires a character"); } c = rb_enc_codepoint_len(RSTRING_PTR(tmp), RSTRING_END(tmp), &n, enc); RB_GC_GUARD(tmp); } else { c = NUM2INT(val); n = rb_enc_codelen(c, enc); } if (n <= 0) { rb_raise(rb_eArgError, "invalid character"); } if (!(flags & FWIDTH)) { CHECK(n); rb_enc_mbcput(c, &buf[blen], enc); blen += n; } else if ((flags & FMINUS)) { CHECK(n); rb_enc_mbcput(c, &buf[blen], enc); blen += n; FILL(' ', width-1); } else { FILL(' ', width-1); CHECK(n); rb_enc_mbcput(c, &buf[blen], enc); blen += n; } } break; case 's': case 'p': format_s: { VALUE arg = GETARG(); long len, slen; if (*p == 'p') arg = rb_inspect(arg); str = rb_obj_as_string(arg); if (OBJ_TAINTED(str)) tainted = 1; len = RSTRING_LEN(str); rb_str_set_len(result, blen); if (coderange != ENC_CODERANGE_BROKEN && scanned < blen) { int cr = coderange; scanned += rb_str_coderange_scan_restartable(buf+scanned, buf+blen, enc, &cr); ENC_CODERANGE_SET(result, (cr == ENC_CODERANGE_UNKNOWN ? ENC_CODERANGE_BROKEN : (coderange = cr))); } enc = rb_enc_check(result, str); if (flags&(FPREC|FWIDTH)) { slen = rb_enc_strlen(RSTRING_PTR(str),RSTRING_END(str),enc); if (slen < 0) { rb_raise(rb_eArgError, "invalid mbstring sequence"); } if ((flags&FPREC) && (prec < slen)) { char *p = rb_enc_nth(RSTRING_PTR(str), RSTRING_END(str), prec, enc); slen = prec; len = p - RSTRING_PTR(str); } /* need to adjust multi-byte string pos */ if ((flags&FWIDTH) && (width > slen)) { width -= (int)slen; if (!(flags&FMINUS)) { CHECK(width); while (width--) { buf[blen++] = ' '; } } CHECK(len); memcpy(&buf[blen], RSTRING_PTR(str), len); RB_GC_GUARD(str); blen += len; if (flags&FMINUS) { CHECK(width); while (width--) { buf[blen++] = ' '; } } rb_enc_associate(result, enc); break; } } PUSH(RSTRING_PTR(str), len); RB_GC_GUARD(str); rb_enc_associate(result, enc); } break; case 'd': case 'i': case 'o': case 'x': case 'X': case 'b': case 'B': case 'u': { volatile VALUE val = GETARG(); int valsign; char nbuf[64], *s; const char *prefix = 0; int sign = 0, dots = 0; char sc = 0; long v = 0; int base, bignum = 0; int len; switch (*p) { case 'd': case 'i': case 'u': sign = 1; break; case 'o': case 'x': case 'X': case 'b': case 'B': if (flags&(FPLUS|FSPACE)) sign = 1; break; } if (flags & FSHARP) { switch (*p) { case 'o': prefix = "0"; break; case 'x': prefix = "0x"; break; case 'X': prefix = "0X"; break; case 'b': prefix = "0b"; break; case 'B': prefix = "0B"; break; } } bin_retry: switch (TYPE(val)) { case T_FLOAT: if (FIXABLE(RFLOAT_VALUE(val))) { val = LONG2FIX((long)RFLOAT_VALUE(val)); goto bin_retry; } val = rb_dbl2big(RFLOAT_VALUE(val)); if (FIXNUM_P(val)) goto bin_retry; bignum = 1; break; case T_STRING: val = rb_str_to_inum(val, 0, TRUE); goto bin_retry; case T_BIGNUM: bignum = 1; break; case T_FIXNUM: v = FIX2LONG(val); break; default: val = rb_Integer(val); goto bin_retry; } switch (*p) { case 'o': base = 8; break; case 'x': case 'X': base = 16; break; case 'b': case 'B': base = 2; break; case 'u': case 'd': case 'i': default: base = 10; break; } if (base != 10) { int numbits = ffs(base)-1; size_t abs_nlz_bits; size_t numdigits = rb_absint_numwords(val, numbits, &abs_nlz_bits); long i; if (INT_MAX-1 < numdigits) /* INT_MAX is used because rb_long2int is used later. */ rb_raise(rb_eArgError, "size too big"); if (sign) { if (numdigits == 0) numdigits = 1; tmp = rb_str_new(NULL, numdigits); valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp), 1, CHAR_BIT-numbits, INTEGER_PACK_BIG_ENDIAN); for (i = 0; i < RSTRING_LEN(tmp); i++) RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]]; s = RSTRING_PTR(tmp); if (valsign < 0) { sc = '-'; width--; } else if (flags & FPLUS) { sc = '+'; width--; } else if (flags & FSPACE) { sc = ' '; width--; } } else { /* Following conditional "numdigits++" guarantees the * most significant digit as * - '1'(bin), '7'(oct) or 'f'(hex) for negative numbers * - '0' for zero * - not '0' for positive numbers. * * It also guarantees the most significant two * digits will not be '11'(bin), '77'(oct), 'ff'(hex) * or '00'. */ if (numdigits == 0 || ((abs_nlz_bits != (size_t)(numbits-1) || !rb_absint_singlebit_p(val)) && (!bignum ? v < 0 : BIGNUM_NEGATIVE_P(val)))) numdigits++; tmp = rb_str_new(NULL, numdigits); valsign = rb_integer_pack(val, RSTRING_PTR(tmp), RSTRING_LEN(tmp), 1, CHAR_BIT-numbits, INTEGER_PACK_2COMP | INTEGER_PACK_BIG_ENDIAN); for (i = 0; i < RSTRING_LEN(tmp); i++) RSTRING_PTR(tmp)[i] = ruby_digitmap[((unsigned char *)RSTRING_PTR(tmp))[i]]; s = RSTRING_PTR(tmp); dots = valsign < 0; } len = rb_long2int(RSTRING_END(tmp) - s); } else if (!bignum) { valsign = 1; if (v < 0) { v = -v; sc = '-'; width--; valsign = -1; } else if (flags & FPLUS) { sc = '+'; width--; } else if (flags & FSPACE) { sc = ' '; width--; } snprintf(nbuf, sizeof(nbuf), "%ld", v); s = nbuf; len = (int)strlen(s); } else { tmp = rb_big2str(val, 10); s = RSTRING_PTR(tmp); valsign = 1; if (s[0] == '-') { s++; sc = '-'; width--; valsign = -1; } else if (flags & FPLUS) { sc = '+'; width--; } else if (flags & FSPACE) { sc = ' '; width--; } len = rb_long2int(RSTRING_END(tmp) - s); } if (dots) { prec -= 2; width -= 2; } if (*p == 'X') { char *pp = s; int c; while ((c = (int)(unsigned char)*pp) != 0) { *pp = rb_enc_toupper(c, enc); pp++; } } if (prefix && !prefix[1]) { /* octal */ if (dots) { prefix = 0; } else if (len == 1 && *s == '0') { len = 0; if (flags & FPREC) prec--; } else if ((flags & FPREC) && (prec > len)) { prefix = 0; } } else if (len == 1 && *s == '0') { prefix = 0; } if (prefix) { width -= (int)strlen(prefix); } if ((flags & (FZERO|FMINUS|FPREC)) == FZERO) { prec = width; width = 0; } else { if (prec < len) { if (!prefix && prec == 0 && len == 1 && *s == '0') len = 0; prec = len; } width -= prec; } if (!(flags&FMINUS)) { CHECK(width); while (width-- > 0) { buf[blen++] = ' '; } } if (sc) PUSH(&sc, 1); if (prefix) { int plen = (int)strlen(prefix); PUSH(prefix, plen); } CHECK(prec - len); if (dots) PUSH("..", 2); if (!sign && valsign < 0) { char c = sign_bits(base, p); while (len < prec--) { buf[blen++] = c; } } else if ((flags & (FMINUS|FPREC)) != FMINUS) { while (len < prec--) { buf[blen++] = '0'; } } PUSH(s, len); RB_GC_GUARD(tmp); CHECK(width); while (width-- > 0) { buf[blen++] = ' '; } } break; case 'f': { VALUE val = GETARG(), num, den; int sign = (flags&FPLUS) ? 1 : 0, zero = 0; long len, done = 0; int prefix = 0; if (!RB_TYPE_P(val, T_RATIONAL)) { nextvalue = val; goto float_value; } if (!(flags&FPREC)) prec = default_float_precision; den = rb_rational_den(val); num = rb_rational_num(val); if (FIXNUM_P(num)) { if ((SIGNED_VALUE)num < 0) { long n = -FIX2LONG(num); num = LONG2FIX(n); sign = -1; } } else if (rb_num_negative_p(num)) { sign = -1; num = rb_funcallv(num, idUMinus, 0, 0); } if (den != INT2FIX(1) || prec > 1) { const ID idDiv = rb_intern("div"); VALUE p10 = rb_int_positive_pow(10, prec); VALUE den_2 = rb_funcall(den, idDiv, 1, INT2FIX(2)); num = rb_funcallv(num, '*', 1, &p10); num = rb_funcallv(num, '+', 1, &den_2); num = rb_funcallv(num, idDiv, 1, &den); } else if (prec >= 0) { zero = prec; } val = rb_obj_as_string(num); len = RSTRING_LEN(val) + zero; if (prec >= len) ++len; /* integer part 0 */ if (sign || (flags&FSPACE)) ++len; if (prec > 0) ++len; /* period */ CHECK(len > width ? len : width); if (sign || (flags&FSPACE)) { buf[blen++] = sign > 0 ? '+' : sign < 0 ? '-' : ' '; prefix++; done++; } len = RSTRING_LEN(val) + zero; t = RSTRING_PTR(val); if (len > prec) { memcpy(&buf[blen], t, len - prec); blen += len - prec; done += len - prec; } else { buf[blen++] = '0'; done++; } if (prec > 0) { buf[blen++] = '.'; done++; } if (zero) { FILL('0', zero); done += zero; } else if (prec > len) { FILL('0', prec - len); memcpy(&buf[blen], t, len); blen += len; done += prec; } else if (prec > 0) { memcpy(&buf[blen], t + len - prec, prec); blen += prec; done += prec; } if ((flags & FWIDTH) && width > done) { int fill = ' '; long shifting = 0; if (!(flags&FMINUS)) { shifting = done; if (flags&FZERO) { shifting -= prefix; fill = '0'; } blen -= shifting; memmove(&buf[blen + width - done], &buf[blen], shifting); } FILL(fill, width - done); blen += shifting; } RB_GC_GUARD(val); break; } case 'g': case 'G': case 'e': case 'E': /* TODO: rational support */ case 'a': case 'A': float_value: { VALUE val = GETARG(); double fval; int i, need; char fbuf[32]; fval = RFLOAT_VALUE(rb_Float(val)); if (isnan(fval) || isinf(fval)) { const char *expr; if (isnan(fval)) { expr = "NaN"; } else { expr = "Inf"; } need = (int)strlen(expr); if ((!isnan(fval) && fval < 0.0) || (flags & FPLUS)) need++; if ((flags & FWIDTH) && need < width) need = width; CHECK(need + 1); snprintf(&buf[blen], need + 1, "%*s", need, ""); if (flags & FMINUS) { if (!isnan(fval) && fval < 0.0) buf[blen++] = '-'; else if (flags & FPLUS) buf[blen++] = '+'; else if (flags & FSPACE) blen++; memcpy(&buf[blen], expr, strlen(expr)); } else { if (!isnan(fval) && fval < 0.0) buf[blen + need - strlen(expr) - 1] = '-'; else if (flags & FPLUS) buf[blen + need - strlen(expr) - 1] = '+'; else if ((flags & FSPACE) && need > width) blen++; memcpy(&buf[blen + need - strlen(expr)], expr, strlen(expr)); } blen += strlen(&buf[blen]); break; } fmt_setup(fbuf, sizeof(fbuf), *p, flags, width, prec); need = 0; if (*p != 'e' && *p != 'E') { i = INT_MIN; frexp(fval, &i); if (i > 0) need = BIT_DIGITS(i); } need += (flags&FPREC) ? prec : default_float_precision; if ((flags&FWIDTH) && need < width) need = width; need += 20; CHECK(need); snprintf(&buf[blen], need, fbuf, fval); blen += strlen(&buf[blen]); } break; } flags = FNONE; } sprint_exit: RB_GC_GUARD(fmt); /* XXX - We cannot validate the number of arguments if (digit)$ style used. */ if (posarg >= 0 && nextarg < argc) { const char *mesg = "too many arguments for format string"; if (RTEST(ruby_debug)) rb_raise(rb_eArgError, "%s", mesg); if (RTEST(ruby_verbose)) rb_warn("%s", mesg); } rb_str_resize(result, blen); if (tainted) OBJ_TAINT(result); return result; }