VALUE rb_RPRuby_Sender_Kernel_internal_backtraceHashForControlFrame( rb_control_frame_t** c_current_frame ) { const char* c_method_name = NULL; int c_sourcefile_line = 0; // create new hash for this frame VALUE rb_frame_hash = rb_hash_new(); VALUE rb_sourcefile_name = Qnil; VALUE rb_sourcefile_line = Qnil; VALUE rb_method_name = Qnil; VALUE rb_object_for_frame = Qnil; if ( ( *c_current_frame )->iseq != 0 ) { if ( ( *c_current_frame )->pc != 0 ) { rb_iseq_t *iseq = ( *c_current_frame )->iseq; // get sourcefile name and set in hash rb_sourcefile_name = iseq->filename; // get sourcefile line and set in hash c_sourcefile_line = rb_vm_get_sourceline( *c_current_frame ); rb_sourcefile_line = INT2FIX( c_sourcefile_line ); // get name of instruction sequence rb_method_name = ID2SYM( rb_intern( StringValuePtr( iseq->name ) ) ); rb_object_for_frame = ( *c_current_frame )->self; } } else if ( RUBYVM_CFUNC_FRAME_P( *c_current_frame ) ) { // get name of method #if RUBY_PATCHLEVEL >= -1 // For 1.9.2: const rb_method_entry_t* c_method_for_frame = ( *c_current_frame )->me; c_method_name = rb_id2name( c_method_for_frame->called_id ); #else // For 1.9.1: c_method_name = rb_id2name( ( *c_current_frame )->method_id ); #endif rb_method_name = ( c_method_name == NULL ? Qnil : ID2SYM( rb_intern( c_method_name ) ) ); rb_object_for_frame = ( *c_current_frame )->self; } // we have to test this case - it works for blocks but there may be other cases too else if ( ( *c_current_frame )->block_iseq != 0 && ( *c_current_frame )->pc == 0) { // If we got here we have a fiber // There doesn't seem to be much that we can tell about a fiber's context VALUE rb_current_fiber = rb_fiber_current(); rb_fiber_t* c_current_fiber = NULL; GetFiberPtr( rb_current_fiber, c_current_fiber); rb_context_t* c_context = & c_current_fiber->cont; // rb_block_t* c_blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP( *c_current_frame ); rb_object_for_frame = ( *c_current_frame )->self; // get sourcefile name and set in hash rb_sourcefile_name = Qnil; // get sourcefile line and set in hash rb_sourcefile_line = Qnil; // get name of instruction sequence rb_method_name = rb_str_new2( "<Fiber>" ); // if we have a fiber we also include its ruby reference since we have so little other context rb_hash_aset( rb_frame_hash, ID2SYM( rb_intern( "fiber" ) ), c_context->self ); // The one time that we know a fiber is in use in the Ruby base is with Enumerators // For now we will handle that with a special case VALUE rb_enumerator_class = rb_const_get( rb_cObject, rb_intern( "Enumerator" ) ); VALUE rb_object_for_frame_klass = ( ( TYPE( rb_object_for_frame ) == T_CLASS ) ? rb_object_for_frame : rb_funcall( rb_object_for_frame, rb_intern( "class" ), 0 ) ); VALUE rb_ancestors = rb_funcall( rb_object_for_frame_klass, rb_intern( "ancestors" ), 0 ); if ( rb_ary_includes( rb_ancestors, rb_enumerator_class ) ) { struct enumerator* c_enumerator = enumerator_ptr( rb_object_for_frame ); rb_object_for_frame = c_enumerator->obj; rb_method_name = ID2SYM( c_enumerator->meth ); } } else if ( ( *c_current_frame )->block_iseq == 0 && ( *c_current_frame )->pc == 0) { // this happens after we had a fiber and we try to go up - which doesn't make sense with a fiber // not sure what we want to do here, if anything return Qnil; } else { // The third possibility is that we have an iseq frame with nil params for what we want // In that case we can simply return the next frame *c_current_frame = RUBY_VM_PREVIOUS_CONTROL_FRAME( *c_current_frame ); // in theory this could crash because we are going forward a frame when we don't know what's there // in practice I think we are ok, since we are only jumping forward from nil frames which should never be at the end // at least - I don't think they should... we shall see. // // a fix would be to check the next frame, but that requires access to the thread or the limit cfp, // which requires passing more context; so for now, I'm leaving it there return rb_RPRuby_Sender_Kernel_internal_backtraceHashForControlFrame( c_current_frame ); } // Push values to return hash rb_hash_aset( rb_frame_hash, ID2SYM( rb_intern( "object" ) ), rb_object_for_frame ); rb_hash_aset( rb_frame_hash, ID2SYM( rb_intern( "file" ) ), rb_sourcefile_name ); rb_hash_aset( rb_frame_hash, ID2SYM( rb_intern( "line" ) ), rb_sourcefile_line ); rb_hash_aset( rb_frame_hash, ID2SYM( rb_intern( "method" ) ), rb_method_name ); return rb_frame_hash; }
void init_mysql2_result() { cBigDecimal = rb_const_get(rb_cObject, rb_intern("BigDecimal")); cDate = rb_const_get(rb_cObject, rb_intern("Date")); cDateTime = rb_const_get(rb_cObject, rb_intern("DateTime")); cMysql2Result = rb_define_class_under(mMysql2, "Result", rb_cObject); rb_define_method(cMysql2Result, "each", rb_mysql_result_each, -1); rb_define_method(cMysql2Result, "fields", rb_mysql_result_fetch_fields, 0); rb_define_method(cMysql2Result, "count", rb_mysql_result_count, 0); rb_define_alias(cMysql2Result, "size", "count"); intern_encoding_from_charset = rb_intern("encoding_from_charset"); intern_encoding_from_charset_code = rb_intern("encoding_from_charset_code"); intern_new = rb_intern("new"); intern_utc = rb_intern("utc"); intern_local = rb_intern("local"); intern_merge = rb_intern("merge"); intern_localtime = rb_intern("localtime"); intern_local_offset = rb_intern("local_offset"); intern_civil = rb_intern("civil"); intern_new_offset = rb_intern("new_offset"); sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys")); sym_as = ID2SYM(rb_intern("as")); sym_array = ID2SYM(rb_intern("array")); sym_local = ID2SYM(rb_intern("local")); sym_utc = ID2SYM(rb_intern("utc")); sym_cast_booleans = ID2SYM(rb_intern("cast_booleans")); sym_database_timezone = ID2SYM(rb_intern("database_timezone")); sym_application_timezone = ID2SYM(rb_intern("application_timezone")); sym_cache_rows = ID2SYM(rb_intern("cache_rows")); sym_cast = ID2SYM(rb_intern("cast")); sym_stream = ID2SYM(rb_intern("stream")); opt_decimal_zero = rb_str_new2("0.0"); rb_global_variable(&opt_decimal_zero); //never GC opt_float_zero = rb_float_new((double)0); rb_global_variable(&opt_float_zero); opt_time_year = INT2NUM(2000); opt_time_month = INT2NUM(1); opt_utc_offset = INT2NUM(0); #ifdef HAVE_RUBY_ENCODING_H binaryEncoding = rb_enc_find("binary"); #endif }
/* * The transaction_id of the offended message. * * @return [Number] the value of attribute transaction_id. */ static VALUE openflow_error_transaction_id( VALUE self ) { return rb_hash_aref( rb_iv_get( self, "@attribute" ), ID2SYM( rb_intern( "transaction_id" ) ) ); }
static inline VALUE vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, int num, const rb_block_t *blockptr, VALUE flag, ID id, const rb_method_entry_t *me, VALUE recv) { VALUE val; start_method_dispatch: if (me != 0) { if ((me->flag == 0)) { normal_method_dispatch: switch (me->def->type) { case VM_METHOD_TYPE_ISEQ:{ vm_setup_method(th, cfp, recv, num, blockptr, flag, me); return Qundef; } case VM_METHOD_TYPE_NOTIMPLEMENTED: case VM_METHOD_TYPE_CFUNC:{ val = vm_call_cfunc(th, cfp, num, recv, blockptr, me); break; } case VM_METHOD_TYPE_ATTRSET:{ if (num != 1) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", num); } val = rb_ivar_set(recv, me->def->body.attr.id, *(cfp->sp - 1)); cfp->sp -= 2; break; } case VM_METHOD_TYPE_IVAR:{ if (num != 0) { rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", num); } val = rb_attr_get(recv, me->def->body.attr.id); cfp->sp -= 1; break; } case VM_METHOD_TYPE_MISSING:{ VALUE *argv = ALLOCA_N(VALUE, num+1); argv[0] = ID2SYM(me->def->original_id); MEMCPY(argv+1, cfp->sp - num, VALUE, num); cfp->sp += - num - 1; val = rb_funcall2(recv, rb_intern("method_missing"), num+1, argv); break; } case VM_METHOD_TYPE_BMETHOD:{ VALUE *argv = ALLOCA_N(VALUE, num); MEMCPY(argv, cfp->sp - num, VALUE, num); cfp->sp += - num - 1; val = vm_call_bmethod(th, recv, num, argv, blockptr, me); break; } case VM_METHOD_TYPE_ZSUPER:{ VALUE klass = RCLASS_SUPER(me->klass); me = rb_method_entry(klass, id); if (me != 0) { goto normal_method_dispatch; } else { goto start_method_dispatch; } } case VM_METHOD_TYPE_OPTIMIZED:{ switch (me->def->body.optimize_type) { case OPTIMIZED_METHOD_TYPE_SEND: { rb_control_frame_t *reg_cfp = cfp; rb_num_t i = num - 1; VALUE sym; if (num == 0) { rb_raise(rb_eArgError, "no method name given"); } sym = TOPN(i); id = SYMBOL_P(sym) ? SYM2ID(sym) : rb_to_id(sym); /* shift arguments */ if (i > 0) { MEMMOVE(&TOPN(i), &TOPN(i-1), VALUE, i); } me = rb_method_entry(CLASS_OF(recv), id); num -= 1; DEC_SP(1); flag |= VM_CALL_FCALL_BIT | VM_CALL_OPT_SEND_BIT; goto start_method_dispatch; } case OPTIMIZED_METHOD_TYPE_CALL: { rb_proc_t *proc; int argc = num; VALUE *argv = ALLOCA_N(VALUE, num); GetProcPtr(recv, proc); MEMCPY(argv, cfp->sp - num, VALUE, num); cfp->sp -= num + 1; val = rb_vm_invoke_proc(th, proc, proc->block.self, argc, argv, blockptr); break; } default: rb_bug("eval_invoke_method: unsupported optimized method type (%d)", me->def->body.optimize_type); } break; } default:{ rb_bug("eval_invoke_method: unsupported method type (%d)", me->def->type); break; } } } else { int noex_safe; if (!(flag & VM_CALL_FCALL_BIT) && (me->flag & NOEX_MASK) & NOEX_PRIVATE) { int stat = NOEX_PRIVATE; if (flag & VM_CALL_VCALL_BIT) { stat |= NOEX_VCALL; } val = vm_method_missing(th, id, recv, num, blockptr, stat); } else if (!(flag & VM_CALL_OPT_SEND_BIT) && (me->flag & NOEX_MASK) & NOEX_PROTECTED) { VALUE defined_class = me->klass; if (TYPE(defined_class) == T_ICLASS) { defined_class = RBASIC(defined_class)->klass; } if (!rb_obj_is_kind_of(cfp->self, defined_class)) { val = vm_method_missing(th, id, recv, num, blockptr, NOEX_PROTECTED); } else { goto normal_method_dispatch; } } else if ((noex_safe = NOEX_SAFE(me->flag)) > th->safe_level && (noex_safe > 2)) { rb_raise(rb_eSecurityError, "calling insecure method: %s", rb_id2name(id)); } else { goto normal_method_dispatch; } } } else { /* method missing */ int stat = 0; if (flag & VM_CALL_VCALL_BIT) { stat |= NOEX_VCALL; } if (flag & VM_CALL_SUPER_BIT) { stat |= NOEX_SUPER; } if (id == idMethodMissing) { VALUE *argv = ALLOCA_N(VALUE, num); vm_method_missing_args(th, argv, num - 1, 0, stat); rb_raise_method_missing(th, num, argv, recv, stat); } else { val = vm_method_missing(th, id, recv, num, blockptr, stat); } } RUBY_VM_CHECK_INTS(); return val; }
/* * call-seq: to_h * * Returns the configuration instance variables as a hash, that can be * passed to the configure method. */ static VALUE cState_to_h(VALUE self) { VALUE result = rb_hash_new(); GET_STATE(self); set_state_ivars(result, self); rb_hash_aset(result, ID2SYM(i_indent), rb_str_new(state->indent, state->indent_len)); rb_hash_aset(result, ID2SYM(i_space), rb_str_new(state->space, state->space_len)); rb_hash_aset(result, ID2SYM(i_space_before), rb_str_new(state->space_before, state->space_before_len)); rb_hash_aset(result, ID2SYM(i_object_nl), rb_str_new(state->object_nl, state->object_nl_len)); rb_hash_aset(result, ID2SYM(i_array_nl), rb_str_new(state->array_nl, state->array_nl_len)); rb_hash_aset(result, ID2SYM(i_allow_nan), state->allow_nan ? Qtrue : Qfalse); rb_hash_aset(result, ID2SYM(i_ascii_only), state->ascii_only ? Qtrue : Qfalse); rb_hash_aset(result, ID2SYM(i_quirks_mode), state->quirks_mode ? Qtrue : Qfalse); rb_hash_aset(result, ID2SYM(i_max_nesting), LONG2FIX(state->max_nesting)); rb_hash_aset(result, ID2SYM(i_depth), LONG2FIX(state->depth)); rb_hash_aset(result, ID2SYM(i_buffer_initial_length), LONG2FIX(state->buffer_initial_length)); return result; }
void init_ruby_class() { #if 0 // For documentation using YARD VALUE opencv = rb_define_module("OpenCV"); #endif if (rb_klass) return; VALUE opencv = rb_module_opencv(); rb_klass = rb_define_class_under(opencv, "CvCapture", rb_cData); VALUE video_interface = rb_hash_new(); /* * :any, :mil, :vfw, :v4l, :v4l2, :fireware, :ieee1394, :dc1394, :cmu1394, * :stereo, :tyzx, :tyzx_left, :tyzx_right, :tyzx_color, :tyzx_z, :qt, :qtuicktime */ rb_define_const(rb_klass, "INTERFACE", video_interface); rb_hash_aset(video_interface, ID2SYM(rb_intern("any")), INT2FIX(CV_CAP_ANY)); rb_hash_aset(video_interface, ID2SYM(rb_intern("mil")), INT2FIX(CV_CAP_MIL)); rb_hash_aset(video_interface, ID2SYM(rb_intern("vfw")), INT2FIX(CV_CAP_VFW)); rb_hash_aset(video_interface, ID2SYM(rb_intern("v4l")), INT2FIX(CV_CAP_V4L)); rb_hash_aset(video_interface, ID2SYM(rb_intern("v4l2")), INT2FIX(CV_CAP_V4L2)); rb_hash_aset(video_interface, ID2SYM(rb_intern("fireware")), INT2FIX(CV_CAP_FIREWARE)); rb_hash_aset(video_interface, ID2SYM(rb_intern("ieee1394")), INT2FIX(CV_CAP_IEEE1394)); rb_hash_aset(video_interface, ID2SYM(rb_intern("dc1394")), INT2FIX(CV_CAP_DC1394)); rb_hash_aset(video_interface, ID2SYM(rb_intern("cmu1394")), INT2FIX(CV_CAP_CMU1394)); rb_hash_aset(video_interface, ID2SYM(rb_intern("stereo")), INT2FIX(CV_CAP_STEREO)); rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx")), INT2FIX(CV_CAP_TYZX)); rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_left")), INT2FIX(CV_TYZX_LEFT)); rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_right")), INT2FIX(CV_TYZX_RIGHT)); rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_color")), INT2FIX(CV_TYZX_COLOR)); rb_hash_aset(video_interface, ID2SYM(rb_intern("tyzx_z")), INT2FIX(CV_TYZX_Z)); rb_hash_aset(video_interface, ID2SYM(rb_intern("qt")), INT2FIX(CV_CAP_QT)); rb_hash_aset(video_interface, ID2SYM(rb_intern("quicktime")), INT2FIX(CV_CAP_QT)); rb_define_singleton_method(rb_klass, "open", RUBY_METHOD_FUNC(rb_open), -1); rb_define_method(rb_klass, "close", RUBY_METHOD_FUNC(rb_close), 0); rb_define_method(rb_klass, "grab", RUBY_METHOD_FUNC(rb_grab), 0); rb_define_method(rb_klass, "retrieve", RUBY_METHOD_FUNC(rb_retrieve), 0); rb_define_method(rb_klass, "query", RUBY_METHOD_FUNC(rb_query), 0); rb_define_method(rb_klass, "millisecond", RUBY_METHOD_FUNC(rb_get_millisecond), 0); rb_define_method(rb_klass, "millisecond=", RUBY_METHOD_FUNC(rb_set_millisecond), 1); rb_define_method(rb_klass, "frames", RUBY_METHOD_FUNC(rb_get_frames), 0); rb_define_method(rb_klass, "frames=", RUBY_METHOD_FUNC(rb_set_frames), 1); rb_define_method(rb_klass, "avi_ratio", RUBY_METHOD_FUNC(rb_get_avi_ratio), 0); rb_define_method(rb_klass, "avi_ratio=", RUBY_METHOD_FUNC(rb_set_avi_ratio), 1); rb_define_method(rb_klass, "size", RUBY_METHOD_FUNC(rb_get_size), 0); rb_define_method(rb_klass, "size=", RUBY_METHOD_FUNC(rb_set_size), 1); rb_define_method(rb_klass, "width", RUBY_METHOD_FUNC(rb_get_width), 0); rb_define_method(rb_klass, "width=", RUBY_METHOD_FUNC(rb_set_width), 1); rb_define_method(rb_klass, "height", RUBY_METHOD_FUNC(rb_get_height), 0); rb_define_method(rb_klass, "height=", RUBY_METHOD_FUNC(rb_set_height), 1); rb_define_method(rb_klass, "fps", RUBY_METHOD_FUNC(rb_get_fps), 0); rb_define_method(rb_klass, "fps=", RUBY_METHOD_FUNC(rb_set_fps), 1); rb_define_method(rb_klass, "fourcc", RUBY_METHOD_FUNC(rb_get_fourcc), 0); rb_define_method(rb_klass, "frame_count", RUBY_METHOD_FUNC(rb_get_frame_count), 0); rb_define_method(rb_klass, "format", RUBY_METHOD_FUNC(rb_get_format), 0); rb_define_method(rb_klass, "mode", RUBY_METHOD_FUNC(rb_get_mode), 0); rb_define_method(rb_klass, "brightness", RUBY_METHOD_FUNC(rb_get_brightness), 0); rb_define_method(rb_klass, "contrast", RUBY_METHOD_FUNC(rb_get_contrast), 0); rb_define_method(rb_klass, "saturation", RUBY_METHOD_FUNC(rb_get_saturation), 0); rb_define_method(rb_klass, "hue", RUBY_METHOD_FUNC(rb_get_hue), 0); rb_define_method(rb_klass, "gain", RUBY_METHOD_FUNC(rb_get_gain), 0); rb_define_method(rb_klass, "exposure", RUBY_METHOD_FUNC(rb_get_exposure), 0); rb_define_method(rb_klass, "convert_rgb", RUBY_METHOD_FUNC(rb_get_convert_rgb), 0); rb_define_method(rb_klass, "rectification", RUBY_METHOD_FUNC(rb_get_rectification), 0); }
VALUE shoes_hash_set(VALUE hsh, ID key, VALUE val) { if (NIL_P(hsh)) hsh = rb_hash_new(); rb_hash_aset(hsh, ID2SYM(key), val); return hsh; }
void init_mysql2_client() { /* verify the libmysql we're about to use was the version we were built against https://github.com/luislavena/mysql-gem/commit/a600a9c459597da0712f70f43736e24b484f8a99 */ int i; int dots = 0; const char *lib = mysql_get_client_info(); for (i = 0; lib[i] != 0 && MYSQL_LINK_VERSION[i] != 0; i++) { if (lib[i] == '.') { dots++; /* we only compare MAJOR and MINOR */ if (dots == 2) break; } if (lib[i] != MYSQL_LINK_VERSION[i]) { rb_raise(rb_eRuntimeError, "Incorrect MySQL client library version! This gem was compiled for %s but the client library is %s.", MYSQL_LINK_VERSION, lib); return; } } /* Initializing mysql library, so different threads could call Client.new */ /* without race condition in the library */ if (mysql_library_init(0, NULL, NULL) != 0) { rb_raise(rb_eRuntimeError, "Could not initialize MySQL client library"); return; } #if 0 mMysql2 = rb_define_module("Mysql2"); Teach RDoc about Mysql2 constant. #endif cMysql2Client = rb_define_class_under(mMysql2, "Client", rb_cObject); rb_define_alloc_func(cMysql2Client, allocate); rb_define_singleton_method(cMysql2Client, "escape", rb_mysql_client_escape, 1); rb_define_method(cMysql2Client, "close", rb_mysql_client_close, 0); rb_define_method(cMysql2Client, "query", rb_mysql_client_query, -1); rb_define_method(cMysql2Client, "abandon_results!", rb_mysql_client_abandon_results, 0); rb_define_method(cMysql2Client, "escape", rb_mysql_client_real_escape, 1); rb_define_method(cMysql2Client, "info", rb_mysql_client_info, 0); rb_define_method(cMysql2Client, "server_info", rb_mysql_client_server_info, 0); rb_define_method(cMysql2Client, "socket", rb_mysql_client_socket, 0); rb_define_method(cMysql2Client, "async_result", rb_mysql_client_async_result, 0); rb_define_method(cMysql2Client, "last_id", rb_mysql_client_last_id, 0); rb_define_method(cMysql2Client, "affected_rows", rb_mysql_client_affected_rows, 0); rb_define_method(cMysql2Client, "thread_id", rb_mysql_client_thread_id, 0); rb_define_method(cMysql2Client, "ping", rb_mysql_client_ping, 0); rb_define_method(cMysql2Client, "select_db", rb_mysql_client_select_db, 1); rb_define_method(cMysql2Client, "more_results?", rb_mysql_client_more_results, 0); rb_define_method(cMysql2Client, "next_result", rb_mysql_client_next_result, 0); rb_define_method(cMysql2Client, "store_result", rb_mysql_client_store_result, 0); rb_define_method(cMysql2Client, "reconnect=", set_reconnect, 1); rb_define_method(cMysql2Client, "warning_count", rb_mysql_client_warning_count, 0); rb_define_method(cMysql2Client, "query_info_string", rb_mysql_info, 0); #ifdef HAVE_RUBY_ENCODING_H rb_define_method(cMysql2Client, "encoding", rb_mysql_client_encoding, 0); #endif rb_define_private_method(cMysql2Client, "connect_timeout=", set_connect_timeout, 1); rb_define_private_method(cMysql2Client, "read_timeout=", set_read_timeout, 1); rb_define_private_method(cMysql2Client, "write_timeout=", set_write_timeout, 1); rb_define_private_method(cMysql2Client, "local_infile=", set_local_infile, 1); rb_define_private_method(cMysql2Client, "charset_name=", set_charset_name, 1); rb_define_private_method(cMysql2Client, "secure_auth=", set_secure_auth, 1); rb_define_private_method(cMysql2Client, "default_file=", set_read_default_file, 1); rb_define_private_method(cMysql2Client, "default_group=", set_read_default_group, 1); rb_define_private_method(cMysql2Client, "init_command=", set_init_command, 1); rb_define_private_method(cMysql2Client, "ssl_set", set_ssl_options, 5); rb_define_private_method(cMysql2Client, "initialize_ext", initialize_ext, 0); rb_define_private_method(cMysql2Client, "connect", rb_connect, 7); sym_id = ID2SYM(rb_intern("id")); sym_version = ID2SYM(rb_intern("version")); sym_async = ID2SYM(rb_intern("async")); sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys")); sym_as = ID2SYM(rb_intern("as")); sym_array = ID2SYM(rb_intern("array")); sym_stream = ID2SYM(rb_intern("stream")); intern_merge = rb_intern("merge"); intern_merge_bang = rb_intern("merge!"); intern_error_number_eql = rb_intern("error_number="); intern_sql_state_eql = rb_intern("sql_state="); #ifdef CLIENT_LONG_PASSWORD rb_const_set(cMysql2Client, rb_intern("LONG_PASSWORD"), LONG2NUM(CLIENT_LONG_PASSWORD)); #endif #ifdef CLIENT_FOUND_ROWS rb_const_set(cMysql2Client, rb_intern("FOUND_ROWS"), LONG2NUM(CLIENT_FOUND_ROWS)); #endif #ifdef CLIENT_LONG_FLAG rb_const_set(cMysql2Client, rb_intern("LONG_FLAG"), LONG2NUM(CLIENT_LONG_FLAG)); #endif #ifdef CLIENT_CONNECT_WITH_DB rb_const_set(cMysql2Client, rb_intern("CONNECT_WITH_DB"), LONG2NUM(CLIENT_CONNECT_WITH_DB)); #endif #ifdef CLIENT_NO_SCHEMA rb_const_set(cMysql2Client, rb_intern("NO_SCHEMA"), LONG2NUM(CLIENT_NO_SCHEMA)); #endif #ifdef CLIENT_COMPRESS rb_const_set(cMysql2Client, rb_intern("COMPRESS"), LONG2NUM(CLIENT_COMPRESS)); #endif #ifdef CLIENT_ODBC rb_const_set(cMysql2Client, rb_intern("ODBC"), LONG2NUM(CLIENT_ODBC)); #endif #ifdef CLIENT_LOCAL_FILES rb_const_set(cMysql2Client, rb_intern("LOCAL_FILES"), LONG2NUM(CLIENT_LOCAL_FILES)); #endif #ifdef CLIENT_IGNORE_SPACE rb_const_set(cMysql2Client, rb_intern("IGNORE_SPACE"), LONG2NUM(CLIENT_IGNORE_SPACE)); #endif #ifdef CLIENT_PROTOCOL_41 rb_const_set(cMysql2Client, rb_intern("PROTOCOL_41"), LONG2NUM(CLIENT_PROTOCOL_41)); #endif #ifdef CLIENT_INTERACTIVE rb_const_set(cMysql2Client, rb_intern("INTERACTIVE"), LONG2NUM(CLIENT_INTERACTIVE)); #endif #ifdef CLIENT_SSL rb_const_set(cMysql2Client, rb_intern("SSL"), LONG2NUM(CLIENT_SSL)); #endif #ifdef CLIENT_IGNORE_SIGPIPE rb_const_set(cMysql2Client, rb_intern("IGNORE_SIGPIPE"), LONG2NUM(CLIENT_IGNORE_SIGPIPE)); #endif #ifdef CLIENT_TRANSACTIONS rb_const_set(cMysql2Client, rb_intern("TRANSACTIONS"), LONG2NUM(CLIENT_TRANSACTIONS)); #endif #ifdef CLIENT_RESERVED rb_const_set(cMysql2Client, rb_intern("RESERVED"), LONG2NUM(CLIENT_RESERVED)); #endif #ifdef CLIENT_SECURE_CONNECTION rb_const_set(cMysql2Client, rb_intern("SECURE_CONNECTION"), LONG2NUM(CLIENT_SECURE_CONNECTION)); #endif #ifdef CLIENT_MULTI_STATEMENTS rb_const_set(cMysql2Client, rb_intern("MULTI_STATEMENTS"), LONG2NUM(CLIENT_MULTI_STATEMENTS)); #endif #ifdef CLIENT_PS_MULTI_RESULTS rb_const_set(cMysql2Client, rb_intern("PS_MULTI_RESULTS"), LONG2NUM(CLIENT_PS_MULTI_RESULTS)); #endif #ifdef CLIENT_SSL_VERIFY_SERVER_CERT rb_const_set(cMysql2Client, rb_intern("SSL_VERIFY_SERVER_CERT"), LONG2NUM(CLIENT_SSL_VERIFY_SERVER_CERT)); #endif #ifdef CLIENT_REMEMBER_OPTIONS rb_const_set(cMysql2Client, rb_intern("REMEMBER_OPTIONS"), LONG2NUM(CLIENT_REMEMBER_OPTIONS)); #endif #ifdef CLIENT_ALL_FLAGS rb_const_set(cMysql2Client, rb_intern("ALL_FLAGS"), LONG2NUM(CLIENT_ALL_FLAGS)); #endif #ifdef CLIENT_BASIC_FLAGS rb_const_set(cMysql2Client, rb_intern("BASIC_FLAGS"), LONG2NUM(CLIENT_BASIC_FLAGS)); #endif }
static void hash_set(VALUE hash, const char *sym, VALUE v) { rb_hash_aset(hash, ID2SYM(rb_intern(sym)), v); }
void rxml_init_reader(void) { BASE_URI_SYMBOL = ID2SYM(rb_intern("base_uri")); ENCODING_SYMBOL = ID2SYM(rb_intern("encoding")); IO_ATTR = rb_intern("@io"); OPTIONS_SYMBOL = ID2SYM(rb_intern("options")); cXMLReader = rb_define_class_under(mXML, "Reader", rb_cObject); rb_define_singleton_method(cXMLReader, "document", rxml_reader_document, 1); rb_define_singleton_method(cXMLReader, "file", rxml_reader_file, -1); rb_define_singleton_method(cXMLReader, "io", rxml_reader_io, -1); rb_define_singleton_method(cXMLReader, "string", rxml_reader_string, -1); rb_define_method(cXMLReader, "[]", rxml_reader_attribute, 1); rb_define_method(cXMLReader, "attribute_count", rxml_reader_attr_count, 0); rb_define_method(cXMLReader, "base_uri", rxml_reader_base_uri, 0); #if LIBXML_VERSION >= 20618 rb_define_method(cXMLReader, "byte_consumed", rxml_reader_byte_consumed, 0); #endif rb_define_method(cXMLReader, "close", rxml_reader_close, 0); #if LIBXML_VERSION >= 20617 rb_define_method(cXMLReader, "column_number", rxml_reader_column_number, 0); #endif rb_define_method(cXMLReader, "depth", rxml_reader_depth, 0); rb_define_method(cXMLReader, "encoding", rxml_reader_encoding, 0); rb_define_method(cXMLReader, "expand", rxml_reader_expand, 0); rb_define_method(cXMLReader, "has_attributes?", rxml_reader_has_attributes, 0); rb_define_method(cXMLReader, "has_value?", rxml_reader_has_value, 0); #if LIBXML_VERSION >= 20617 rb_define_method(cXMLReader, "line_number", rxml_reader_line_number, 0); #endif rb_define_method(cXMLReader, "local_name", rxml_reader_local_name, 0); rb_define_method(cXMLReader, "lookup_namespace", rxml_reader_lookup_namespace, 1); rb_define_method(cXMLReader, "move_to_attribute", rxml_reader_move_to_attr, 1); rb_define_method(cXMLReader, "move_to_first_attribute", rxml_reader_move_to_first_attr, 0); rb_define_method(cXMLReader, "move_to_next_attribute", rxml_reader_move_to_next_attr, 0); rb_define_method(cXMLReader, "move_to_element", rxml_reader_move_to_element, 0); rb_define_method(cXMLReader, "name", rxml_reader_name, 0); rb_define_method(cXMLReader, "namespace_uri", rxml_reader_namespace_uri, 0); rb_define_method(cXMLReader, "next", rxml_reader_next, 0); rb_define_method(cXMLReader, "next_sibling", rxml_reader_next_sibling, 0); rb_define_method(cXMLReader, "node", rxml_reader_node, 0); rb_define_method(cXMLReader, "node_type", rxml_reader_node_type, 0); rb_define_method(cXMLReader, "normalization", rxml_reader_normalization, 0); rb_define_method(cXMLReader, "prefix", rxml_reader_prefix, 0); rb_define_method(cXMLReader, "quote_char", rxml_reader_quote_char, 0); rb_define_method(cXMLReader, "read", rxml_reader_read, 0); rb_define_method(cXMLReader, "read_attribute_value", rxml_reader_read_attr_value, 0); rb_define_method(cXMLReader, "read_inner_xml", rxml_reader_read_inner_xml, 0); rb_define_method(cXMLReader, "read_outer_xml", rxml_reader_read_outer_xml, 0); rb_define_method(cXMLReader, "read_state", rxml_reader_read_state, 0); rb_define_method(cXMLReader, "read_string", rxml_reader_read_string, 0); rb_define_method(cXMLReader, "relax_ng_validate", rxml_reader_relax_ng_validate, 1); rb_define_method(cXMLReader, "standalone", rxml_reader_standalone, 0); #if LIBXML_VERSION >= 20620 rb_define_method(cXMLReader, "schema_validate", rxml_reader_schema_validate, 1); #endif rb_define_method(cXMLReader, "value", rxml_reader_value, 0); rb_define_method(cXMLReader, "xml_lang", rxml_reader_xml_lang, 0); rb_define_method(cXMLReader, "xml_version", rxml_reader_xml_version, 0); rb_define_method(cXMLReader, "default?", rxml_reader_default, 0); rb_define_method(cXMLReader, "empty_element?", rxml_reader_empty_element, 0); rb_define_method(cXMLReader, "namespace_declaration?", rxml_reader_namespace_declaration, 0); rb_define_method(cXMLReader, "valid?", rxml_reader_valid, 0); /* Constants */ rb_define_const(cXMLReader, "LOADDTD", INT2FIX(XML_PARSER_LOADDTD)); rb_define_const(cXMLReader, "DEFAULTATTRS", INT2FIX(XML_PARSER_DEFAULTATTRS)); rb_define_const(cXMLReader, "VALIDATE", INT2FIX(XML_PARSER_VALIDATE)); rb_define_const(cXMLReader, "SUBST_ENTITIES", INT2FIX(XML_PARSER_SUBST_ENTITIES)); rb_define_const(cXMLReader, "SEVERITY_VALIDITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_WARNING)); rb_define_const(cXMLReader, "SEVERITY_VALIDITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_VALIDITY_ERROR)); rb_define_const(cXMLReader, "SEVERITY_WARNING", INT2FIX(XML_PARSER_SEVERITY_WARNING)); rb_define_const(cXMLReader, "SEVERITY_ERROR", INT2FIX(XML_PARSER_SEVERITY_ERROR)); rb_define_const(cXMLReader, "TYPE_NONE", INT2FIX(XML_READER_TYPE_NONE)); rb_define_const(cXMLReader, "TYPE_ELEMENT", INT2FIX(XML_READER_TYPE_ELEMENT)); rb_define_const(cXMLReader, "TYPE_ATTRIBUTE", INT2FIX(XML_READER_TYPE_ATTRIBUTE)); rb_define_const(cXMLReader, "TYPE_TEXT", INT2FIX(XML_READER_TYPE_TEXT)); rb_define_const(cXMLReader, "TYPE_CDATA", INT2FIX(XML_READER_TYPE_CDATA)); rb_define_const(cXMLReader, "TYPE_ENTITY_REFERENCE", INT2FIX(XML_READER_TYPE_ENTITY_REFERENCE)); rb_define_const(cXMLReader, "TYPE_ENTITY", INT2FIX(XML_READER_TYPE_ENTITY)); rb_define_const(cXMLReader, "TYPE_PROCESSING_INSTRUCTION", INT2FIX(XML_READER_TYPE_PROCESSING_INSTRUCTION)); rb_define_const(cXMLReader, "TYPE_COMMENT", INT2FIX(XML_READER_TYPE_COMMENT)); rb_define_const(cXMLReader, "TYPE_DOCUMENT", INT2FIX(XML_READER_TYPE_DOCUMENT)); rb_define_const(cXMLReader, "TYPE_DOCUMENT_TYPE", INT2FIX(XML_READER_TYPE_DOCUMENT_TYPE)); rb_define_const(cXMLReader, "TYPE_DOCUMENT_FRAGMENT", INT2FIX(XML_READER_TYPE_DOCUMENT_FRAGMENT)); rb_define_const(cXMLReader, "TYPE_NOTATION", INT2FIX(XML_READER_TYPE_NOTATION)); rb_define_const(cXMLReader, "TYPE_WHITESPACE", INT2FIX(XML_READER_TYPE_WHITESPACE)); rb_define_const(cXMLReader, "TYPE_SIGNIFICANT_WHITESPACE", INT2FIX(XML_READER_TYPE_SIGNIFICANT_WHITESPACE)); rb_define_const(cXMLReader, "TYPE_END_ELEMENT", INT2FIX(XML_READER_TYPE_END_ELEMENT)); rb_define_const(cXMLReader, "TYPE_END_ENTITY", INT2FIX(XML_READER_TYPE_END_ENTITY)); rb_define_const(cXMLReader, "TYPE_XML_DECLARATION", INT2FIX(XML_READER_TYPE_XML_DECLARATION)); /* Read states */ rb_define_const(cXMLReader, "MODE_INITIAL", INT2FIX(XML_TEXTREADER_MODE_INITIAL)); rb_define_const(cXMLReader, "MODE_INTERACTIVE", INT2FIX(XML_TEXTREADER_MODE_INTERACTIVE)); rb_define_const(cXMLReader, "MODE_ERROR", INT2FIX(XML_TEXTREADER_MODE_ERROR)); rb_define_const(cXMLReader, "MODE_EOF", INT2FIX(XML_TEXTREADER_MODE_EOF)); rb_define_const(cXMLReader, "MODE_CLOSED", INT2FIX(XML_TEXTREADER_MODE_CLOSED)); rb_define_const(cXMLReader, "MODE_READING", INT2FIX(XML_TEXTREADER_MODE_READING)); }
/* * call-seq: * IplImage.smoothness(<i>lowFreqRatio, blankDensity, messyDensity, highFreqRatio</i>) -> [ symbol, float, float ] * * Determines if the image's smoothness is either, :smooth, :messy, or :blank. * * Original Author: [email protected] */ VALUE rb_smoothness(int argc, VALUE *argv, VALUE self) { VALUE lowFreqRatio, blankDensity, messyDensity, highFreqRatio; rb_scan_args(argc, argv, "04", &lowFreqRatio, &blankDensity, &messyDensity, &highFreqRatio); double f_lowFreqRatio, f_blankDensity, f_messyDensity, f_highFreqRatio; double outLowDensity, outHighDensity; if (TYPE(lowFreqRatio) == T_NIL) { f_lowFreqRatio = 10 / 128.0f; } else { Check_Type(lowFreqRatio, T_FLOAT); f_lowFreqRatio = NUM2DBL(lowFreqRatio); } if (TYPE(blankDensity) == T_NIL) { f_blankDensity = 1.2f; } else { Check_Type(blankDensity, T_FLOAT); f_blankDensity = NUM2DBL(blankDensity); } if (TYPE(messyDensity) == T_NIL) { f_messyDensity = 0.151f; } else { Check_Type(messyDensity, T_FLOAT); f_messyDensity = NUM2DBL(messyDensity); } if (TYPE(highFreqRatio) == T_NIL) { f_highFreqRatio = 5 / 128.0f; } else { Check_Type(highFreqRatio, T_FLOAT); f_highFreqRatio = NUM2DBL(highFreqRatio); } IplImage *pFourierImage; IplImage *p64DepthImage; // the image is required to be in depth of 64 if (IPLIMAGE(self)->depth == 64) { p64DepthImage = NULL; pFourierImage = create_fourier_image(IPLIMAGE(self)); } else { p64DepthImage = rb_cvCreateImage(cvGetSize(IPLIMAGE(self)), IPL_DEPTH_64F, 1); cvConvertScale(CVARR(self), p64DepthImage, 1.0, 0.0); pFourierImage = create_fourier_image(p64DepthImage); } Smoothness result = compute_smoothness(pFourierImage, f_lowFreqRatio, f_blankDensity, f_messyDensity, f_highFreqRatio, outLowDensity, outHighDensity); cvReleaseImage(&pFourierImage); if (p64DepthImage != NULL) cvReleaseImage(&p64DepthImage); switch(result) { case SMOOTH: return rb_ary_new3(3, ID2SYM(rb_intern("smooth")), rb_float_new(outLowDensity), rb_float_new(outHighDensity)); case MESSY: return rb_ary_new3(3, ID2SYM(rb_intern("messy")), rb_float_new(outLowDensity), rb_float_new(outHighDensity)); case BLANK: return rb_ary_new3(3, ID2SYM(rb_intern("blank")), rb_float_new(outLowDensity), rb_float_new(outHighDensity)); default: return rb_ary_new3(3, NULL, rb_float_new(outLowDensity), rb_float_new(outHighDensity)); } }
void rb_name_class(VALUE klass, ID id) { rb_ivar_set(klass, classid, ID2SYM(id)); }
void rb_const_set(VALUE klass, ID id, VALUE val) { VALUE sym = ID2SYM(id); rb_mod_const_set(klass, sym, val); }
VALUE rb_const_get(VALUE klass, ID id) { VALUE sym = ID2SYM(id); VALUE ret = rb_mod_const_get(1, &sym, klass); return ret; }
VALUE rb_tracearg_method_id(rb_trace_arg_t *trace_arg) { fill_id_and_klass(trace_arg); return trace_arg->id ? ID2SYM(trace_arg->id) : Qnil; }
void Init_thrift_native() { // cached classes thrift_module = rb_const_get(rb_cObject, rb_intern("Thrift")); thrift_bytes_module = rb_const_get(thrift_module, rb_intern("Bytes")); thrift_types_module = rb_const_get(thrift_module, rb_intern("Types")); rb_cSet = rb_const_get(rb_cObject, rb_intern("Set")); protocol_exception_class = rb_const_get(thrift_module, rb_intern("ProtocolException")); // Init ttype constants TTYPE_BOOL = FIX2INT(rb_const_get(thrift_types_module, rb_intern("BOOL"))); TTYPE_BYTE = FIX2INT(rb_const_get(thrift_types_module, rb_intern("BYTE"))); TTYPE_I16 = FIX2INT(rb_const_get(thrift_types_module, rb_intern("I16"))); TTYPE_I32 = FIX2INT(rb_const_get(thrift_types_module, rb_intern("I32"))); TTYPE_I64 = FIX2INT(rb_const_get(thrift_types_module, rb_intern("I64"))); TTYPE_DOUBLE = FIX2INT(rb_const_get(thrift_types_module, rb_intern("DOUBLE"))); TTYPE_STRING = FIX2INT(rb_const_get(thrift_types_module, rb_intern("STRING"))); TTYPE_MAP = FIX2INT(rb_const_get(thrift_types_module, rb_intern("MAP"))); TTYPE_SET = FIX2INT(rb_const_get(thrift_types_module, rb_intern("SET"))); TTYPE_LIST = FIX2INT(rb_const_get(thrift_types_module, rb_intern("LIST"))); TTYPE_STRUCT = FIX2INT(rb_const_get(thrift_types_module, rb_intern("STRUCT"))); // method ids validate_method_id = rb_intern("validate"); write_struct_begin_method_id = rb_intern("write_struct_begin"); write_struct_end_method_id = rb_intern("write_struct_end"); write_field_begin_method_id = rb_intern("write_field_begin"); write_field_end_method_id = rb_intern("write_field_end"); write_boolean_method_id = rb_intern("write_bool"); write_byte_method_id = rb_intern("write_byte"); write_i16_method_id = rb_intern("write_i16"); write_i32_method_id = rb_intern("write_i32"); write_i64_method_id = rb_intern("write_i64"); write_double_method_id = rb_intern("write_double"); write_string_method_id = rb_intern("write_string"); write_map_begin_method_id = rb_intern("write_map_begin"); write_map_end_method_id = rb_intern("write_map_end"); write_list_begin_method_id = rb_intern("write_list_begin"); write_list_end_method_id = rb_intern("write_list_end"); write_set_begin_method_id = rb_intern("write_set_begin"); write_set_end_method_id = rb_intern("write_set_end"); read_bool_method_id = rb_intern("read_bool"); read_byte_method_id = rb_intern("read_byte"); read_i16_method_id = rb_intern("read_i16"); read_i32_method_id = rb_intern("read_i32"); read_i64_method_id = rb_intern("read_i64"); read_string_method_id = rb_intern("read_string"); read_double_method_id = rb_intern("read_double"); read_map_begin_method_id = rb_intern("read_map_begin"); read_map_end_method_id = rb_intern("read_map_end"); read_list_begin_method_id = rb_intern("read_list_begin"); read_list_end_method_id = rb_intern("read_list_end"); read_set_begin_method_id = rb_intern("read_set_begin"); read_set_end_method_id = rb_intern("read_set_end"); read_struct_begin_method_id = rb_intern("read_struct_begin"); read_struct_end_method_id = rb_intern("read_struct_end"); read_field_begin_method_id = rb_intern("read_field_begin"); read_field_end_method_id = rb_intern("read_field_end"); keys_method_id = rb_intern("keys"); entries_method_id = rb_intern("entries"); write_field_stop_method_id = rb_intern("write_field_stop"); skip_method_id = rb_intern("skip"); write_method_id = rb_intern("write"); read_all_method_id = rb_intern("read_all"); read_into_buffer_method_id = rb_intern("read_into_buffer"); force_binary_encoding_id = rb_intern("force_binary_encoding"); convert_to_utf8_byte_buffer_id = rb_intern("convert_to_utf8_byte_buffer"); convert_to_string_id = rb_intern("convert_to_string"); // constant ids fields_const_id = rb_intern("FIELDS"); transport_ivar_id = rb_intern("@trans"); strict_read_ivar_id = rb_intern("@strict_read"); strict_write_ivar_id = rb_intern("@strict_write"); // cached symbols type_sym = ID2SYM(rb_intern("type")); name_sym = ID2SYM(rb_intern("name")); key_sym = ID2SYM(rb_intern("key")); value_sym = ID2SYM(rb_intern("value")); element_sym = ID2SYM(rb_intern("element")); class_sym = ID2SYM(rb_intern("class")); Init_struct(); Init_binary_protocol_accelerated(); Init_compact_protocol(); Init_memory_buffer(); }
void init_mysql2_client() { // verify the libmysql we're about to use was the version we were built against // https://github.com/luislavena/mysql-gem/commit/a600a9c459597da0712f70f43736e24b484f8a99 int i; int dots = 0; const char *lib = mysql_get_client_info(); for (i = 0; lib[i] != 0 && MYSQL_SERVER_VERSION[i] != 0; i++) { if (lib[i] == '.') { dots++; // we only compare MAJOR and MINOR if (dots == 2) break; } if (lib[i] != MYSQL_SERVER_VERSION[i]) { rb_raise(rb_eRuntimeError, "Incorrect MySQL client library version! This gem was compiled for %s but the client library is %s.", MYSQL_SERVER_VERSION, lib); return; } } cMysql2Client = rb_define_class_under(mMysql2, "Client", rb_cObject); rb_define_alloc_func(cMysql2Client, allocate); rb_define_singleton_method(cMysql2Client, "escape", rb_mysql_client_escape, 1); rb_define_method(cMysql2Client, "close", rb_mysql_client_close, 0); rb_define_method(cMysql2Client, "query", rb_mysql_client_query, -1); rb_define_method(cMysql2Client, "escape", rb_mysql_client_real_escape, 1); rb_define_method(cMysql2Client, "info", rb_mysql_client_info, 0); rb_define_method(cMysql2Client, "server_info", rb_mysql_client_server_info, 0); rb_define_method(cMysql2Client, "socket", rb_mysql_client_socket, 0); rb_define_method(cMysql2Client, "async_result", rb_mysql_client_async_result, 0); rb_define_method(cMysql2Client, "last_id", rb_mysql_client_last_id, 0); rb_define_method(cMysql2Client, "affected_rows", rb_mysql_client_affected_rows, 0); rb_define_method(cMysql2Client, "thread_id", rb_mysql_client_thread_id, 0); rb_define_method(cMysql2Client, "ping", rb_mysql_client_ping, 0); #ifdef HAVE_RUBY_ENCODING_H rb_define_method(cMysql2Client, "encoding", rb_mysql_client_encoding, 0); #endif rb_define_private_method(cMysql2Client, "reconnect=", set_reconnect, 1); rb_define_private_method(cMysql2Client, "connect_timeout=", set_connect_timeout, 1); rb_define_private_method(cMysql2Client, "charset_name=", set_charset_name, 1); rb_define_private_method(cMysql2Client, "ssl_set", set_ssl_options, 5); rb_define_private_method(cMysql2Client, "init_connection", init_connection, 0); rb_define_private_method(cMysql2Client, "connect", rb_connect, 7); intern_encoding_from_charset = rb_intern("encoding_from_charset"); sym_id = ID2SYM(rb_intern("id")); sym_version = ID2SYM(rb_intern("version")); sym_async = ID2SYM(rb_intern("async")); sym_symbolize_keys = ID2SYM(rb_intern("symbolize_keys")); sym_as = ID2SYM(rb_intern("as")); sym_array = ID2SYM(rb_intern("array")); intern_merge = rb_intern("merge"); intern_error_number_eql = rb_intern("error_number="); intern_sql_state_eql = rb_intern("sql_state="); #ifdef CLIENT_LONG_PASSWORD rb_const_set(cMysql2Client, rb_intern("LONG_PASSWORD"), INT2NUM(CLIENT_LONG_PASSWORD)); #endif #ifdef CLIENT_FOUND_ROWS rb_const_set(cMysql2Client, rb_intern("FOUND_ROWS"), INT2NUM(CLIENT_FOUND_ROWS)); #endif #ifdef CLIENT_LONG_FLAG rb_const_set(cMysql2Client, rb_intern("LONG_FLAG"), INT2NUM(CLIENT_LONG_FLAG)); #endif #ifdef CLIENT_CONNECT_WITH_DB rb_const_set(cMysql2Client, rb_intern("CONNECT_WITH_DB"), INT2NUM(CLIENT_CONNECT_WITH_DB)); #endif #ifdef CLIENT_NO_SCHEMA rb_const_set(cMysql2Client, rb_intern("NO_SCHEMA"), INT2NUM(CLIENT_NO_SCHEMA)); #endif #ifdef CLIENT_COMPRESS rb_const_set(cMysql2Client, rb_intern("COMPRESS"), INT2NUM(CLIENT_COMPRESS)); #endif #ifdef CLIENT_ODBC rb_const_set(cMysql2Client, rb_intern("ODBC"), INT2NUM(CLIENT_ODBC)); #endif #ifdef CLIENT_LOCAL_FILES rb_const_set(cMysql2Client, rb_intern("LOCAL_FILES"), INT2NUM(CLIENT_LOCAL_FILES)); #endif #ifdef CLIENT_IGNORE_SPACE rb_const_set(cMysql2Client, rb_intern("IGNORE_SPACE"), INT2NUM(CLIENT_IGNORE_SPACE)); #endif #ifdef CLIENT_PROTOCOL_41 rb_const_set(cMysql2Client, rb_intern("PROTOCOL_41"), INT2NUM(CLIENT_PROTOCOL_41)); #endif #ifdef CLIENT_INTERACTIVE rb_const_set(cMysql2Client, rb_intern("INTERACTIVE"), INT2NUM(CLIENT_INTERACTIVE)); #endif #ifdef CLIENT_SSL rb_const_set(cMysql2Client, rb_intern("SSL"), INT2NUM(CLIENT_SSL)); #endif #ifdef CLIENT_IGNORE_SIGPIPE rb_const_set(cMysql2Client, rb_intern("IGNORE_SIGPIPE"), INT2NUM(CLIENT_IGNORE_SIGPIPE)); #endif #ifdef CLIENT_TRANSACTIONS rb_const_set(cMysql2Client, rb_intern("TRANSACTIONS"), INT2NUM(CLIENT_TRANSACTIONS)); #endif #ifdef CLIENT_RESERVED rb_const_set(cMysql2Client, rb_intern("RESERVED"), INT2NUM(CLIENT_RESERVED)); #endif #ifdef CLIENT_SECURE_CONNECTION rb_const_set(cMysql2Client, rb_intern("SECURE_CONNECTION"), INT2NUM(CLIENT_SECURE_CONNECTION)); #endif #ifdef CLIENT_MULTI_STATEMENTS rb_const_set(cMysql2Client, rb_intern("MULTI_STATEMENTS"), INT2NUM(CLIENT_MULTI_STATEMENTS)); #endif #ifdef CLIENT_PS_MULTI_RESULTS rb_const_set(cMysql2Client, rb_intern("PS_MULTI_RESULTS"), INT2NUM(CLIENT_PS_MULTI_RESULTS)); #endif #ifdef CLIENT_SSL_VERIFY_SERVER_CERT rb_const_set(cMysql2Client, rb_intern("SSL_VERIFY_SERVER_CERT"), INT2NUM(CLIENT_SSL_VERIFY_SERVER_CERT)); #endif #ifdef CLIENT_REMEMBER_OPTIONS rb_const_set(cMysql2Client, rb_intern("REMEMBER_OPTIONS"), INT2NUM(CLIENT_REMEMBER_OPTIONS)); #endif #ifdef CLIENT_ALL_FLAGS rb_const_set(cMysql2Client, rb_intern("ALL_FLAGS"), INT2NUM(CLIENT_ALL_FLAGS)); #endif #ifdef CLIENT_BASIC_FLAGS rb_const_set(cMysql2Client, rb_intern("BASIC_FLAGS"), INT2NUM(CLIENT_BASIC_FLAGS)); #endif }
static void SearchFont(VALUE rbFilePathOrName, VALUE* volatile rbRealFilePath, int* ttcIndex) { *rbRealFilePath = Qnil; if (ttcIndex != NULL) { *ttcIndex = -1; } *rbRealFilePath = strb_GetCompletePath(rbFilePathOrName, false); if (!NIL_P(*rbRealFilePath)) { return; } volatile VALUE rbFontNameSymbol = ID2SYM(rb_intern_str(rbFilePathOrName)); FontFileInfo* info = fontFileInfos; while (info) { if (info->rbFontNameSymbol == rbFontNameSymbol) { *rbRealFilePath = rb_str_new2(rb_id2name(SYM2ID(info->rbFileNameSymbol))); #ifdef WIN32 volatile VALUE rbTemp = rb_str_new2(rb_id2name(SYM2ID(rbWindowsFontDirPathSymbol))); *rbRealFilePath = rb_str_concat(rb_str_cat2(rbTemp, "\\"), *rbRealFilePath); #endif if (ttcIndex != NULL) { *ttcIndex = info->ttcIndex; } return; } info = info->next; } #ifdef HAVE_FONTCONFIG_FONTCONFIG_H if (!FcInit()) { FcFini(); rb_raise(strb_GetStarRubyErrorClass(), "can't initialize fontconfig library"); return; } int nameLength = RSTRING_LEN(rbFilePathOrName) + 1; char name[nameLength]; strncpy(name, StringValueCStr(rbFilePathOrName), nameLength); char* delimiter = strchr(name, ','); char* style = NULL; if (delimiter) { *delimiter = '\0'; style = delimiter + 1; char* nameTail = delimiter - 1; while (*nameTail == ' ') { *nameTail = '\0'; nameTail--; } while (*style == ' ') { style++; } } FcPattern* pattern = FcPatternBuild(NULL, FC_FAMILY, FcTypeString, name, NULL); if (style && 0 < strlen(style)) { FcPatternAddString(pattern, FC_STYLE, (FcChar8*)style); } FcObjectSet* objectSet = FcObjectSetBuild(FC_FAMILY, FC_FILE, NULL); FcFontSet* fontSet = FcFontList(NULL, pattern, objectSet); if (objectSet) { FcObjectSetDestroy(objectSet); } if (pattern) { FcPatternDestroy(pattern); } if (fontSet) { for (int i = 0; i < fontSet->nfont; i++) { FcChar8* fileName = NULL; if (FcPatternGetString(fontSet->fonts[i], FC_FILE, 0, &fileName) == FcResultMatch) { FcChar8* fontName = FcNameUnparse(fontSet->fonts[i]); *rbRealFilePath = rb_str_new2((char*)fileName); volatile VALUE rbFontName = rb_str_new2((char*)fontName); free(fontName); fontName = NULL; if (ttcIndex != NULL && strchr(StringValueCStr(rbFontName), ',')) { *ttcIndex = 0; } } } FcFontSetDestroy(fontSet); } FcFini(); if (!NIL_P(*rbRealFilePath)) { return; } #endif return; }
VALUE rb_str_format(int argc, const VALUE *argv, VALUE fmt) { 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; ID id = 0; 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 == '<') ? '>' : '}'; for (; p < end && *p != term; ) { p += rb_enc_mbclen(p, end, enc); } if (p >= end) { rb_raise(rb_eArgError, "malformed name - unmatched parenthesis"); } if (id) { rb_raise(rb_eArgError, "name%.*s after <%s>", (int)(p - start + 1), start, rb_id2name(id)); } id = rb_intern3(start + 1, p - start - 1, enc); nextvalue = GETNAMEARG(ID2SYM(id), start, (int)(p - start + 1)); if (nextvalue == Qundef) { rb_raise(rb_eKeyError, "key%.*s not found", (int)(p - start + 1), 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); } 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); blen += len; if (flags&FMINUS) { CHECK(width); while (width--) { buf[blen++] = ' '; } } rb_enc_associate(result, enc); break; } } PUSH(RSTRING_PTR(str), len); rb_enc_associate(result, enc); } break; case 'd': case 'i': case 'o': case 'x': case 'X': case 'b': case 'B': case 'u': { volatile VALUE tmp1; volatile VALUE val = GETARG(); char fbuf[32], nbuf[64], *s; const char *prefix = 0; int sign = 0, dots = 0; char sc = 0; long v = 0; int base, bignum = 0; int len, pos; 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 (!bignum) { if (base == 2) { val = rb_int2big(v); goto bin_retry; } if (sign) { char c = *p; if (c == 'i') c = 'd'; /* %d and %i are identical */ if (v < 0) { v = -v; sc = '-'; width--; } else if (flags & FPLUS) { sc = '+'; width--; } else if (flags & FSPACE) { sc = ' '; width--; } snprintf(fbuf, sizeof(fbuf), "%%l%c", c); snprintf(nbuf, sizeof(nbuf), fbuf, v); s = nbuf; } else { s = nbuf; if (v < 0) { dots = 1; } snprintf(fbuf, sizeof(fbuf), "%%l%c", *p == 'X' ? 'x' : *p); snprintf(++s, sizeof(nbuf) - 1, fbuf, v); if (v < 0) { char d = 0; s = remove_sign_bits(s, base); switch (base) { case 16: d = 'f'; break; case 8: d = '7'; break; } if (d && *s != d) { *--s = d; } } } len = (int)strlen(s); } else { if (sign) { tmp = rb_big2str(val, base); s = RSTRING_PTR(tmp); if (s[0] == '-') { s++; sc = '-'; width--; } else if (flags & FPLUS) { sc = '+'; width--; } else if (flags & FSPACE) { sc = ' '; width--; } } else { if (!RBIGNUM_SIGN(val)) { val = rb_big_clone(val); rb_big_2comp(val); } tmp1 = tmp = rb_big2str0(val, base, RBIGNUM_SIGN(val)); s = RSTRING_PTR(tmp); if (*s == '-') { dots = 1; if (base == 10) { rb_warning("negative number for %%u specifier"); } s = remove_sign_bits(++s, base); switch (base) { case 16: if (s[0] != 'f') *--s = 'f'; break; case 8: if (s[0] != '7') *--s = '7'; break; case 2: if (s[0] != '1') *--s = '1'; break; } } } len = rb_long2int(RSTRING_END(tmp) - s); } pos = -1; 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 (!bignum && v < 0) { char c = sign_bits(base, p); while (len < prec--) { buf[blen++] = c; } } else if ((flags & (FMINUS|FPREC)) != FMINUS) { char c; if (!sign && bignum && !RBIGNUM_SIGN(val)) c = sign_bits(base, p); else c = '0'; while (len < prec--) { buf[blen++] = c; } } PUSH(s, len); CHECK(width); while (width-- > 0) { buf[blen++] = ' '; } } break; case 'f': case 'g': case 'G': case 'e': case 'E': { VALUE val = GETARG(); double fval; int i, need = 6; 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 : 6; 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: /* 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; }
static VALUE fntype_initialize(int argc, VALUE* argv, VALUE self) { FunctionType *fnInfo; ffi_status status; VALUE rbReturnType = Qnil, rbParamTypes = Qnil, rbOptions = Qnil; VALUE rbEnums = Qnil, rbConvention = Qnil, rbBlocking = Qnil; #if defined(_WIN32) || defined(__WIN32__) VALUE rbConventionStr; #endif int i, nargs; nargs = rb_scan_args(argc, argv, "21", &rbReturnType, &rbParamTypes, &rbOptions); if (nargs >= 3 && rbOptions != Qnil) { rbConvention = rb_hash_aref(rbOptions, ID2SYM(rb_intern("convention"))); rbEnums = rb_hash_aref(rbOptions, ID2SYM(rb_intern("enums"))); rbBlocking = rb_hash_aref(rbOptions, ID2SYM(rb_intern("blocking"))); } Check_Type(rbParamTypes, T_ARRAY); Data_Get_Struct(self, FunctionType, fnInfo); fnInfo->parameterCount = (int) RARRAY_LEN(rbParamTypes); fnInfo->parameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->parameterTypes)); fnInfo->ffiParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(ffi_type *)); fnInfo->nativeParameterTypes = xcalloc(fnInfo->parameterCount, sizeof(*fnInfo->nativeParameterTypes)); fnInfo->rbParameterTypes = rb_ary_new2(fnInfo->parameterCount); fnInfo->rbEnums = rbEnums; fnInfo->blocking = RTEST(rbBlocking); fnInfo->hasStruct = false; for (i = 0; i < fnInfo->parameterCount; ++i) { VALUE entry = rb_ary_entry(rbParamTypes, i); VALUE type = rbffi_Type_Lookup(entry); if (!RTEST(type)) { VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL); rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName)); } if (rb_obj_is_kind_of(type, rbffi_FunctionTypeClass)) { REALLOC_N(fnInfo->callbackParameters, VALUE, fnInfo->callbackCount + 1); fnInfo->callbackParameters[fnInfo->callbackCount++] = type; } if (rb_obj_is_kind_of(type, rbffi_StructByValueClass)) { fnInfo->hasStruct = true; } rb_ary_push(fnInfo->rbParameterTypes, type); Data_Get_Struct(type, Type, fnInfo->parameterTypes[i]); fnInfo->ffiParameterTypes[i] = fnInfo->parameterTypes[i]->ffiType; fnInfo->nativeParameterTypes[i] = fnInfo->parameterTypes[i]->nativeType; } fnInfo->rbReturnType = rbffi_Type_Lookup(rbReturnType); if (!RTEST(fnInfo->rbReturnType)) { VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL); rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName)); } if (rb_obj_is_kind_of(fnInfo->rbReturnType, rbffi_StructByValueClass)) { fnInfo->hasStruct = true; } Data_Get_Struct(fnInfo->rbReturnType, Type, fnInfo->returnType); fnInfo->ffiReturnType = fnInfo->returnType->ffiType; #if defined(_WIN32) || defined(__WIN32__) rbConventionStr = (rbConvention != Qnil) ? rb_funcall2(rbConvention, rb_intern("to_s"), 0, NULL) : Qnil; fnInfo->abi = (rbConventionStr != Qnil && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0) ? FFI_STDCALL : FFI_DEFAULT_ABI; #else fnInfo->abi = FFI_DEFAULT_ABI; #endif status = ffi_prep_cif(&fnInfo->ffi_cif, fnInfo->abi, fnInfo->parameterCount, fnInfo->ffiReturnType, fnInfo->ffiParameterTypes); switch (status) { case FFI_BAD_ABI: rb_raise(rb_eArgError, "Invalid ABI specified"); case FFI_BAD_TYPEDEF: rb_raise(rb_eArgError, "Invalid argument type specified"); case FFI_OK: break; default: rb_raise(rb_eArgError, "Unknown FFI error"); } fnInfo->invoke = rbffi_GetInvoker(fnInfo); return self; }
// // Everything exposed to Ruby is exposed here. // void shoes_ruby_init() { progname = rb_str_new2("(eval)"); rb_define_variable("$0", &progname); rb_define_variable("$PROGRAM_NAME", &progname); instance_eval_proc = rb_eval_string("lambda{|o,b| o.instance_eval(&b)}"); rb_gc_register_address(&instance_eval_proc); ssNestSlot = rb_eval_string("{:height => 1.0}"); rb_gc_register_address(&ssNestSlot); s_aref = rb_intern("[]="); s_perc = rb_intern("%"); s_mult = rb_intern("*"); SYMBOL_DEFS(SYMBOL_INTERN); symAltQuest = ID2SYM(rb_intern("alt_?")); symAltSlash = ID2SYM(rb_intern("alt_/")); symAltEqual = ID2SYM(rb_intern("alt_=")); symAltDot = ID2SYM(rb_intern("alt_.")); symAltSemiColon = ID2SYM(rb_intern("alt_;")); // // I want all elements to be addressed Shoes::Name, but also available in // a separate mixin (cTypes), for inclusion in every Shoes.app block. // cTypes = rb_define_module("Shoes"); rb_mod_remove_const(rb_cObject, rb_str_new2("Shoes")); cShoesWindow = rb_define_class_under(cTypes, "Window", rb_cObject); cMouse = rb_define_class_under(cTypes, "Mouse", rb_cObject); cCanvas = rb_define_class_under(cTypes, "Canvas", rb_cObject); rb_define_alloc_func(cCanvas, shoes_canvas_alloc); rb_define_method(cCanvas, "top", CASTHOOK(shoes_canvas_get_top), 0); rb_define_method(cCanvas, "left", CASTHOOK(shoes_canvas_get_left), 0); rb_define_method(cCanvas, "width", CASTHOOK(shoes_canvas_get_width), 0); rb_define_method(cCanvas, "height", CASTHOOK(shoes_canvas_get_height), 0); rb_define_method(cCanvas, "scroll_height", CASTHOOK(shoes_canvas_get_scroll_height), 0); rb_define_method(cCanvas, "scroll_max", CASTHOOK(shoes_canvas_get_scroll_max), 0); rb_define_method(cCanvas, "scroll_top", CASTHOOK(shoes_canvas_get_scroll_top), 0); rb_define_method(cCanvas, "scroll_top=", CASTHOOK(shoes_canvas_set_scroll_top), 1); rb_define_method(cCanvas, "displace", CASTHOOK(shoes_canvas_displace), 2); rb_define_method(cCanvas, "move", CASTHOOK(shoes_canvas_move), 2); rb_define_method(cCanvas, "style", CASTHOOK(shoes_canvas_style), -1); rb_define_method(cCanvas, "parent", CASTHOOK(shoes_canvas_get_parent), 0); rb_define_method(cCanvas, "contents", CASTHOOK(shoes_canvas_contents), 0); rb_define_method(cCanvas, "children", CASTHOOK(shoes_canvas_children), 0); rb_define_method(cCanvas, "draw", CASTHOOK(shoes_canvas_draw), 2); rb_define_method(cCanvas, "hide", CASTHOOK(shoes_canvas_hide), 0); rb_define_method(cCanvas, "show", CASTHOOK(shoes_canvas_show), 0); rb_define_method(cCanvas, "toggle", CASTHOOK(shoes_canvas_toggle), 0); rb_define_method(cCanvas, "remove", CASTHOOK(shoes_canvas_remove), 0); rb_define_method(cCanvas, "refresh_slot", CASTHOOK(shoes_canvas_refresh_slot), 0); rb_define_method(cCanvas, "refresh", CASTHOOK(shoes_canvas_refresh_slot), 0); rb_define_method(cCanvas, "cursor", CASTHOOK(shoes_canvas_get_cursor), 0); rb_define_method(cCanvas, "cursor=", CASTHOOK(shoes_canvas_set_cursor), 1); cShoes = rb_define_class("Shoes", cCanvas); rb_include_module(cShoes, cTypes); rb_const_set(cShoes, rb_intern("Types"), cTypes); shoes_version_init(); // other Shoes:: constants rb_const_set(cTypes, rb_intern("RAD2PI"), rb_float_new(SHOES_RAD2PI)); rb_const_set(cTypes, rb_intern("TWO_PI"), rb_float_new(SHOES_PIM2)); rb_const_set(cTypes, rb_intern("HALF_PI"), rb_float_new(SHOES_HALFPI)); rb_const_set(cTypes, rb_intern("PI"), rb_float_new(SHOES_PI)); cApp = rb_define_class_under(cTypes, "App", rb_cObject); rb_define_alloc_func(cApp, shoes_app_alloc); rb_define_method(cApp, "fullscreen", CASTHOOK(shoes_app_get_fullscreen), 0); rb_define_method(cApp, "fullscreen=", CASTHOOK(shoes_app_set_fullscreen), 1); rb_define_method(cApp, "name", CASTHOOK(shoes_app_get_title), 0); rb_define_method(cApp, "name=", CASTHOOK(shoes_app_set_title), 1); rb_define_method(cApp, "location", CASTHOOK(shoes_app_location), 0); rb_define_method(cApp, "started?", CASTHOOK(shoes_app_is_started), 0); rb_define_method(cApp, "left", CASTHOOK(shoes_app_get_window_x_position), 0); rb_define_method(cApp, "top", CASTHOOK(shoes_app_get_window_y_position), 0); rb_define_method(cApp, "move", CASTHOOK(shoes_app_set_window_position), 2); rb_define_method(cApp, "width", CASTHOOK(shoes_app_get_width), 0); rb_define_method(cApp, "height", CASTHOOK(shoes_app_get_height), 0); rb_define_method(cApp, "resize", CASTHOOK(shoes_app_resize_window), 2); rb_define_method(cApp, "resizable", CASTHOOK(shoes_app_get_resizable), 0); rb_define_method(cApp, "resizable=", CASTHOOK(shoes_app_set_resizable), 1); rb_define_method(cApp, "slot", CASTHOOK(shoes_app_slot), 0); rb_define_method(cApp, "set_window_icon_path", CASTHOOK(shoes_app_set_icon), 1); // New in 3.2.19 rb_define_method(cApp, "set_window_title", CASTHOOK(shoes_app_set_wtitle), 1); // New in 3.2.19 rb_define_method(cApp, "opacity", CASTHOOK(shoes_app_get_opacity), 0); rb_define_method(cApp, "opacity=", CASTHOOK(shoes_app_set_opacity), 1); rb_define_method(cApp, "decorated", CASTHOOK(shoes_app_get_decoration), 0); rb_define_method(cApp, "decorated=", CASTHOOK(shoes_app_set_decoration), 1); rb_define_alias(cApp, "decorated?", "decorated"); rb_define_method(cApp, "cache", CASTHOOK(shoes_app_get_cache), 0); rb_define_method(cApp, "cache=", CASTHOOK(shoes_app_set_cache), 1); rb_define_method(cApp, "cache_clear", CASTHOOK(shoes_app_clear_cache), 1); rb_define_method(cApp, "event=", CASTHOOK(shoes_app_set_event_handler), 1); rb_define_method(cApp, "replay_event", CASTHOOK(shoes_app_replay_event), 1); rb_define_method(cApp, "monitor", CASTHOOK(shoes_app_monitor_get), 0); rb_define_method(cApp, "monitor=", CASTHOOK(shoes_app_monitor_set), 1); rb_define_method(cApp, "id", CASTHOOK(shoes_app_id), 0); /* Settings holds global values, not per app values. Part of shoes_world_t */ cSettings = rb_define_class_under(cTypes, "Settings", rb_cObject); rb_define_alloc_func(cSettings, shoes_settings_alloc); rb_define_method(cSettings, "dbus", CASTHOOK(shoes_settings_dbus),0); rb_define_method(cSettings, "app_name", CASTHOOK(shoes_settings_app_name),0); rb_define_method(cSettings, "app_name=", CASTHOOK(shoes_settings_set_app_name),1); rb_define_method(cSettings, "icon_path", CASTHOOK(shoes_settings_app_icon),0); rb_define_method(cSettings, "icon_path=", CASTHOOK(shoes_settings_set_app_icon),1); rb_define_method(cSettings, "theme", CASTHOOK(shoes_settings_get_theme),0); rb_define_method(cSettings, "theme=", CASTHOOK(shoes_settings_set_theme),1); rb_define_method(cSettings, "mdi", CASTHOOK(shoes_settings_mdi),0); rb_define_method(cSettings, "use_menus", CASTHOOK(shoes_settings_menu),0); rb_define_method(cSettings, "rdomain", CASTHOOK(shoes_settings_rdomain),0); rb_define_method(cSettings, "rdomain=", CASTHOOK(shoes_settings_set_rdomain),1); rb_define_method(cSettings, "monitor_count", CASTHOOK(shoes_settings_monitor_count),0); rb_define_method(cSettings, "monitor_geometry", CASTHOOK(shoes_settings_monitor_geometry),1); rb_define_method(cSettings, "monitor_default", CASTHOOK(shoes_settings_monitor_default), 0); rb_define_method(cSettings, "extra1", CASTHOOK(shoes_setting_extra1), 0); rb_define_method(cSettings, "extra2", CASTHOOK(shoes_setting_extra2), 0); rb_define_method(cSettings, "wintmo", CASTHOOK(shoes_setting_get_wintmo), 0); rb_define_method(cSettings, "wintmo=", CASTHOOK(shoes_setting_set_wintmo), 1); rb_define_method(cSettings, "display_backend", CASTHOOK(shoes_setting_display_backend), 0); cDialog = rb_define_class_under(cTypes, "Dialog", cApp); eInvMode = rb_define_class_under(cTypes, "InvalidModeError", rb_eStandardError); eNotImpl = rb_define_class_under(cTypes, "NotImplementedError", rb_eStandardError); eImageError = rb_define_class_under(cTypes, "ImageError", rb_eStandardError); C(HEX_SOURCE, "/^(?:0x|#)?([0-9A-F]{2})([0-9A-F]{2})([0-9A-F]{2})$/i"); C(HEX3_SOURCE, "/^(?:0x|#)?([0-9A-F])([0-9A-F])([0-9A-F])$/i"); C(RGB_SOURCE, "/^rgb\\((\\d+), *(\\d+), *(\\d+)\\)$/i"); C(RGBA_SOURCE, "/^rgb\\((\\d+), *(\\d+), *(\\d+), *(\\d+)\\)$/i"); C(GRAY_SOURCE, "/^gray\\((\\d+)\\)$/i"); C(GRAYA_SOURCE, "/^gray\\((\\d+), *(\\d+)\\)$/i"); C(LF, "/\\r?\\n/"); rb_eval_string( "def Shoes.escape(string);" "string.gsub(/&/n, '&').gsub(/\\\"/n, '"').gsub(/>/n, '>').gsub(/</n, '<');" "end" ); rb_define_singleton_method(cShoes, "APPS", CASTHOOK(shoes_apps_get), 0); rb_define_singleton_method(cShoes, "app", CASTHOOK(shoes_app_main), -1); rb_define_singleton_method(cShoes, "p", CASTHOOK(shoes_p), 1); rb_define_singleton_method(cShoes, "log", CASTHOOK(shoes_log), 0); rb_define_singleton_method(cShoes, "show_console", CASTHOOK(shoes_app_console), 0); // New in 3.2.23 rb_define_singleton_method(cShoes, "terminal", CASTHOOK(shoes_app_terminal), -1); // New in 3.3.2 replaces console rb_define_singleton_method(cShoes, "quit", CASTHOOK(shoes_app_quit), 0); // Shoes 3.3.2 rb_define_singleton_method(cShoes, "settings", CASTHOOK(shoes_app_settings), 0); // Shoes 3.3.7 //rb_define_singleton_method(cShoes, "exit", CASTHOOK(shoes_app_quit), 0); // // Canvas methods // See ruby.h for the complete list of Canvas method signatures. // Macros are used to build App redirection methods, which should be // speedier than method_missing. // CANVAS_DEFS(RUBY_M); // // Shoes Kernel methods // //rb_define_method(rb_mKernel, "quit", CASTHOOK(shoes_app_quit), 0); //rb_define_method(rb_mKernel, "exit", CASTHOOK(shoes_app_quit), 0); rb_define_method(rb_mKernel, "secret_exit_hook", CASTHOOK(shoes_exit_setup),0); //unused? rb_define_method(rb_mKernel, "debug", CASTHOOK(shoes_canvas_debug), 1); rb_define_method(rb_mKernel, "info", CASTHOOK(shoes_canvas_info), 1); rb_define_method(rb_mKernel, "warn", CASTHOOK(shoes_canvas_warn), 1); rb_define_method(rb_mKernel, "error", CASTHOOK(shoes_canvas_error), 1); cFlow = rb_define_class_under(cTypes, "Flow", cShoes); cStack = rb_define_class_under(cTypes, "Stack", cShoes); cMask = rb_define_class_under(cTypes, "Mask", cShoes); cWidget = rb_define_class_under(cTypes, "Widget", cShoes); rb_define_method(cApp, "method_missing", CASTHOOK(shoes_app_method_missing), -1); rb_define_method(rb_mKernel, "alert", CASTHOOK(shoes_dialog_alert), -1); rb_define_method(rb_mKernel, "ask", CASTHOOK(shoes_dialog_ask), -1); rb_define_method(rb_mKernel, "confirm", CASTHOOK(shoes_dialog_confirm), -1); rb_define_method(rb_mKernel, "ask_color", CASTHOOK(shoes_dialog_color), 1); rb_define_method(rb_mKernel, "ask_open_file", CASTHOOK(shoes_dialog_open), -1); rb_define_method(rb_mKernel, "ask_save_file", CASTHOOK(shoes_dialog_save), -1); rb_define_method(rb_mKernel, "ask_open_folder", CASTHOOK(shoes_dialog_open_folder), -1); rb_define_method(rb_mKernel, "ask_save_folder", CASTHOOK(shoes_dialog_save_folder), -1); rb_define_method(rb_mKernel, "font", CASTHOOK(shoes_font), 1); SHOES_TYPES_INIT; }
bool RoxorCore::respond_to(VALUE obj, VALUE klass, SEL sel, bool priv, bool check_override) { if (klass == Qnil) { klass = CLASS_OF(obj); } else { assert(!check_override); } IMP imp = NULL; const bool overriden = check_override ? ((imp = class_getMethodImplementation((Class)klass, selRespondTo)) != basic_respond_to_imp) : false; if (!overriden) { lock(); const long key = respond_to_key((Class)klass, sel); std::map<long, int>::iterator iter = respond_to_cache.find(key); int iter_cached = (iter != respond_to_cache.end()); unlock(); int status; if (iter_cached) { status = iter->second; } else { Method m = class_getInstanceMethod((Class)klass, sel); if (m == NULL) { const char *selname = sel_getName(sel); sel = helper_sel(selname, strlen(selname)); if (sel != NULL) { m = class_getInstanceMethod((Class)klass, sel); } } IMP imp = method_getImplementation(m); if (UNAVAILABLE_IMP(imp) || imp == (IMP)rb_f_notimplement) { status = RESPOND_TO_NOT_EXIST; } else { rb_vm_method_node_t *node = method_node_get(m); if (node != NULL && (node->flags & VM_METHOD_PRIVATE)) { status = RESPOND_TO_PRIVATE; } else { status = RESPOND_TO_PUBLIC; } } lock(); respond_to_cache[key] = status; unlock(); } return status == RESPOND_TO_PUBLIC || (priv && status == RESPOND_TO_PRIVATE); } else { if (imp == NULL || imp == _objc_msgForward) { // The class does not respond to respond_to?:, it's probably // NSProxy-based. return false; } VALUE args[2]; int n = 0; args[n++] = ID2SYM(rb_intern(sel_getName(sel))); if (priv) { rb_vm_method_node_t *node = method_node_get(imp); if (node != NULL && (2 < node->arity.min || (node->arity.max != -1 && 2 > node->arity.max))) { // Do nothing, custom respond_to? method incompatible arity. } else { args[n++] = Qtrue; } } return rb_vm_call(obj, selRespondTo, n, args) == Qtrue; } }
/* * call-seq: configure(opts) * * Configure this State instance with the Hash _opts_, and return * itself. */ static VALUE cState_configure(VALUE self, VALUE opts) { VALUE tmp; GET_STATE(self); tmp = rb_check_convert_type(opts, T_HASH, "Hash", "to_hash"); if (NIL_P(tmp)) tmp = rb_convert_type(opts, T_HASH, "Hash", "to_h"); opts = tmp; tmp = rb_hash_aref(opts, ID2SYM(i_indent)); if (RTEST(tmp)) { unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); state->indent = fstrndup(RSTRING_PTR(tmp), len + 1); state->indent_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_space)); if (RTEST(tmp)) { unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); state->space = fstrndup(RSTRING_PTR(tmp), len + 1); state->space_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_space_before)); if (RTEST(tmp)) { unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); state->space_before = fstrndup(RSTRING_PTR(tmp), len + 1); state->space_before_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_array_nl)); if (RTEST(tmp)) { unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); state->array_nl = fstrndup(RSTRING_PTR(tmp), len + 1); state->array_nl_len = len; } tmp = rb_hash_aref(opts, ID2SYM(i_object_nl)); if (RTEST(tmp)) { unsigned long len; Check_Type(tmp, T_STRING); len = RSTRING_LEN(tmp); state->object_nl = fstrndup(RSTRING_PTR(tmp), len + 1); state->object_nl_len = len; } tmp = ID2SYM(i_max_nesting); state->max_nesting = 100; if (option_given_p(opts, tmp)) { VALUE max_nesting = rb_hash_aref(opts, tmp); if (RTEST(max_nesting)) { Check_Type(max_nesting, T_FIXNUM); state->max_nesting = FIX2LONG(max_nesting); } else { state->max_nesting = 0; } } tmp = ID2SYM(i_depth); state->depth = 0; if (option_given_p(opts, tmp)) { VALUE depth = rb_hash_aref(opts, tmp); if (RTEST(depth)) { Check_Type(depth, T_FIXNUM); state->depth = FIX2LONG(depth); } else { state->depth = 0; } } tmp = ID2SYM(i_buffer_initial_length); if (option_given_p(opts, tmp)) { VALUE buffer_initial_length = rb_hash_aref(opts, tmp); if (RTEST(buffer_initial_length)) { long initial_length; Check_Type(buffer_initial_length, T_FIXNUM); initial_length = FIX2LONG(buffer_initial_length); if (initial_length > 0) state->buffer_initial_length = initial_length; } } tmp = rb_hash_aref(opts, ID2SYM(i_allow_nan)); state->allow_nan = RTEST(tmp); tmp = rb_hash_aref(opts, ID2SYM(i_ascii_only)); state->ascii_only = RTEST(tmp); tmp = rb_hash_aref(opts, ID2SYM(i_quirks_mode)); state->quirks_mode = RTEST(tmp); return self; }
VALUE rb_vm_dispatch(void *_vm, struct mcache *cache, VALUE top, VALUE self, Class klass, SEL sel, rb_vm_block_t *block, unsigned char opt, int argc, const VALUE *argv) { RoxorVM *vm = (RoxorVM *)_vm; #if ROXOR_VM_DEBUG bool cached = true; #endif bool cache_method = true; Class current_super_class = vm->get_current_super_class(); SEL current_super_sel = vm->get_current_super_sel(); if (opt & DISPATCH_SUPER) { // TODO goto recache; } if (cache->sel != sel || cache->klass != klass || cache->flag == 0) { recache: #if ROXOR_VM_DEBUG cached = false; #endif Method method; if (opt & DISPATCH_SUPER) { if (!sel_equal(klass, current_super_sel, sel)) { current_super_sel = sel; current_super_class = klass; } else { // Let's make sure the current_super_class is valid before // using it; we check this by verifying that it's a real // super class of the current class, as we may be calling // a super method of the same name but on a totally different // class hierarchy. Class k = klass; bool current_super_class_ok = false; while (k != NULL) { if (k == current_super_class) { current_super_class_ok = true; break; } k = class_getSuperclass(k); } if (!current_super_class_ok) { current_super_class = klass; } } method = rb_vm_super_lookup(current_super_class, sel, ¤t_super_class); } else { current_super_sel = 0; method = class_getInstanceMethod(klass, sel); } if (method != NULL) { recache2: IMP imp = method_getImplementation(method); if (UNAVAILABLE_IMP(imp)) { // Method was undefined. goto call_method_missing; } rb_vm_method_node_t *node = GET_CORE()->method_node_get(method); if (node != NULL) { // ruby call fill_rcache(cache, klass, sel, node); } else { // objc call fill_ocache(cache, self, klass, imp, sel, method, argc); } if (opt & DISPATCH_SUPER) { cache->flag |= MCACHE_SUPER; } } else { // Method is not found... #if !defined(MACRUBY_STATIC) // Force a method resolving, because the objc cache might be // wrong. if (rb_vm_resolve_method(klass, sel)) { goto recache; } #endif // Does the receiver implements -forwardInvocation:? if ((opt & DISPATCH_SUPER) == 0 && rb_objc_supports_forwarding(self, sel)) { //#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 // In earlier versions of the Objective-C runtime, there seems // to be a bug where class_getInstanceMethod isn't atomic, // and might return NULL while at the exact same time another // thread registers the related method. // As a work-around, we double-check if the method still does // not exist here. If he does, we can dispatch it properly. // note: OS X 10.7 also, this workaround is required. see #1476 method = class_getInstanceMethod(klass, sel); if (method != NULL) { goto recache2; } //#endif fill_ocache(cache, self, klass, (IMP)objc_msgSend, sel, NULL, argc); goto dispatch; } // Let's see if are not trying to call a Ruby method that accepts // a regular argument then an optional Hash argument, to be // compatible with the Ruby specification. const char *selname = (const char *)sel; size_t selname_len = strlen(selname); if (argc > 1) { const char *p = strchr(selname, ':'); if (p != NULL && p + 1 != '\0') { char *tmp = (char *)malloc(selname_len + 1); assert(tmp != NULL); strncpy(tmp, selname, p - selname + 1); tmp[p - selname + 1] = '\0'; sel = sel_registerName(tmp); VALUE h = rb_hash_new(); bool ok = true; p += 1; for (int i = 1; i < argc; i++) { const char *p2 = strchr(p, ':'); if (p2 == NULL) { ok = false; break; } strlcpy(tmp, p, selname_len); tmp[p2 - p] = '\0'; p = p2 + 1; rb_hash_aset(h, ID2SYM(rb_intern(tmp)), argv[i]); } free(tmp); tmp = NULL; if (ok) { argc = 2; ((VALUE *)argv)[1] = h; // bad, I know... Method m = class_getInstanceMethod(klass, sel); if (m != NULL) { method = m; cache_method = false; goto recache2; } } } } // Enable helpers for classes which are not RubyObject based. if ((RCLASS_VERSION(klass) & RCLASS_IS_OBJECT_SUBCLASS) != RCLASS_IS_OBJECT_SUBCLASS) { // Let's try to see if we are not given a helper selector. SEL new_sel = helper_sel(selname, selname_len); if (new_sel != NULL) { Method m = class_getInstanceMethod(klass, new_sel); if (m != NULL) { sel = new_sel; method = m; // We need to invert arguments because // #[]= and setObject:forKey: take arguments // in a reverse order if (new_sel == selSetObjectForKey && argc == 2) { VALUE swap = argv[0]; ((VALUE *)argv)[0] = argv[1]; ((VALUE *)argv)[1] = swap; cache_method = false; } goto recache2; } } } // Let's see if we are not trying to call a BridgeSupport function. if (selname[selname_len - 1] == ':') { selname_len--; } std::string name(selname, selname_len); bs_element_function_t *bs_func = GET_CORE()->find_bs_function(name); if (bs_func != NULL) { if ((unsigned)argc < bs_func->args_count || ((unsigned)argc > bs_func->args_count && bs_func->variadic == false)) { rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, bs_func->args_count); } std::string types; vm_gen_bs_func_types(argc, argv, bs_func, types); cache->flag = MCACHE_FCALL; cache->sel = sel; cache->klass = klass; cache->as.fcall.bs_function = bs_func; cache->as.fcall.imp = (IMP)dlsym(RTLD_DEFAULT, bs_func->name); assert(cache->as.fcall.imp != NULL); cache->as.fcall.stub = (rb_vm_c_stub_t *)GET_CORE()->gen_stub( types, bs_func->variadic, bs_func->args_count, false); } else { // Still nothing, then let's call #method_missing. goto call_method_missing; } } } dispatch: if (cache->flag & MCACHE_RCALL) { if (!cache_method) { cache->flag = 0; } #if ROXOR_VM_DEBUG printf("ruby dispatch %c[<%s %p> %s] (imp %p block %p argc %d opt %d cache %p cached %s)\n", class_isMetaClass(klass) ? '+' : '-', class_getName(klass), (void *)self, sel_getName(sel), cache->as.rcall.node->ruby_imp, block, argc, opt, cache, cached ? "true" : "false"); #endif bool block_already_current = vm->is_block_current(block); Class current_klass = vm->get_current_class(); if (!block_already_current) { vm->add_current_block(block); } vm->set_current_class(NULL); Class old_current_super_class = vm->get_current_super_class(); vm->set_current_super_class(current_super_class); SEL old_current_super_sel = vm->get_current_super_sel(); vm->set_current_super_sel(current_super_sel); const bool should_pop_broken_with = sel != selInitialize && sel != selInitialize2; struct Finally { bool block_already_current; Class current_class; Class current_super_class; SEL current_super_sel; bool should_pop_broken_with; RoxorVM *vm; Finally(bool _block_already_current, Class _current_class, Class _current_super_class, SEL _current_super_sel, bool _should_pop_broken_with, RoxorVM *_vm) { block_already_current = _block_already_current; current_class = _current_class; current_super_class = _current_super_class; current_super_sel = _current_super_sel; should_pop_broken_with = _should_pop_broken_with; vm = _vm; } ~Finally() { if (!block_already_current) { vm->pop_current_block(); } vm->set_current_class(current_class); if (should_pop_broken_with) { vm->pop_broken_with(); } vm->set_current_super_class(current_super_class); vm->set_current_super_sel(current_super_sel); vm->pop_current_binding(); } } finalizer(block_already_current, current_klass, old_current_super_class, old_current_super_sel, should_pop_broken_with, vm); // DTrace probe: method__entry if (MACRUBY_METHOD_ENTRY_ENABLED()) { char *class_name = (char *)rb_class2name((VALUE)klass); char *method_name = (char *)sel_getName(sel); char file[PATH_MAX]; unsigned long line = 0; GET_CORE()->symbolize_backtrace_entry(1, file, sizeof file, &line, NULL, 0); MACRUBY_METHOD_ENTRY(class_name, method_name, file, line); } VALUE v = ruby_dispatch(top, self, sel, cache->as.rcall.node, opt, argc, argv); // DTrace probe: method__return if (MACRUBY_METHOD_RETURN_ENABLED()) { char *class_name = (char *)rb_class2name((VALUE)klass); char *method_name = (char *)sel_getName(sel); char file[PATH_MAX]; unsigned long line = 0; GET_CORE()->symbolize_backtrace_entry(1, file, sizeof file, &line, NULL, 0); MACRUBY_METHOD_RETURN(class_name, method_name, file, line); } return v; } else if (cache->flag & MCACHE_OCALL) { if (cache->as.ocall.argc != argc) { goto recache; } if (!cache_method) { cache->flag = 0; } if (block != NULL) { rb_warn("passing a block to an Objective-C method - " \ "will be ignored"); } else if (sel == selNew) { if (self == rb_cNSMutableArray) { self = rb_cRubyArray; } } else if (sel == selClass) { // Because +[NSObject class] returns self. if (RCLASS_META(klass)) { return RCLASS_MODULE(self) ? rb_cModule : rb_cClass; } // Because the CF classes should be hidden, for Ruby compat. if (self == Qnil) { return rb_cNilClass; } if (self == Qtrue) { return rb_cTrueClass; } if (self == Qfalse) { return rb_cFalseClass; } return rb_class_real((VALUE)klass, true); } #if ROXOR_VM_DEBUG printf("objc dispatch %c[<%s %p> %s] imp=%p cache=%p argc=%d (cached=%s)\n", class_isMetaClass(klass) ? '+' : '-', class_getName(klass), (void *)self, sel_getName(sel), cache->as.ocall.imp, cache, argc, cached ? "true" : "false"); #endif id ocrcv = RB2OC(self); if (cache->as.ocall.bs_method != NULL) { Class ocklass = object_getClass(ocrcv); for (int i = 0; i < (int)cache->as.ocall.bs_method->args_count; i++) { bs_element_arg_t *arg = &cache->as.ocall.bs_method->args[i]; if (arg->sel_of_type != NULL) { // BridgeSupport tells us that this argument contains a // selector of the given type, but we don't have any // information regarding the target. RubyCocoa and the // other ObjC bridges do not really require it since they // use the NSObject message forwarding mechanism, but // MacRuby registers all methods in the runtime. // // Therefore, we apply here a naive heuristic by assuming // that either the receiver or one of the arguments of this // call is the future target. const int arg_i = arg->index; assert(arg_i >= 0 && arg_i < argc); if (argv[arg_i] != Qnil) { ID arg_selid = rb_to_id(argv[arg_i]); SEL arg_sel = sel_registerName(rb_id2name(arg_selid)); if (reinstall_method_maybe(ocklass, arg_sel, arg->sel_of_type)) { goto sel_target_found; } for (int j = 0; j < argc; j++) { if (j != arg_i && !SPECIAL_CONST_P(argv[j])) { if (reinstall_method_maybe(*(Class *)argv[j], arg_sel, arg->sel_of_type)) { goto sel_target_found; } } } } sel_target_found: // There can only be one sel_of_type argument. break; } } } return __rb_vm_objc_dispatch(cache->as.ocall.stub, cache->as.ocall.imp, ocrcv, sel, argc, argv); } else if (cache->flag & MCACHE_FCALL) { #if ROXOR_VM_DEBUG printf("C dispatch %s() imp=%p argc=%d (cached=%s)\n", cache->as.fcall.bs_function->name, cache->as.fcall.imp, argc, cached ? "true" : "false"); #endif return (*cache->as.fcall.stub)(cache->as.fcall.imp, argc, argv); } printf("method dispatch is b0rked\n"); abort(); call_method_missing: // Before calling method_missing, let's check if we are not in the following // cases: // // def foo; end; foo(42) // def foo(x); end; foo // // If yes, we need to raise an ArgumentError exception instead. const char *selname = sel_getName(sel); const size_t selname_len = strlen(selname); SEL new_sel = 0; if (argc > 0 && selname[selname_len - 1] == ':') { char buf[100]; assert(sizeof buf > selname_len - 1); strlcpy(buf, selname, sizeof buf); buf[selname_len - 1] = '\0'; new_sel = sel_registerName(buf); } else if (argc == 0) { char buf[100]; snprintf(buf, sizeof buf, "%s:", selname); new_sel = sel_registerName(buf); } if (new_sel != 0) { Method m = class_getInstanceMethod(klass, new_sel); if (m != NULL) { IMP mimp = method_getImplementation(m); if (!UNAVAILABLE_IMP(mimp)) { unsigned expected_argc; rb_vm_method_node_t *node = GET_CORE()->method_node_get(m); if (node != NULL) { expected_argc = node->arity.min; } else { expected_argc = rb_method_getNumberOfArguments(m); expected_argc -= 2; // removing receiver and selector } rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, expected_argc); } } } rb_vm_method_missing_reason_t status; if (opt & DISPATCH_VCALL) { status = METHOD_MISSING_VCALL; } else if (opt & DISPATCH_SUPER) { status = METHOD_MISSING_SUPER; } else { status = METHOD_MISSING_DEFAULT; } return method_missing((VALUE)self, sel, block, argc, argv, status); }
static VALUE variadic_initialize(VALUE self, VALUE rbFunction, VALUE rbParameterTypes, VALUE rbReturnType, VALUE options) { VariadicInvoker* invoker = NULL; VALUE retval = Qnil; VALUE convention = Qnil; VALUE fixed = Qnil; #if defined(_WIN32) || defined(__WIN32__) VALUE rbConventionStr; #endif int i; Check_Type(options, T_HASH); convention = rb_hash_aref(options, ID2SYM(rb_intern("convention"))); Data_Get_Struct(self, VariadicInvoker, invoker); invoker->rbEnums = rb_hash_aref(options, ID2SYM(rb_intern("enums"))); invoker->rbAddress = rbFunction; invoker->function = rbffi_AbstractMemory_Cast(rbFunction, rbffi_PointerClass)->address; #if (defined(_WIN32) || defined(__WIN32__)) && defined(FFI_STDCALL) rbConventionStr = rb_funcall2(convention, rb_intern("to_s"), 0, NULL); invoker->abi = (RTEST(convention) && strcmp(StringValueCStr(rbConventionStr), "stdcall") == 0) ? FFI_STDCALL : FFI_DEFAULT_ABI; #else invoker->abi = FFI_DEFAULT_ABI; #endif invoker->rbReturnType = rbffi_Type_Lookup(rbReturnType); if (!RTEST(invoker->rbReturnType)) { VALUE typeName = rb_funcall2(rbReturnType, rb_intern("inspect"), 0, NULL); rb_raise(rb_eTypeError, "Invalid return type (%s)", RSTRING_PTR(typeName)); } Data_Get_Struct(rbReturnType, Type, invoker->returnType); invoker->paramCount = -1; fixed = rb_ary_new2(RARRAY_LEN(rbParameterTypes) - 1); for (i = 0; i < RARRAY_LEN(rbParameterTypes); ++i) { VALUE entry = rb_ary_entry(rbParameterTypes, i); VALUE rbType = rbffi_Type_Lookup(entry); Type* type; if (!RTEST(rbType)) { VALUE typeName = rb_funcall2(entry, rb_intern("inspect"), 0, NULL); rb_raise(rb_eTypeError, "Invalid parameter type (%s)", RSTRING_PTR(typeName)); } Data_Get_Struct(rbType, Type, type); if (type->nativeType != NATIVE_VARARGS) { rb_ary_push(fixed, entry); } } /* * @fixed and @type_map are used by the parameter mangling ruby code */ rb_iv_set(self, "@fixed", fixed); rb_iv_set(self, "@type_map", rb_hash_aref(options, ID2SYM(rb_intern("type_map")))); return retval; }
/* 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)) { 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_yield(self); rb_funcall(self, rb_intern("close"), 0); } return self; }
/* * Message originator identifier. * * @return [Number] the value of attribute datapath_id. */ static VALUE openflow_error_datapath_id( VALUE self ) { return rb_hash_aref( rb_iv_get( self, "@attribute" ), ID2SYM( rb_intern( "datapath_id" ) ) ); }
VALUE rb_tracearg_event(rb_trace_arg_t *trace_arg) { return ID2SYM(get_event_id(trace_arg->event)); }
/* * The command or action that failed. * * @return [Number] the value of attribute type. */ static VALUE openflow_error_type( VALUE self ) { return rb_hash_aref( rb_iv_get( self, "@attribute" ), ID2SYM( rb_intern( "type" ) ) ); }
/* * call-seq: * Kernel.backtrace_includes?( method_or_object, ... ) -> true or false * Kernel.backtrace_includes?( number_of_frames, method_or_object, ... ) -> true or false * * Returns whether specified methods or objects or classes are in the current backtrace context. * Kernel.backtrace_includes? begins with the prior frame, so asking if the backtrace includes the current method * will only report true if the current method is part of the earlier call chain. */ VALUE rb_RPRuby_Sender_Kernel_backtrace_includes( int argc, VALUE* args, VALUE rb_self ) { // this function is also used for // * backtrace_includes_one_of? // * backtrace_includes_frame? // * backtrace_includes_one_of_frames? // create tracking array VALUE rb_tracking_array = rb_ary_new(); // populate tracking array with methods/objects // optional - if first arg is Qtrue, we are looking for one of the args instead of all of the args int c_which_arg = 0; BOOL c_requires_all_items = TRUE; if ( args[ 0 ] == Qnil || ( argc > 1 && args[ 1 ] == Qnil ) ) { c_which_arg++; c_requires_all_items = FALSE; } BOOL c_return_frame = FALSE; if ( args[ 0 ] == Qfalse || ( argc > 1 && args[ 1 ] == Qfalse ) ) { c_which_arg++; c_return_frame = TRUE; } BOOL c_return_all_frames = FALSE; if ( args[ 0 ] == Qtrue || ( argc > 1 && args[ 1 ] == Qtrue ) ) { c_which_arg++; c_return_all_frames = TRUE; } int c_args_offset = c_which_arg; for ( ; c_which_arg < argc ; c_which_arg++ ) { rb_ary_push( rb_tracking_array, args[ c_which_arg ] ); } rb_thread_t* c_thread = GET_THREAD(); // Get the current frame - we're doing a backtrace, so our current working frame to start is the first previous thread rb_control_frame_t* c_current_context_frame = RUBY_VM_PREVIOUS_CONTROL_FRAME( RUBY_VM_PREVIOUS_CONTROL_FRAME( c_thread->cfp ) ); // c_top_of_control_frame describes the top edge of the stack trace // set c_top_of_control_frame to the first frame in <main> rb_control_frame_t* c_top_of_control_frame = RUBY_VM_NEXT_CONTROL_FRAME( RUBY_VM_NEXT_CONTROL_FRAME( (void *)( c_thread->stack + c_thread->stack_size ) ) ); VALUE rb_test_index_array = rb_ary_new(); // :object // instance or class rb_ary_push( rb_test_index_array, ID2SYM( rb_intern( "object" ) ) ); // :method rb_ary_push( rb_test_index_array, ID2SYM( rb_intern( "method" ) ) ); // :file rb_ary_push( rb_test_index_array, ID2SYM( rb_intern( "file" ) ) ); // :line rb_ary_push( rb_test_index_array, ID2SYM( rb_intern( "line" ) ) ); // only used if c_return_all_frames == TRUE VALUE rb_frame_hashes_array = Qnil; if ( c_return_all_frames == TRUE ) { rb_frame_hashes_array = rb_ary_new(); } VALUE rb_frame_hash = Qnil; // for each control frame: while ( c_current_context_frame < c_top_of_control_frame ) { // iterate each array member int c_which_member; for ( c_which_member = 0 ; c_which_member < RARRAY_LEN( rb_tracking_array ) ; c_which_member++ ) { VALUE rb_this_arg = args[ c_which_member + c_args_offset ]; BOOL matched = FALSE; rb_frame_hash = rb_RPRuby_Sender_Kernel_internal_backtraceHashForControlFrame( & c_current_context_frame ); // if we have a hash we are testing multiple items in a frame if ( TYPE( rb_this_arg ) == T_HASH ) { VALUE rb_frame_test_array = rb_obj_clone( rb_test_index_array ); // for each element that we could test for int c_which_index; int c_skipped_index_count = 0; for ( c_which_index = 0 ; c_which_index < RARRAY_LEN( rb_frame_test_array ) ; c_which_index++ ) { VALUE rb_this_index = RARRAY_PTR( rb_frame_test_array )[ c_which_index ]; // see if our requested test hash includes the potential test element if ( rb_hash_lookup( rb_this_arg, rb_this_index ) != Qnil ) { VALUE rb_required_element = rb_hash_aref( rb_this_arg, rb_this_index ); VALUE rb_frame_element = rb_hash_aref( rb_frame_hash, rb_this_index ); // if it does, we need to see if the current frame's element matches this element VALUE rb_required_element_klass; if ( rb_required_element == rb_frame_element // if we have a string, which is a filename || ( TYPE( rb_required_element ) == T_STRING && rb_funcall( rb_frame_element, rb_intern( "==" ), 1, rb_required_element ) == Qtrue ) // if we have a class, which is a special case for :object || ( rb_this_index == ID2SYM( rb_intern( "class" ) ) && ( rb_required_element_klass = ( ( TYPE( rb_required_element ) == T_CLASS ) ? rb_required_element : rb_funcall( rb_required_element, rb_intern( "class" ), 0 ) ) ) && rb_required_element_klass == rb_required_element ) ) { rb_ary_delete_at( rb_frame_test_array, c_which_index ); c_which_index--; } } else { c_skipped_index_count++; } if ( RARRAY_LEN( rb_frame_test_array ) == c_skipped_index_count ) { if ( c_return_frame == TRUE ) { return rb_frame_hash; } else if ( c_return_all_frames == TRUE ) { rb_ary_push( rb_frame_hashes_array, rb_frame_hash ); } else { return Qtrue; } } } } else { // :object => <class:instance> if ( TYPE( rb_this_arg ) == T_OBJECT ) { if ( rb_hash_aref( rb_frame_hash, ID2SYM( rb_intern( "object" ) ) ) == rb_this_arg ) { matched = TRUE; } } // :object => <class> else if ( TYPE( rb_this_arg ) == T_CLASS ) { VALUE rb_frame_object = rb_hash_aref( rb_frame_hash, ID2SYM( rb_intern( "object" ) ) ); VALUE rb_frame_object_klass = TYPE( rb_frame_object ) == T_CLASS ? rb_frame_object : rb_funcall( rb_frame_object, rb_intern( "class" ), 0 ); if ( rb_frame_object_klass == rb_this_arg ) { matched = TRUE; } } // :method => :method else if ( TYPE( rb_this_arg ) == T_SYMBOL ) { if ( rb_hash_aref( rb_frame_hash, ID2SYM( rb_intern( "method" ) ) ) == rb_this_arg ) { matched = TRUE; } } // :file => "filename" else if ( TYPE( rb_this_arg ) == T_STRING ) { VALUE rb_filename = rb_hash_aref( rb_frame_hash, ID2SYM( rb_intern( "file" ) ) ); VALUE rb_comparison = rb_funcall( rb_filename, rb_intern( "==" ), 1, rb_this_arg ); if ( rb_comparison == Qtrue ) { matched = TRUE; } } // :line => number else if ( TYPE( rb_this_arg ) == T_FIXNUM ) { if ( rb_hash_aref( rb_frame_hash, ID2SYM( rb_intern( "line" ) ) ) == rb_this_arg ) { matched = TRUE; } } // if array member exists in frame, remove from array if ( matched ) { if ( c_requires_all_items == FALSE ) { if ( c_return_frame == TRUE ) { return rb_frame_hash; } else { return Qtrue; } } else { // delete this index rb_ary_delete_at( rb_tracking_array, c_which_member ); // decrement the loop iterator so that the increase is offset // this is necessary since we just removed an index and are iterating vs. the length of the array c_which_member--; } } } } // if array is empty, return true // we check here as well as at the end so we can stop iterating the backtrace if we find all our items if ( RARRAY_LEN( rb_tracking_array ) == 0 ) { if ( c_return_frame == TRUE ) { return rb_frame_hash; } else if ( c_return_all_frames == TRUE ) { rb_ary_push( rb_frame_hashes_array, rb_frame_hash ); return rb_frame_hashes_array; } else { return Qtrue; } } c_current_context_frame = RUBY_VM_PREVIOUS_CONTROL_FRAME( c_current_context_frame ); } if ( c_return_all_frames == TRUE && RARRAY_LEN( rb_frame_hashes_array ) > 0 ) { return rb_frame_hashes_array; } // if we finish iterating frames and still have items in the array, return false else if ( RARRAY_LEN( rb_tracking_array ) > 0 ) { if ( c_return_frame == TRUE ) { return Qnil; } else { return Qfalse; } } // otherwise, return true else if ( c_return_frame == TRUE ) { return rb_frame_hash; } else { return Qtrue; } // we don't get here return Qnil; }