1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

* variable.c (rb_mod_const_at): use hash table as internal

data. [new]

* variable.c (rb_mod_const_of): ditto.

* variable.c (rb_const_list): new function to convert internal
  data (hash table) to array of strings.

* eval.c (rb_mod_s_constants): data handling scheme has changed.

* eval.c (rb_add_method): should not call rb_secure(), for
  last_func may not be set.

* io.c (rb_io_ctl): ioctl should accept any integer within C long
  range.

* marshal.c (r_object): wrong type check for modules.

* marshal.c (w_object): should not dump anonymous classes/modules.

* io.c (rb_open_file): use rb_file_sysopen_internal() if the 3rd
  argument (permission flags) is given. [new, should be backported?]

* io.c (rb_io_mode_binmode): mode string (e.g. "r+") to flags to
  open(2).

* eval.c (rb_eval): NODE_REXPAND expand an array of 1 element as
  the element itself. [new, should be backported?]

* parse.y (ret_args): should treat "*[a]" in rhs expression as
  "a", not "[a]".

* regex.c (re_compile_pattern): should push option modifier at the
  right place.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1504 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2001-06-05 07:19:39 +00:00
parent 21524a3fc0
commit d6c60dbf6d
10 changed files with 422 additions and 251 deletions

View file

@ -1,11 +1,58 @@
Tue Jun 5 16:15:58 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* variable.c (rb_mod_const_at): use hash table as internal
data. [new]
* variable.c (rb_mod_const_of): ditto.
* variable.c (rb_const_list): new function to convert internal
data (hash table) to array of strings.
* eval.c (rb_mod_s_constants): data handling scheme has changed.
Tue Jun 5 15:16:06 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_add_method): should not call rb_secure(), for
last_func may not be set.
* io.c (rb_io_ctl): ioctl should accept any integer within C long
range.
Tue Jun 5 13:41:13 2001 WATANABE Hirofumi <eban@ruby-lang.org> Tue Jun 5 13:41:13 2001 WATANABE Hirofumi <eban@ruby-lang.org>
* ext/etc/extconf.rb: use egrep_cpp. * ext/etc/extconf.rb: use egrep_cpp.
Tue Jun 5 12:44:59 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* marshal.c (r_object): wrong type check for modules.
* marshal.c (w_object): should not dump anonymous classes/modules.
Tue Jun 5 01:19:34 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* io.c (rb_open_file): use rb_file_sysopen_internal() if the 3rd
argument (permission flags) is given. [new, should be backported?]
* io.c (rb_io_mode_binmode): mode string (e.g. "r+") to flags to
open(2).
Mon Jun 4 23:55:54 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_eval): NODE_REXPAND expand an array of 1 element as
the element itself. [new, should be backported?]
* parse.y (ret_args): should treat "*[a]" in rhs expression as
"a", not "[a]".
Mon Jun 4 04:14:53 2001 Wakou Aoyama <wakou@fsinet.or.jp> Mon Jun 4 04:14:53 2001 Wakou Aoyama <wakou@fsinet.or.jp>
* lib/shellwords.rb: don't destroy argument. * lib/shellwords.rb: don't destroy argument.
Sat Jun 2 23:23:05 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
* regex.c (re_compile_pattern): should push option modifier at the
right place.
Sat Jun 2 23:05:20 2001 Shugo Maeda <shugo@ruby-lang.org> Sat Jun 2 23:05:20 2001 Shugo Maeda <shugo@ruby-lang.org>
* lib/cgi/session.rb: don't use module_function for Class. * lib/cgi/session.rb: don't use module_function for Class.

53
eval.c
View file

@ -228,10 +228,7 @@ rb_add_method(klass, mid, node, noex)
NODE *body; NODE *body;
if (NIL_P(klass)) klass = rb_cObject; if (NIL_P(klass)) klass = rb_cObject;
if (klass == rb_cObject) { if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
rb_secure(4);
}
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
rb_raise(rb_eSecurityError, "Insecure: can't define method"); rb_raise(rb_eSecurityError, "Insecure: can't define method");
} }
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module"); if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
@ -1474,15 +1471,19 @@ static VALUE
rb_mod_s_constants() rb_mod_s_constants()
{ {
NODE *cbase = RNODE(ruby_frame->cbase); NODE *cbase = RNODE(ruby_frame->cbase);
VALUE ary = rb_ary_new(); void *data = 0;
while (cbase) { while (cbase) {
if (!NIL_P(cbase->nd_clss)) rb_mod_const_at(cbase->nd_clss, ary); if (!NIL_P(cbase->nd_clss)) {
data = rb_mod_const_at(cbase->nd_clss, data);
}
cbase = cbase->nd_next; cbase = cbase->nd_next;
} }
if (!NIL_P(ruby_cbase)) rb_mod_const_of(ruby_cbase, ary); if (!NIL_P(ruby_cbase)) {
return ary; data = rb_mod_const_of(ruby_cbase, data);
}
return rb_const_list(data);
} }
void void
@ -2349,12 +2350,19 @@ rb_eval(self, n)
} }
break; break;
case NODE_REXPAND:
result = rb_eval(self, node->nd_head);
if (TYPE(result) != T_ARRAY) {
result = rb_Array(result);
}
if (RARRAY(result)->len == 1) {
result = RARRAY(result)->ptr[0];
}
break;
case NODE_YIELD: case NODE_YIELD:
if (node->nd_stts) { if (node->nd_stts) {
result = rb_eval(self, node->nd_stts); result = rb_eval(self, node->nd_stts);
if (nd_type(node->nd_stts) == NODE_RESTARGS && RARRAY(result)->len == 1) {
result = RARRAY(result)->ptr[0];
}
} }
else { else {
result = Qnil; result = Qnil;
@ -8602,6 +8610,28 @@ rb_thread_key_p(thread, id)
return Qfalse; return Qfalse;
} }
static int
thread_keys_i(key, value, ary)
ID key;
VALUE value, ary;
{
rb_ary_push(ary, ID2SYM(key));
return ST_CONTINUE;
}
static VALUE
rb_thread_keys(thread)
VALUE thread;
{
rb_thread_t th = rb_thread_check(thread);
VALUE ary = rb_ary_new();
if (th->locals) {
st_foreach(th->locals, thread_keys_i, ary);
}
return ary;
}
static VALUE static VALUE
rb_thread_inspect(thread) rb_thread_inspect(thread)
VALUE thread; VALUE thread;
@ -8823,6 +8853,7 @@ Init_Thread()
rb_define_method(rb_cThread, "[]", rb_thread_aref, 1); rb_define_method(rb_cThread, "[]", rb_thread_aref, 1);
rb_define_method(rb_cThread, "[]=", rb_thread_aset, 2); rb_define_method(rb_cThread, "[]=", rb_thread_aset, 2);
rb_define_method(rb_cThread, "key?", rb_thread_key_p, 1); rb_define_method(rb_cThread, "key?", rb_thread_key_p, 1);
rb_define_method(rb_cThread, "keys", rb_thread_keys, 0);
rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0); rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0);

View file

@ -367,9 +367,10 @@ VALUE rb_ivar_set _((VALUE, ID, VALUE));
VALUE rb_ivar_defined _((VALUE, ID)); VALUE rb_ivar_defined _((VALUE, ID));
VALUE rb_obj_instance_variables _((VALUE)); VALUE rb_obj_instance_variables _((VALUE));
VALUE rb_obj_remove_instance_variable _((VALUE, VALUE)); VALUE rb_obj_remove_instance_variable _((VALUE, VALUE));
VALUE rb_mod_const_at _((VALUE, VALUE)); void *rb_mod_const_at _((VALUE, void*));
void *rb_mod_const_of _((VALUE, void*));
VALUE rb_const_list _((void*));
VALUE rb_mod_constants _((VALUE)); VALUE rb_mod_constants _((VALUE));
VALUE rb_mod_const_of _((VALUE, VALUE));
VALUE rb_mod_remove_const _((VALUE, VALUE)); VALUE rb_mod_remove_const _((VALUE, VALUE));
int rb_const_defined_at _((VALUE, ID)); int rb_const_defined_at _((VALUE, ID));
int rb_autoload_defined _((ID)); int rb_autoload_defined _((ID));

138
io.c
View file

@ -1253,8 +1253,9 @@ rb_io_mode_flags(mode)
const char *mode; const char *mode;
{ {
int flags = 0; int flags = 0;
const char *m = mode;
switch (mode[0]) { switch (*m++) {
case 'r': case 'r':
flags |= FMODE_READABLE; flags |= FMODE_READABLE;
break; break;
@ -1269,22 +1270,22 @@ rb_io_mode_flags(mode)
rb_raise(rb_eArgError, "illegal access mode %s", mode); rb_raise(rb_eArgError, "illegal access mode %s", mode);
} }
if (mode[1] == 'b') { if (*m == 'b') {
flags |= FMODE_BINMODE; flags |= FMODE_BINMODE;
mode++; m++;
} }
if (mode[1] == '+') { if (*m == '+') {
flags |= FMODE_READWRITE; flags |= FMODE_READWRITE;
if (mode[2] != 0) goto error; if (m[1] != 0) goto error;
} }
else if (mode[1] != 0) goto error; else if (*m != 0) goto error;
return flags; return flags;
} }
static int static int
rb_io_mode_flags2(mode) rb_io_binmode_flags(mode)
int mode; int mode;
{ {
int flags; int flags;
@ -1310,8 +1311,46 @@ rb_io_mode_flags2(mode)
return flags; return flags;
} }
int
rb_io_mode_binmode(mode)
const char *mode;
{
int flags = 0;
const char *m = mode;
switch (*m++) {
case 'r':
flags |= O_RDONLY;
break;
case 'w':
flags |= O_WRONLY | O_CREAT | O_TRUNC;
break;
case 'a':
flags |= O_WRONLY | O_CREAT | O_APPEND;
break;
default:
error:
rb_raise(rb_eArgError, "illegal access mode %s", mode);
}
if (*m == 'b') {
#ifdef O_BINARY
flags |= O_BINARY;
#endif
m++;
}
if (*m == '+') {
flags |= O_RDWR;
if (m[1] != 0) goto error;
}
else if (*m != 0) goto error;
return flags;
}
static char* static char*
rb_io_flags_mode(flags) rb_io_modestr(flags)
int flags; int flags;
{ {
static char mode[4]; static char mode[4];
@ -1454,8 +1493,8 @@ rb_file_sysopen_internal(io, fname, flags, mode)
MakeOpenFile(io, fptr); MakeOpenFile(io, fptr);
fd = rb_sysopen(fname, flags, mode); fd = rb_sysopen(fname, flags, mode);
m = rb_io_flags_mode(flags); m = rb_io_modestr(flags);
fptr->mode = rb_io_mode_flags2(flags); fptr->mode = rb_io_binmode_flags(flags);
fptr->f = rb_fdopen(fd, m); fptr->f = rb_fdopen(fd, m);
fptr->path = strdup(fname); fptr->path = strdup(fname);
@ -1733,38 +1772,49 @@ rb_io_s_popen(argc, argv, klass)
return rb_io_popen(str, argc, argv, klass); return rb_io_popen(str, argc, argv, klass);
} }
static VALUE
rb_open_file(argc, argv, io)
int argc;
VALUE *argv;
VALUE io;
{
VALUE fname, vmode, file, perm;
char *path, *mode;
int flags, fmode;
rb_scan_args(argc, argv, "12", &fname, &vmode, &perm);
SafeStringValue(fname);
path = RSTRING(fname)->ptr;
if (FIXNUM_P(vmode) || !NIL_P(perm)) {
flags = FIXNUM_P(vmode) ? NUM2INT(vmode) : rb_io_mode_binmode(StringValuePtr(vmode));
fmode = NIL_P(perm) ? 0666 : NUM2INT(perm);
file = rb_file_sysopen_internal(io, path, flags, fmode);
}
else {
mode = NIL_P(vmode) ? "r" : StringValuePtr(vmode);
file = rb_file_open_internal(io, RSTRING(fname)->ptr, mode);
}
return io;
}
static VALUE static VALUE
rb_file_s_open(argc, argv, klass) rb_file_s_open(argc, argv, klass)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE klass; VALUE klass;
{ {
VALUE fname, vmode, file, perm;
char *path, *mode;
NEWOBJ(io, struct RFile); NEWOBJ(io, struct RFile);
OBJSETUP(io, klass, T_FILE); OBJSETUP(io, klass, T_FILE);
rb_scan_args(argc, argv, "12", &fname, &vmode, &perm);
SafeStringValue(fname);
path = RSTRING(fname)->ptr;
RFILE(io)->fptr = 0; RFILE(io)->fptr = 0;
if (FIXNUM_P(vmode)) {
int flags = NUM2INT(vmode);
int fmode = NIL_P(perm) ? 0666 : NUM2INT(perm);
file = rb_file_sysopen_internal((VALUE)io, path, flags, fmode);
}
else {
mode = NIL_P(vmode) ? "r" : StringValuePtr(vmode);
file = rb_file_open_internal((VALUE)io, RSTRING(fname)->ptr, mode);
}
rb_open_file(argc, argv, (VALUE)io);
if (rb_block_given_p()) { if (rb_block_given_p()) {
return rb_ensure(rb_yield, file, rb_io_close, file); return rb_ensure(rb_yield, (VALUE)io, rb_io_close, (VALUE)io);
} }
return file; return (VALUE)io;
} }
static VALUE static VALUE
@ -2395,38 +2445,17 @@ rb_file_initialize(argc, argv, io)
VALUE *argv; VALUE *argv;
VALUE io; VALUE io;
{ {
VALUE fname, vmode, file, perm;
char *path, *mode;
rb_scan_args(argc, argv, "12", &fname, &vmode, &perm);
SafeStringValue(fname);
path = RSTRING(fname)->ptr;
if (RFILE(io)->fptr) { if (RFILE(io)->fptr) {
rb_io_close_m(io); rb_io_close_m(io);
free(RFILE(io)->fptr); free(RFILE(io)->fptr);
RFILE(io)->fptr = 0; RFILE(io)->fptr = 0;
} }
if (FIXNUM_P(vmode)) { rb_open_file(argc, argv, io);
int flags = NUM2INT(vmode);
int fmode = NIL_P(perm) ? 0666 : NUM2INT(perm);
file = rb_file_sysopen_internal(io, path, flags, fmode);
}
else {
if (NIL_P(vmode)) {
mode = "r";
}
else {
mode = StringValuePtr(vmode);
}
file = rb_file_open_internal(io, RSTRING(fname)->ptr, mode);
}
if (rb_block_given_p()) { if (rb_block_given_p()) {
rb_warn("File::new() does not take block; use File::open() instead"); rb_warn("File::new() does not take block; use File::open() instead");
} }
return file; return io;
} }
static VALUE static VALUE
@ -2852,7 +2881,7 @@ rb_f_select(argc, argv, obj)
#if !defined(MSDOS) && !defined(__human68k__) #if !defined(MSDOS) && !defined(__human68k__)
static int static int
io_cntl(fd,cmd,narg,io_p) io_cntl(fd, cmd, narg, io_p)
int fd, cmd, io_p; int fd, cmd, io_p;
long narg; long narg;
{ {
@ -2902,6 +2931,9 @@ rb_io_ctl(io, req, arg, io_p)
else if (arg == Qtrue) { else if (arg == Qtrue) {
narg = 1; narg = 1;
} }
else if (rb_obj_is_kind_of(arg, rb_cInteger)) {
narg = NUM2LONG(arg);
}
else { else {
StringValue(arg); StringValue(arg);

View file

@ -52,7 +52,7 @@ shortlen(len, ds)
#endif #endif
#define MARSHAL_MAJOR 4 #define MARSHAL_MAJOR 4
#define MARSHAL_MINOR 5 #define MARSHAL_MINOR 6
#define TYPE_NIL '0' #define TYPE_NIL '0'
#define TYPE_TRUE 'T' #define TYPE_TRUE 'T'
@ -348,6 +348,10 @@ w_object(obj, arg, limit)
w_byte(TYPE_CLASS, arg); w_byte(TYPE_CLASS, arg);
{ {
VALUE path = rb_class_path(obj); VALUE path = rb_class_path(obj);
if (RSTRING(path)->ptr[0] == '#') {
rb_raise(rb_eArgError, "can't dump anonymous class %s",
RSTRING(path)->ptr);
}
w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg); w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);
} }
break; break;
@ -356,6 +360,10 @@ w_object(obj, arg, limit)
w_byte(TYPE_MODULE, arg); w_byte(TYPE_MODULE, arg);
{ {
VALUE path = rb_class_path(obj); VALUE path = rb_class_path(obj);
if (RSTRING(path)->ptr[0] == '#') {
rb_raise(rb_eArgError, "can't dump anonymous module %s",
RSTRING(path)->ptr);
}
w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg); w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg);
} }
break; break;
@ -991,7 +999,7 @@ r_object(arg)
char *buf; char *buf;
r_bytes(buf, arg); r_bytes(buf, arg);
m = rb_path2class(buf); m = rb_path2class(buf);
if (TYPE(m) != T_CLASS) { if (TYPE(m) != T_MODULE) {
rb_raise(rb_eTypeError, "%s is not a module", buf); rb_raise(rb_eTypeError, "%s is not a module", buf);
} }
return r_regist(m, arg); return r_regist(m, arg);

2
node.h
View file

@ -89,6 +89,7 @@ enum node_type {
NODE_ARGSCAT, NODE_ARGSCAT,
NODE_ARGSPUSH, NODE_ARGSPUSH,
NODE_RESTARGS, NODE_RESTARGS,
NODE_REXPAND,
NODE_BLOCK_ARG, NODE_BLOCK_ARG,
NODE_BLOCK_PASS, NODE_BLOCK_PASS,
NODE_DEFN, NODE_DEFN,
@ -304,6 +305,7 @@ typedef struct RNode {
#define NEW_ARGSCAT(a,b) rb_node_newnode(NODE_ARGSCAT,a,b,0) #define NEW_ARGSCAT(a,b) rb_node_newnode(NODE_ARGSCAT,a,b,0)
#define NEW_ARGSPUSH(a,b) rb_node_newnode(NODE_ARGSPUSH,a,b,0) #define NEW_ARGSPUSH(a,b) rb_node_newnode(NODE_ARGSPUSH,a,b,0)
#define NEW_RESTARGS(a) rb_node_newnode(NODE_RESTARGS,a,0,0) #define NEW_RESTARGS(a) rb_node_newnode(NODE_RESTARGS,a,0,0)
#define NEW_REXPAND(a) rb_node_newnode(NODE_REXPAND,a,0,0)
#define NEW_BLOCK_ARG(v) rb_node_newnode(NODE_BLOCK_ARG,v,0,local_cnt(v)) #define NEW_BLOCK_ARG(v) rb_node_newnode(NODE_BLOCK_ARG,v,0,local_cnt(v))
#define NEW_BLOCK_PASS(b) rb_node_newnode(NODE_BLOCK_PASS,0,b,0) #define NEW_BLOCK_PASS(b) rb_node_newnode(NODE_BLOCK_PASS,0,b,0)
#define NEW_ALIAS(n,o) rb_node_newnode(NODE_ALIAS,o,n,0) #define NEW_ALIAS(n,o) rb_node_newnode(NODE_ALIAS,o,n,0)

View file

@ -425,7 +425,7 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem
} }
| lhs '=' mrhs_basic | lhs '=' mrhs_basic
{ {
$$ = node_assign($1, $3); $$ = node_assign($1, ret_args($3));
} }
| mlhs '=' mrhs | mlhs '=' mrhs
{ {
@ -1146,7 +1146,7 @@ mrhs_basic : args ',' arg
| tSTAR arg | tSTAR arg
{ {
value_expr($2); value_expr($2);
$$ = $2; $$ = NEW_RESTARGS($2);
} }
primary : literal primary : literal
@ -4671,6 +4671,9 @@ ret_args(node)
rb_compile_error("block argument should not be given"); rb_compile_error("block argument should not be given");
} }
} }
if (nd_type(node) == NODE_RESTARGS) {
nd_set_type(node, NODE_REXPAND);
}
return node; return node;
} }

303
regex.c
View file

@ -543,7 +543,7 @@ print_mbc(c)
reset the pointers that pointed into the old allocation to point to reset the pointers that pointed into the old allocation to point to
the correct places in the new allocation. If extending the buffer the correct places in the new allocation. If extending the buffer
results in it being larger than 1 << 16, then flag memory exhausted. */ results in it being larger than 1 << 16, then flag memory exhausted. */
#define EXTEND_BUFFER \ #define EXTEND_BUFFER \
do { char *old_buffer = bufp->buffer; \ do { char *old_buffer = bufp->buffer; \
if (bufp->allocated == (1L<<16)) goto too_big; \ if (bufp->allocated == (1L<<16)) goto too_big; \
bufp->allocated *= 2; \ bufp->allocated *= 2; \
@ -1260,7 +1260,6 @@ re_compile_pattern(pattern, size, bufp)
int had_char_class = 0; int had_char_class = 0;
int options = bufp->options; int options = bufp->options;
int old_options = 0;
bufp->fastmap_accurate = 0; bufp->fastmap_accurate = 0;
bufp->must = 0; bufp->must = 0;
@ -1683,167 +1682,182 @@ re_compile_pattern(pattern, size, bufp)
break; break;
case '(': case '(':
old_options = options; {
PATFETCH(c); int old_options = options;
if (c == '?') {
int negative = 0;
int push_option = 0; int push_option = 0;
PATFETCH_RAW(c); int casefold = 0;
PATFETCH(c);
if (c == '?') {
int negative = 0;
PATFETCH_RAW(c);
switch (c) {
case 'x': case 'p': case 'm': case 'i': case '-':
for (;;) {
switch (c) {
case '-':
negative = 1;
break;
case ':':
case ')':
break;
case 'x':
if (negative)
options &= ~RE_OPTION_EXTENDED;
else
options |= RE_OPTION_EXTENDED;
break;
case 'p':
if (negative) {
if ((options&RE_OPTION_POSIXLINE) == RE_OPTION_POSIXLINE) {
options &= ~RE_OPTION_POSIXLINE;
}
}
else if ((options&RE_OPTION_POSIXLINE) != RE_OPTION_POSIXLINE) {
options |= RE_OPTION_POSIXLINE;
}
push_option = 1;
break;
case 'm':
if (negative) {
if (options&RE_OPTION_MULTILINE) {
options &= ~RE_OPTION_MULTILINE;
}
}
else if (!(options&RE_OPTION_MULTILINE)) {
options |= RE_OPTION_MULTILINE;
}
push_option = 1;
break;
case 'i':
if (negative) {
if (options&RE_OPTION_IGNORECASE) {
options &= ~RE_OPTION_IGNORECASE;
}
}
else if (!(options&RE_OPTION_IGNORECASE)) {
options |= RE_OPTION_IGNORECASE;
}
casefold = 1;
break;
default:
FREE_AND_RETURN(stackb, "undefined (?...) inline option");
}
if (c == ')') {
c = '#'; /* read whole in-line options */
break;
}
if (c == ':') break;
PATFETCH_RAW(c);
}
break;
case '#':
for (;;) {
PATFETCH(c);
if (c == ')') break;
}
c = '#';
break;
case ':':
case '=':
case '!':
case '>':
break;
default:
FREE_AND_RETURN(stackb, "undefined (?...) sequence");
}
}
else {
PATUNFETCH;
c = '(';
}
if (c == '#') {
if (push_option) {
BUFPUSH(option_set);
BUFPUSH(options);
}
if (casefold) {
if (options & RE_OPTION_IGNORECASE)
BUFPUSH(casefold_on);
else
BUFPUSH(casefold_off);
}
break;
}
if (stackp+8 >= stacke) {
DOUBLE_STACK(int);
}
/* Laststart should point to the start_memory that we are about
to push (unless the pattern has RE_NREGS or more ('s). */
/* obsolete: now RE_NREGS is just a default register size. */
*stackp++ = b - bufp->buffer;
*stackp++ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
*stackp++ = begalt - bufp->buffer;
switch (c) { switch (c) {
case 'x': case 'p': case 'm': case 'i': case '-': case '(':
for (;;) { BUFPUSH(start_memory);
switch (c) { BUFPUSH(regnum);
case '-': *stackp++ = regnum++;
negative = 1; *stackp++ = b - bufp->buffer;
break; BUFPUSH(0);
/* too many ()'s to fit in a byte. (max 254) */
case ':': if (regnum >= RE_REG_MAX) goto too_big;
case ')':
break;
case 'x':
if (negative)
options &= ~RE_OPTION_EXTENDED;
else
options |= RE_OPTION_EXTENDED;
break;
case 'p':
if (negative) {
if ((options&RE_OPTION_POSIXLINE) == RE_OPTION_POSIXLINE) {
options &= ~RE_OPTION_POSIXLINE;
}
}
else if ((options&RE_OPTION_POSIXLINE) != RE_OPTION_POSIXLINE) {
options |= RE_OPTION_POSIXLINE;
}
push_option = 1;
break;
case 'm':
if (negative) {
if (options&RE_OPTION_MULTILINE) {
options &= ~RE_OPTION_MULTILINE;
}
}
else if (!(options&RE_OPTION_MULTILINE)) {
options |= RE_OPTION_MULTILINE;
}
push_option = 1;
break;
case 'i':
if (negative) {
if (options&RE_OPTION_IGNORECASE) {
options &= ~RE_OPTION_IGNORECASE;
BUFPUSH(casefold_off);
}
}
else if (!(options&RE_OPTION_IGNORECASE)) {
options |= RE_OPTION_IGNORECASE;
BUFPUSH(casefold_on);
}
break;
default:
FREE_AND_RETURN(stackb, "undefined (?...) inline option");
}
if (c == ')') {
c = '#'; /* read whole in-line options */
break;
}
if (c == ':') break;
PATFETCH_RAW(c);
}
break; break;
case '#':
for (;;) {
PATFETCH(c);
if (c == ')') break;
}
c = '#';
break;
case ':':
case '=': case '=':
case '!': case '!':
case '>': case '>':
BUFPUSH(start_nowidth);
*stackp++ = b - bufp->buffer;
BUFPUSH(0); /* temporary value */
BUFPUSH(0);
if (c != '!') break;
BUFPUSH(on_failure_jump);
*stackp++ = b - bufp->buffer;
BUFPUSH(0); /* temporary value */
BUFPUSH(0);
break; break;
case ':':
BUFPUSH(start_paren);
pending_exact = 0;
default: default:
FREE_AND_RETURN(stackb, "undefined (?...) sequence"); break;
} }
if (push_option) { if (push_option) {
BUFPUSH(option_set); BUFPUSH(option_set);
BUFPUSH(options); BUFPUSH(options);
} }
if (casefold) {
if (options & RE_OPTION_IGNORECASE)
BUFPUSH(casefold_on);
else
BUFPUSH(casefold_off);
}
*stackp++ = c;
*stackp++ = old_options;
fixup_alt_jump = 0;
laststart = 0;
begalt = b;
} }
else {
PATUNFETCH;
c = '(';
}
if (c == '#') break;
if (stackp+8 >= stacke) {
DOUBLE_STACK(int);
}
/* Laststart should point to the start_memory that we are about
to push (unless the pattern has RE_NREGS or more ('s). */
/* obsolete: now RE_NREGS is just a default register size. */
*stackp++ = b - bufp->buffer;
*stackp++ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0;
*stackp++ = begalt - bufp->buffer;
switch (c) {
case '(':
BUFPUSH(start_memory);
BUFPUSH(regnum);
*stackp++ = regnum++;
*stackp++ = b - bufp->buffer;
BUFPUSH(0);
/* too many ()'s to fit in a byte. (max 254) */
if (regnum >= RE_REG_MAX) goto too_big;
break;
case '=':
case '!':
case '>':
BUFPUSH(start_nowidth);
*stackp++ = b - bufp->buffer;
BUFPUSH(0); /* temporary value */
BUFPUSH(0);
if (c != '!') break;
BUFPUSH(on_failure_jump);
*stackp++ = b - bufp->buffer;
BUFPUSH(0); /* temporary value */
BUFPUSH(0);
break;
case ':':
BUFPUSH(start_paren);
pending_exact = 0;
default:
break;
}
*stackp++ = c;
*stackp++ = old_options;
fixup_alt_jump = 0;
laststart = 0;
begalt = b;
break; break;
case ')': case ')':
if (stackp == stackb) if (stackp == stackb)
FREE_AND_RETURN(stackb, "unmatched )"); FREE_AND_RETURN(stackb, "unmatched )");
if (options != stackp[-1]) {
if ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) {
BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on);
}
BUFPUSH(option_set);
BUFPUSH(stackp[-1]);
}
pending_exact = 0; pending_exact = 0;
if (fixup_alt_jump) { if (fixup_alt_jump) {
/* Push a dummy failure point at the end of the /* Push a dummy failure point at the end of the
@ -1856,6 +1870,13 @@ re_compile_pattern(pattern, size, bufp)
to `fixup_alt_jump', in the `handle_alt' case below. */ to `fixup_alt_jump', in the `handle_alt' case below. */
store_jump(fixup_alt_jump, jump, b); store_jump(fixup_alt_jump, jump, b);
} }
if (options != stackp[-1]) {
if ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) {
BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on);
}
BUFPUSH(option_set);
BUFPUSH(stackp[-1]);
}
p0 = b; p0 = b;
options = *--stackp; options = *--stackp;
switch (c = *--stackp) { switch (c = *--stackp) {

View file

@ -1092,21 +1092,6 @@ rb_const_get(klass, id)
return Qnil; /* not reached */ return Qnil; /* not reached */
} }
static int
sv_i(key, value, ary)
ID key;
VALUE value;
VALUE ary;
{
if (rb_is_const_id(key)) {
VALUE kval = rb_str_new2(rb_id2name(key));
if (!rb_ary_includes(ary, kval)) {
rb_ary_push(ary, kval);
}
}
return ST_CONTINUE;
}
VALUE VALUE
rb_mod_remove_const(mod, name) rb_mod_remove_const(mod, name)
VALUE mod, name; VALUE mod, name;
@ -1134,44 +1119,85 @@ rb_mod_remove_const(mod, name)
} }
static int static int
autoload_i(key, name, ary) sv_i(key, value, tbl)
ID key; ID key;
const char *name; VALUE value;
VALUE ary; st_table *tbl;
{ {
VALUE kval = rb_str_new2(rb_id2name(key)); if (rb_is_const_id(key)) {
if (!rb_ary_includes(ary, kval)) { if (!st_lookup(tbl, key, 0)) {
rb_ary_push(ary, kval); st_insert(tbl, key, key);
}
} }
return ST_CONTINUE; return ST_CONTINUE;
} }
VALUE static int
rb_mod_const_at(mod, ary) autoload_i(key, name, tbl)
VALUE mod, ary; ID key;
const char *name;
st_table *tbl;
{ {
if (RCLASS(mod)->iv_tbl) { if (!st_lookup(tbl, key, 0)) {
st_foreach(RCLASS(mod)->iv_tbl, sv_i, ary); st_insert(tbl, key, key);
} }
if ((VALUE)mod == rb_cObject) { return ST_CONTINUE;
st_foreach(rb_class_tbl, sv_i, ary);
if (autoload_tbl) {
st_foreach(autoload_tbl, autoload_i, ary);
}
}
return ary;
} }
VALUE void*
rb_mod_const_of(mod, ary) rb_mod_const_at(mod, data)
VALUE mod; VALUE mod;
VALUE ary; void *data;
{
st_table *tbl = data;
if (!tbl) {
tbl = st_init_numtable();
}
if (RCLASS(mod)->iv_tbl) {
st_foreach(RCLASS(mod)->iv_tbl, sv_i, tbl);
}
if ((VALUE)mod == rb_cObject) {
st_foreach(rb_class_tbl, sv_i, tbl);
if (autoload_tbl) {
st_foreach(autoload_tbl, autoload_i, tbl);
}
}
return tbl;
}
void*
rb_mod_const_of(mod, data)
VALUE mod;
void *data;
{ {
for (;;) { for (;;) {
rb_mod_const_at(mod, ary); data = rb_mod_const_at(mod, data);
mod = RCLASS(mod)->super; mod = RCLASS(mod)->super;
if (!mod) break; if (!mod) break;
} }
return data;
}
static int
list_i(key, value, ary)
ID key, value;
VALUE ary;
{
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
return ST_CONTINUE;
}
VALUE
rb_const_list(data)
void *data;
{
st_table *tbl = data;
VALUE ary;
if (!tbl) return rb_ary_new2(0);
ary = rb_ary_new2(tbl->num_entries);
st_foreach(tbl, list_i, ary);
return ary; return ary;
} }
@ -1179,7 +1205,7 @@ VALUE
rb_mod_constants(mod) rb_mod_constants(mod)
VALUE mod; VALUE mod;
{ {
return rb_mod_const_of(mod, rb_ary_new()); return rb_const_list(rb_mod_const_of(mod, 0));
} }
int int

View file

@ -1,4 +1,4 @@
#define RUBY_VERSION "1.7.1" #define RUBY_VERSION "1.7.1"
#define RUBY_RELEASE_DATE "2001-06-01" #define RUBY_RELEASE_DATE "2001-06-05"
#define RUBY_VERSION_CODE 171 #define RUBY_VERSION_CODE 171
#define RUBY_RELEASE_CODE 20010601 #define RUBY_RELEASE_CODE 20010605