$search
00001 #include <ruby.h> 00002 #include <set> 00003 00004 #ifndef RUBINIUS 00005 #ifdef RUBY_IS_19 00006 #include "ruby_internals-1.9.h" 00007 #else 00008 #include "ruby_internals-1.8.h" 00009 #endif 00010 #endif 00011 00012 static VALUE mUtilrb; 00013 00014 using namespace std; 00015 00016 #ifndef RUBINIUS 00017 static VALUE enumerable_each_uniq_i(VALUE i, VALUE* memo) 00018 { 00019 set<VALUE>& seen = *reinterpret_cast< set<VALUE>* >(memo); 00020 if (seen.find(i) == seen.end()) 00021 { 00022 seen.insert(i); 00023 return rb_yield(i); 00024 } 00025 else 00026 return Qnil; 00027 00028 } 00029 00030 /* :nodoc: */ 00031 static VALUE enumerable_each_uniq(VALUE self) 00032 { 00033 set<VALUE> seen; 00034 rb_iterate(rb_each, self, 00035 RUBY_METHOD_FUNC(enumerable_each_uniq_i), (VALUE)&seen); 00036 return self; 00037 } 00038 00039 /* call-seq: 00040 * Kernel.is_singleton?(object) 00041 * 00042 * Returns true if +self+ is a singleton class 00043 */ 00044 static VALUE kernel_is_singleton_p(VALUE self) 00045 { 00046 if (BUILTIN_TYPE(self) == T_CLASS && FL_TEST(self, FL_SINGLETON)) 00047 return Qtrue; 00048 else 00049 return Qfalse; 00050 } 00051 00052 #ifndef RUBY_IS_19 00053 00054 /* call-seq: 00055 * proc.same_body?(other) => true or false 00056 * 00057 * Returns true if +self+ and +other+ have the same body 00058 */ 00059 static VALUE proc_same_body_p(VALUE self, VALUE other) 00060 { 00061 if (self == other) return Qtrue; 00062 if (TYPE(other) != T_DATA) return Qfalse; 00063 if (RDATA(other)->dmark != RDATA(self)->dmark) return Qfalse; 00064 if (CLASS_OF(self) != CLASS_OF(other)) return Qfalse; 00065 00066 struct BLOCK* data, *data2; 00067 Data_Get_Struct(self, struct BLOCK, data); 00068 Data_Get_Struct(other, struct BLOCK, data2); 00069 return (data->body == data2->body) ? Qtrue : Qfalse; 00070 } 00071 00072 /* call-seq: 00073 * proc.file 00074 * 00075 * Returns the file in which the proc body is defined, or nil 00076 */ 00077 static VALUE proc_file(VALUE self) 00078 { 00079 struct BLOCK *data; 00080 NODE *node; 00081 00082 Data_Get_Struct(self, struct BLOCK, data); 00083 if ((node = data->frame.node) || (node = data->body)) 00084 return rb_str_new2(node->nd_file); 00085 else 00086 return Qnil; 00087 } 00088 00089 /* call-seq: 00090 * proc.line 00091 * 00092 * Returns the line at which the proc body is defined, or nil 00093 */ 00094 static VALUE proc_line(VALUE self) 00095 { 00096 struct BLOCK *data; 00097 NODE *node; 00098 00099 Data_Get_Struct(self, struct BLOCK, data); 00100 if ((node = data->frame.node) || (node = data->body)) 00101 return INT2FIX(nd_line(node)); 00102 else 00103 return Qnil; 00104 } 00105 00106 #endif 00107 00108 static VALUE kernel_is_immediate(VALUE klass, VALUE object) 00109 { return IMMEDIATE_P(object) ? Qtrue : Qfalse; } 00110 #endif 00111 00112 static VALUE kernel_crash(VALUE klass) 00113 { *((int*)0) = 10; } 00114 00115 extern "C" void Init_value_set(); 00116 extern "C" void Init_swap(); 00117 extern "C" void Init_weakref(VALUE mUtilrb); 00118 extern "C" void Init_proc(); 00119 00120 extern "C" void Init_utilrb_ext() 00121 { 00122 mUtilrb = rb_define_module("Utilrb"); 00123 00124 #ifndef RUBINIUS 00125 rb_define_method(rb_mEnumerable, "each_uniq", RUBY_METHOD_FUNC(enumerable_each_uniq), 0); 00126 rb_define_method(rb_mKernel, "is_singleton?", RUBY_METHOD_FUNC(kernel_is_singleton_p), 0); 00127 #ifndef RUBY_IS_19 00128 rb_define_method(rb_cProc, "same_body?", RUBY_METHOD_FUNC(proc_same_body_p), 1); 00129 rb_define_method(rb_cProc, "file", RUBY_METHOD_FUNC(proc_file), 0); 00130 rb_define_method(rb_cProc, "line", RUBY_METHOD_FUNC(proc_line), 0); 00131 #endif 00132 00133 rb_define_singleton_method(rb_mKernel, "crash!", RUBY_METHOD_FUNC(kernel_crash), 0); 00134 rb_define_singleton_method(rb_mKernel, "immediate?", RUBY_METHOD_FUNC(kernel_is_immediate), 1); 00135 00136 Init_swap(); 00137 Init_weakref(mUtilrb); 00138 #endif 00139 00140 Init_proc(); 00141 00142 Init_value_set(); 00143 } 00144