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>
* 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>
* 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>
* 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;
if (NIL_P(klass)) klass = rb_cObject;
if (klass == rb_cObject) {
rb_secure(4);
}
if (rb_safe_level() >= 4 && !OBJ_TAINTED(klass)) {
if (rb_safe_level() >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
rb_raise(rb_eSecurityError, "Insecure: can't define method");
}
if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
@ -1474,15 +1471,19 @@ static VALUE
rb_mod_s_constants()
{
NODE *cbase = RNODE(ruby_frame->cbase);
VALUE ary = rb_ary_new();
void *data = 0;
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;
}
if (!NIL_P(ruby_cbase)) rb_mod_const_of(ruby_cbase, ary);
return ary;
if (!NIL_P(ruby_cbase)) {
data = rb_mod_const_of(ruby_cbase, data);
}
return rb_const_list(data);
}
void
@ -2349,12 +2350,19 @@ rb_eval(self, n)
}
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:
if (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 {
result = Qnil;
@ -8602,6 +8610,28 @@ rb_thread_key_p(thread, id)
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
rb_thread_inspect(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_aset, 2);
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);

View file

@ -367,9 +367,10 @@ VALUE rb_ivar_set _((VALUE, ID, VALUE));
VALUE rb_ivar_defined _((VALUE, ID));
VALUE rb_obj_instance_variables _((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_const_of _((VALUE, VALUE));
VALUE rb_mod_remove_const _((VALUE, VALUE));
int rb_const_defined_at _((VALUE, ID));
int rb_autoload_defined _((ID));

138
io.c
View file

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

View file

@ -52,7 +52,7 @@ shortlen(len, ds)
#endif
#define MARSHAL_MAJOR 4
#define MARSHAL_MINOR 5
#define MARSHAL_MINOR 6
#define TYPE_NIL '0'
#define TYPE_TRUE 'T'
@ -348,6 +348,10 @@ w_object(obj, arg, limit)
w_byte(TYPE_CLASS, arg);
{
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);
}
break;
@ -356,6 +360,10 @@ w_object(obj, arg, limit)
w_byte(TYPE_MODULE, arg);
{
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);
}
break;
@ -991,7 +999,7 @@ r_object(arg)
char *buf;
r_bytes(buf, arg);
m = rb_path2class(buf);
if (TYPE(m) != T_CLASS) {
if (TYPE(m) != T_MODULE) {
rb_raise(rb_eTypeError, "%s is not a module", buf);
}
return r_regist(m, arg);

2
node.h
View file

@ -89,6 +89,7 @@ enum node_type {
NODE_ARGSCAT,
NODE_ARGSPUSH,
NODE_RESTARGS,
NODE_REXPAND,
NODE_BLOCK_ARG,
NODE_BLOCK_PASS,
NODE_DEFN,
@ -304,6 +305,7 @@ typedef struct RNode {
#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_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_PASS(b) rb_node_newnode(NODE_BLOCK_PASS,0,b,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
{
$$ = node_assign($1, $3);
$$ = node_assign($1, ret_args($3));
}
| mlhs '=' mrhs
{
@ -1146,7 +1146,7 @@ mrhs_basic : args ',' arg
| tSTAR arg
{
value_expr($2);
$$ = $2;
$$ = NEW_RESTARGS($2);
}
primary : literal
@ -4671,6 +4671,9 @@ ret_args(node)
rb_compile_error("block argument should not be given");
}
}
if (nd_type(node) == NODE_RESTARGS) {
nd_set_type(node, NODE_REXPAND);
}
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
the correct places in the new allocation. If extending the buffer
results in it being larger than 1 << 16, then flag memory exhausted. */
#define EXTEND_BUFFER \
#define EXTEND_BUFFER \
do { char *old_buffer = bufp->buffer; \
if (bufp->allocated == (1L<<16)) goto too_big; \
bufp->allocated *= 2; \
@ -1260,7 +1260,6 @@ re_compile_pattern(pattern, size, bufp)
int had_char_class = 0;
int options = bufp->options;
int old_options = 0;
bufp->fastmap_accurate = 0;
bufp->must = 0;
@ -1683,167 +1682,182 @@ re_compile_pattern(pattern, size, bufp)
break;
case '(':
old_options = options;
PATFETCH(c);
if (c == '?') {
int negative = 0;
{
int old_options = options;
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) {
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;
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);
}
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 '#':
for (;;) {
PATFETCH(c);
if (c == ')') break;
}
c = '#';
break;
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;
case ':':
BUFPUSH(start_paren);
pending_exact = 0;
default:
FREE_AND_RETURN(stackb, "undefined (?...) sequence");
break;
}
if (push_option) {
BUFPUSH(option_set);
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;
case ')':
if (stackp == stackb)
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;
if (fixup_alt_jump) {
/* 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. */
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;
options = *--stackp;
switch (c = *--stackp) {

View file

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

View file

@ -1,4 +1,4 @@
#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_RELEASE_CODE 20010601
#define RUBY_RELEASE_CODE 20010605