summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog30
-rw-r--r--array.c40
-rw-r--r--dir.c2
-rw-r--r--eval.c55
-rw-r--r--file.c47
-rw-r--r--hash.c2
-rw-r--r--intern.h2
-rw-r--r--io.c65
-rw-r--r--object.c8
-rw-r--r--parse.y55
-rw-r--r--ruby.c4
-rw-r--r--sample/ruby-mode.el2
-rw-r--r--signal.c17
-rw-r--r--string.c35
14 files changed, 242 insertions, 122 deletions
diff --git a/ChangeLog b/ChangeLog
index 46a1f9472b3..b8852c118bf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,33 @@
+Thu Apr 16 01:38:02 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * array.c (ary_flatten): new method.
+
+ * eval.c (rb_longjmp): prints exception information with `-d'.
+
+ * object.c (any_to_s): remove class name restriction.
+
+ * file.c (thread_flock): do not block other threads.
+
+ * eval.c (thread_trap_eval): signals are now delivered to the
+ current thread again. In case that the current thread is dead,
+ signals are forwarded to the main thread.
+
+ * string.c (str_new4): need not to duplicate frozen strings.
+
+Wed Apr 15 01:22:56 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * string.c (str_dup_frozen): do not duplicate frozen strings.
+
+ * parse.y (yylex): allow nested parenthesises.
+
+ * io.c (obj_displayln): prints newline after `display'ing the
+ receiver.
+
+ * io.c (io_puts): avoid generating "\n" each time. use RS_default
+ instead.
+
+ * io.c (f_p): ditto.
+
Tue Apr 14 11:34:50 1998 Yukihiro Matsumoto <matz@netlab.co.jp>
* experimental release 1.1b9_10.
diff --git a/array.c b/array.c
index f706a04a826..d88c333dd22 100644
--- a/array.c
+++ b/array.c
@@ -1234,6 +1234,44 @@ ary_nitems(ary)
return INT2FIX(n);
}
+static VALUE
+ary_flatten_bang(ary)
+ VALUE ary;
+{
+ int i;
+ int mod = 0;
+
+ ary_modify(ary);
+ for (;;) {
+ int lmod = 0;
+
+ for (i=0; i<RARRAY(ary)->len; i++) {
+ if (TYPE(RARRAY(ary)->ptr[i]) == T_ARRAY) {
+ VALUE ary2 = RARRAY(ary)->ptr[i];
+
+ ary_replace(ary, i, RARRAY(ary2)->len, ary2);
+ i += RARRAY(ary2)->len - 1;
+ lmod++;
+ }
+ }
+ if (lmod == 0) break;
+ mod = lmod;
+ }
+
+ if (mod == 0) return Qnil;
+ return ary;
+}
+
+static VALUE
+ary_flatten(ary)
+ VALUE ary;
+{
+ VALUE v = ary_flatten_bang(ary_clone(ary));
+
+ if (NIL_P(v)) return ary;
+ return v;
+}
+
extern VALUE mEnumerable;
void
@@ -1304,6 +1342,8 @@ Init_Array()
rb_define_method(cArray, "uniq!", ary_uniq_bang, 0);
rb_define_method(cArray, "compact", ary_compact, 0);
rb_define_method(cArray, "compact!", ary_compact_bang, 0);
+ rb_define_method(cArray, "flatten", ary_flatten, 0);
+ rb_define_method(cArray, "flatten!", ary_flatten_bang, 0);
rb_define_method(cArray, "nitems", ary_nitems, 0);
cmp = rb_intern("<=>");
diff --git a/dir.c b/dir.c
index a4b8b8db94e..4c380e6b98c 100644
--- a/dir.c
+++ b/dir.c
@@ -413,7 +413,7 @@ dir_foreach(io, dirname)
{
VALUE dir;
- dir = dir_s_open(cDir, dirname);
+ dir = rb_funcall(cDir, rb_intern("open"), 1, dirname);
return rb_ensure(dir_each, dir, dir_close, dir);
}
diff --git a/eval.c b/eval.c
index 0ae56d2c3d2..60a5d0c930e 100644
--- a/eval.c
+++ b/eval.c
@@ -727,17 +727,8 @@ error_print()
if (NIL_P(errinfo)) return;
if (!NIL_P(errat)) {
- VALUE mesg = Qnil;
+ VALUE mesg = RARRAY(errat)->ptr[0];
- switch (TYPE(errat)) {
- case T_STRING:
- mesg = errat;
- errat = Qnil;
- break;
- case T_ARRAY:
- mesg = RARRAY(errat)->ptr[0];
- break;
- }
if (NIL_P(mesg)) error_pos();
else {
fwrite(RSTRING(mesg)->ptr, 1, RSTRING(mesg)->len, stderr);
@@ -2681,7 +2672,13 @@ rb_longjmp(tag, mesg, at)
if (NIL_P(errinfo) && NIL_P(mesg)) {
errinfo = exc_new(eRuntimeError, 0, 0);
}
-
+#if 1
+ if (debug) {
+ fprintf(stderr, "Exception `%s' occurred at %s:%d\n",
+ rb_class2name(CLASS_OF(errinfo)),
+ sourcefile, sourceline);
+ }
+#endif
if (!NIL_P(at)) {
errat = check_errat(at);
}
@@ -2698,6 +2695,11 @@ rb_longjmp(tag, mesg, at)
}
str_freeze(errinfo);
}
+#if 0
+ if (debug) {
+ error_print();
+ }
+#endif
trap_restore_mask();
JUMP_TAG(tag);
@@ -5540,17 +5542,17 @@ thread_schedule()
curr = curr->prev;
}
- FOREACH_THREAD_FROM(curr,th) {
+ FOREACH_THREAD_FROM(curr, th) {
if (th->status != THREAD_STOPPED && th->status != THREAD_KILLED) {
next = th;
break;
}
}
- END_FOREACH_FROM(curr,th);
+ END_FOREACH_FROM(curr, th);
if (num_waiting_on_join) {
- FOREACH_THREAD_FROM(curr,th) {
- if ((th->wait_for & WAIT_JOIN) && thread_dead(th->join)) {
+ FOREACH_THREAD_FROM(curr, th) {
+ if ((th->wait_for&WAIT_JOIN) && thread_dead(th->join)) {
th->join = 0;
th->wait_for &= ~WAIT_JOIN;
th->status = THREAD_RUNNABLE;
@@ -5558,7 +5560,7 @@ thread_schedule()
if (!next) next = th;
}
}
- END_FOREACH_FROM(curr,th);
+ END_FOREACH_FROM(curr, th);
}
if (num_waiting_on_fd > 0 || num_waiting_on_timer > 0) {
@@ -5572,19 +5574,19 @@ thread_schedule()
max = 0;
FD_ZERO(&readfds);
if (num_waiting_on_fd > 0) {
- FOREACH_THREAD_FROM(curr,th) {
+ FOREACH_THREAD_FROM(curr, th) {
if (th->wait_for & WAIT_FD) {
FD_SET(th->fd, &readfds);
if (th->fd > max) max = th->fd;
}
}
- END_FOREACH_FROM(curr,th);
+ END_FOREACH_FROM(curr, th);
}
delay = DELAY_INFTY;
if (num_waiting_on_timer > 0) {
now = timeofday();
- FOREACH_THREAD_FROM(curr,th) {
+ FOREACH_THREAD_FROM(curr, th) {
if (th->wait_for & WAIT_TIME) {
if (th->delay <= now) {
th->delay = 0.0;
@@ -5597,7 +5599,7 @@ thread_schedule()
}
}
}
- END_FOREACH_FROM(curr,th);
+ END_FOREACH_FROM(curr, th);
}
/* Do the select if needed */
if (num_waiting_on_fd > 0 || !next) {
@@ -5626,7 +5628,7 @@ thread_schedule()
if (n > 0) {
/* Some descriptors are ready.
Make the corresponding threads runnable. */
- FOREACH_THREAD_FROM(curr,th) {
+ FOREACH_THREAD_FROM(curr, th) {
if ((th->wait_for&WAIT_FD)
&& FD_ISSET(th->fd, &readfds)) {
/* Wake up only one thread per fd. */
@@ -5638,7 +5640,7 @@ thread_schedule()
if (!next) next = th; /* Found one. */
}
}
- END_FOREACH_FROM(curr,th);
+ END_FOREACH_FROM(curr, th);
}
}
/* The delays for some of the threads should have expired.
@@ -5649,12 +5651,12 @@ thread_schedule()
if (!next) {
curr_thread->file = sourcefile;
curr_thread->line = sourceline;
- FOREACH_THREAD_FROM(curr,th) {
+ FOREACH_THREAD_FROM(curr, th) {
fprintf(stderr, "%s:%d:deadlock 0x%x: %d:%d %s\n",
th->file, th->line, th->thread, th->status,
th->wait_for, th==main_thread?"(main)":"");
}
- END_FOREACH_FROM(curr,th);
+ END_FOREACH_FROM(curr, th);
/* raise fatal error to main thread */
thread_deadlock();
}
@@ -6272,11 +6274,12 @@ thread_trap_eval(cmd, sig)
int sig;
{
thread_critical = 0;
- thread_ready(main_thread);
- if (curr_thread == main_thread) {
+ if (!thread_dead(curr_thread)) {
+ thread_ready(curr_thread);
rb_trap_eval(cmd, sig);
return;
}
+ thread_ready(main_thread);
thread_save_context(curr_thread);
if (setjmp(curr_thread->context)) {
return;
diff --git a/file.c b/file.c
index 3ed9e2ff60e..75a6da7e211 100644
--- a/file.c
+++ b/file.c
@@ -189,7 +189,7 @@ file_tell(obj)
GetOpenFile(obj, fptr);
pos = ftell(fptr->f);
- if (ferror(fptr->f) != 0) rb_sys_fail(0);
+ if (ferror(fptr->f) != 0) rb_sys_fail(fptr->path);
return int2inum(pos);
}
@@ -203,10 +203,10 @@ file_seek(obj, offset, ptrname)
GetOpenFile(obj, fptr);
pos = fseek(fptr->f, NUM2INT(offset), NUM2INT(ptrname));
- if (pos != 0) rb_sys_fail(0);
+ if (pos != 0) rb_sys_fail(fptr->path);
clearerr(fptr->f);
- return obj;
+ return INT2FIX(0);
}
static VALUE
@@ -218,10 +218,10 @@ file_set_pos(obj, offset)
GetOpenFile(obj, fptr);
pos = fseek(fptr->f, NUM2INT(offset), 0);
- if (pos != 0) rb_sys_fail(0);
+ if (pos != 0) rb_sys_fail(fptr->path);
clearerr(fptr->f);
- return obj;
+ return INT2NUM(pos);
}
static VALUE
@@ -231,10 +231,10 @@ file_rewind(obj)
OpenFile *fptr;
GetOpenFile(obj, fptr);
- if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(0);
+ if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(fptr->path);
clearerr(fptr->f);
- return obj;
+ return INT2FIX(0);
}
static VALUE
@@ -1100,7 +1100,7 @@ file_s_symlink(obj, from, to)
if (symlink(RSTRING(from)->ptr, RSTRING(to)->ptr) < 0)
rb_sys_fail(RSTRING(from)->ptr);
- return TRUE;
+ return INT2FIX(0);
#else
rb_notimplement();
#endif
@@ -1384,7 +1384,7 @@ file_s_truncate(obj, path, len)
rb_notimplement();
# endif
#endif
- return TRUE;
+ return INT2FIX(0);
}
static VALUE
@@ -1409,8 +1409,32 @@ file_truncate(obj, len)
rb_notimplement();
# endif
#endif
- return TRUE;
+ return INT2FIX(0);
+}
+
+#if defined(THREAD) && defined(EWOULDBLOCK)
+static int
+thread_flock(fd, op)
+ int fd, op;
+{
+ if (thread_alone() || (op & LOCK_NB)) {
+ return flock(fd, op);
+ }
+ op |= LOCK_NB;
+ while (flock(fd, op) < 0) {
+ switch (errno) {
+ case EINTR: /* can be happen? */
+ case EWOULDBLOCK:
+ thread_schedule(); /* busy wait */
+ break;
+ default:
+ return -1;
+ }
+ }
+ return 0;
}
+#define flock thread_flock
+#endif
static VALUE
file_flock(obj, operation)
@@ -1430,8 +1454,9 @@ file_flock(obj, operation)
#endif
rb_sys_fail(fptr->path);
}
- return obj;
+ return INT2FIX(0);
}
+#undef flock
static void
test_check(n, argc, argv)
diff --git a/hash.c b/hash.c
index daa1e624a85..2569b425176 100644
--- a/hash.c
+++ b/hash.c
@@ -450,7 +450,7 @@ hash_aset(hash, key, val)
return Qnil;
}
if (TYPE(key) == T_STRING) {
- key = str_dup_freezed(key);
+ key = str_dup_frozen(key);
}
st_insert(RHASH(hash)->tbl, key, val);
return val;
diff --git a/intern.h b/intern.h
index 4e6bc58ae3f..2b87408ac71 100644
--- a/intern.h
+++ b/intern.h
@@ -251,7 +251,7 @@ VALUE str_times _((VALUE, VALUE));
VALUE str_substr _((VALUE, int, int));
void str_modify _((VALUE));
VALUE str_freeze _((VALUE));
-VALUE str_dup_freezed _((VALUE));
+VALUE str_dup_frozen _((VALUE));
VALUE str_taint _((VALUE));
VALUE str_tainted _((VALUE));
VALUE str_resize _((VALUE, int));
diff --git a/io.c b/io.c
index ee3f23b8c99..ee5f19e0699 100644
--- a/io.c
+++ b/io.c
@@ -455,7 +455,7 @@ io_gets_method(argc, argv, io)
if (c != EOF &&
(!rslen ||
RSTRING(str)->len < rslen ||
- memcmp(RSTRING(str)->ptr+RSTRING(str)->len-rslen, rsptr, rslen))) {
+ memcmp(RSTRING(str)->ptr+RSTRING(str)->len-rslen,rsptr,rslen))) {
append = 1;
goto again;
}
@@ -820,7 +820,7 @@ io_binmode(io)
fptr->mode |= FMODE_BINMODE;
#endif
- return io;
+ return INT2FIX(0);
}
int
@@ -1419,7 +1419,7 @@ io_puts(argc, argv, out)
/* if no argument given, print newline. */
if (argc == 0) {
- io_write(out, str_new2("\n"));
+ io_write(out, RS_default);
return Qnil;
}
for (i=0; i<argc; i++) {
@@ -1439,7 +1439,7 @@ io_puts(argc, argv, out)
line = obj_as_string(line);
io_write(out, line);
if (RSTRING(line)->ptr[RSTRING(line)->len-1] != '\n') {
- io_write(out, str_new2("\n"));
+ io_write(out, RS_default);
}
}
@@ -1456,20 +1456,11 @@ f_puts(argc, argv)
}
static VALUE
-f_p(argc, argv, self)
- int argc;
- VALUE *argv;
- VALUE self;
+f_p(self, obj)
+ VALUE self, obj;
{
- VALUE str;
-
- if (argc > 0) {
- rb_scan_args(argc, argv, "1", &self);
- }
- str = rb_inspect(self);
- Check_Type(str, T_STRING);
- io_write(rb_defout, str);
- io_write(rb_defout, str_new2("\n"));
+ io_write(rb_defout, rb_inspect(obj));
+ io_write(rb_defout, RS_default);
return Qnil;
}
@@ -1478,7 +1469,7 @@ void
rb_p(obj) /* for debug print within C code */
VALUE obj;
{
- f_p(0, 0, obj);
+ f_p(0, obj);
}
static VALUE
@@ -1500,6 +1491,26 @@ obj_display(argc, argv, self)
return Qnil;
}
+static VALUE
+obj_displayln(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
+{
+ VALUE out;
+ VALUE str;
+
+ rb_scan_args(argc, argv, "01", &out);
+ if (NIL_P(out)) {
+ out = rb_defout;
+ }
+
+ io_write(out, self);
+ io_write(rb_defout, RS_default);
+
+ return Qnil;
+}
+
static void
io_defset(val, id)
VALUE val;
@@ -1546,15 +1557,15 @@ prep_stdio(f, mode, klass)
VALUE klass;
{
OpenFile *fp;
- NEWOBJ(obj, struct RFile);
- OBJSETUP(obj, klass, T_FILE);
+ NEWOBJ(io, struct RFile);
+ OBJSETUP(io, klass, T_FILE);
- MakeOpenFile(obj, fp);
+ MakeOpenFile(io, fp);
fp->f = f;
fp->mode = mode;
- obj_call_init((VALUE)obj);
+ obj_call_init((VALUE)io);
- return (VALUE)obj;
+ return (VALUE)io;
}
static VALUE
@@ -1735,8 +1746,8 @@ f_getc()
}
static VALUE
-f_ungetc(obj, c)
- VALUE obj, c;
+f_ungetc(self, c)
+ VALUE self, c;
{
if (!next_argv()) {
ArgError("no stream to ungetc");
@@ -2423,8 +2434,9 @@ Init_IO()
rb_define_global_function("`", f_backquote, 1);
rb_define_global_function("pipe", io_s_pipe, 0);
- rb_define_method(mKernel, "p", f_p, -1);
+ rb_define_global_function("p", f_p, 1);
rb_define_method(mKernel, "display", obj_display, -1);
+ rb_define_method(mKernel, "displayln", obj_displayln, -1);
cIO = rb_define_class("IO", cObject);
rb_include_module(cIO, mEnumerable);
@@ -2442,6 +2454,7 @@ Init_IO()
RS = RS_default = str_new2("\n"); ORS = Qnil;
rb_global_variable(&RS_default);
+ str_freeze(RS_default); /* avoid modifying RS_default */
rb_define_hooked_variable("$/", &RS, 0, rb_str_setter);
rb_define_hooked_variable("$-0", &RS, 0, rb_str_setter);
rb_define_hooked_variable("$\\", &ORS, 0, rb_str_setter);
diff --git a/object.c b/object.c
index fa553912608..09545441ec9 100644
--- a/object.c
+++ b/object.c
@@ -118,10 +118,12 @@ VALUE
any_to_s(obj)
VALUE obj;
{
- char buf[256];
+ char *s;
+ char *cname = rb_class2name(CLASS_OF(obj));
- sprintf(buf, "#<%s:0x%x>", rb_class2name(CLASS_OF(obj)), obj);
- return str_new2(buf);
+ s = ALLOCA_N(char, strlen(cname)+6+16+1); /* 6:tags 16:addr 1:eos */
+ sprintf(s, "#<%s:0x%x>", cname, obj);
+ return str_new2(s);
}
VALUE
diff --git a/parse.y b/parse.y
index 1db24ef38aa..6d69b02d69e 100644
--- a/parse.y
+++ b/parse.y
@@ -1824,12 +1824,13 @@ read_escape()
}
static int
-parse_regx(term)
+parse_regx(term, paren)
int term;
{
register int c;
char kcode = 0;
int once = 0;
+ int nest = 0;
int casefold = 0;
int in_brack = 0;
int re_start = sourceline;
@@ -1837,7 +1838,7 @@ parse_regx(term)
newtok();
while ((c = nextc()) != -1) {
- if (!in_brack && c == term) {
+ if ((!in_brack && c == term) || nest > 0) {
goto regx_end;
}
@@ -1888,6 +1889,8 @@ parse_regx(term)
}
/* fall through */
default:
+ if (c == paren) nest++;
+ if (c == term) nest--;
if (c == '\n') {
sourceline++;
}
@@ -1961,23 +1964,24 @@ parse_regx(term)
return 0;
}
-static int parse_qstring();
+static int parse_qstring _((int,int));
static int
-parse_string(func,term)
- int func, term;
+parse_string(func, term, paren)
+ int func, term, paren;
{
int c;
NODE *list = 0;
int strstart;
+ int nest = 0;
if (func == '\'') {
- return parse_qstring(term);
+ return parse_qstring(term, paren);
}
strstart = sourceline;
newtok();
- while ((c = nextc()) != term) {
+ while ((c = nextc()) != term || nest > 0) {
if (c == -1) {
unterm_str:
sourceline = strstart;
@@ -2011,6 +2015,8 @@ parse_string(func,term)
}
continue;
}
+ if (c == paren) nest++;
+ if (c == term) nest--;
tokadd(c);
}
@@ -2037,15 +2043,16 @@ parse_string(func,term)
}
static int
-parse_qstring(term)
+parse_qstring(term, paren)
int term;
{
int strstart;
int c;
+ int nest = 0;
strstart = sourceline;
newtok();
- while ((c = nextc()) != term) {
+ while ((c = nextc()) != term || nest > 0) {
if (c == -1) {
sourceline = strstart;
Error("unterminated string meets end of file");
@@ -2079,6 +2086,8 @@ parse_qstring(term)
tokadd('\\');
}
}
+ if (c == paren) nest++;
+ if (c == term) nest--;
tokadd(c);
}
@@ -2089,10 +2098,10 @@ parse_qstring(term)
}
static int
-parse_quotedword(term)
- int term;
+parse_quotedword(term, paren)
+ int term, paren;
{
- if (parse_qstring(term) == 0) return 0;
+ if (parse_qstring(term, paren) == 0) return 0;
yylval.node = NEW_CALL(NEW_STR(yylval.val), rb_intern("split"), 0);
return tDSTRING;
}
@@ -2406,13 +2415,13 @@ retry:
return '>';
case '"':
- return parse_string(c,c);
+ return parse_string(c,c,c);
case '`':
if (lex_state == EXPR_FNAME) return c;
- return parse_string(c,c);
+ return parse_string(c,c,c);
case '\'':
- return parse_qstring(c);
+ return parse_qstring(c,c);
case '?':
if (lex_state == EXPR_END) {
@@ -2700,7 +2709,7 @@ retry:
case '/':
if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
- return parse_regx('/');
+ return parse_regx('/', '/');
}
if ((c = nextc()) == '=') {
lex_state = EXPR_BEG;
@@ -2711,7 +2720,7 @@ retry:
if (space_seen && !isspace(c)) {
pushback(c);
arg_ambiguous();
- return parse_regx('/');
+ return parse_regx('/', '/');
}
}
lex_state = EXPR_BEG;
@@ -2792,6 +2801,7 @@ retry:
case '%':
if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
int term;
+ int paren;
c = nextc();
quotation:
@@ -2815,6 +2825,7 @@ retry:
Error("unterminated quoted string meets end of file");
return 0;
}
+ paren = term;
if (term == '(') term = ')';
else if (term == '[') term = ']';
else if (term == '{') term = '}';
@@ -2822,19 +2833,19 @@ retry:
switch (c) {
case 'Q':
- return parse_string('"', term);
+ return parse_string('"', term, paren);
case 'q':
- return parse_qstring(term);
+ return parse_qstring(term, paren);
case 'w':
- return parse_quotedword(term);
+ return parse_quotedword(term, paren);
case 'x':
- return parse_string('`', term);
+ return parse_string('`', term, paren);
case 'r':
- return parse_regx(term);
+ return parse_regx(term, paren);
default:
yyerror("unknown type of %string");
diff --git a/ruby.c b/ruby.c
index 2c220500dc9..72866e14155 100644
--- a/ruby.c
+++ b/ruby.c
@@ -477,9 +477,7 @@ load_file(fname, script)
line = io_gets(f);
line_start++;
- if (RSTRING(line)->len > 2
- && RSTRING(line)->ptr[0] == '!') {
-
+ if (RSTRING(line)->len > 2 && RSTRING(line)->ptr[0] == '!') {
if ((p = strstr(RSTRING(line)->ptr, "ruby")) == 0) {
/* not ruby script, kick the program */
char **argv;
diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el
index 33e9d2ce4da..f7e2fddbfad 100644
--- a/sample/ruby-mode.el
+++ b/sample/ruby-mode.el
@@ -646,7 +646,7 @@ An end of a defun is found by moving forward from the beginning of one."
"\\)[ \n\t()]")
2)
;; variables
- '("\\(^\\|[^_]\\)\\b\\(nil\\|self\\|true\\|false\\)\\b[^_]"
+ '("\\(^\\|[^_]\\)\\b\\(nil\\|self\\|true\\|false\\)\\b\\([^_]\\|$\\)"
2 font-lock-variable-name-face)
;; variables
'("\\[$@].\\([a-zA-Z0-9_]\\)"
diff --git a/signal.c b/signal.c
index c6ade3907ae..22c33d2440f 100644
--- a/signal.c
+++ b/signal.c
@@ -271,6 +271,11 @@ posix_signal(signum, handler)
}
#endif
+#ifdef THREAD
+# define rb_interrupt thread_interrupt
+# define rb_trap_eval thread_trap_eval
+#endif
+
static RETSIGTYPE
sighandle(sig)
int sig;
@@ -285,11 +290,7 @@ sighandle(sig)
if (trap_immediate) {
trap_immediate = 0;
if (sig == SIGINT && !trap_list[SIGINT]) {
-#ifdef THREAD
- thread_interrupt();
-#else
rb_interrupt();
-#endif
}
rb_trap_eval(trap_list[sig], sig);
trap_immediate = 1;
@@ -334,18 +335,10 @@ rb_trap_exec()
if (trap_pending_list[i]) {
trap_pending_list[i] = 0;
if (i == SIGINT && trap_list[SIGINT] == 0) {
-#ifdef THREAD
- thread_interrupt();
-#else
rb_interrupt();
-#endif
return;
}
-#ifdef THREAD
- thread_trap_eval(trap_list[i], i);
-#else
rb_trap_eval(trap_list[i], i);
-#endif
}
}
trap_pending = 0;
diff --git a/string.c b/string.c
index 086c8723406..19321c09e5f 100644
--- a/string.c
+++ b/string.c
@@ -84,23 +84,25 @@ VALUE
str_new4(orig)
VALUE orig;
{
- NEWOBJ(str, struct RString);
- OBJSETUP(str, cString, T_STRING);
-
- str->len = RSTRING(orig)->len;
- str->ptr = RSTRING(orig)->ptr;
if (RSTRING(orig)->orig) {
- str->orig = RSTRING(orig)->orig;
+ return str_freeze(RSTRING(orig)->orig);
+ }
+ else if (FL_TEST(orig, STR_FREEZE)) {
+ return orig;
}
else {
+ NEWOBJ(str, struct RString);
+ OBJSETUP(str, cString, T_STRING);
+
+ str->len = RSTRING(orig)->len;
+ str->ptr = RSTRING(orig)->ptr;
RSTRING(orig)->orig = (VALUE)str;
str->orig = 0;
+ if (rb_safe_level() >= 3) {
+ FL_SET(str, STR_TAINT);
+ }
+ return (VALUE)str;
}
- if (rb_safe_level() >= 3) {
- FL_SET(str, STR_TAINT);
- }
-
- return (VALUE)str;
}
static void
@@ -362,12 +364,15 @@ str_frozen_p(str)
}
VALUE
-str_dup_freezed(str)
+str_dup_frozen(str)
VALUE str;
{
- str = str_dup(str);
- str_freeze(str);
- return str;
+ if (RSTRING(str)->orig) {
+ return str_freeze(RSTRING(str)->orig);
+ }
+ if (FL_TEST(str, STR_FREEZE))
+ return str;
+ return str_freeze(str_dup(str));
}
VALUE