mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* eval.c (ruby_run): should set toplevel visibility again here.
* eval.c (rb_eval): should not rely on ruby_class == rb_cObject check. Besides allow implicit publicity for attribute set methods. * parse.y (primary): need not to check class_nest, just set whether method is an attrset or not. * string.c (rb_str_each_line): p might be at the top of the string. * variable.c (rb_path2class): should not use rb_eval_string(). * parse.y (str_extend): expression substitution can contain string terminator again. * parse.y (yylex): the warning message "invalid character syntax" was never issued. * file.c (rb_find_file): $LOAD_PATH must not be empty. * file.c (rb_find_file_ext): ditto. * range.c (range_eq): class check should be based on range.class, instead of Range to work with Range.dup. * range.c (range_eql): ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_6@2888 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d65fac5daa
commit
f33958990a
14 changed files with 546 additions and 129 deletions
43
ChangeLog
43
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
Mon Sep 23 02:46:29 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* eval.c (ruby_run): should set toplevel visibility again here.
|
||||
|
||||
* eval.c (rb_eval): should not rely on ruby_class == rb_cObject
|
||||
check. Besides allow implicit publicity for attribute set
|
||||
methods.
|
||||
|
||||
* parse.y (primary): need not to check class_nest, just set
|
||||
whether method is an attrset or not.
|
||||
|
||||
Sun Sep 22 17:08:11 2002 Tanaka Akira <akr@m17n.org>
|
||||
|
||||
* string.c (rb_str_each_line): p might be at the top of the
|
||||
string.
|
||||
|
||||
Sun Sep 22 15:31:33 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
||||
|
||||
* lib/mkmf.rb: some backports.
|
||||
|
@ -97,6 +113,15 @@ Fri Sep 6 05:11:48 2002 Minero Aoki <aamine@loveruby.net>
|
|||
|
||||
* intern.h (rb_gc_mark_parser): added.
|
||||
|
||||
Thu Sep 5 18:32:32 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* variable.c (rb_path2class): should not use rb_eval_string().
|
||||
|
||||
Thu Sep 5 15:33:16 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* parse.y (str_extend): expression substitution can contain string
|
||||
terminator again.
|
||||
|
||||
Thu Sep 5 13:09:22 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
||||
|
||||
* eval.c (rb_eval): overriding false constant with class/module
|
||||
|
@ -108,6 +133,11 @@ Thu Sep 5 13:09:22 2002 Nobuyoshi Nakada <nobu.nokada@softhome.net>
|
|||
* ruby.c (require_libraries): not clear source file.
|
||||
[ruby-dev:18074]
|
||||
|
||||
Wed Sep 4 05:10:16 2002 Koji Arai <jca02266@nifty.ne.jp>
|
||||
|
||||
* parse.y (yylex): the warning message "invalid
|
||||
character syntax" was never issued.
|
||||
|
||||
Tue Sep 3 00:22:43 2002 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* gc.c (gc_sweep): does reclaim nodes in also compile time, if we
|
||||
|
@ -119,6 +149,19 @@ Tue Sep 3 00:22:43 2002 Minero Aoki <aamine@loveruby.net>
|
|||
|
||||
* intern.h (ruby_parser_stack_on_heap): added.
|
||||
|
||||
Tue Aug 27 15:03:35 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* file.c (rb_find_file): $LOAD_PATH must not be empty.
|
||||
|
||||
* file.c (rb_find_file_ext): ditto.
|
||||
|
||||
Tue Aug 27 02:35:21 2002 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||
|
||||
* range.c (range_eq): class check should be based on range.class,
|
||||
instead of Range to work with Range.dup.
|
||||
|
||||
* range.c (range_eql): ditto.
|
||||
|
||||
Sun Aug 25 20:10:32 2002 Wakou Aoyama <wakou@ruby-lang.org>
|
||||
|
||||
* lib/cgi.rb (CGI#form): fix ruby-bugs-ja:PR#280, add default action.
|
||||
|
|
2
class.c
2
class.c
|
@ -643,7 +643,7 @@ rb_singleton_class(obj)
|
|||
klass = RBASIC(obj)->klass;
|
||||
}
|
||||
else {
|
||||
klass = rb_make_metaclass(obj, RBASIC(obj)->klass);
|
||||
klass = rb_make_metaclass(obj, CLASS_OF(obj));
|
||||
}
|
||||
if (OBJ_TAINTED(obj)) {
|
||||
OBJ_TAINT(klass);
|
||||
|
|
|
@ -913,7 +913,7 @@ case "$target_os" in
|
|||
CFLAGS="$CFLAGS -pipe -no-precomp"
|
||||
;;
|
||||
darwin*)
|
||||
CFLAGS="$CFLAGS -pipe -no-precomp"
|
||||
CFLAGS="$CFLAGS -pipe"
|
||||
;;
|
||||
os2_emx)
|
||||
CFLAGS="$CFLAGS -DOS2"
|
||||
|
|
2
error.c
2
error.c
|
@ -469,7 +469,9 @@ static VALUE *syserr_list;
|
|||
#endif
|
||||
|
||||
#if !defined(NT) && !defined(__FreeBSD__) && !defined(__NetBSD__) && !defined(__OpenBSD__) && !defined(sys_nerr)
|
||||
# if !defined(__APPLE__) || (__APPLE_CC__ < 1151)
|
||||
extern int sys_nerr;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
static VALUE
|
||||
|
|
18
eval.c
18
eval.c
|
@ -1216,6 +1216,8 @@ ruby_run()
|
|||
Init_stack(&tmp);
|
||||
PUSH_TAG(PROT_NONE);
|
||||
PUSH_ITER(ITER_NOT);
|
||||
/* default visibility is private at toplevel */
|
||||
SCOPE_SET(SCOPE_PRIVATE);
|
||||
if ((state = EXEC_TAG()) == 0) {
|
||||
eval_node(ruby_top_self, ruby_eval_tree);
|
||||
}
|
||||
|
@ -2995,15 +2997,15 @@ rb_eval(self, n)
|
|||
}
|
||||
}
|
||||
|
||||
if (SCOPE_TEST(SCOPE_PRIVATE) || node->nd_mid == init) {
|
||||
if (node->nd_noex == NOEX_PUBLIC) {
|
||||
noex = NOEX_PUBLIC; /* means is is an attrset */
|
||||
}
|
||||
else if (SCOPE_TEST(SCOPE_PRIVATE) || node->nd_mid == init) {
|
||||
noex = NOEX_PRIVATE;
|
||||
}
|
||||
else if (SCOPE_TEST(SCOPE_PROTECTED)) {
|
||||
noex = NOEX_PROTECTED;
|
||||
}
|
||||
else if (ruby_class == rb_cObject) {
|
||||
noex = node->nd_noex;
|
||||
}
|
||||
else {
|
||||
noex = NOEX_PUBLIC;
|
||||
}
|
||||
|
@ -3159,8 +3161,8 @@ rb_eval(self, n)
|
|||
}
|
||||
else {
|
||||
module = rb_define_module_id(node->nd_cname);
|
||||
rb_const_set(ruby_class, node->nd_cname, module);
|
||||
rb_set_class_path(module,ruby_class,rb_id2name(node->nd_cname));
|
||||
rb_const_set(ruby_class, node->nd_cname, module);
|
||||
}
|
||||
if (ruby_wrapper) {
|
||||
rb_extend_object(module, ruby_wrapper);
|
||||
|
@ -7946,7 +7948,7 @@ void
|
|||
rb_thread_wait_for(time)
|
||||
struct timeval time;
|
||||
{
|
||||
double date;
|
||||
double limit;
|
||||
|
||||
if (rb_thread_critical ||
|
||||
curr_thread == curr_thread->next ||
|
||||
|
@ -7986,9 +7988,9 @@ rb_thread_wait_for(time)
|
|||
}
|
||||
}
|
||||
|
||||
date = timeofday() + (double)time.tv_sec + (double)time.tv_usec*1e-6;
|
||||
limit = timeofday() + (double)time.tv_sec + (double)time.tv_usec*1e-6;
|
||||
curr_thread->status = THREAD_STOPPED;
|
||||
curr_thread->delay = date;
|
||||
curr_thread->delay = limit;
|
||||
curr_thread->wait_for = WAIT_TIME;
|
||||
rb_thread_schedule();
|
||||
}
|
||||
|
|
|
@ -48,20 +48,44 @@ int *tclDummyMathPtr = (int *) matherr;
|
|||
/*---- module TclTkLib ----*/
|
||||
|
||||
struct invoke_queue {
|
||||
Tcl_Event ev;
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE obj;
|
||||
int done;
|
||||
VALUE result;
|
||||
int safe_level;
|
||||
VALUE *result;
|
||||
VALUE thread;
|
||||
struct invoke_queue *next;
|
||||
};
|
||||
|
||||
static struct invoke_queue *iqueue;
|
||||
static VALUE main_thread;
|
||||
static VALUE eventloop_thread;
|
||||
static VALUE watchdog_thread;
|
||||
Tcl_Interp *current_interp;
|
||||
|
||||
/*
|
||||
* 'event_loop_max' is a maximum events which the eventloop processes in one
|
||||
* term of thread scheduling. 'no_event_tick' is the count-up value when
|
||||
* there are no event for processing.
|
||||
* 'timer_tick' is a limit of one term of thread scheduling.
|
||||
* If 'timer_tick' == 0, then not use the timer for thread scheduling.
|
||||
*/
|
||||
static int tick_counter;
|
||||
#define DEFAULT_EVENT_LOOP_MAX 800
|
||||
#define DEFAULT_NO_EVENT_TICK 10
|
||||
#define DEFAULT_TIMER_TICK 0
|
||||
static int event_loop_max = DEFAULT_EVENT_LOOP_MAX;
|
||||
static int no_event_tick = DEFAULT_NO_EVENT_TICK;
|
||||
static int timer_tick = DEFAULT_TIMER_TICK;
|
||||
|
||||
#if TCL_MAJOR_VERSION >= 8
|
||||
static int ip_ruby _((ClientData, Tcl_Interp *, int, Tcl_Obj *CONST*));
|
||||
#else
|
||||
static int ip_ruby _((ClientData, Tcl_Interp *, int, char **));
|
||||
#endif
|
||||
|
||||
/* Tk_ThreadTimer */
|
||||
static Tcl_TimerToken timer_token;
|
||||
static Tcl_TimerToken timer_token = (Tcl_TimerToken)NULL;
|
||||
|
||||
/* timer callback */
|
||||
static void _timer_for_tcl _((ClientData));
|
||||
|
@ -73,44 +97,265 @@ _timer_for_tcl(clientData)
|
|||
VALUE thread;
|
||||
|
||||
Tk_DeleteTimerHandler(timer_token);
|
||||
timer_token = Tk_CreateTimerHandler(100, _timer_for_tcl, (ClientData)0);
|
||||
|
||||
CHECK_INTS;
|
||||
q = iqueue;
|
||||
while (q) {
|
||||
tmp = q;
|
||||
q = q->next;
|
||||
if (!tmp->done) {
|
||||
tmp->done = 1;
|
||||
tmp->result = ip_invoke_real(tmp->argc, tmp->argv, tmp->obj);
|
||||
thread = tmp->thread;
|
||||
tmp = tmp->next;
|
||||
rb_thread_run(thread);
|
||||
}
|
||||
if (timer_tick > 0) {
|
||||
timer_token = Tk_CreateTimerHandler(timer_tick, _timer_for_tcl,
|
||||
(ClientData)0);
|
||||
} else {
|
||||
timer_token = (Tcl_TimerToken)NULL;
|
||||
}
|
||||
rb_thread_schedule();
|
||||
|
||||
/* rb_thread_schedule(); */
|
||||
timer_tick += event_loop_max;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
set_eventloop_tick(self, tick)
|
||||
VALUE self;
|
||||
VALUE tick;
|
||||
{
|
||||
int ttick = NUM2INT(tick);
|
||||
|
||||
if (ttick < 0) {
|
||||
rb_raise(rb_eArgError, "timer-tick parameter must be 0 or plus number");
|
||||
}
|
||||
|
||||
/* delete old timer callback */
|
||||
Tk_DeleteTimerHandler(timer_token);
|
||||
|
||||
timer_tick = ttick;
|
||||
if (timer_tick > 0) {
|
||||
/* start timer callback */
|
||||
timer_token = Tk_CreateTimerHandler(timer_tick, _timer_for_tcl,
|
||||
(ClientData)0);
|
||||
} else {
|
||||
timer_token = (Tcl_TimerToken)NULL;
|
||||
}
|
||||
|
||||
return tick;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
get_eventloop_tick(self)
|
||||
VALUE self;
|
||||
{
|
||||
return INT2NUM(timer_tick);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
set_eventloop_weight(self, loop_max, no_event)
|
||||
VALUE self;
|
||||
VALUE loop_max;
|
||||
VALUE no_event;
|
||||
{
|
||||
int lpmax = NUM2INT(loop_max);
|
||||
int no_ev = NUM2INT(no_event);
|
||||
|
||||
if (lpmax <= 0 || no_ev <= 0) {
|
||||
rb_raise(rb_eArgError, "weight parameters must be plus number");
|
||||
}
|
||||
|
||||
event_loop_max = lpmax;
|
||||
no_event_tick = no_ev;
|
||||
|
||||
return rb_ary_new3(2, loop_max, no_event);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
get_eventloop_weight(self)
|
||||
VALUE self;
|
||||
{
|
||||
return rb_ary_new3(2, INT2NUM(event_loop_max), INT2NUM(no_event_tick));
|
||||
}
|
||||
|
||||
VALUE
|
||||
lib_mainloop_core(check_root_widget)
|
||||
VALUE check_root_widget;
|
||||
{
|
||||
VALUE current = eventloop_thread;
|
||||
int check = (check_root_widget == Qtrue);
|
||||
|
||||
Tk_DeleteTimerHandler(timer_token);
|
||||
if (timer_tick > 0) {
|
||||
timer_token = Tk_CreateTimerHandler(timer_tick, _timer_for_tcl,
|
||||
(ClientData)0);
|
||||
} else {
|
||||
timer_token = (Tcl_TimerToken)NULL;
|
||||
}
|
||||
|
||||
for(;;) {
|
||||
tick_counter = 0;
|
||||
while(tick_counter < event_loop_max) {
|
||||
if (Tcl_DoOneEvent(TCL_ALL_EVENTS | TCL_DONT_WAIT)) {
|
||||
tick_counter++;
|
||||
} else {
|
||||
tick_counter += no_event_tick;
|
||||
}
|
||||
if (watchdog_thread != 0 && eventloop_thread != current) {
|
||||
return Qnil;
|
||||
}
|
||||
}
|
||||
if (check && Tk_GetNumMainWindows() == 0) {
|
||||
break;
|
||||
}
|
||||
rb_thread_schedule();
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE
|
||||
lib_mainloop_ensure(parent_evloop)
|
||||
VALUE parent_evloop;
|
||||
{
|
||||
Tk_DeleteTimerHandler(timer_token);
|
||||
timer_token = (Tcl_TimerToken)NULL;
|
||||
DUMP2("mainloop-ensure: current-thread : %lx\n", rb_thread_current());
|
||||
DUMP2("mainloop-ensure: eventloop-thread : %lx\n", eventloop_thread);
|
||||
if (eventloop_thread == rb_thread_current()) {
|
||||
DUMP2("tcltklib: eventloop-thread -> %lx\n", parent_evloop);
|
||||
eventloop_thread = parent_evloop;
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
lib_mainloop_launcher(check_rootwidget)
|
||||
VALUE check_rootwidget;
|
||||
{
|
||||
VALUE parent_evloop = eventloop_thread;
|
||||
|
||||
eventloop_thread = rb_thread_current();
|
||||
|
||||
if (ruby_debug) {
|
||||
fprintf(stderr, "tcltklib: eventloop-thread : %lx -> %lx\n",
|
||||
parent_evloop, eventloop_thread);
|
||||
}
|
||||
|
||||
return rb_ensure(lib_mainloop_core, check_rootwidget,
|
||||
lib_mainloop_ensure, parent_evloop);
|
||||
}
|
||||
|
||||
/* execute Tk_MainLoop */
|
||||
static VALUE
|
||||
lib_mainloop(self)
|
||||
lib_mainloop(argc, argv, self)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE self;
|
||||
{
|
||||
timer_token = Tk_CreateTimerHandler(100, _timer_for_tcl, (ClientData)0);
|
||||
DUMP1("start Tk_Mainloop");
|
||||
Tk_MainLoop();
|
||||
DUMP1("stop Tk_Mainloop");
|
||||
Tk_DeleteTimerHandler(timer_token);
|
||||
VALUE check_rootwidget;
|
||||
|
||||
if (rb_scan_args(argc, argv, "01", &check_rootwidget) == 0) {
|
||||
check_rootwidget = Qtrue;
|
||||
} else if (RTEST(check_rootwidget)) {
|
||||
check_rootwidget = Qtrue;
|
||||
} else {
|
||||
check_rootwidget = Qfalse;
|
||||
}
|
||||
|
||||
return lib_mainloop_launcher(check_rootwidget);
|
||||
}
|
||||
|
||||
VALUE
|
||||
lib_watchdog_core(check_rootwidget)
|
||||
VALUE check_rootwidget;
|
||||
{
|
||||
VALUE current = eventloop_thread;
|
||||
VALUE evloop;
|
||||
int check = (check_rootwidget == Qtrue);
|
||||
ID stop = rb_intern("stop?");
|
||||
|
||||
/* check other watchdog thread */
|
||||
if (watchdog_thread != 0) {
|
||||
if (rb_funcall(watchdog_thread, stop, 0) == Qtrue) {
|
||||
rb_funcall(watchdog_thread, rb_intern("kill"), 0);
|
||||
} else {
|
||||
return Qnil;
|
||||
}
|
||||
}
|
||||
watchdog_thread = rb_thread_current();
|
||||
|
||||
/* watchdog start */
|
||||
do {
|
||||
if (eventloop_thread == 0
|
||||
|| rb_funcall(eventloop_thread, stop, 0) == Qtrue) {
|
||||
/* start new eventloop thread */
|
||||
DUMP2("eventloop thread %lx is sleeping or dead", eventloop_thread);
|
||||
evloop = rb_thread_create(lib_mainloop_launcher,
|
||||
(void*)&check_rootwidget);
|
||||
DUMP2("create new eventloop thread %lx", evloop);
|
||||
rb_thread_run(evloop);
|
||||
} else {
|
||||
rb_thread_schedule();
|
||||
}
|
||||
} while(!check || Tk_GetNumMainWindows() != 0);
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE
|
||||
lib_watchdog_ensure(arg)
|
||||
VALUE arg;
|
||||
{
|
||||
eventloop_thread = 0; /* stop eventloops */
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
lib_mainloop_watchdog(argc, argv, self)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE self;
|
||||
{
|
||||
VALUE check_rootwidget;
|
||||
|
||||
if (rb_scan_args(argc, argv, "01", &check_rootwidget) == 0) {
|
||||
check_rootwidget = Qtrue;
|
||||
} else if (RTEST(check_rootwidget)) {
|
||||
check_rootwidget = Qtrue;
|
||||
} else {
|
||||
check_rootwidget = Qfalse;
|
||||
}
|
||||
|
||||
return rb_ensure(lib_watchdog_core, check_rootwidget,
|
||||
lib_watchdog_ensure, Qnil);
|
||||
}
|
||||
|
||||
static VALUE
|
||||
lib_do_one_event(argc, argv, self)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE self;
|
||||
{
|
||||
VALUE obj, vflags;
|
||||
int flags;
|
||||
|
||||
if (rb_scan_args(argc, argv, "01", &vflags) == 0) {
|
||||
flags = 0;
|
||||
} else {
|
||||
Check_Type(vflags, T_FIXNUM);
|
||||
flags = FIX2INT(vflags);
|
||||
}
|
||||
return INT2NUM(Tcl_DoOneEvent(flags));
|
||||
}
|
||||
|
||||
/*---- class TclTkIp ----*/
|
||||
struct tcltkip {
|
||||
Tcl_Interp *ip; /* the interpreter */
|
||||
int return_value; /* return value */
|
||||
};
|
||||
|
||||
static struct tcltkip *
|
||||
get_ip(self)
|
||||
VALUE self;
|
||||
{
|
||||
struct tcltkip *ptr;
|
||||
|
||||
Data_Get_Struct(self, struct tcltkip, ptr);
|
||||
if (ptr == 0) {
|
||||
rb_raise(rb_eTypeError, "uninitialized TclTkIp");
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Tcl command `ruby' */
|
||||
static VALUE
|
||||
ip_eval_rescue(failed, einfo)
|
||||
|
@ -126,10 +371,7 @@ static VALUE
|
|||
lib_restart(self)
|
||||
VALUE self;
|
||||
{
|
||||
struct tcltkip *ptr; /* tcltkip data struct */
|
||||
|
||||
/* get the data struct */
|
||||
Data_Get_Struct(self, struct tcltkip, ptr);
|
||||
struct tcltkip *ptr = get_ip(self);
|
||||
|
||||
/* destroy the root wdiget */
|
||||
ptr->return_value = Tcl_Eval(ptr->ip, "destroy .");
|
||||
|
@ -185,7 +427,9 @@ ip_ruby(clientData, interp, argc, argv)
|
|||
DUMP2("rb_eval_string(%s)", arg);
|
||||
old_trapflg = rb_trap_immediate;
|
||||
rb_trap_immediate = 0;
|
||||
res = rb_rescue(rb_eval_string, (VALUE)arg, ip_eval_rescue, (VALUE)&failed);
|
||||
res = rb_rescue2(rb_eval_string, (VALUE)arg,
|
||||
ip_eval_rescue, (VALUE)&failed,
|
||||
rb_eStandardError, rb_eScriptError, 0);
|
||||
rb_trap_immediate = old_trapflg;
|
||||
|
||||
Tcl_ResetResult(interp);
|
||||
|
@ -221,8 +465,10 @@ ip_free(ptr)
|
|||
struct tcltkip *ptr;
|
||||
{
|
||||
DUMP1("Tcl_DeleteInterp");
|
||||
Tcl_DeleteInterp(ptr->ip);
|
||||
free(ptr);
|
||||
if (ptr) {
|
||||
Tcl_DeleteInterp(ptr->ip);
|
||||
free(ptr);
|
||||
}
|
||||
}
|
||||
|
||||
/* create and initialize interpreter */
|
||||
|
@ -276,10 +522,7 @@ ip_eval(self, str)
|
|||
{
|
||||
char *s;
|
||||
char *buf; /* Tcl_Eval requires re-writable string region */
|
||||
struct tcltkip *ptr; /* tcltkip data struct */
|
||||
|
||||
/* get the data struct */
|
||||
Data_Get_Struct(self, struct tcltkip, ptr);
|
||||
struct tcltkip *ptr = get_ip(self);
|
||||
|
||||
/* call Tcl_Eval() */
|
||||
s = STR2CSTR(str);
|
||||
|
@ -310,7 +553,7 @@ ip_toUTF8(self, str, encodename)
|
|||
struct tcltkip *ptr;
|
||||
char *buf;
|
||||
|
||||
Data_Get_Struct(self,struct tcltkip, ptr);
|
||||
ptr = get_ip(self);
|
||||
interp = ptr->ip;
|
||||
|
||||
encoding = Tcl_GetEncoding(interp,STR2CSTR(encodename));
|
||||
|
@ -341,7 +584,7 @@ ip_fromUTF8(self, str, encodename)
|
|||
struct tcltkip *ptr;
|
||||
char *buf;
|
||||
|
||||
Data_Get_Struct(self,struct tcltkip, ptr);
|
||||
ptr = get_ip(self);
|
||||
interp = ptr->ip;
|
||||
|
||||
encoding = Tcl_GetEncoding(interp,STR2CSTR(encodename));
|
||||
|
@ -367,10 +610,11 @@ ip_invoke_real(argc, argv, obj)
|
|||
VALUE *argv;
|
||||
VALUE obj;
|
||||
{
|
||||
VALUE v;
|
||||
struct tcltkip *ptr; /* tcltkip data struct */
|
||||
int i;
|
||||
Tcl_CmdInfo info;
|
||||
char *cmd;
|
||||
char *cmd, *s;
|
||||
char **av = (char **)NULL;
|
||||
#if TCL_MAJOR_VERSION >= 8
|
||||
Tcl_Obj **ov = (Tcl_Obj **)NULL;
|
||||
|
@ -378,10 +622,11 @@ ip_invoke_real(argc, argv, obj)
|
|||
#endif
|
||||
|
||||
/* get the data struct */
|
||||
Data_Get_Struct(obj, struct tcltkip, ptr);
|
||||
ptr = get_ip(obj);
|
||||
|
||||
/* get the command name string */
|
||||
cmd = STR2CSTR(argv[0]);
|
||||
v = argv[0];
|
||||
cmd = STR2CSTR(v);
|
||||
|
||||
/* map from the command name to a C procedure */
|
||||
if (!Tcl_GetCommandInfo(ptr->ip, cmd, &info)) {
|
||||
|
@ -394,8 +639,9 @@ ip_invoke_real(argc, argv, obj)
|
|||
/* object interface */
|
||||
ov = (Tcl_Obj **)ALLOCA_N(Tcl_Obj *, argc+1);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
char *s = STR2CSTR(argv[i]);
|
||||
ov[i] = Tcl_NewStringObj(s, strlen(s));
|
||||
v = argv[i];
|
||||
s = STR2CSTR(v);
|
||||
ov[i] = Tcl_NewStringObj(s, RSTRING(v)->len);
|
||||
Tcl_IncrRefCount(ov[i]);
|
||||
}
|
||||
ov[argc] = (Tcl_Obj *)NULL;
|
||||
|
@ -406,8 +652,8 @@ ip_invoke_real(argc, argv, obj)
|
|||
/* string interface */
|
||||
av = (char **)ALLOCA_N(char *, argc+1);
|
||||
for (i = 0; i < argc; ++i) {
|
||||
char *s = STR2CSTR(argv[i]);
|
||||
|
||||
v = argv[i];
|
||||
s = STR2CSTR(v);
|
||||
av[i] = ALLOCA_N(char, strlen(s)+1);
|
||||
strcpy(av[i], s);
|
||||
}
|
||||
|
@ -435,8 +681,9 @@ ip_invoke_real(argc, argv, obj)
|
|||
else
|
||||
#endif
|
||||
{
|
||||
ptr->return_value = (*info.proc)(info.clientData,
|
||||
ptr->ip, argc, av);
|
||||
TRAP_BEG;
|
||||
ptr->return_value = (*info.proc)(info.clientData, ptr->ip, argc, av);
|
||||
TRAP_END;
|
||||
}
|
||||
|
||||
if (ptr->return_value == TCL_ERROR) {
|
||||
|
@ -447,48 +694,104 @@ ip_invoke_real(argc, argv, obj)
|
|||
return rb_str_new2(ptr->ip->result);
|
||||
}
|
||||
|
||||
VALUE
|
||||
ivq_safelevel_handler(arg, ivq)
|
||||
VALUE arg;
|
||||
VALUE ivq;
|
||||
{
|
||||
struct invoke_queue *q;
|
||||
|
||||
Data_Get_Struct(ivq, struct invoke_queue, q);
|
||||
DUMP2("(safe-level handler) $SAFE = %d", q->safe_level);
|
||||
rb_set_safe_level(q->safe_level);
|
||||
return ip_invoke_real(q->argc, q->argv, q->obj);
|
||||
}
|
||||
|
||||
int invoke_queue_handler _((Tcl_Event *, int));
|
||||
int
|
||||
invoke_queue_handler(evPtr, flags)
|
||||
Tcl_Event *evPtr;
|
||||
int flags;
|
||||
{
|
||||
struct invoke_queue *tmp, *q = (struct invoke_queue *)evPtr;
|
||||
|
||||
DUMP1("do_invoke_queue_handler");
|
||||
DUMP2("invoke queue_thread : %lx", rb_thread_current());
|
||||
DUMP2("added by thread : %lx", q->thread);
|
||||
|
||||
if (q->done) {
|
||||
/* processed by another event-loop */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* process it */
|
||||
q->done = 1;
|
||||
|
||||
/* check safe-level */
|
||||
if (rb_safe_level() != q->safe_level) {
|
||||
*(q->result) = rb_funcall(rb_proc_new(ivq_safelevel_handler,
|
||||
Data_Wrap_Struct(rb_cData,0,0,q)),
|
||||
rb_intern("call"), 0);
|
||||
} else {
|
||||
*(q->result) = ip_invoke_real(q->argc, q->argv, q->obj);
|
||||
}
|
||||
|
||||
/* back to caller */
|
||||
rb_thread_run(q->thread);
|
||||
|
||||
/* end of handler : remove it */
|
||||
return 1;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
ip_invoke(argc, argv, obj)
|
||||
int argc;
|
||||
VALUE *argv;
|
||||
VALUE obj;
|
||||
{
|
||||
struct invoke_queue *tmp, *p;
|
||||
VALUE result = rb_thread_current();
|
||||
struct invoke_queue *tmp;
|
||||
VALUE current = rb_thread_current();
|
||||
VALUE result;
|
||||
VALUE *alloc_argv, *alloc_result;
|
||||
Tcl_QueuePosition position;
|
||||
|
||||
if (result == main_thread) {
|
||||
return ip_invoke_real(argc, argv, obj);
|
||||
if (eventloop_thread == 0 || current == eventloop_thread) {
|
||||
DUMP2("invoke from current eventloop %lx", current);
|
||||
return ip_invoke_real(argc, argv, obj);
|
||||
}
|
||||
tmp = ALLOC(struct invoke_queue);
|
||||
|
||||
DUMP2("invoke from thread %lx (NOT current eventloop)", current);
|
||||
|
||||
/* allocate memory (protected from Tcl_ServiceEvent) */
|
||||
alloc_argv = ALLOC_N(VALUE,argc);
|
||||
MEMCPY(alloc_argv, argv, VALUE, argc);
|
||||
alloc_result = ALLOC(VALUE);
|
||||
|
||||
/* allocate memory (freed by Tcl_ServiceEvent */
|
||||
tmp = (struct invoke_queue *)Tcl_Alloc(sizeof(struct invoke_queue));
|
||||
|
||||
/* construct event data */
|
||||
tmp->done = 0;
|
||||
tmp->obj = obj;
|
||||
tmp->argc = argc;
|
||||
tmp->argv = ALLOC_N(VALUE, argc);
|
||||
MEMCPY(tmp->argv, argv, VALUE, argc);
|
||||
tmp->thread = result;
|
||||
tmp->done = 0;
|
||||
tmp->argv = alloc_argv;
|
||||
tmp->result = alloc_result;
|
||||
tmp->thread = current;
|
||||
tmp->safe_level = rb_safe_level();
|
||||
tmp->ev.proc = invoke_queue_handler;
|
||||
position = TCL_QUEUE_TAIL;
|
||||
|
||||
tmp->next = iqueue;
|
||||
iqueue = tmp;
|
||||
/* add the handler to Tcl event queue */
|
||||
Tcl_QueueEvent(&tmp->ev, position);
|
||||
|
||||
/* wait for the handler to be processed */
|
||||
rb_thread_stop();
|
||||
result = tmp->result;
|
||||
if (iqueue == tmp) {
|
||||
iqueue = tmp->next;
|
||||
free(tmp->argv);
|
||||
free(tmp);
|
||||
return result;
|
||||
}
|
||||
|
||||
p = iqueue;
|
||||
while (p->next) {
|
||||
if (p->next == tmp) {
|
||||
p->next = tmp->next;
|
||||
free(tmp->argv);
|
||||
free(tmp);
|
||||
break;
|
||||
}
|
||||
p = p->next;
|
||||
}
|
||||
/* get result & free allocated memory */
|
||||
result = *alloc_result;
|
||||
free(alloc_argv);
|
||||
free(alloc_result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -500,7 +803,7 @@ ip_retval(self)
|
|||
struct tcltkip *ptr; /* tcltkip data struct */
|
||||
|
||||
/* get the data strcut */
|
||||
Data_Get_Struct(self, struct tcltkip, ptr);
|
||||
ptr = get_ip(self);
|
||||
|
||||
return (INT2FIX(ptr->return_value));
|
||||
}
|
||||
|
@ -521,6 +824,8 @@ Init_tcltklib()
|
|||
VALUE lib = rb_define_module("TclTkLib");
|
||||
VALUE ip = rb_define_class("TclTkIp", rb_cObject);
|
||||
|
||||
VALUE ev_flag = rb_define_module_under(lib, "EventFlag");
|
||||
|
||||
#if defined USE_TCL_STUBS && defined USE_TK_STUBS
|
||||
extern int ruby_tcltk_stubs();
|
||||
int ret = ruby_tcltk_stubs();
|
||||
|
@ -528,10 +833,26 @@ Init_tcltklib()
|
|||
rb_raise(rb_eLoadError, "tcltklib: tcltk_stubs init error(%d)", ret);
|
||||
#endif
|
||||
|
||||
rb_define_const(ev_flag, "WINDOW", INT2FIX(TCL_WINDOW_EVENTS));
|
||||
rb_define_const(ev_flag, "FILE", INT2FIX(TCL_FILE_EVENTS));
|
||||
rb_define_const(ev_flag, "TIMER", INT2FIX(TCL_TIMER_EVENTS));
|
||||
rb_define_const(ev_flag, "IDLE", INT2FIX(TCL_IDLE_EVENTS));
|
||||
rb_define_const(ev_flag, "ALL", INT2FIX(TCL_ALL_EVENTS));
|
||||
rb_define_const(ev_flag, "DONT_WAIT", INT2FIX(TCL_DONT_WAIT));
|
||||
|
||||
eTkCallbackBreak = rb_define_class("TkCallbackBreak", rb_eStandardError);
|
||||
eTkCallbackContinue = rb_define_class("TkCallbackContinue",rb_eStandardError);
|
||||
|
||||
rb_define_module_function(lib, "mainloop", lib_mainloop, 0);
|
||||
rb_define_module_function(lib, "mainloop", lib_mainloop, -1);
|
||||
rb_define_module_function(lib, "mainloop_watchdog",
|
||||
lib_mainloop_watchdog, -1);
|
||||
rb_define_module_function(lib, "do_one_event", lib_do_one_event, -1);
|
||||
rb_define_module_function(lib, "set_eventloop_tick",set_eventloop_tick,1);
|
||||
rb_define_module_function(lib, "get_eventloop_tick",get_eventloop_tick,0);
|
||||
rb_define_module_function(lib, "set_eventloop_weight",
|
||||
set_eventloop_weight, 2);
|
||||
rb_define_module_function(lib, "get_eventloop_weight",
|
||||
get_eventloop_weight, 0);
|
||||
|
||||
rb_define_singleton_method(ip, "new", ip_new, 0);
|
||||
rb_define_method(ip, "_eval", ip_eval, 1);
|
||||
|
@ -539,10 +860,19 @@ Init_tcltklib()
|
|||
rb_define_method(ip, "_fromUTF8",ip_fromUTF8,2);
|
||||
rb_define_method(ip, "_invoke", ip_invoke, -1);
|
||||
rb_define_method(ip, "_return_value", ip_retval, 0);
|
||||
rb_define_method(ip, "mainloop", lib_mainloop, 0);
|
||||
rb_define_method(ip, "mainloop", lib_mainloop, -1);
|
||||
rb_define_method(ip, "mainloop_watchdog", lib_mainloop_watchdog, -1);
|
||||
rb_define_method(ip, "do_one_event", lib_do_one_event, -1);
|
||||
rb_define_method(ip, "set_eventloop_tick", set_eventloop_tick, 1);
|
||||
rb_define_method(ip, "get_eventloop_tick", get_eventloop_tick, 0);
|
||||
rb_define_method(ip, "set_eventloop_weight", set_eventloop_weight, 2);
|
||||
rb_define_method(ip, "get_eventloop_weight", get_eventloop_weight, 0);
|
||||
rb_define_method(ip, "restart", lib_restart, 0);
|
||||
|
||||
main_thread = rb_thread_current();
|
||||
eventloop_thread = 0;
|
||||
watchdog_thread = 0;
|
||||
|
||||
#ifdef __MACOS__
|
||||
_macinit();
|
||||
#endif
|
||||
|
|
15
file.c
15
file.c
|
@ -2198,6 +2198,7 @@ rb_find_file_ext(filep, ext)
|
|||
VALUE str = RARRAY(rb_load_path)->ptr[i];
|
||||
|
||||
Check_SafeStr(str);
|
||||
if (RSTRING(str)->len == 0) return 0;
|
||||
path = RSTRING(str)->ptr;
|
||||
for (j=0; ext[j]; j++) {
|
||||
fname = rb_str_dup(*filep);
|
||||
|
@ -2262,15 +2263,23 @@ rb_find_file(path)
|
|||
}
|
||||
}
|
||||
tmp = rb_ary_join(tmp, rb_str_new2(PATH_SEP));
|
||||
lpath = STR2CSTR(tmp);
|
||||
if (rb_safe_level() >= 2 && !rb_path_check(lpath)) {
|
||||
rb_raise(rb_eSecurityError, "loading from unsafe path %s", lpath);
|
||||
if (RSTRING(tmp)->len == 0) {
|
||||
lpath = 0;
|
||||
}
|
||||
else {
|
||||
lpath = STR2CSTR(tmp);
|
||||
if (rb_safe_level() >= 2 && !rb_path_check(lpath)) {
|
||||
rb_raise(rb_eSecurityError, "loading from unsafe path %s", lpath);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
lpath = 0;
|
||||
}
|
||||
|
||||
if (!lpath) {
|
||||
return 0; /* no path, no load */
|
||||
}
|
||||
f = dln_find_file(f, lpath);
|
||||
if (file_load_ok(f)) {
|
||||
return rb_str_new2(f);
|
||||
|
|
|
@ -46,17 +46,19 @@ module URI
|
|||
# hname = *urlc
|
||||
# hvalue = *urlc
|
||||
# header = hname "=" hvalue
|
||||
HEADER_REGEXP = "(?:[^?=&]*=[^?=&]*)".freeze
|
||||
header_pattern = "(?:[^?=&]*=[^?=&]*)"
|
||||
HEADER_REGEXP = /#{header_pattern}/
|
||||
# headers = "?" header *( "&" header )
|
||||
# to = #mailbox
|
||||
# mailtoURL = "mailto:" [ to ] [ headers ]
|
||||
MAILBOX_REGEXP = "(?:[^(),%?=&]|#{PATTERN::ESCAPED})".freeze
|
||||
mailbox_pattern = "(?:[^(),%?=&]|#{PATTERN::ESCAPED})"
|
||||
MAILBOX_REGEXP = /#{mailbox_pattern}/
|
||||
MAILTO_REGEXP = Regexp.new("
|
||||
\\A
|
||||
(#{MAILBOX_REGEXP}*?) (?# 1: to)
|
||||
(#{mailbox_pattern}*?) (?# 1: to)
|
||||
(?:
|
||||
\\?
|
||||
(#{HEADER_REGEXP}(?:\\&#{HEADER_REGEXP})*) (?# 2: headers)
|
||||
(#{header_pattern}(?:\\&#{header_pattern})*) (?# 2: headers)
|
||||
)?
|
||||
\\z
|
||||
", Regexp::EXTENDED, 'N').freeze
|
||||
|
|
4
object.c
4
object.c
|
@ -114,8 +114,8 @@ rb_obj_dup(obj)
|
|||
VALUE dup;
|
||||
|
||||
dup = rb_funcall(obj, clone, 0, 0);
|
||||
if (TYPE(dup) != TYPE(obj)) {
|
||||
rb_raise(rb_eTypeError, "dupulicated object must be same type");
|
||||
if (TYPE(dup) != TYPE(obj) || rb_obj_class(dup) != rb_obj_class(obj)) {
|
||||
rb_raise(rb_eTypeError, "dupulicated object must be same class");
|
||||
}
|
||||
if (!SPECIAL_CONST_P(dup)) {
|
||||
OBJSETUP(dup, rb_obj_class(obj), BUILTIN_TYPE(obj));
|
||||
|
|
46
parse.y
46
parse.y
|
@ -1362,8 +1362,7 @@ primary : literal
|
|||
}
|
||||
if ($8) $5 = NEW_ENSURE($5, $8);
|
||||
|
||||
/* NOEX_PRIVATE for toplevel */
|
||||
$$ = NEW_DEFN($2, $4, $5, class_nest?NOEX_PUBLIC:NOEX_PRIVATE);
|
||||
$$ = NEW_DEFN($2, $4, $5, NOEX_PRIVATE);
|
||||
if (is_attrset_id($2)) $$->nd_noex = NOEX_PUBLIC;
|
||||
fixpos($$, $4);
|
||||
local_pop();
|
||||
|
@ -3154,22 +3153,22 @@ yylex()
|
|||
}
|
||||
if (ISSPACE(c)){
|
||||
if (lex_state != EXPR_ARG){
|
||||
int c = 0;
|
||||
int c2 = 0;
|
||||
switch (c) {
|
||||
case ' ':
|
||||
c = 's';
|
||||
c2 = 's';
|
||||
break;
|
||||
case '\n':
|
||||
c = 'n';
|
||||
c2 = 'n';
|
||||
break;
|
||||
case '\t':
|
||||
c = 't';
|
||||
c2 = 't';
|
||||
break;
|
||||
case '\v':
|
||||
c = 'v';
|
||||
c2 = 'v';
|
||||
break;
|
||||
}
|
||||
if (c) {
|
||||
if (c2) {
|
||||
rb_warn("invalid character syntax; use ?\\%c", c);
|
||||
}
|
||||
}
|
||||
|
@ -4066,13 +4065,13 @@ str_extend(list, term, paren)
|
|||
|
||||
case '{':
|
||||
if (c == '{') brace = '}';
|
||||
brace_nest = 0;
|
||||
brace_nest = 1;
|
||||
do {
|
||||
loop_again:
|
||||
c = nextc();
|
||||
switch (c) {
|
||||
case -1:
|
||||
if (brace_nest > 0) {
|
||||
if (brace_nest > 1) {
|
||||
yyerror("bad substitution in string");
|
||||
newtok();
|
||||
return list;
|
||||
|
@ -4080,8 +4079,8 @@ str_extend(list, term, paren)
|
|||
return (NODE*)-1;
|
||||
case '}':
|
||||
if (c == brace) {
|
||||
if (brace_nest == 0) break;
|
||||
brace_nest--;
|
||||
if (brace_nest == 0) break;
|
||||
}
|
||||
tokadd(c);
|
||||
goto loop_again;
|
||||
|
@ -4099,6 +4098,22 @@ str_extend(list, term, paren)
|
|||
case '{':
|
||||
if (brace != -1) brace_nest++;
|
||||
default:
|
||||
/* within brace */
|
||||
if (brace_nest > 0) {
|
||||
if (ismbchar(c)) {
|
||||
int i, len = mbclen(c)-1;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
tokadd(c);
|
||||
c = nextc();
|
||||
}
|
||||
}
|
||||
else {
|
||||
tokadd(c);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* out of brace */
|
||||
if (c == paren) paren_nest++;
|
||||
else if (c == term && (!paren || paren_nest-- == 0)) {
|
||||
pushback(c);
|
||||
|
@ -4109,14 +4124,7 @@ str_extend(list, term, paren)
|
|||
newtok();
|
||||
return list;
|
||||
}
|
||||
else if (ismbchar(c)) {
|
||||
int i, len = mbclen(c)-1;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
tokadd(c);
|
||||
c = nextc();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
tokadd(c);
|
||||
break;
|
||||
|
|
4
range.c
4
range.c
|
@ -90,7 +90,7 @@ static VALUE
|
|||
range_eq(range, obj)
|
||||
VALUE range, obj;
|
||||
{
|
||||
if (!rb_obj_is_kind_of(obj, rb_cRange)) return Qfalse;
|
||||
if (!rb_obj_is_kind_of(obj, rb_obj_class(range))) return Qfalse;
|
||||
|
||||
if (!rb_equal(rb_ivar_get(range, id_beg), rb_ivar_get(obj, id_beg)))
|
||||
return Qfalse;
|
||||
|
@ -140,7 +140,7 @@ range_eql(range, obj)
|
|||
VALUE range, obj;
|
||||
{
|
||||
if (range == obj) return Qtrue;
|
||||
if (!rb_obj_is_kind_of(obj, rb_cRange)) return Qfalse;
|
||||
if (!rb_obj_is_kind_of(obj, rb_obj_class(range))) return Qfalse;
|
||||
|
||||
if (!rb_eql(rb_ivar_get(range, id_beg), rb_ivar_get(obj, id_beg)))
|
||||
return Qfalse;
|
||||
|
|
2
string.c
2
string.c
|
@ -2354,7 +2354,7 @@ rb_str_each_line(argc, argv, str)
|
|||
if (*++p != '\n') continue;
|
||||
while (*p == '\n') p++;
|
||||
}
|
||||
if (p[-1] == newline &&
|
||||
if (RSTRING(str)->ptr < p && p[-1] == newline &&
|
||||
(rslen <= 1 ||
|
||||
rb_memcmp(RSTRING(rs)->ptr, p-rslen, rslen) == 0)) {
|
||||
line = rb_str_new(s, p - s);
|
||||
|
|
37
variable.c
37
variable.c
|
@ -221,19 +221,40 @@ VALUE
|
|||
rb_path2class(path)
|
||||
const char *path;
|
||||
{
|
||||
VALUE c;
|
||||
const char *pbeg, *p;
|
||||
ID id;
|
||||
VALUE c = rb_cObject;
|
||||
|
||||
if (path[0] == '#') {
|
||||
rb_raise(rb_eArgError, "can't retrieve anonymous class %s", path);
|
||||
}
|
||||
c = rb_eval_string(path);
|
||||
switch (TYPE(c)) {
|
||||
case T_MODULE:
|
||||
case T_CLASS:
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "class path %s does not point class", path);
|
||||
pbeg = p = path;
|
||||
while (*p) {
|
||||
VALUE str;
|
||||
|
||||
while (*p && *p != ':') p++;
|
||||
str = rb_str_new(pbeg, p-pbeg);
|
||||
id = rb_intern(RSTRING(str)->ptr);
|
||||
if (p[0] == ':') {
|
||||
if (p[1] != ':') goto undefined_class;
|
||||
p += 2;
|
||||
pbeg = p;
|
||||
}
|
||||
if (!rb_const_defined(c, id)) {
|
||||
undefined_class:
|
||||
rb_raise(rb_eArgError, "undefined class/module %s", rb_id2name(id));
|
||||
rb_raise(rb_eArgError, "undefined class/module %s", path);
|
||||
}
|
||||
c = rb_const_get_at(c, id);
|
||||
switch (TYPE(c)) {
|
||||
case T_MODULE:
|
||||
case T_CLASS:
|
||||
break;
|
||||
default:
|
||||
rb_raise(rb_eTypeError, "%s does not refer class/module %d", path, TYPE(c));
|
||||
}
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define RUBY_VERSION "1.6.7"
|
||||
#define RUBY_RELEASE_DATE "2002-09-22"
|
||||
#define RUBY_RELEASE_DATE "2002-09-25"
|
||||
#define RUBY_VERSION_CODE 167
|
||||
#define RUBY_RELEASE_CODE 20020922
|
||||
#define RUBY_RELEASE_CODE 20020925
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue