void rb_check_type(VALUE x, int t) { const struct types *type = builtin_types; const struct types *const typeend = builtin_types + sizeof(builtin_types) / sizeof(builtin_types[0]); int xt; if (x == Qundef) { rb_bug("undef leaked to the Ruby space"); } xt = TYPE(x); if (xt != t || (xt == T_DATA && RTYPEDDATA_P(x))) { while (type < typeend) { if (type->type == t) { const char *etype; if (NIL_P(x)) { etype = "nil"; } else if (FIXNUM_P(x)) { etype = "Fixnum"; } else if (SYMBOL_P(x)) { etype = "Symbol"; } else if (rb_special_const_p(x)) { etype = RSTRING_PTR(rb_obj_as_string(x)); } else { etype = rb_obj_classname(x); } rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", etype, type->name); } type++; } if (xt > T_MASK && xt <= 0x3f) { rb_fatal("unknown type 0x%x (0x%x given, probably comes from extension library for ruby 1.8)", t, xt); } rb_bug("unknown type 0x%x (0x%x given)", t, xt); } }
/* =begin --- OraNumber.new() =end */ static VALUE ora_number_initialize(int argc, VALUE *argv, VALUE self) { ora_vnumber_t *ovn = get_ora_number(self); volatile VALUE arg; rb_scan_args(argc, argv, "01", &arg); ovn->size = 1; ovn->num.exponent = 0x80; memset(ovn->num.mantissa, 0, sizeof(ovn->num.mantissa)); if (argc == 1) { if (TYPE(arg) != T_STRING) { arg = rb_obj_as_string(arg); } if (ora_number_from_str(ovn, RSTRING_ORATEXT(arg), RSTRING_LEN(arg)) != 0) { rb_raise(rb_eArgError, "could not convert '%s' to OraNumber", RSTRING_PTR(arg)); } } return Qnil; }
static VALUE oci8_lob_write(VALUE self, VALUE data) { oci8_lob_t *lob = DATA_PTR(self); oci8_svcctx_t *svcctx = oci8_get_svcctx(lob->svc); ub4 amt; lob_open(lob); if (TYPE(data) != T_STRING) { data = rb_obj_as_string(data); } if (lob->lobtype == OCI_TEMP_CLOB) { data = rb_str_export_to_enc(data, oci8_encoding); } RB_GC_GUARD(data); amt = RSTRING_LEN(data); oci_lc(OCILobWrite_nb(svcctx, svcctx->base.hp.svc, oci8_errhp, lob->base.hp.lob, &amt, lob->pos + 1, RSTRING_PTR(data), amt, OCI_ONE_PIECE, NULL, NULL, 0, lob->csfrm)); lob->pos += amt; return UINT2NUM(amt); }
static VALUE rg_write(VALUE self, VALUE buf) { gssize count; gsize bytes_written; GIOStatus status; GError* err = NULL; buf = rb_obj_as_string(buf); StringValue(buf); count = RSTRING_LEN(buf); status = g_io_channel_write_chars(_SELF(self), RVAL2CSTR(buf), count, &bytes_written, &err); ioc_error(status, err); return UINT2NUM(bytes_written); }
static int load_script(int argc, char **argv) { VALUE r_argv, fname; int state, i; if (argc < 1) { return 0; } r_argv = rb_const_get(rb_mKernel, rb_intern("ARGV")); rb_ary_clear(r_argv); for (i = 1; i < argc; i++) { rb_ary_push(r_argv, rb_tainted_str_new2(argv[i])); } fname = rb_funcall(rb_cFile, ExpandPath, 1, rb_str_new2(argv[0])); rb_load_protect(fname, 1, &state); if (state) { VALUE errinfo, errstr, errat; int n, i; const char *cstr; errinfo = rb_errinfo(); errstr = rb_obj_as_string(errinfo); cstr = StringValueCStr(errstr); if (strcmp(cstr, "exit")) { ngraph_err_puts(cstr); errat = rb_funcall(errinfo, rb_intern("backtrace"), 0); if (! NIL_P(errat)) { n = RARRAY_LEN(errat); for (i = 0; i < n; i ++) { errstr = rb_str_new2("\tfrom "); rb_str_append(errstr, rb_ary_entry(errat, i)); ngraph_err_puts(StringValueCStr(errstr)); } } } } rb_gc_start(); return 0; }
/* * call-seq: * context.register_namespace(prefix, uri) -> (true|false) * * Register the specified namespace URI with the specified prefix * in this context. * context.register_namespace('xi', 'http://www.w3.org/2001/XInclude') */ static VALUE rxml_xpath_context_register_namespace(VALUE self, VALUE prefix, VALUE uri) { xmlXPathContextPtr ctxt; Data_Get_Struct(self, xmlXPathContext, ctxt); /* Prefix could be a symbol. */ prefix = rb_obj_as_string(prefix); if (xmlXPathRegisterNs(ctxt, (xmlChar*) StringValuePtr(prefix), (xmlChar*) StringValuePtr(uri)) == 0) { return (Qtrue); } else { /* Should raise an exception, IMHO (whose?, why shouldnt it? -danj)*/ rb_warning("register namespace failed"); return (Qfalse); } }
/* * call-seq: * * s = Kgio::Socket.new(:INET, :STREAM) * addr = Socket.pack_sockaddr_in(80, "example.com") * s.kgio_fastopen("hello world", addr) -> nil * * Starts a TCP connection using TCP Fast Open. This uses a blocking * sendto() syscall and is only available on Ruby 1.9 or later. * This raises exceptions (including Errno::EINPROGRESS/Errno::EAGAIN) * on errors. Using this is only recommended for blocking sockets. * * Timeouts may be set with setsockopt: * * s.setsockopt(:SOCKET, :SNDTIMEO, [1,0].pack("l_l_")) */ static VALUE fastopen(VALUE sock, VALUE buf, VALUE addr) { struct tfo_args a; VALUE str = (TYPE(buf) == T_STRING) ? buf : rb_obj_as_string(buf); ssize_t w; a.fd = my_fileno(sock); a.buf = RSTRING_PTR(str); a.buflen = (size_t)RSTRING_LEN(str); a.addr = sockaddr_from(&a.addrlen, addr); /* n.b. rb_thread_blocking_region preserves errno */ w = (ssize_t)rb_thread_io_blocking_region(tfo_sendto, &a, a.fd); if (w < 0) rb_sys_fail("sendto"); if ((size_t)w == a.buflen) return Qnil; return rb_str_subseq(str, w, a.buflen - w); }
static VALUE exc_inspect(VALUE exc) { VALUE str, klass; klass = CLASS_OF(exc); exc = rb_obj_as_string(exc); if (RSTRING_LEN(exc) == 0) { return rb_str_dup(rb_class_name(klass)); } str = rb_str_buf_new2("#<"); klass = rb_class_name(klass); rb_str_buf_append(str, klass); rb_str_buf_cat(str, ": ", 2); rb_str_buf_append(str, exc); rb_str_buf_cat(str, ">", 1); return str; }
static void err_append(const char *s) { rb_thread_t *th = GET_THREAD(); if (th->parse_in_eval) { if (NIL_P(th->errinfo)) { th->errinfo = rb_exc_new2(rb_eSyntaxError, s); } else { VALUE str = rb_obj_as_string(GET_THREAD()->errinfo); rb_str_cat2(str, "\n"); rb_str_cat2(str, s); th->errinfo = rb_exc_new3(rb_eSyntaxError, str); } } else { rb_write_error(s); rb_write_error("\n"); } }
static void ruby_script_error() { VALUE errinfo, lasterr, array; int i; errinfo = rb_errinfo(); if(!NIL_P(errinfo)) { lasterr = rb_gv_get("$!"); VALUE tmp2 = rb_class_path(CLASS_OF(lasterr)); VALUE tmp = rb_obj_as_string(lasterr); ilog(L_ERROR, "RUBY ERROR: %s: %s", StringValueCStr(tmp2), StringValueCStr(tmp)); array = rb_funcall(errinfo, rb_intern("backtrace"), 0); for (i = 0; i < RARRAY_LEN(array); ++i) { tmp = rb_ary_entry(array, i); ilog(L_DEBUG, "RUBY BACKTRACE: %s", StringValueCStr(tmp)); } } }
/* * call-seq: * node << ("string" | node) -> XML::Node * * Add the specified string or XML::Node to this node's * content. The returned node is the node that was * added and not self, thereby allowing << calls to * be chained. */ VALUE ruby_xml_node_content_add(VALUE self, VALUE obj) { xmlNodePtr xnode; VALUE str; Data_Get_Struct(self, xmlNode, xnode); /* XXX This should only be legal for a CDATA type node, I think, * resulting in a merge of content, as if a string were passed * danj 070827 */ if (rb_obj_is_kind_of(obj, cXMLNode)) { ruby_xml_node_child_set(self, obj); } else { str = rb_obj_as_string(obj); if (NIL_P(str) || TYPE(str) != T_STRING) rb_raise(rb_eTypeError, "invalid argument: must be string or XML::Node"); xmlNodeAddContent(xnode, (xmlChar*)StringValuePtr(str)); } return(self); }
/* * call-seq: * query_parser.parse(query_string) -> Query * * Parse a query string returning a Query object if parsing was successful. * Will raise a QueryParseException if unsuccessful. */ static VALUE frt_qp_parse(VALUE self, VALUE rstr) { const char *msg = NULL; volatile VALUE rq; GET_QP; rstr = rb_obj_as_string(rstr); TRY rq = frt_get_q(qp_parse(qp, RSTRING(rstr)->ptr)); break; default: msg = xcontext.msg; HANDLED(); XENDTRY if (msg) { rb_raise(cQueryParseException, msg); } return rq; }
void rb_check_type(VALUE x, int t) { const struct types *type = builtin_types; const struct types *const typeend = builtin_types + sizeof(builtin_types) / sizeof(builtin_types[0]); if (x == Qundef) { rb_bug("undef leaked to the Ruby space"); } if (TYPE(x) != t) { while (type < typeend) { if (type->type == t) { const char *etype; if (NIL_P(x)) { etype = "nil"; } else if (FIXNUM_P(x)) { etype = "Fixnum"; } else if (SYMBOL_P(x)) { etype = "Symbol"; } else if (rb_special_const_p(x)) { etype = RSTRING_PTR(rb_obj_as_string(x)); } else { etype = rb_obj_classname(x); } rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", etype, type->name); } type++; } rb_bug("unknown type 0x%x (0x%x given)", t, TYPE(x)); } }
static void err_append(const char *s) { extern VALUE ruby_errinfo; if (ruby_in_eval) { if (NIL_P(ruby_errinfo)) { ruby_errinfo = rb_exc_new2(rb_eSyntaxError, s); } else { VALUE str = rb_obj_as_string(ruby_errinfo); rb_str_cat2(str, "\n"); rb_str_cat2(str, s); ruby_errinfo = rb_exc_new3(rb_eSyntaxError, str); } } else { rb_write_error(s); rb_write_error("\n"); } }
/* * call-seq: * XML::Node.new_comment(content = nil) -> XML::Node * * Create a new comment node, optionally setting * the node's content. * */ static VALUE rxml_node_new_comment(int argc, VALUE *argv, VALUE klass) { VALUE content = Qnil; xmlNodePtr xnode; rb_scan_args(argc, argv, "01", &content); if (NIL_P(content)) { xnode = xmlNewComment(NULL); } else { content = rb_obj_as_string(content); xnode = xmlNewComment((xmlChar*) StringValueCStr(content)); } if (xnode == NULL) rxml_raise(&xmlLastError); return rxml_node_wrap(xnode); }
static void * initFunc(xsltTransformContextPtr ctxt, const xmlChar *uri) { VALUE modules = rb_iv_get(xslt, "@modules"); VALUE obj = rb_hash_aref(modules, rb_str_new2((const char *)uri)); VALUE args = { Qfalse }; VALUE methods = rb_funcall(obj, rb_intern("instance_methods"), 1, args); VALUE inst; nokogiriXsltStylesheetTuple *wrapper; int i; for(i = 0; i < RARRAY_LEN(methods); i++) { VALUE method_name = rb_obj_as_string(RARRAY_PTR(methods)[i]); xsltRegisterExtFunction(ctxt, (unsigned char *)StringValuePtr(method_name), uri, method_caller); } Data_Get_Struct(ctxt->style->_private, nokogiriXsltStylesheetTuple, wrapper); inst = rb_class_new_instance(0, NULL, obj); rb_ary_push(wrapper->func_instances, inst); return (void *)inst; }
char * rubyeval (char *input) { VALUE rubyval; char * retval = NULL; if (input && *input) { ruby_startstop(1); rubyval = rb_rescue2(internal_rubyeval, (VALUE)input, eval_failed, 0, rb_eException, 0); if (rubyval == Qnil) retval = NULL; else { VALUE x; x = rb_obj_as_string(rubyval); retval = StringValuePtr(x); } } RETURN_STR(retval); /* XXX Is this malloced or not? */ }
/* * call-seq: * XML::Node.new_cdata(content = nil) -> XML::Node * * Create a new #CDATA node, optionally setting * the node's content. */ static VALUE rxml_node_new_cdata(int argc, VALUE *argv, VALUE klass) { VALUE content = Qnil; xmlNodePtr xnode; rb_scan_args(argc, argv, "01", &content); if (NIL_P(content)) { xnode = xmlNewCDataBlock(NULL, NULL, 0); } else { content = rb_obj_as_string(content); xnode = xmlNewCDataBlock(NULL, (xmlChar*) StringValuePtr(content), RSTRING_LEN(content)); } if (xnode == NULL) rxml_raise(&xmlLastError); return rxml_node_wrap(xnode); }
/** * Print the Ruby Stack Trace in an ows:ExceptionReport XML Document * * @param m the conf maps containing the main.cfg settings * @see printExceptionReportResponse */ void ruby_trace_error(maps* m){ #if RUBY_VERSION_MINOR == 8 VALUE lasterr = rb_gv_get("$!"); #else VALUE lasterr = rb_errinfo(); VALUE ruby_errinfo = lasterr; #endif VALUE message = rb_obj_as_string(lasterr); VALUE lklass = rb_class_path(CLASS_OF(lasterr)); #if RUBY_VERSION_MINOR == 8 char *trace=(char*)malloc((strlen(RSTRING(lklass)->ptr)+strlen(RSTRING(message)->ptr)+3)*sizeof(char)); sprintf(trace,"%s: %s",RSTRING_PTR(lklass),RSTRING_PTR(message)); #else char *trace=(char*)malloc((strlen(RSTRING_PTR(lklass))+strlen(RSTRING_PTR(message))+3)*sizeof(char)); sprintf(trace,"%s: %s",RSTRING_PTR(lklass),RSTRING_PTR(message)); #endif if(!NIL_P(ruby_errinfo)) { VALUE ary = rb_funcall(ruby_errinfo, rb_intern("backtrace"), 0); int c; for (c=0; c<RARRAY_LEN(ary); c++) { int len=strlen(trace); char *tmp0=zStrdup(trace); #if RUBY_VERSION_MINOR == 8 trace=(char *) realloc(trace,(len+strlen(RSTRING(RARRAY(ary)->ptr[c])->ptr)+2)*sizeof(char)); sprintf(trace,"%s\n%s",tmp0,RSTRING(RARRAY(ary)->ptr[c])->ptr); #else trace=(char *) realloc(trace,(len+strlen(RSTRING_PTR(RARRAY_PTR(ary)[c]))+2)*sizeof(char)); sprintf(trace,"%s\n%s",tmp0,RSTRING_PTR(RARRAY_PTR(ary)[c])); #endif free(tmp0); } } map* err=createMap("text",trace); addToMap(err,"code","NoApplicableCode"); printExceptionReportResponse(m,err); }
/* * call-seq: * conn.putline( str) -> nil * conn.putline( ary) -> nil * conn.putline( str) { ... } -> nil * * Sends the string to the backend server. * You have to open the stream with a +COPY+ command using +copy_stdin+. * * If +str+ doesn't end in a newline, one is appended. If the argument * is +ary+, a line will be built using +stringize_line+. * * If the connection is in nonblocking mode and no data could be sent * the closure will be called and its value will be returned. */ VALUE pgconn_putline( VALUE self, VALUE arg) { struct pgconn_data *c; VALUE str; const char *p; int l; int r; switch (TYPE( arg)) { case T_STRING: str = arg; break; case T_ARRAY: str = pgconn_stringize_line( self, arg); break; default: str = rb_obj_as_string( arg); break; } if (RSTRING_PTR( str)[ RSTRING_LEN( str) - 1] != '\n') { VALUE t; t = rb_str_dup( str); rb_str_buf_cat( t, "\n", 1); str = t; } Data_Get_Struct( self, struct pgconn_data, c); p = pgconn_destring( c, str, &l); r = PQputCopyData( c->conn, p, l); if (r < 0) rb_raise( rb_ePgConnCopy, "Copy from stdin failed."); else if (r == 0) return rb_yield( Qnil); return Qnil; }
static VALUE rg_puts(int argc, VALUE *argv, VALUE self) { int i; VALUE line; /* if no argument given, print newline. */ if (argc == 0) { rg_write(self, default_rs); return Qnil; } for (i=0; i<argc; i++) { if (NIL_P(argv[i])) { line = rb_str_new2("nil"); } else { line = rbg_check_array_type(argv[i]); if (!NIL_P(line)) { #ifdef HAVE_RB_EXEC_RECURSIVE rb_exec_recursive(ioc_puts_ary, line, self); #else rb_protect_inspect(ioc_puts_ary, line, self); #endif continue; } line = rb_obj_as_string(argv[i]); } rg_write(self, line); if (RSTRING_LEN(line) == 0 || RSTRING_PTR(line)[RSTRING_LEN(line)-1] != '\n') { rg_write(self, default_rs); } } return Qnil; }
static void xmlformatter_write_obj(gonzui_xmlformatter_t *xf, VALUE obj) { char *p; char *data; size_t size; if (SYMBOL_P(obj)) { data = rb_id2name(SYM2ID(obj)); size = strlen(data); } else { struct RString *s = RSTRING(rb_obj_as_string(obj)); data = s->ptr; size = s->len; } if (xf->size + size * 6 > xf->max_size) { xf->max_size += BLOCK_SIZE; xf->data = realloc(xf->data, xf->max_size); } for (p = data; *p; p++) { int c = *p; if (c == '<') { memcpy(xf->data + xf->size, "<", 4); xf->size += 4; } else if (c == '>') { memcpy(xf->data + xf->size, ">", 4); xf->size += 4; } else if (c == '&') { memcpy(xf->data + xf->size, "&", 5); xf->size += 5; } else if (c == '"') { memcpy(xf->data + xf->size, """, 6); xf->size += 6; } else { xf->data[xf->size++] = c; } } }
// // This function was borrowed from the kross code. It puts out // an error message and stacktrace on stderr for the current exception. // static void show_exception_message() { VALUE info = rb_gv_get("$!"); VALUE bt = rb_funcall(info, rb_intern("backtrace"), 0); VALUE message = RARRAY_PTR(bt)[0]; VALUE message2 = rb_obj_as_string(info); QString errormessage = QString("%1: %2 (%3)") .arg( StringValueCStr(message) ) .arg( StringValueCStr(message2) ) .arg( rb_class2name(CLASS_OF(info)) ); fprintf(stderr, "%s\n", errormessage.toLatin1().data()); QString tracemessage; for(int i = 1; i < RARRAY_LEN(bt); ++i) { if( TYPE(RARRAY_PTR(bt)[i]) == T_STRING ) { QString s = QString("%1\n").arg( StringValueCStr(RARRAY_PTR(bt)[i]) ); Q_ASSERT( ! s.isNull() ); tracemessage += s; fprintf(stderr, "\t%s", s.toLatin1().data()); } } }
static void fill_iovec(struct wrv_args *a) { int i; struct iovec *curvec; a->iov_cnt = RARRAY_LENINT(a->buf); a->batch_len = 0; if (a->iov_cnt == 0) return; if (a->iov_cnt > iov_max) a->iov_cnt = iov_max; rb_str_resize(a->vec_buf, sizeof(struct iovec) * a->iov_cnt); curvec = a->vec = (struct iovec*)RSTRING_PTR(a->vec_buf); for (i=0; i < a->iov_cnt; i++, curvec++) { VALUE str = rb_ary_entry(a->buf, i); long str_len, next_len; if (TYPE(str) != T_STRING) { str = rb_obj_as_string(str); rb_ary_store(a->buf, i, str); } str_len = RSTRING_LEN(str); /* lets limit total memory to write, * but always take first string */ next_len = a->batch_len + str_len; if (i && next_len > WRITEV_MEMLIMIT) { a->iov_cnt = i; break; } a->batch_len = next_len; curvec->iov_base = RSTRING_PTR(str); curvec->iov_len = str_len; } }
static char * ruby__sfvextra(rb_printf_buffer *fp, size_t valsize, void *valp, long *sz, int sign) { VALUE value, result = (VALUE)fp->_bf._base; rb_encoding *enc; char *cp; if (valsize != sizeof(VALUE)) return 0; value = *(VALUE *)valp; if (RBASIC(result)->klass) { rb_raise(rb_eRuntimeError, "rb_vsprintf reentered"); } if (sign == '+') { value = rb_inspect(value); } else { value = rb_obj_as_string(value); if (sign == ' ') value = QUOTE(value); } enc = rb_enc_compatible(result, value); if (enc) { rb_enc_associate(result, enc); } else { enc = rb_enc_get(result); value = rb_str_conv_enc_opts(value, rb_enc_get(value), enc, ECONV_UNDEF_REPLACE|ECONV_INVALID_REPLACE, Qnil); *(volatile VALUE *)valp = value; } StringValueCStr(value); RSTRING_GETMEM(value, cp, *sz); ((rb_printf_buffer_extra *)fp)->value = value; OBJ_INFECT(result, value); return cp; }
static VALUE defout_write(VALUE self, VALUE str) { str = rb_obj_as_string(str); rb_str_cat(self, RSTRING_PTR(str), RSTRING_LEN(str)); return Qnil; }
static void exception_print(FILE *out, int cgi) { VALUE errat; VALUE eclass; VALUE einfo; if (NIL_P(ruby_errinfo)) return; errat = rb_funcall(ruby_errinfo, rb_intern("backtrace"), 0); if (!NIL_P(errat)) { VALUE mesg = RARRAY_PTR(errat)[0]; if (NIL_P(mesg)) { error_pos(out, cgi); } else { if (cgi) write_escaping_html(out, RSTRING_PTR(mesg), RSTRING_LEN(mesg)); else fwrite(RSTRING_PTR(mesg), 1, RSTRING_LEN(mesg), out); } } eclass = CLASS_OF(ruby_errinfo); einfo = rb_obj_as_string(ruby_errinfo); if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) { fprintf(out, ": unhandled exception\n"); } else { VALUE epath; epath = rb_class_path(eclass); if (RSTRING_LEN(einfo) == 0) { fprintf(out, ": "); if (cgi) write_escaping_html(out, RSTRING_PTR(epath), RSTRING_LEN(epath)); else fwrite(RSTRING_PTR(epath), 1, RSTRING_LEN(epath), out); if (cgi) fprintf(out, "<br>\n"); else fprintf(out, "\n"); } else { char *tail = 0; int len = RSTRING_LEN(einfo); if (RSTRING_PTR(epath)[0] == '#') epath = 0; if ((tail = strchr(RSTRING_PTR(einfo), '\n')) != NULL) { len = tail - RSTRING_PTR(einfo); tail++; /* skip newline */ } fprintf(out, ": "); if (cgi) write_escaping_html(out, RSTRING_PTR(einfo), len); else fwrite(RSTRING_PTR(einfo), 1, len, out); if (epath) { fprintf(out, " ("); if (cgi) write_escaping_html(out, RSTRING_PTR(epath), RSTRING_LEN(epath)); else fwrite(RSTRING_PTR(epath), 1, RSTRING_LEN(epath), out); if (cgi) fprintf(out, ")<br>\n"); else fprintf(out, ")\n"); } if (tail) { if (cgi) write_escaping_html(out, tail, RSTRING_LEN(einfo) - len - 1); else fwrite(tail, 1, RSTRING_LEN(einfo) - len - 1, out); if (cgi) fprintf(out, "<br>\n"); else fprintf(out, "\n"); } } } if (!NIL_P(errat)) { int i; struct RArray *ep = RARRAY(errat); #define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5) #define TRACE_HEAD 8 #define TRACE_TAIL 5 rb_ary_pop(errat); ep = RARRAY(errat); for (i=1; i<RARRAY_LEN(ep); i++) { if (TYPE(RARRAY_PTR(ep)[i]) == T_STRING) { if (cgi) { fprintf(out, "<div class=\"backtrace\">from "); write_escaping_html(out, RSTRING_PTR(RARRAY_PTR(ep)[i]), RSTRING_LEN(RARRAY_PTR(ep)[i])); } else { fprintf(out, " from "); fwrite(RSTRING_PTR(RARRAY_PTR(ep)[i]), 1, RSTRING_LEN(RARRAY_PTR(ep)[i]), out); } if (cgi) fprintf(out, "<br></div>\n"); else fprintf(out, "\n"); } if (i == TRACE_HEAD && RARRAY_LEN(ep) > TRACE_MAX) { char buff[BUFSIZ]; if (cgi) snprintf(buff, BUFSIZ, "<div class=\"backtrace\">... %ld levels...\n", RARRAY_LEN(ep) - TRACE_HEAD - TRACE_TAIL); else snprintf(buff, BUFSIZ, " ... %ld levels...<br></div>\n", RARRAY_LEN(ep) - TRACE_HEAD - TRACE_TAIL); if (cgi) write_escaping_html(out, buff, strlen(buff)); else fputs(buff, out); i = RARRAY_LEN(ep) - TRACE_TAIL; } } } }
VALUE rb_czmq_timer_s_new(int argc, VALUE *argv, VALUE timer) { VALUE delay, times, proc, callback; size_t timer_delay; zmq_timer_wrapper *tr = NULL; rb_scan_args(argc, argv, "21&", &delay, ×, &proc, &callback); if (NIL_P(proc) && NIL_P(callback)) rb_raise(rb_eArgError, "no callback given!"); if (NIL_P(proc)) { rb_need_block(); } else { callback = proc; } if (TYPE(delay) != T_FIXNUM && TYPE(delay) != T_FLOAT) rb_raise(rb_eTypeError, "wrong delay type %s (expected Fixnum or Float)", RSTRING_PTR(rb_obj_as_string(delay))); Check_Type(times, T_FIXNUM); timer_delay = (size_t)(((TYPE(delay) == T_FIXNUM) ? FIX2LONG(delay) : RFLOAT_VALUE(delay)) * 1000); timer = Data_Make_Struct(rb_cZmqTimer, zmq_timer_wrapper, rb_czmq_mark_timer, rb_czmq_free_timer_gc, tr); tr->cancelled = FALSE; tr->delay = timer_delay; tr->times = FIX2INT(times); tr->callback = callback; rb_obj_call_init(timer, 0, NULL); return timer; }
static void setup_send_buffer(struct rw_args *x, VALUE buffer) { buffer = rb_obj_as_string(buffer); x->msg_ptr = RSTRING_PTR(buffer); x->msg_len = (size_t)RSTRING_LEN(buffer); }
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; }