/* * call-seq: * Krypt::PEM.decode(data) { |der, name, i| block } -> Array * * +data+ can be either a PEM-encoded String, an IO-like object that features * a +read+ method or any arbitrary object that has a +to_pem+ method returning * either a String or an IO-like object. * * Returns an Array that contains the DER-encoded results in the order they * were decoded. PEM data can potentially consist of multiple elements, a * common example being 'trusted certificate bundles' that contain a set of * to-be-trusted certificates. * * If additionally a block is given, +block+ is called for each element that is * decoded, where +der+ contains the decoded element, +name+ the identifier of * the current element (e.g. 'CERTIFICATE') and +i+ the index of the current * element starting with 0. * * === Example: Decoding a simple certificate file * * File.open("certificate.pem", "rb") do |f| * cert = Krypt::PEM.decode(f)[0] * # process the certificate * end * * === Example: Decoding multiple elements contained in one file * * File.open("trusted-certs.pem", "rb") do |f| * Krypt::PEM.decode(f) do |der, name, i| * puts "Element #{i}: #{name}" * File.open("cert-#{i}.der", "wb") do |g| * g.print der * end * end * end */ static VALUE krypt_pem_decode(VALUE self, VALUE pem) { VALUE ary, der; size_t i = 0; int result; binyo_instream *in = krypt_instream_new_pem(krypt_instream_new_value_pem(pem)); ary = rb_ary_new(); while ((result = int_consume_stream(in, &der)) == KRYPT_OK) { if (NIL_P(der)) break; rb_ary_push(ary, der); if(rb_block_given_p()) { uint8_t *name; size_t len; VALUE vname; if (krypt_pem_get_last_name(in, &name, &len) == BINYO_ERR) goto error; vname = rb_str_new((const char *) name, len); xfree(name); rb_yield_values(3, der, vname, SIZET2NUM(i++)); } krypt_pem_continue_stream(in); } if (result == KRYPT_ERR) goto error; binyo_instream_free(in); return ary; error: binyo_instream_free(in); krypt_error_raise(eKryptPEMError, "Error while decoding PEM data"); return Qnil; }
/* * call-seq: * Sedna.connect(details) -> Sedna instance * Sedna.connect(details) {|sedna| ... } -> nil * * Establishes a new connection to a \Sedna XML database. Accepts a hash that * describes which database to connect to. * * If a block is given, the block is executed if a connection was successfully * established. The connection is closed at the end of the block or if the * stack is unwinded (if an exception is raised, for example). If called * without a block, a Sedna object that represents the connection is returned. * The connection should be closed by calling Sedna#close. * * If a connection cannot be initiated, a Sedna::ConnectionError is raised. * If the authentication fails, a Sedna::AuthenticationError is raised. * * This method does not block other threads in Ruby 1.9.1+ -- connections that * are initiated in different threads will be created concurrently. You can * use Sedna.blocking? to verify if the extension supports non-blocking * behaviour. * * ==== Valid connection details keys * * * <tt>:host</tt> - Host name or IP address to which to connect to (defaults to +localhost+). * * <tt>:database</tt> - Name of the database to connect to (defaults to +test+). * * <tt>:username</tt> - User name to authenticate with (defaults to +SYSTEM+). * * <tt>:password</tt> - Password to authenticate with (defaults to +MANAGER+). * * ==== Examples * * Call without a block and close the connection afterwards. * * sedna = Sedna.connect :database => "my_db", :host => "my_host" * # Query the database and close afterwards. * sedna.close * * Call with a block. The connection is closed automatically. * * Sedna.connect :database => "my_db", :host => "my_host" do |sedna| * # Query the database. * # The connection is closed automatically. * end */ static VALUE cSedna_s_connect(VALUE klass, VALUE options) { int status; // Create a new instance. VALUE obj = rb_funcall(klass, rb_intern("new"), 1, options); if(rb_block_given_p()) { // If a block is given, yield the instance, and make sure we always return... rb_protect(rb_yield, obj, &status); // ...to ensure that the connection is closed afterwards. cSedna_close(obj); // Re-raise any exception. if(status != 0) rb_jump_tag(status); // Always return nil if successful. return Qnil; } else { // If no block is given, simply return the instance. return obj; } }
static VALUE rb_struct_s_def(int argc, VALUE *argv, VALUE klass) { VALUE name, rest; long i; VALUE st; ID id; rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS); name = argv[0]; if (SYMBOL_P(name)) { name = Qnil; } else { --argc; ++argv; } rest = rb_ary_tmp_new(argc); for (i=0; i<argc; i++) { id = rb_to_id(argv[i]); RARRAY_ASET(rest, i, ID2SYM(id)); rb_ary_set_len(rest, i+1); } if (NIL_P(name)) { st = anonymous_struct(klass); } else { st = new_struct(name, klass); } setup_struct(st, rest); if (rb_block_given_p()) { rb_mod_module_eval(0, 0, st); } return st; }
/* * call-seq: * remotes.rename(remote, new_name) { |str| } -> remote * remotes.rename(name, new_name) { |str| } -> remote * * Renames a remote. * * All remote-tracking branches and configuration settings * for the remote are updated. * * Non-default refspecs cannot be renamed automatically and will be * yielded to the given block. * * Anonymous, in-memory remotes created through * +ReferenceCollection#create_anonymous+ can not be given a name through * this method. * * Returns a new Rugged::Remote object with the new name. */ static VALUE rb_git_remote_collection_rename(VALUE self, VALUE rb_name_or_remote, VALUE rb_new_name) { VALUE rb_repo = rugged_owner(self); git_repository *repo; size_t i; int error, exception; git_strarray problems; if (!rb_block_given_p()) rb_raise(rb_eArgError, "Rugged::RemoteCollection#rename must be called with a block"); Check_Type(rb_new_name, T_STRING); if (rb_obj_is_kind_of(rb_name_or_remote, rb_cRuggedRemote)) rb_name_or_remote = rb_funcall(rb_name_or_remote, rb_intern("name"), 0); if (TYPE(rb_name_or_remote) != T_STRING) rb_raise(rb_eTypeError, "Expecting a String or Rugged::Remote instance"); rugged_check_repo(rb_repo); Data_Get_Struct(rb_repo, git_repository, repo); error = git_remote_rename(&problems, repo, StringValueCStr(rb_name_or_remote), StringValueCStr(rb_new_name)); rugged_exception_check(error); for (i = exception = 0; !exception && i < problems.count; ++i) { rb_protect(rb_yield, rb_str_new_utf8(problems.strings[i]), &exception); } git_strarray_free(&problems); if (exception) rb_jump_tag(exception); return rb_git_remote_collection_aref(self, rb_new_name); }
int ossl_pem_passwd_cb(char *buf, int max_len, int flag, void *pwd) { int len, status = 0; VALUE rflag, pass; if (pwd || !rb_block_given_p()) return PEM_def_callback(buf, max_len, flag, pwd); while (1) { /* * when the flag is nonzero, this passphrase * will be used to perform encryption; otherwise it will * be used to perform decryption. */ rflag = flag ? Qtrue : Qfalse; pass = rb_protect(ossl_pem_passwd_cb0, rflag, &status); if (status) { /* ignore an exception raised. */ rb_set_errinfo(Qnil); return -1; } len = RSTRING_LENINT(pass); if (len < 4) { /* 4 is OpenSSL hardcoded limit */ rb_warning("password must be longer than 4 bytes"); continue; } if (len > max_len) { rb_warning("password must be shorter then %d bytes", max_len-1); continue; } memcpy(buf, RSTRING_PTR(pass), len); break; } return len; }
static VALUE rb_struct_s_def(int argc, VALUE *argv, VALUE klass) { VALUE name, rest; long i; VALUE st; ID id; rb_scan_args(argc, argv, "1*", &name, &rest); if (!NIL_P(name) && SYMBOL_P(name)) { rb_ary_unshift(rest, name); name = Qnil; } for (i=0; i<RARRAY_LEN(rest); i++) { id = rb_to_id(RARRAY_PTR(rest)[i]); RARRAY_PTR(rest)[i] = ID2SYM(id); } st = make_struct(name, rest, klass); if (rb_block_given_p()) { rb_mod_module_eval(0, 0, st); } return st; }
/* :nodoc: */ static VALUE generator_initialize(int argc, VALUE *argv, VALUE obj) { VALUE proc; if (argc == 0) { rb_need_block(); proc = rb_block_proc(); } else { rb_scan_args(argc, argv, "1", &proc); if (!rb_obj_is_proc(proc)) rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc)", rb_obj_classname(proc)); if (rb_block_given_p()) { rb_warn("given block not used"); } } return generator_init(obj, proc); }
VALUE shoes_canvas_shape(int argc, VALUE *argv, VALUE self) { int x; double x1, y1, x2, y2; cairo_t *shape = NULL; cairo_path_t *line = NULL; SETUP_SHAPE(); shape = canvas->shape; attr = shoes_shape_attr(argc, argv, 2, s_left, s_top); canvas->shape = cairo_create(cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 1, 1)); cairo_move_to(canvas->shape, 0, 0); if (rb_block_given_p()) rb_yield(Qnil); cairo_path_extents(canvas->shape, &x1, &y1, &x2, &y2); x = x2 - x1; ATTRSET(attr, width, INT2NUM(x)); x = y2 - y1; ATTRSET(attr, height, INT2NUM(x)); line = cairo_copy_path(canvas->shape); canvas->shape = shape; return shoes_add_shape(self, s_shape, attr, line); }
static VALUE rb_struct_s_def(VALUE klass, SEL sel, int argc, VALUE *argv) { VALUE name, rest; long i, count; VALUE st; ID id; rb_scan_args(argc, argv, "1*", &name, &rest); if (!NIL_P(name) && SYMBOL_P(name)) { rb_ary_unshift(rest, name); name = Qnil; } for (i = 0, count = RARRAY_LEN(rest); i < count; i++) { id = rb_to_id(RARRAY_AT(rest, i)); rb_ary_store(rest, i, ID2SYM(id)); } st = make_struct(name, rest, klass); if (rb_block_given_p()) { rb_mod_module_eval(st, 0, 0, 0); } return st; }
static VALUE fdbm_fetch(VALUE obj, VALUE keystr, VALUE ifnone) { datum key, value; struct dbmdata *dbmp; DBM *dbm; long len; ExportStringValue(keystr); len = RSTRING_LEN(keystr); if (TOO_LONG(len)) goto not_found; key.dptr = RSTRING_PTR(keystr); key.dsize = (DSIZE_TYPE)len; GetDBM2(obj, dbmp, dbm); value = dbm_fetch(dbm, key); if (value.dptr == 0) { not_found: if (ifnone == Qnil && rb_block_given_p()) return rb_yield(rb_tainted_str_new(key.dptr, key.dsize)); return ifnone; } return rb_tainted_str_new(value.dptr, value.dsize); }
/* :nodoc: */ static VALUE rb_git_remote_each(VALUE klass, VALUE rb_repo) { git_repository *repo; git_strarray remotes; size_t i; int error = 0; int exception = 0; if (!rb_block_given_p()) return rb_funcall(klass, rb_intern("to_enum"), 2, CSTR2SYM("each"), rb_repo); rugged_check_repo(rb_repo); Data_Get_Struct(rb_repo, git_repository, repo); error = git_remote_list(&remotes, repo); rugged_exception_check(error); for (i = 0; !exception && !error && i < remotes.count; ++i) { git_remote *remote; error = git_remote_load(&remote, repo, remotes.strings[i]); if (!error) { rb_protect( rb_yield, rugged_remote_new(klass, rb_repo, remote), &exception); } } git_strarray_free(&remotes); if (exception) rb_jump_tag(exception); rugged_exception_check(error); return Qnil; }
void rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, Type** paramTypes, FFIStorage* paramStorage, void** ffiValues, VALUE* callbackParameters, int callbackCount, VALUE enums) { VALUE callbackProc = Qnil; FFIStorage* param = ¶mStorage[0]; int i, argidx, cbidx, argCount; if (unlikely(paramCount != -1 && paramCount != argc)) { if (argc == (paramCount - 1) && callbackCount == 1 && rb_block_given_p()) { callbackProc = rb_block_proc(); } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, paramCount); } } argCount = paramCount != -1 ? paramCount : argc; for (i = 0, argidx = 0, cbidx = 0; i < argCount; ++i) { Type* paramType = paramTypes[i]; int type; if (unlikely(paramType->nativeType == NATIVE_MAPPED)) { VALUE values[] = { argv[argidx], Qnil }; argv[argidx] = rb_funcall2(((MappedType *) paramType)->rbConverter, id_to_native, 2, values); paramType = ((MappedType *) paramType)->type; } type = argidx < argc ? TYPE(argv[argidx]) : T_NONE; ffiValues[i] = param; switch (paramType->nativeType) { case NATIVE_INT8: param->s8 = NUM2INT(argv[argidx]); ++argidx; ADJ(param, INT8); break; case NATIVE_INT16: param->s16 = NUM2INT(argv[argidx]); ++argidx; ADJ(param, INT16); break; case NATIVE_INT32: if (unlikely(type == T_SYMBOL && enums != Qnil)) { VALUE value = rb_funcall(enums, id_map_symbol, 1, argv[argidx]); param->s32 = NUM2INT(value); } else { param->s32 = NUM2INT(argv[argidx]); } ++argidx; ADJ(param, INT32); break; case NATIVE_BOOL: if (type != T_TRUE && type != T_FALSE) { rb_raise(rb_eTypeError, "wrong argument type (expected a boolean parameter)"); } param->s8 = argv[argidx++] == Qtrue; ADJ(param, INT8); break; case NATIVE_UINT8: param->u8 = NUM2UINT(argv[argidx]); ADJ(param, INT8); ++argidx; break; case NATIVE_UINT16: param->u16 = NUM2UINT(argv[argidx]); ADJ(param, INT16); ++argidx; break; case NATIVE_UINT32: param->u32 = NUM2UINT(argv[argidx]); ADJ(param, INT32); ++argidx; break; case NATIVE_INT64: param->i64 = NUM2LL(argv[argidx]); ADJ(param, INT64); ++argidx; break; case NATIVE_UINT64: param->u64 = NUM2ULL(argv[argidx]); ADJ(param, INT64); ++argidx; break; case NATIVE_LONG: *(ffi_sarg *) param = NUM2LONG(argv[argidx]); ADJ(param, LONG); ++argidx; break; case NATIVE_ULONG: *(ffi_arg *) param = NUM2ULONG(argv[argidx]); ADJ(param, LONG); ++argidx; break; case NATIVE_FLOAT32: param->f32 = (float) NUM2DBL(argv[argidx]); ADJ(param, FLOAT32); ++argidx; break; case NATIVE_FLOAT64: param->f64 = NUM2DBL(argv[argidx]); ADJ(param, FLOAT64); ++argidx; break; case NATIVE_LONGDOUBLE: param->ld = rbffi_num2longdouble(argv[argidx]); ADJ(param, LONGDOUBLE); ++argidx; break; case NATIVE_STRING: if (type == T_NIL) { param->ptr = NULL; } else { if (rb_safe_level() >= 1 && OBJ_TAINTED(argv[argidx])) { rb_raise(rb_eSecurityError, "Unsafe string parameter"); } param->ptr = StringValueCStr(argv[argidx]); } ADJ(param, ADDRESS); ++argidx; break; case NATIVE_POINTER: case NATIVE_BUFFER_IN: case NATIVE_BUFFER_OUT: case NATIVE_BUFFER_INOUT: param->ptr = getPointer(argv[argidx++], type); ADJ(param, ADDRESS); break; case NATIVE_FUNCTION: case NATIVE_CALLBACK: if (callbackProc != Qnil) { param->ptr = callback_param(callbackProc, callbackParameters[cbidx++]); } else { param->ptr = callback_param(argv[argidx], callbackParameters[cbidx++]); ++argidx; } ADJ(param, ADDRESS); break; case NATIVE_STRUCT: ffiValues[i] = getPointer(argv[argidx++], type); break; default: rb_raise(rb_eArgError, "Invalid parameter type: %d", paramType->nativeType); } } }
/* * call-seq: * conn.sasl_bind(dn=nil, mech=nil, cred=nil, sctrls=nil, cctrls=nil, sasl_options=nil) => self * conn.sasl_bind(dn=nil, mech=nil, cred=nil, sctrls=nil, cctrls=nil, sasl_options=nil) * { |conn| } => nil * * Bind an LDAP connection, using the DN, +dn+, the mechanism, +mech+, and the * credential, +cred+. * * +sctrls+ is an array of server controls, whilst +cctrls+ is an array of * client controls. * * sasl_options is a hash which should have the following keys: * * - +:authcid+ and +:authzid+ for alternate SASL authentication * - +realm+ to specify the SASL realm * * If a block is given, +self+ is yielded to the block. */ VALUE rb_ldap_conn_sasl_bind (int argc, VALUE argv[], VALUE self) { RB_LDAP_DATA *ldapdata; VALUE arg1, arg2, arg3, arg4, arg5, sasl_options = Qnil; int version; char *dn = NULL; char *mechanism = NULL; struct berval *cred = ALLOCA_N (struct berval, 1); LDAPControl **serverctrls = NULL; LDAPControl **clientctrls = NULL; /* struct berval *servercred = NULL; char *sasl_realm = NULL; char *sasl_authc_id = NULL; char *sasl_authz_id = NULL; char *sasl_secprops = NULL; struct berval passwd = { 0, NULL }; */ unsigned sasl_flags = LDAP_SASL_AUTOMATIC; Data_Get_Struct (self, RB_LDAP_DATA, ldapdata); if (!ldapdata->ldap) { if (rb_iv_get (self, "@args") != Qnil) { rb_ldap_conn_rebind (self); GET_LDAP_DATA (self, ldapdata); } else { rb_raise (rb_eLDAP_InvalidDataError, "The LDAP handler has already unbound."); } } if (ldapdata->bind) { rb_raise (rb_eLDAP_Error, "already bound."); }; switch (rb_scan_args (argc, argv, "24", &arg1, &arg2, &arg3, &arg4, &arg5, &sasl_options)) { case 6: /* nothing. this requires credentials to be parsed first. we'll get defaults after arg-scanning */ case 5: if(!NIL_P(arg5)) clientctrls = rb_ldap_get_controls (arg5); /* down seems more likely */ case 4: if(!NIL_P(arg4)) serverctrls = rb_ldap_get_controls (arg4); /* down seems more likely */ case 3: if(!NIL_P(arg3)) { cred->bv_val = StringValueCStr (arg3); cred->bv_len = RSTRING_LEN (arg3); } /* down seems more likely */ case 2: /* don't need the cred for GSSAPI */ dn = StringValuePtr (arg1); mechanism = StringValuePtr (arg2); if (rb_iv_get (self, "@sasl_quiet") == Qtrue) sasl_flags = LDAP_SASL_QUIET; break; default: rb_bug ("rb_ldap_conn_bind_s"); } ldap_get_option (ldapdata->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); if (version < LDAP_VERSION3) { version = LDAP_VERSION3; ldapdata->err = ldap_set_option (ldapdata->ldap, LDAP_OPT_PROTOCOL_VERSION, &version); Check_LDAP_Result (ldapdata->err); } /* the following works for GSSAPI, at least */ ldapdata->err = ldap_sasl_interactive_bind_s (ldapdata->ldap, dn, mechanism, serverctrls, clientctrls, sasl_flags, rb_ldap_sasl_interaction, (void*)sasl_options); if (ldapdata->err == LDAP_SASL_BIND_IN_PROGRESS) { rb_raise (rb_eNotImpError, "SASL authentication is not fully supported."); /* How can I implement this with portability? */ /* VALUE scred; scred = rb_tainted_str_new(servercred->bv_val, servercred->bv_len); */ } else { Check_LDAP_Result (ldapdata->err); ldapdata->bind = 1; } if (rb_block_given_p ()) { rb_ensure (rb_yield, self, rb_ldap_conn_unbind, self); return Qnil; } else { return self; }; }
/* * call-seq: * CSound.open(...) => snd * CSound.open(...) {|snd| block } => obj * * With no associated block, <code>open</code> is a synonym for * <code>CSound.new</code>. If the optional code block is given, it will be * passed <i>snd</i> as an argument, and the CSound object will automatically be * closed when the block terminates. In this instance, <code>CSound.open</code> * returns the value of the block. */ static VALUE ra_sound_s_open(int argc, VALUE *argv, VALUE klass) { VALUE obj = rb_class_new_instance(argc, argv, klass); if(!rb_block_given_p()) return obj; return rb_ensure(rb_yield, obj, ra_sound_close_safe, obj); }
/* Method: Draw#annotate(img, w, h, x, y, text) <{optional parms}> Purpose: annotates an image with text Returns: self Notes: Additional Draw attribute methods may be called in the optional block, which is executed in the context of an Draw object. */ VALUE Draw_annotate( VALUE self, VALUE image_arg, VALUE width_arg, VALUE height_arg, VALUE x_arg, VALUE y_arg, VALUE text) { Draw *draw; Image *image; unsigned long width, height; long x, y; AffineMatrix keep; char geometry_str[50]; // Save the affine matrix in case it is modified by // Draw#rotation= Data_Get_Struct(self, Draw, draw); keep = draw->info->affine; image_arg = rm_cur_image(image_arg); image = rm_check_frozen(image_arg); // If we have an optional parm block, run it in self's context, // allowing the app a chance to modify the object's attributes if (rb_block_given_p()) { (void)rb_obj_instance_eval(0, NULL, self); } // Translate & store in Draw structure #if defined(HAVE_INTERPRETIMAGEPROPERTIES) draw->info->text = InterpretImageProperties(NULL, image, StringValuePtr(text)); #else draw->info->text = InterpretImageAttributes(NULL, image, StringValuePtr(text)); #endif if (!draw->info->text) { rb_raise(rb_eArgError, "no text"); } // Create geometry string, copy to Draw structure, overriding // any previously existing value. width = NUM2ULONG(width_arg); height = NUM2ULONG(height_arg); x = NUM2LONG(x_arg); y = NUM2LONG(y_arg); if (width == 0 && height == 0) { sprintf(geometry_str, "%+ld%+ld", x, y); } // WxH is non-zero else { sprintf(geometry_str, "%lux%lu%+ld%+ld", width, height, x, y); } magick_clone_string(&draw->info->geometry, geometry_str); (void) AnnotateImage(image, draw->info); magick_free(draw->info->text); draw->info->text = NULL; draw->info->affine = keep; rm_check_image_exception(image, RetainOnError); return self; }
/** :call-seq: Color.new # The default color. Let's say: black Color.new :white # or any other QGlobalColor. These are cached. Color.new Color Color.new Color, alpha Color.new Brush Color.new '#rgb' # must be hexadecimals, case insensitive Color.new '#rrggbb' Color.new '#rrrgggbbb' Color.new '#rrrrggggbbbb' Color.new '#rgba' # etc Color.new red, green, blue, opaqueness = 255 # all values must be between 0 and 255 Color.new gray_value, opaqueness = 255 Color.new red, green, blue, opaqueness = 1.0 # all values must be between 0.0 and 1.0 Color.new gray_value, opaqueness = 1.0 Color.new [array_args] # splatted Color.new Hash # same as Control constructor Color.new { initblock } # same as Control constructor Colors have neither parents nor children */ static VALUE cColor_initialize(int argc, VALUE *argv, VALUE v_self) { trace1("cColor_initialize, argc=%d", argc); RPP::QColor self = v_self; VALUE v_colorsym, v_g, v_b, v_a; rb_scan_args(argc, argv, "04", &v_colorsym, &v_g, &v_b, &v_a); track4("cColor_initialize(%s, %s, %s, %s)", v_colorsym, v_g, v_b, v_a); const RPP::Object colorsym = v_colorsym; const RPP::Object g = v_g, b = v_b, a = v_a; switch (colorsym.type()) { case T_HASH: return self.call("setupQuickyhash", colorsym); case T_NIL: if (rb_block_given_p()) { trace("instance_eval on block"); return self.instance_eval(); } trace("default color assign"); *self = QColor(); return Qnil; case T_DATA: if (colorsym.is_kind_of(cColor)) { trace("when Color"); if (!g.isNil()) colorsym.call("alpha=", g); *self = *RPP::QColor(colorsym); return Qnil; } if (colorsym.is_kind_of(cBrush)) { trace("when Brush"); *self = *RPP::QColor(colorsym.call("color")); return Qnil; } break; case T_STRING: { trace("when String"); const char *s = RPP::String(colorsym); if (*s == '#') { const size_t l = strlen(s); char t[l + 1]; strcpy(t, s); s = t; for (char *u = t; *u; u++) *u = toupper(*u); switch (l) { case 5: { // 17 * 0xf = 17 * 15 = 255. How nice. const int alpha = hex2int(t[4]) * 17; t[4] = 0; QColor * const r = new QColor(t); r->setAlpha(alpha); *self = *r; return Qnil; } case 9: { const int alpha = hex2int(t[7]) * 16 + hex2int(t[8]); t[7] = 0; QColor * const r = new QColor(t); r->setAlpha(alpha); *self = *r; return Qnil; } case 13: { const int alpha = hex2int(t[10]) * 256 + hex2int(t[11]) * 16 + hex2int(t[12]); t[10] = 0; QColor * const r = new QColor(t); r->setAlphaF(alpha / 4096.0); *self = *r; return Qnil; } case 17: { const int alpha = hex2int(t[13]) * 65536 + hex2int(t[14]) * 256 + hex2int(t[15]) * 16 + hex2int(t[16]); t[13] = 0; QColor * const r = new QColor(t); r->setAlphaF(alpha / 65536.0); *self = *r; return Qnil; } default: break; } // switch strlen return cColorWrap(new QColor(s)); } // strings starting with '#' QColor * const r = new QColor(s); trace5("ordinary string '%s' -> r:%d, g:%d, b: %d, a:%d", s, r->red(), r->green(), r->blue(), r->alpha()); trace1("QColorptr = %p", r); *self = *r; return Qnil; } case T_ARRAY: { trace("when Array"); const RPP::Array ary(colorsym, RPP::VERYUNSAFE); return cColor_initialize(ary.len(), ary.ptr(), self); } case T_FIXNUM: { trace("when Fixnum"); if (b.isNil()) { const int gray = colorsym.to_i(); const int alpha = g.isNil() ? 255 : g.to_i(); *self = QColor(gray, gray, gray, alpha); return Qnil; } const int alpha = a.isNil() ? 255 : a.to_i(); *self = QColor(colorsym.to_i(), g.to_i(), b.to_i(), alpha); return Qnil; } case T_FLOAT: { trace("when Float"); if (b.isNil()) { const double gray = colorsym.to_f(); const double alpha = g.isNil() ? 1.0 : g.to_i(); *self = QColor(gray, gray, gray, alpha); return Qnil; } const double alpha = a.isNil() ? 1.0 : a.to_i(); *self = QColor(colorsym.to_f(), g.to_f(), b.to_f(), alpha); return Qnil; } case T_SYMBOL: { trace("when Symbol"); const Qt::GlobalColor gc = cColor_sym2color(cColor, colorsym); *self = QColor(gc); return Qnil; } } // switch TYPE colorsym rb_raise(rb_eArgError, "invalid color %s, %s, %s, %s", colorsym.inspect(), g.inspect(), b.inspect(), a.inspect()); } // cColor_initialize
/* * Registers a query logger or a callback that is called when a * query log event is emitted. * * @overload register(logger, options={}) * @param logger [#log, #reopen, #fin] The query logger. It is easy to * inherit {QueryLogger}. * * @!macro query-logger.register.options * @param options [::Hash] The options. * @option options [Symbol, String, Integer or nil] :flags (:default) * Flags describe what query log should be logged. * * If `flags` is String, it is parsed by {QueryLogger::Flags.parse}. * * @return void * * @overload register(options={}) * @yield [action, flag, timestamp, info, message] * ... * * @!macro query-logger.register.options */ static VALUE rb_grn_query_logger_s_register (int argc, VALUE *argv, VALUE klass) { VALUE rb_context = Qnil; grn_ctx *context; VALUE rb_logger, rb_callback; VALUE rb_options, rb_command, rb_result_code, rb_destination; VALUE rb_cache, rb_size, rb_score, rb_default, rb_all, rb_flags; unsigned int flags = GRN_QUERY_LOG_NONE; rb_scan_args(argc, argv, "02&", &rb_logger, &rb_options, &rb_callback); if (rb_block_given_p()) { rb_logger = rb_funcall(cGrnCallbackQueryLogger, id_new, 1, rb_callback); } rb_grn_scan_options(rb_options, "command", &rb_command, "result_code", &rb_result_code, "destination", &rb_destination, "cache", &rb_cache, "size", &rb_size, "score", &rb_score, "default", &rb_default, "all", &rb_all, "flags", &rb_flags, NULL); if (RVAL2CBOOL(rb_command)) { flags |= GRN_QUERY_LOG_COMMAND; } if (RVAL2CBOOL(rb_result_code)) { flags |= GRN_QUERY_LOG_RESULT_CODE; } if (RVAL2CBOOL(rb_destination)) { flags |= GRN_QUERY_LOG_DESTINATION; } if (RVAL2CBOOL(rb_cache)) { flags |= GRN_QUERY_LOG_CACHE; } if (RVAL2CBOOL(rb_size)) { flags |= GRN_QUERY_LOG_SIZE; } if (RVAL2CBOOL(rb_score)) { flags |= GRN_QUERY_LOG_SCORE; } if (RVAL2CBOOL(rb_default)) { flags |= GRN_QUERY_LOG_DEFAULT; } if (RVAL2CBOOL(rb_all)) { flags |= GRN_QUERY_LOG_ALL; } if (!NIL_P(rb_flags)) { flags = rb_funcall(mGrnQueryLoggerFlags, id_parse, 2, rb_flags, UINT2NUM(flags)); } rb_grn_query_logger.flags = flags; rb_grn_query_logger.user_data = (void *)rb_logger; context = rb_grn_context_ensure(&rb_context); grn_query_logger_set(context, &rb_grn_query_logger); rb_grn_context_check(context, rb_logger); rb_cv_set(klass, "@@current_logger", rb_logger); return Qnil; }
static VALUE zipruby_archive_s_open_buffer(int argc, VALUE *argv, VALUE self) { VALUE buffer, flags, comp_level; VALUE archive; struct zipruby_archive *p_archive; void *data = NULL; int len = 0, i_flags = 0; int errorp; int i_comp_level = Z_BEST_COMPRESSION; int buffer_is_temporary = 0; rb_scan_args(argc, argv, "03", &buffer, &flags, &comp_level); if (FIXNUM_P(buffer) && NIL_P(comp_level)) { comp_level = flags; flags = buffer; buffer = Qnil; } if (!NIL_P(flags)) { i_flags = NUM2INT(flags); } if (!NIL_P(comp_level)) { i_comp_level = NUM2INT(comp_level); if (i_comp_level != Z_DEFAULT_COMPRESSION && i_comp_level != Z_NO_COMPRESSION && (i_comp_level < Z_BEST_SPEED || Z_BEST_COMPRESSION < i_comp_level)) { rb_raise(rb_eArgError, "Wrong compression level %d", i_comp_level); } } if (i_flags & ZIP_CREATE) { if (!NIL_P(buffer)) { Check_Type(buffer, T_STRING); } else { buffer = rb_str_new("", 0); buffer_is_temporary = 1; } i_flags = (i_flags | ZIP_TRUNCATE); } else if (TYPE(buffer) == T_STRING) { data = RSTRING_PTR(buffer); len = RSTRING_LEN(buffer); } else if (rb_obj_is_instance_of(buffer, rb_cProc)) { data = (void *) buffer; len = -1; } else { rb_raise(rb_eTypeError, "wrong argument type %s (expected String or Proc)", rb_class2name(CLASS_OF(buffer))); } archive = rb_funcall(Archive, rb_intern("new"), 0); Data_Get_Struct(archive, struct zipruby_archive, p_archive); if ((p_archive->tmpfilnam = zipruby_tmpnam(data, len)) == NULL) { rb_raise(Error, "Open archive failed: Failed to create temporary file"); } if ((p_archive->archive = zip_open(p_archive->tmpfilnam, i_flags, &errorp)) == NULL) { char errstr[ERRSTR_BUFSIZE]; zip_error_to_str(errstr, ERRSTR_BUFSIZE, errorp, errno); rb_raise(Error, "Open archive failed: %s", errstr); } // p_archive->archive->comp_level = i_comp_level; p_archive->path = rb_str_new2(p_archive->tmpfilnam); p_archive->flags = i_flags; p_archive->buffer = buffer; p_archive->sources = rb_ary_new(); if (rb_block_given_p()) { VALUE retval; int status; retval = rb_protect(rb_yield, archive, &status); zipruby_archive_close(archive); if (status != 0) { rb_jump_tag(status); } return buffer_is_temporary ? buffer : retval; } else { return archive; } }
bool blockGiven() { return rb_block_given_p(); }
void rbffi_SetupCallParams(int argc, VALUE* argv, int paramCount, NativeType* paramTypes, FFIStorage* paramStorage, void** ffiValues, VALUE* callbackParameters, int callbackCount, VALUE enums) { VALUE callbackProc = Qnil; FFIStorage* param = ¶mStorage[0]; int i, argidx, cbidx, argCount; if (paramCount != -1 && paramCount != argc) { if (argc == (paramCount - 1) && callbackCount == 1 && rb_block_given_p()) { callbackProc = rb_block_proc(); } else { rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, paramCount); } } argCount = paramCount != -1 ? paramCount : argc; for (i = 0, argidx = 0, cbidx = 0; i < argCount; ++i) { int type = argidx < argc ? TYPE(argv[argidx]) : T_NONE; ffiValues[i] = param; switch (paramTypes[i]) { case NATIVE_INT8: param->s8 = getSignedInt(argv[argidx++], type, -128, 127, "char", Qnil); ADJ(param, INT8); break; case NATIVE_INT16: param->s16 = getSignedInt(argv[argidx++], type, -0x8000, 0x7fff, "short", Qnil); ADJ(param, INT16); break; case NATIVE_INT32: case NATIVE_ENUM: param->s32 = getSignedInt(argv[argidx++], type, -0x80000000, 0x7fffffff, "int", enums); ADJ(param, INT32); break; case NATIVE_BOOL: if (type != T_TRUE && type != T_FALSE) { rb_raise(rb_eTypeError, "wrong argument type (expected a boolean parameter)"); } param->s8 = argv[argidx++] == Qtrue; ADJ(param, INT8); break; case NATIVE_UINT8: param->u8 = getUnsignedInt(argv[argidx++], type, 0xff, "unsigned char"); ADJ(param, INT8); break; case NATIVE_UINT16: param->u16 = getUnsignedInt(argv[argidx++], type, 0xffff, "unsigned short"); ADJ(param, INT16); break; case NATIVE_UINT32: /* Special handling/checking for unsigned 32 bit integers */ param->u32 = getUnsignedInt32(argv[argidx++], type); ADJ(param, INT32); break; case NATIVE_INT64: if (type != T_FIXNUM && type != T_BIGNUM) { rb_raise(rb_eTypeError, "Expected an Integer parameter"); } param->i64 = NUM2LL(argv[argidx]); ADJ(param, INT64); ++argidx; break; case NATIVE_UINT64: if (type != T_FIXNUM && type != T_BIGNUM) { rb_raise(rb_eTypeError, "Expected an Integer parameter"); } param->u64 = NUM2ULL(argv[argidx]); ADJ(param, INT64); ++argidx; break; case NATIVE_LONG: *(ffi_sarg *) param = NUM2LONG(argv[argidx]); ADJ(param, LONG); ++argidx; break; case NATIVE_ULONG: *(ffi_arg *) param = NUM2ULONG(argv[argidx]); ADJ(param, LONG); ++argidx; break; case NATIVE_FLOAT32: if (type != T_FLOAT && type != T_FIXNUM) { rb_raise(rb_eTypeError, "Expected a Float parameter"); } param->f32 = (float) NUM2DBL(argv[argidx]); ADJ(param, FLOAT32); ++argidx; break; case NATIVE_FLOAT64: if (type != T_FLOAT && type != T_FIXNUM) { rb_raise(rb_eTypeError, "Expected a Float parameter"); } param->f64 = NUM2DBL(argv[argidx]); ADJ(param, FLOAT64); ++argidx; break; case NATIVE_STRING: param->ptr = getString(argv[argidx++], type); ADJ(param, ADDRESS); break; case NATIVE_POINTER: case NATIVE_BUFFER_IN: case NATIVE_BUFFER_OUT: case NATIVE_BUFFER_INOUT: param->ptr = getPointer(argv[argidx++], type); ADJ(param, ADDRESS); break; case NATIVE_FUNCTION: case NATIVE_CALLBACK: if (callbackProc != Qnil) { param->ptr = callback_param(callbackProc, callbackParameters[cbidx++]); } else { param->ptr = callback_param(argv[argidx], callbackParameters[cbidx++]); ++argidx; } ADJ(param, ADDRESS); break; case NATIVE_STRUCT: ffiValues[i] = getPointer(argv[argidx++], type); break; default: rb_raise(rb_eArgError, "Invalid parameter type: %d", paramTypes[i]); } } }
int rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) { int i; const char *p = fmt; VALUE *var; va_list vargs; int f_var = 0, f_block = 0; int n_lead = 0, n_opt = 0, n_trail = 0, n_mand; int argi = 0; if (ISDIGIT(*p)) { n_lead = *p - '0'; p++; if (ISDIGIT(*p)) { n_opt = *p - '0'; p++; if (ISDIGIT(*p)) { n_trail = *p - '0'; p++; goto block_arg; } } } if (*p == '*') { f_var = 1; p++; if (ISDIGIT(*p)) { n_trail = *p - '0'; p++; } } block_arg: if (*p == '&') { f_block = 1; p++; } if (*p != '\0') { rb_fatal("bad scan arg format: %s", fmt); } n_mand = n_lead + n_trail; if (argc < n_mand) goto argc_error; va_start(vargs, fmt); /* capture leading mandatory arguments */ for (i = n_lead; i-- > 0; ) { var = va_arg(vargs, VALUE *); if (var) *var = argv[argi]; argi++; } /* capture optional arguments */ for (i = n_opt; i-- > 0; ) { var = va_arg(vargs, VALUE *); if (argi < argc - n_trail) { if (var) *var = argv[argi]; argi++; } else { if (var) *var = Qnil; } } /* capture variable length arguments */ if (f_var) { int n_var = argc - argi - n_trail; var = va_arg(vargs, VALUE *); if (0 < n_var) { if (var) *var = rb_ary_new4(n_var, &argv[argi]); argi += n_var; } else { if (var) *var = rb_ary_new(); } } /* capture trailing mandatory arguments */ for (i = n_trail; i-- > 0; ) { var = va_arg(vargs, VALUE *); if (var) *var = argv[argi]; argi++; } /* capture iterator block */ if (f_block) { var = va_arg(vargs, VALUE *); if (rb_block_given_p()) { *var = rb_block_proc(); } else { *var = Qnil; } } va_end(vargs); if (argi < argc) goto argc_error; return argc; argc_error: if (0 < n_opt) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d..%d%s)", argc, n_mand, n_mand + n_opt, f_var ? "+" : ""); else rb_raise(rb_eArgError, "wrong number of arguments (%d for %d%s)", argc, n_mand, f_var ? "+" : ""); }
int rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) { int i; const char *p = fmt; VALUE *var; va_list vargs; int f_var = 0, f_hash = 0, f_block = 0; int n_lead = 0, n_opt = 0, n_trail = 0, n_mand; int argi = 0; VALUE hash = Qnil; if (ISDIGIT(*p)) { n_lead = *p - '0'; p++; if (ISDIGIT(*p)) { n_opt = *p - '0'; p++; if (ISDIGIT(*p)) { n_trail = *p - '0'; p++; goto block_arg; } } } if (*p == '*') { f_var = 1; p++; if (ISDIGIT(*p)) { n_trail = *p - '0'; p++; } } block_arg: if (*p == ':') { f_hash = 1; p++; } if (*p == '&') { f_block = 1; p++; } if (*p != '\0') { rb_fatal("bad scan arg format: %s", fmt); } n_mand = n_lead + n_trail; if (argc < n_mand) goto argc_error; va_start(vargs, fmt); /* capture an option hash - phase 1: pop */ if (f_hash && n_mand < argc) { VALUE last = argv[argc - 1]; if (NIL_P(last)) { /* nil is taken as an empty option hash only if it is not ambiguous; i.e. '*' is not specified and arguments are given more than sufficient */ if (!f_var && n_mand + n_opt < argc) argc--; } else { hash = rb_check_hash_type(last); if (!NIL_P(hash)) { VALUE opts = rb_extract_keywords(&hash); if (!hash) argc--; hash = opts ? opts : Qnil; } } } /* capture leading mandatory arguments */ for (i = n_lead; i-- > 0; ) { var = va_arg(vargs, VALUE *); if (var) *var = argv[argi]; argi++; } /* capture optional arguments */ for (i = n_opt; i-- > 0; ) { var = va_arg(vargs, VALUE *); if (argi < argc - n_trail) { if (var) *var = argv[argi]; argi++; } else { if (var) *var = Qnil; } } /* capture variable length arguments */ if (f_var) { int n_var = argc - argi - n_trail; var = va_arg(vargs, VALUE *); if (0 < n_var) { if (var) *var = rb_ary_new4(n_var, &argv[argi]); argi += n_var; } else { if (var) *var = rb_ary_new(); } } /* capture trailing mandatory arguments */ for (i = n_trail; i-- > 0; ) { var = va_arg(vargs, VALUE *); if (var) *var = argv[argi]; argi++; } /* capture an option hash - phase 2: assignment */ if (f_hash) { var = va_arg(vargs, VALUE *); if (var) *var = hash; } /* capture iterator block */ if (f_block) { var = va_arg(vargs, VALUE *); if (rb_block_given_p()) { *var = rb_block_proc(); } else { *var = Qnil; } } va_end(vargs); if (argi < argc) { argc_error: rb_error_arity(argc, n_mand, f_var ? UNLIMITED_ARGUMENTS : n_mand + n_opt); } return argc; }
/* * call-seq: * ProcTable.ps(pid=nil) * ProcTable.ps(pid=nil){ |ps| ... } * * In block form, yields a ProcTableStruct for each process entry that you * have rights to. This method returns an array of ProcTableStruct's in * non-block form. * * If a +pid+ is provided, then only a single ProcTableStruct is yielded or * returned, or nil if no process information is found for that +pid+. */ static VALUE pt_ps(int argc, VALUE* argv, VALUE klass){ int err; char state[8]; struct kinfo_proc* procs; VALUE v_pid, v_tty_num, v_tty_dev, v_start_time; VALUE v_pstruct = Qnil; VALUE v_array = rb_ary_new(); size_t length, count; size_t i = 0; int g; VALUE v_cmdline, v_exe, v_environ, v_groups; // Passed into sysctl call static const int name_mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; rb_scan_args(argc, argv, "01", &v_pid); // Get size of proc kproc buffer err = sysctl( (int *) name_mib, PROC_MIB_LEN, NULL, &length, NULL, 0); if(err == -1) rb_raise(cProcTableError, "sysctl: %s", strerror(errno)); // Populate the kproc buffer procs = ruby_xmalloc(length); err = sysctl( (int *) name_mib, PROC_MIB_LEN, procs, &length, NULL, 0); if(err == -1) rb_raise(cProcTableError, "sysctl: %s", strerror(errno)); // If we're here, we got our list count = length / sizeof(struct kinfo_proc); for(i = 0; i < count; i++) { v_tty_num = Qnil; v_tty_dev = Qnil; v_start_time = Qnil; // If a PID is provided, skip unless the PID matches if( (!NIL_P(v_pid)) && (procs[i].kp_proc.p_pid != NUM2INT(v_pid)) ) continue; // cmdline will be set only if process exists and belongs to current user or // current user is root v_cmdline = Qnil; v_exe = Qnil; v_environ = Qnil; argv_of_pid(procs[i].kp_proc.p_pid, &v_cmdline, &v_exe, &v_environ); // Get the start time of the process v_start_time = rb_time_new( procs[i].kp_proc.p_un.__p_starttime.tv_sec, procs[i].kp_proc.p_un.__p_starttime.tv_usec ); // Get the state of the process switch(procs[i].kp_proc.p_stat) { case SIDL: strcpy(state, "idle"); break; case SRUN: strcpy(state, "run"); break; case SSLEEP: strcpy(state, "sleep"); break; case SSTOP: strcpy(state, "stop"); break; case SZOMB: strcpy(state, "zombie"); break; default: strcpy(state, "unknown"); break; } // Get ttynum and ttydev. If ttynum is -1, there is no tty. if(procs[i].kp_eproc.e_tdev != -1){ v_tty_num = INT2FIX(procs[i].kp_eproc.e_tdev), v_tty_dev = rb_str_new2(devname(procs[i].kp_eproc.e_tdev, S_IFCHR)); } v_groups = rb_ary_new(); for (g = 0; g < procs[i].kp_eproc.e_ucred.cr_ngroups; ++g) rb_ary_push(v_groups, INT2FIX(procs[i].kp_eproc.e_ucred.cr_groups[g])); v_pstruct = rb_struct_new( sProcStruct, INT2FIX(procs[i].kp_proc.p_pid), INT2FIX(procs[i].kp_eproc.e_ppid), INT2FIX(procs[i].kp_eproc.e_pgid), INT2FIX(procs[i].kp_eproc.e_pcred.p_ruid), INT2FIX(procs[i].kp_eproc.e_pcred.p_rgid), INT2FIX(procs[i].kp_eproc.e_ucred.cr_uid), rb_ary_entry(v_groups, 0), v_groups, INT2FIX(procs[i].kp_eproc.e_pcred.p_svuid), INT2FIX(procs[i].kp_eproc.e_pcred.p_svgid), rb_str_new2(procs[i].kp_proc.p_comm), rb_str_new2(state), rb_float_new(procs[i].kp_proc.p_pctcpu), Qnil, v_tty_num, v_tty_dev, rb_str_new2(procs[i].kp_eproc.e_wmesg), INT2FIX(procs[i].kp_proc.p_rtime.tv_sec), INT2FIX(procs[i].kp_proc.p_priority), INT2FIX(procs[i].kp_proc.p_usrpri), INT2FIX(procs[i].kp_proc.p_nice), v_cmdline, v_exe, v_environ, v_start_time, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_maxrss) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_ixrss) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_idrss) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_isrss) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_minflt) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_majflt) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nswap) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_inblock) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_oublock) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_msgsnd) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_msgrcv) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nsignals) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nvcsw) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nivcsw) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_utime.tv_sec) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_stime.tv_sec) : Qnil ); OBJ_FREEZE(v_pstruct); // This is read-only data if(rb_block_given_p()) rb_yield(v_pstruct); else rb_ary_push(v_array, v_pstruct); } if(procs) free(procs); if(!rb_block_given_p()){ if(NIL_P(v_pid)) return v_array; else return v_pstruct; } return Qnil; }
/* * It creates a table that manages records by double array trie. * ブロックを指定すると、そのブロックに生成したテーブルが渡さ * れ、ブロックを抜けると自動的にテーブルが破棄される。 * * @example * #無名一時テーブルを生成する。 * Groonga::DoubleArrayTrie.create * * #無名永続テーブルを生成する。 * Groonga::DoubleArrayTrie.create(:path => "/tmp/hash.grn") * * #名前付き永続テーブルを生成する。ただし、ファイル名は気に * #しない。 * Groonga::DoubleArrayTrie.create(:name => "Bookmarks", * :persistent => true) * * #それぞれのレコードに512バイトの値を格納できる無名一時テー * #ブルを生成する。 * Groonga::DoubleArrayTrie.create(:value => 512) * * #キーとして文字列を使用する無名一時テーブルを生成する。 * Groonga::DoubleArrayTrie.create(:key_type => Groonga::Type::SHORT_TEXT) * * #キーとして文字列を使用する無名一時テーブルを生成する。 * #(キーの種類を表すオブジェクトは文字列で指定。) * Groonga::DoubleArrayTrie.create(:key_type => "ShortText") * * #キーとしてBookmarksテーブルのレコードを使用す * #る無名一時テーブルを生成する。 * bookmarks = Groonga::DoubleArrayTrie.create(:name => "Bookmarks") * Groonga::DoubleArrayTrie.create(:key_type => bookmarks) * * #キーとしてBookmarksテーブルのレコードを使用す * #る無名一時テーブルを生成する。 * #(テーブルは文字列で指定。) * Groonga::DoubleArrayTrie.create(:name => "Bookmarks") * Groonga::DoubleArrayTrie.create(:key_type => "Bookmarks") * * #全文検索用のトークンをバイグラムで切り出す無名一時テーブ * #ルを生成する。 * bookmarks = Groonga::DoubleArrayTrie.create(:name => "Bookmarks") * bookmarks.define_column("comment", "Text") * terms = Groonga::DoubleArrayTrie.create(:name => "Terms", * :default_tokenizer => "TokenBigram") * terms.define_index_column("content", bookmarks, * :source => "Bookmarks.comment") * * @overload create(options={}) * @return [Groonga::DoubleArrayTrie] * @!macro [new] double-array-trie.create.options * @param [::Hash] options The name and value * pairs. Omitted names are initialized as the default value. * @option options [Groonga::Context] :context (Groonga::Context.default) * テーブルが利用する {Groonga::Context} 。 * @option options :name * テーブルの名前。名前をつけると、 {Groonga::Context#[]} に名 * 前を指定してテーブルを取得することができる。省略すると * 無名テーブルになり、テーブルIDでのみ取得できる。 * @option options :path * テーブルを保存するパス。パスを指定すると永続テーブルとな * り、プロセス終了後もレコードは保持される。次回起動時に * {Groonga::Context#[]} で保存されたレコードを利用する * ことができる。省略すると一時テーブルになり、プロセスが終 * 了するとレコードは破棄される。 * @option options :persistent * +true+ を指定すると永続テーブルとなる。 +path+ を省略した * 場合は自動的にパスが付加される。 +:context+ で指定した * {Groonga::Context} に結びついているデータベースが一時デー * タベースの場合は例外が発生する。 * * @option options :key_normalize (false) Keys are normalized * if this value is @true@. * * @deprecated Use @:normalizer => "NormalizerAuto"@ instead. * * @option options :key_with_sis * +true+ を指定するとキーの文字列の全suffixが自動的に登 * 録される。 * @option options :key_type * キーの種類を示すオブジェクトを指定する。キーの種類には型 * 名("Int32"や"ShortText"など)または {Groonga::Type} または * テーブル( {Groonga::Array} 、{Groonga::Hash} 、 * {Groonga::DoubleArrayTrie} のどれか)を指定する。 * {Groonga::Type} を指定した場合は、その型が示す範囲の値をキー * として使用する。ただし、キーの最大サイズは4096バイトで * あるため、 {Groonga::Type::TEXT} や {Groonga::Type::LONG_TEXT} * は使用できない。 * * テーブルを指定した場合はレコードIDをキーとして使用する。 * 指定したテーブルの {Groonga::Record} をキーとして使用するこ * ともでき、その場合は自動的に {Groonga::Record} からレコード * IDを取得する。 * * 省略した場合はShortText型をキーとして使用する。この場合、 * 4096バイトまで使用可能である。 * @option options :value_type * 値の型を指定する。省略すると値のための領域を確保しない。 * 値を保存したい場合は必ず指定すること。 * * 参考: {Groonga::Type.new} * * @option options :default_tokenizer * {Groonga::IndexColumn} で使用するトークナイザを指定する。 * デフォルトでは何も設定されていないので、テーブルに * {Groonga::IndexColumn} を定義する場合は * @"TokenBigram"@ などを指定する必要がある。 * * @option options [::Array<String, Groonga::Procedure>, nil] * :token_filters (nil) The token filters to be used in the * table. * * @option options :sub_records * +true+ を指定すると {#group} でグループ化したときに、 * {Groonga::Record#n_sub_records} でグループに含まれるレコー * ドの件数を取得できる。 * * @option options [String, Groonga::Procedure, nil] :normalizer * The normalizer that is used by {Groonga::IndexColumn}. You * can specify this by normalizer name as String such as * @"NormalizerAuto"@ or normalizer object. * * @!macro double-array-trie.create.options * @overload create(options={}) * @yield [table] * @!macro double-array-trie.create.options */ static VALUE rb_grn_double_array_trie_s_create (int argc, VALUE *argv, VALUE klass) { grn_ctx *context; grn_obj *key_type = NULL, *value_type = NULL, *table; const char *name = NULL, *path = NULL; unsigned name_size = 0; grn_obj_flags flags = GRN_OBJ_TABLE_DAT_KEY; VALUE rb_table; VALUE options, rb_context, rb_name, rb_path, rb_persistent; VALUE rb_key_normalize, rb_key_with_sis, rb_key_type; VALUE rb_value_type; VALUE rb_default_tokenizer; VALUE rb_token_filters; VALUE rb_sub_records; VALUE rb_normalizer; rb_scan_args(argc, argv, "01", &options); rb_grn_scan_options(options, "context", &rb_context, "name", &rb_name, "path", &rb_path, "persistent", &rb_persistent, "key_normalize", &rb_key_normalize, "key_with_sis", &rb_key_with_sis, "key_type", &rb_key_type, "value_type", &rb_value_type, "default_tokenizer", &rb_default_tokenizer, "token_filters", &rb_token_filters, "sub_records", &rb_sub_records, "normalizer", &rb_normalizer, NULL); context = rb_grn_context_ensure(&rb_context); if (!NIL_P(rb_name)) { name = StringValuePtr(rb_name); name_size = RSTRING_LEN(rb_name); flags |= GRN_OBJ_PERSISTENT; } if (!NIL_P(rb_path)) { path = StringValueCStr(rb_path); flags |= GRN_OBJ_PERSISTENT; } if (RVAL2CBOOL(rb_persistent)) flags |= GRN_OBJ_PERSISTENT; if (RVAL2CBOOL(rb_key_normalize)) flags |= GRN_OBJ_KEY_NORMALIZE; if (RVAL2CBOOL(rb_key_with_sis)) flags |= GRN_OBJ_KEY_WITH_SIS; if (NIL_P(rb_key_type)) { key_type = grn_ctx_at(context, GRN_DB_SHORT_TEXT); } else { key_type = RVAL2GRNOBJECT(rb_key_type, &context); } if (!NIL_P(rb_value_type)) value_type = RVAL2GRNOBJECT(rb_value_type, &context); if (RVAL2CBOOL(rb_sub_records)) flags |= GRN_OBJ_WITH_SUBREC; table = grn_table_create(context, name, name_size, path, flags, key_type, value_type); if (!table) rb_grn_context_check(context, rb_ary_new4(argc, argv)); rb_table = GRNOBJECT2RVAL(klass, context, table, GRN_TRUE); if (!NIL_P(rb_default_tokenizer)) rb_funcall(rb_table, rb_intern("default_tokenizer="), 1, rb_default_tokenizer); if (!NIL_P(rb_token_filters)) rb_funcall(rb_table, rb_intern("token_filters="), 1, rb_token_filters); if (!NIL_P(rb_normalizer)) rb_funcall(rb_table, rb_intern("normalizer="), 1, rb_normalizer); if (rb_block_given_p()) return rb_ensure(rb_yield, rb_table, rb_grn_object_close, rb_table); else return rb_table; }
/* * call-seq: * ProcTable.ps(pid=nil) * ProcTable.ps(pid=nil){ |ps| ... } * * In block form, yields a ProcTableStruct for each process entry that you * have rights to. This method returns an array of ProcTableStruct's in * non-block form. * * If a +pid+ is provided, then only a single ProcTableStruct is yielded or * returned, or nil if no process information is found for that +pid+. */ static VALUE pt_ps(int argc, VALUE* argv, VALUE klass){ int err; char state[8]; struct kinfo_proc* procs; VALUE v_pid, v_tty_num, v_tty_dev, v_start_time; VALUE v_pstruct = Qnil; VALUE v_array = rb_ary_new(); size_t length, count; size_t i = 0; char args[ARGS_MAX_LEN+1]; // Passed into sysctl call static const int name_mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0}; rb_scan_args(argc, argv, "01", &v_pid); // Get size of proc kproc buffer err = sysctl( (int *) name_mib, PROC_MIB_LEN, NULL, &length, NULL, 0); if(err == -1) rb_raise(cProcTableError, "sysctl: %s", strerror(errno)); // Populate the kproc buffer procs = malloc(length); if(procs == NULL) rb_raise(cProcTableError, "malloc: %s", strerror(errno)); err = sysctl( (int *) name_mib, PROC_MIB_LEN, procs, &length, NULL, 0); if(err == -1) rb_raise(cProcTableError, "sysctl: %s", strerror(errno)); // If we're here, we got our list count = length / sizeof(struct kinfo_proc); for(i = 0; i < count; i++) { v_tty_num = Qnil; v_tty_dev = Qnil; v_start_time = Qnil; // If a PID is provided, skip unless the PID matches if( (!NIL_P(v_pid)) && (procs[i].kp_proc.p_pid != NUM2INT(v_pid)) ) continue; *args = '\0'; /* Query the command line args */ /* TODO: Cmd line not working for now - fix */ /*args_mib[ARGS_MIB_LEN - 1] = procs[i].kp_proc.p_pid; args_err = sysctl( (int *) args_mib, ARGS_MIB_LEN, args, &args_size, NULL, 0); if(args_err >= 0) { fprintf(stderr, "Ret: %d LEN: %d\n", err, args_size); char *c; for(c = args; c < args+args_size; c++) if(*c == '\0') *c = ' '; args[args_size] = '\0'; } else { fprintf(stderr, "err: %s LEN: %d\n", strerror(errno), args_size); }*/ char cmdline[ARGS_MAX_LEN+1]; argv_of_pid(procs[i].kp_proc.p_pid, &cmdline); /* free(cmdline); */ // Get the start time of the process v_start_time = rb_time_new( procs[i].kp_proc.p_un.__p_starttime.tv_sec, procs[i].kp_proc.p_un.__p_starttime.tv_usec ); // Get the state of the process switch(procs[i].kp_proc.p_stat) { case SIDL: strcpy(state, "idle"); break; case SRUN: strcpy(state, "run"); break; case SSLEEP: strcpy(state, "sleep"); break; case SSTOP: strcpy(state, "stop"); break; case SZOMB: strcpy(state, "zombie"); break; default: strcpy(state, "unknown"); break; } // Get ttynum and ttydev. If ttynum is -1, there is no tty. if(procs[i].kp_eproc.e_tdev != -1){ v_tty_num = INT2FIX(procs[i].kp_eproc.e_tdev), v_tty_dev = rb_str_new2(devname(procs[i].kp_eproc.e_tdev, S_IFCHR)); } v_pstruct = rb_struct_new( sProcStruct, INT2FIX(procs[i].kp_proc.p_pid), INT2FIX(procs[i].kp_eproc.e_ppid), INT2FIX(procs[i].kp_eproc.e_pgid), INT2FIX(procs[i].kp_eproc.e_pcred.p_ruid), INT2FIX(procs[i].kp_eproc.e_pcred.p_rgid), rb_str_new2(procs[i].kp_proc.p_comm), rb_str_new2(state), rb_float_new(procs[i].kp_proc.p_pctcpu), Qnil, v_tty_num, v_tty_dev, rb_str_new2(procs[i].kp_eproc.e_wmesg), INT2FIX(procs[i].kp_proc.p_rtime.tv_sec), INT2FIX(procs[i].kp_proc.p_priority), INT2FIX(procs[i].kp_proc.p_usrpri), INT2FIX(procs[i].kp_proc.p_nice), rb_str_new2(cmdline), v_start_time, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_maxrss) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_ixrss) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_idrss) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_isrss) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_minflt) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_majflt) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nswap) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_inblock) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_oublock) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_msgsnd) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_msgrcv) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nsignals) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nvcsw) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_nivcsw) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_utime.tv_sec) : Qnil, (procs[i].kp_proc.p_ru && procs[i].kp_proc.p_stat != 5) ? LONG2NUM(procs[i].kp_proc.p_ru->ru_stime.tv_sec) : Qnil ); OBJ_FREEZE(v_pstruct); // This is read-only data if(rb_block_given_p()) rb_yield(v_pstruct); else rb_ary_push(v_array, v_pstruct); } if(procs) free(procs); if(!rb_block_given_p()){ if(NIL_P(v_pid)) return v_array; else return v_pstruct; } return Qnil; }
static VALUE cCommand_execute_reader(int argc, VALUE *argv, VALUE self) { VALUE query, reader; VALUE field_names, field_types; unsigned int field_count; unsigned int i; char guess_default_field_types = 0; VALUE connection = rb_iv_get(self, "@connection"); VALUE mysql_connection = rb_iv_get(connection, "@connection"); if (Qnil == mysql_connection) { rb_raise(eConnectionError, "This connection has already been closed."); } MYSQL *db = DATA_PTR(mysql_connection); MYSQL_RES *response = 0; MYSQL_FIELD *field; query = build_query_from_args(self, argc, argv); response = cCommand_execute(self, connection, db, query); if (!response) { return Qnil; } field_count = mysql_field_count(db); reader = rb_funcall(cReader, ID_NEW, 0); rb_iv_set(reader, "@connection", connection); rb_iv_set(reader, "@reader", Data_Wrap_Struct(rb_cObject, 0, 0, response)); rb_iv_set(reader, "@opened", Qfalse); rb_iv_set(reader, "@field_count", INT2NUM(field_count)); field_names = rb_ary_new(); field_types = rb_iv_get(self, "@field_types"); if ( field_types == Qnil || 0 == RARRAY_LEN(field_types) ) { field_types = rb_ary_new(); guess_default_field_types = 1; } else if (RARRAY_LEN(field_types) != field_count) { // Whoops... wrong number of types passed to set_types. Close the reader and raise // and error rb_funcall(reader, rb_intern("close"), 0); rb_raise(rb_eArgError, "Field-count mismatch. Expected %ld fields, but the query yielded %d", RARRAY_LEN(field_types), field_count); } for(i = 0; i < field_count; i++) { field = mysql_fetch_field_direct(response, i); rb_ary_push(field_names, rb_str_new2(field->name)); if (1 == guess_default_field_types) { rb_ary_push(field_types, infer_ruby_type(field)); } } rb_iv_set(reader, "@fields", field_names); rb_iv_set(reader, "@field_types", field_types); if (rb_block_given_p()) { rb_yield(reader); rb_funcall(reader, rb_intern("close"), 0); } return reader; }
/* * call-seq: * initialize(lib = nil, flags = DL::RTLD_LAZY | DL::RTLD_GLOBAL) * * Create a new handler that opens library named +lib+ with +flags+. If no * library is specified, RTLD_DEFAULT is used. */ VALUE rb_dlhandle_initialize(int argc, VALUE argv[], VALUE self) { void *ptr; struct dl_handle *dlhandle; VALUE lib, flag; char *clib; int cflag; const char *err; switch( rb_scan_args(argc, argv, "02", &lib, &flag) ){ case 0: clib = NULL; cflag = RTLD_LAZY | RTLD_GLOBAL; break; case 1: clib = NIL_P(lib) ? NULL : StringValuePtr(lib); cflag = RTLD_LAZY | RTLD_GLOBAL; break; case 2: clib = NIL_P(lib) ? NULL : StringValuePtr(lib); cflag = NUM2INT(flag); break; default: rb_bug("rb_dlhandle_new"); } rb_secure(2); #if defined(_WIN32) if( !clib ){ HANDLE rb_libruby_handle(void); ptr = rb_libruby_handle(); } else if( STRCASECMP(clib, "libc") == 0 # ifdef RUBY_COREDLL || STRCASECMP(clib, RUBY_COREDLL) == 0 || STRCASECMP(clib, RUBY_COREDLL".dll") == 0 # endif ){ # ifdef _WIN32_WCE ptr = dlopen("coredll.dll", cflag); # else ptr = w32_coredll(); # endif } else #endif ptr = dlopen(clib, cflag); #if defined(HAVE_DLERROR) if( !ptr && (err = dlerror()) ){ rb_raise(rb_eDLError, "%s", err); } #else if( !ptr ){ err = dlerror(); rb_raise(rb_eDLError, "%s", err); } #endif TypedData_Get_Struct(self, struct dl_handle, &dlhandle_data_type, dlhandle); if( dlhandle->ptr && dlhandle->open && dlhandle->enable_close ){ dlclose(dlhandle->ptr); } dlhandle->ptr = ptr; dlhandle->open = 1; dlhandle->enable_close = 0; if( rb_block_given_p() ){ rb_ensure(rb_yield, self, rb_dlhandle_close, self); } return Qnil; }
/* call-seq: SQLite3::Database.new(file, options = {}) * * Create a new Database object that opens the given file. If utf16 * is +true+, the filename is interpreted as a UTF-16 encoded string. * * By default, the new database will return result rows as arrays * (#results_as_hash) and has type translation disabled (#type_translation=). */ static VALUE initialize(int argc, VALUE *argv, VALUE self) { sqlite3RubyPtr ctx; VALUE file; VALUE opts; VALUE zvfs; #ifdef HAVE_SQLITE3_OPEN_V2 int mode = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; #endif int status; Data_Get_Struct(self, sqlite3Ruby, ctx); rb_scan_args(argc, argv, "12", &file, &opts, &zvfs); #if defined StringValueCStr StringValuePtr(file); rb_check_safe_obj(file); #else Check_SafeStr(file); #endif if(NIL_P(opts)) opts = rb_hash_new(); else Check_Type(opts, T_HASH); #ifdef HAVE_RUBY_ENCODING_H if(UTF16_LE_P(file) || UTF16_BE_P(file)) { status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db); } else { #endif if(Qtrue == rb_hash_aref(opts, sym_utf16)) { status = sqlite3_open16(utf16_string_value_ptr(file), &ctx->db); } else { #ifdef HAVE_RUBY_ENCODING_H if(!UTF8_P(file)) { file = rb_str_export_to_enc(file, rb_utf8_encoding()); } #endif if (Qtrue == rb_hash_aref(opts, ID2SYM(rb_intern("readonly")))) { #ifdef HAVE_SQLITE3_OPEN_V2 mode = SQLITE_OPEN_READONLY; #else rb_raise(rb_eNotImpError, "sqlite3-ruby was compiled against a version of sqlite that does not support readonly databases"); #endif } #ifdef HAVE_SQLITE3_OPEN_V2 status = sqlite3_open_v2( StringValuePtr(file), &ctx->db, mode, NIL_P(zvfs) ? NULL : StringValuePtr(zvfs) ); #else status = sqlite3_open( StringValuePtr(file), &ctx->db ); #endif } #ifdef HAVE_RUBY_ENCODING_H } #endif CHECK(ctx->db, status) rb_iv_set(self, "@tracefunc", Qnil); rb_iv_set(self, "@authorizer", Qnil); rb_iv_set(self, "@encoding", Qnil); rb_iv_set(self, "@busy_handler", Qnil); rb_iv_set(self, "@collations", rb_hash_new()); rb_iv_set(self, "@functions", rb_hash_new()); rb_iv_set(self, "@results_as_hash", rb_hash_aref(opts, sym_results_as_hash)); rb_iv_set(self, "@type_translation", rb_hash_aref(opts, sym_type_translation)); #ifdef HAVE_SQLITE3_OPEN_V2 rb_iv_set(self, "@readonly", mode == SQLITE_OPEN_READONLY ? Qtrue : Qfalse); #else rb_iv_set(self, "@readonly", Qfalse); #endif if(rb_block_given_p()) { rb_ensure(rb_yield, self, sqlite3_rb_close, self); } return self; }
static void in_callback_argument_from_ruby(RBGIArgMetadata *metadata, GArray *in_args) { gpointer callback_function; GIArgInfo *arg_info; GIArgument *callback_argument; GIArgument *closure_argument = NULL; GIArgument *destroy_argument = NULL; RBGICallback *callback = NULL; arg_info = &(metadata->arg_info); callback_argument = &(g_array_index(in_args, GIArgument, metadata->in_arg_index)); if (metadata->closure_in_arg_index != -1) { closure_argument = &(g_array_index(in_args, GIArgument, metadata->closure_in_arg_index)); } if (metadata->destroy_in_arg_index != -1) { destroy_argument = &(g_array_index(in_args, GIArgument, metadata->destroy_in_arg_index)); } if (!rb_block_given_p() && g_arg_info_may_be_null(arg_info)) { callback_argument->v_pointer = NULL; if (closure_argument) { closure_argument->v_pointer = NULL; } if (destroy_argument) { destroy_argument->v_pointer = NULL; } return; } callback_function = find_callback_function(arg_info); if (callback_function) { callback_argument->v_pointer = callback_function; } else { callback = RB_ZALLOC(RBGICallback); callback->type_info = g_arg_info_get_type(arg_info); callback->callback_info = g_type_info_get_interface(callback->type_info); callback->closure = g_callable_info_prepare_closure(callback->callback_info, &(callback->cif), ffi_closure_callback, callback); callback_argument->v_pointer = callback->closure; } if (closure_argument) { RBGICallbackData *callback_data; callback_data = ALLOC(RBGICallbackData); callback_data->callback = callback; callback_data->metadata = metadata; callback_data->rb_callback = rb_block_proc(); callback_data_guard_from_gc(callback_data); closure_argument->v_pointer = callback_data; } if (destroy_argument) { destroy_argument->v_pointer = destroy_notify; } }
int rb_scan_args(int argc, const VALUE *argv, const char *fmt, ...) { int i; const char *p = fmt; VALUE *var; va_list vargs; int f_var = 0, f_hash = 0, f_block = 0; int n_lead = 0, n_opt = 0, n_trail = 0, n_mand; int argi = 0; VALUE hash = Qnil; if (ISDIGIT(*p)) { n_lead = *p - '0'; p++; if (ISDIGIT(*p)) { n_opt = *p - '0'; p++; if (ISDIGIT(*p)) { n_trail = *p - '0'; p++; goto block_arg; } } } if (*p == '*') { f_var = 1; p++; if (ISDIGIT(*p)) { n_trail = *p - '0'; p++; } } block_arg: if (*p == ':') { f_hash = 1; p++; } if (*p == '&') { f_block = 1; p++; } if (*p != '\0') { rb_fatal("bad scan arg format: %s", fmt); } n_mand = n_lead + n_trail; if (argc < n_mand) goto argc_error; va_start(vargs, fmt); /* capture an option hash - phase 1: pop */ if (f_hash && n_mand < argc) { VALUE last = argv[argc - 1]; if (NIL_P(last)) { /* nil is taken as an empty option hash only if it is not ambiguous; i.e. '*' is not specified and arguments are given more than sufficient */ if (!f_var && n_mand + n_opt < argc) argc--; } else { hash = rb_check_convert_type(last, T_HASH, "Hash", "to_hash"); if (!NIL_P(hash)) argc--; } } /* capture leading mandatory arguments */ for (i = n_lead; i-- > 0; ) { var = va_arg(vargs, VALUE *); if (var) *var = argv[argi]; argi++; } /* capture optional arguments */ for (i = n_opt; i-- > 0; ) { var = va_arg(vargs, VALUE *); if (argi < argc - n_trail) { if (var) *var = argv[argi]; argi++; } else { if (var) *var = Qnil; } } /* capture variable length arguments */ if (f_var) { int n_var = argc - argi - n_trail; var = va_arg(vargs, VALUE *); if (0 < n_var) { if (var) *var = rb_ary_new4(n_var, &argv[argi]); argi += n_var; } else { if (var) *var = rb_ary_new(); } } /* capture trailing mandatory arguments */ for (i = n_trail; i-- > 0; ) { var = va_arg(vargs, VALUE *); if (var) *var = argv[argi]; argi++; } /* capture an option hash - phase 2: assignment */ if (f_hash) { var = va_arg(vargs, VALUE *); if (var) *var = hash; } /* capture iterator block */ if (f_block) { var = va_arg(vargs, VALUE *); if (rb_block_given_p()) { *var = rb_block_proc(); } else { *var = Qnil; } } va_end(vargs); if (argi < argc) goto argc_error; return argc; argc_error: if (0 < n_opt) rb_raise(rb_eArgError, "wrong number of arguments (%d for %d..%d%s)", argc, n_mand, n_mand + n_opt, f_var ? "+" : ""); else rb_raise(rb_eArgError, "wrong number of arguments (%d for %d%s)", argc, n_mand, f_var ? "+" : ""); }