Go to the documentation of this file.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
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
00040
00041
00042
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
00055
00056
00057
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
00073
00074
00075
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
00090
00091
00092
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