mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* ruby.c (proc_options): unexpected SecurityError happens when -T4.
* regex.c (re_compile_pattern): * \1 .. \9 should be backreferences always. * regex.c (re_match): backreferences corresponding to unclosed/unmatched parentheses should fail always. * string.c (rb_str_cat): use rb_str_buf_cat() if possible. [new] * string.c (rb_str_append): ditto. * string.c (rb_str_buf_cat): remove unnecessary check (type, taint, modify) to gain performance. * string.c (rb_str_buf_append): ditto. * string.c (rb_str_buf_new): buffering string function. [new] * string.c (rb_str_buf_append): ditto. * string.c (rb_str_buf_cat): ditto. * time.c (make_time_t): local time adjustment revised. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@1476 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
4cd1cd7201
commit
abfaac7a6c
24 changed files with 925 additions and 423 deletions
78
ChangeLog
78
ChangeLog
|
@ -1,3 +1,38 @@
|
||||||
|
Tue May 29 17:24:23 2001 K.Kosako <kosako@sofnec.co.jp>
|
||||||
|
|
||||||
|
* ruby.c (proc_options): unexpected SecurityError happens when -T4.
|
||||||
|
|
||||||
|
Tue May 29 18:46:04 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* regex.c (re_compile_pattern): * \1 .. \9 should be
|
||||||
|
backreferences always.
|
||||||
|
|
||||||
|
* regex.c (re_match): backreferences corresponding to
|
||||||
|
unclosed/unmatched parentheses should fail always.
|
||||||
|
|
||||||
|
Tue May 29 16:35:49 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* string.c (rb_str_cat): use rb_str_buf_cat() if possible. [new]
|
||||||
|
|
||||||
|
* string.c (rb_str_append): ditto.
|
||||||
|
|
||||||
|
* string.c (rb_str_buf_cat): remove unnecessary check (type,
|
||||||
|
taint, modify) to gain performance.
|
||||||
|
|
||||||
|
* string.c (rb_str_buf_append): ditto.
|
||||||
|
|
||||||
|
* string.c (rb_str_buf_finish): removed.
|
||||||
|
|
||||||
|
Tue May 29 02:05:55 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* string.c (rb_str_buf_new): buffering string function. [new]
|
||||||
|
|
||||||
|
* string.c (rb_str_buf_append): ditto.
|
||||||
|
|
||||||
|
* string.c (rb_str_buf_cat): ditto.
|
||||||
|
|
||||||
|
* string.c (rb_str_buf_finish): ditto.
|
||||||
|
|
||||||
Mon May 28 23:20:43 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
Mon May 28 23:20:43 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||||
|
|
||||||
* configure.in: remove unnecessary AC_CANONICAL_BUILD
|
* configure.in: remove unnecessary AC_CANONICAL_BUILD
|
||||||
|
@ -21,6 +56,10 @@ Mon May 28 22:12:01 2001 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||||
* ext/extconf.rb.in: make the priority of the make rule of .c
|
* ext/extconf.rb.in: make the priority of the make rule of .c
|
||||||
higher than .C .
|
higher than .C .
|
||||||
|
|
||||||
|
Mon May 28 13:22:19 2001 Tanaka Akira <akr@m17n.org>
|
||||||
|
|
||||||
|
* time.c (make_time_t): local time adjustment revised.
|
||||||
|
|
||||||
Mon May 28 02:20:38 2001 Akinori MUSHA <knu@iDaemons.org>
|
Mon May 28 02:20:38 2001 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
* dir.c (glob_helper): teach has_magic() to handle flags and get
|
* dir.c (glob_helper): teach has_magic() to handle flags and get
|
||||||
|
@ -29,10 +68,38 @@ Mon May 28 02:20:38 2001 Akinori MUSHA <knu@iDaemons.org>
|
||||||
* dir.c (fnmatch): fix a bug when FNM_PATHNAME and FNM_PERIOD are
|
* dir.c (fnmatch): fix a bug when FNM_PATHNAME and FNM_PERIOD are
|
||||||
specified at the same time.
|
specified at the same time.
|
||||||
|
|
||||||
|
Sat May 26 09:55:26 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* parse.y: accomplish extended syntax described in [ruby-talk:14525]
|
||||||
|
using tSPC token. [new, experimental]
|
||||||
|
|
||||||
Sat May 26 07:05:45 2001 Usaku Nakamura <usa@osb.att.ne.jp>
|
Sat May 26 07:05:45 2001 Usaku Nakamura <usa@osb.att.ne.jp>
|
||||||
|
|
||||||
* MANIFEST: add win32/dir.h .
|
* MANIFEST: add win32/dir.h .
|
||||||
|
|
||||||
|
Fri May 25 20:03:51 2001 Pascal Rigaux <pixel@mandrakesoft.com>
|
||||||
|
|
||||||
|
* dln.c (dln_find_1): should exclude directories in executable
|
||||||
|
file lookup.
|
||||||
|
|
||||||
|
Fri May 25 18:00:26 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* class.c (rb_obj_singleton_methods): list methods in extended
|
||||||
|
modules if optional argument is true. [new]
|
||||||
|
|
||||||
|
Fri May 25 14:19:25 2001 K.Kosako <kosako@sofnec.co.jp>
|
||||||
|
|
||||||
|
* string.c (rb_str_replace): add taint status infection
|
||||||
|
(OBJ_INFECT()).
|
||||||
|
|
||||||
|
* string.c (rb_str_crypt): ditto.
|
||||||
|
|
||||||
|
* string.c (rb_str_ljust): ditto.
|
||||||
|
|
||||||
|
* string.c (rb_str_rjust): ditto.
|
||||||
|
|
||||||
|
* string.c (rb_str_center): ditto.
|
||||||
|
|
||||||
Fri May 25 05:39:03 2001 Akinori MUSHA <knu@iDaemons.org>
|
Fri May 25 05:39:03 2001 Akinori MUSHA <knu@iDaemons.org>
|
||||||
|
|
||||||
* ext/sha1/sha1-ruby.c (sha1_hexdigest): fix buffer overflow. The
|
* ext/sha1/sha1-ruby.c (sha1_hexdigest): fix buffer overflow. The
|
||||||
|
@ -54,6 +121,17 @@ Fri May 25 00:53:41 2001 Akinori MUSHA <knu@iDaemons.org>
|
||||||
* ext/dbm/extconf.rb: fix support for *BSD and set $CFLAGS
|
* ext/dbm/extconf.rb: fix support for *BSD and set $CFLAGS
|
||||||
properly.
|
properly.
|
||||||
|
|
||||||
|
Thu May 24 16:10:33 2001 Yukihiro Matsumoto <matz@ruby-lang.org>
|
||||||
|
|
||||||
|
* range.c (range_member): check based on "<=>" comparison. [new]
|
||||||
|
|
||||||
|
* range.c (range_check): add "succ" check if first end is not a
|
||||||
|
numeric.
|
||||||
|
|
||||||
|
* range.c (range_eqq): comparison should based on "<=>".
|
||||||
|
|
||||||
|
* range.c (range_each): ditto.
|
||||||
|
|
||||||
Thu May 24 16:08:21 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
Thu May 24 16:08:21 2001 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||||
|
|
||||||
* mkconfig.rb: autoconf 2.50 support.
|
* mkconfig.rb: autoconf 2.50 support.
|
||||||
|
|
40
array.c
40
array.c
|
@ -739,26 +739,11 @@ inspect_join(ary, arg)
|
||||||
return rb_ary_join(arg[0], arg[1]);
|
return rb_ary_join(arg[0], arg[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static long
|
|
||||||
str_cpy(str, idx, str2)
|
|
||||||
VALUE str;
|
|
||||||
long idx;
|
|
||||||
VALUE str2;
|
|
||||||
{
|
|
||||||
long len = idx + RSTRING(str2)->len;
|
|
||||||
|
|
||||||
if (RSTRING(str)->len < len) {
|
|
||||||
rb_str_resize(str, len);
|
|
||||||
}
|
|
||||||
memcpy(RSTRING(str)->ptr+idx, RSTRING(str2)->ptr, RSTRING(str2)->len);
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_ary_join(ary, sep)
|
rb_ary_join(ary, sep)
|
||||||
VALUE ary, sep;
|
VALUE ary, sep;
|
||||||
{
|
{
|
||||||
long len, i, j;
|
long len, i;
|
||||||
int taint = 0;
|
int taint = 0;
|
||||||
VALUE result, tmp;
|
VALUE result, tmp;
|
||||||
|
|
||||||
|
@ -778,9 +763,8 @@ rb_ary_join(ary, sep)
|
||||||
if (!NIL_P(sep) && TYPE(sep) == T_STRING) {
|
if (!NIL_P(sep) && TYPE(sep) == T_STRING) {
|
||||||
len += RSTRING(sep)->len * RARRAY(ary)->len - 1;
|
len += RSTRING(sep)->len * RARRAY(ary)->len - 1;
|
||||||
}
|
}
|
||||||
result = rb_str_new(0, len);
|
result = rb_str_buf_new(len);
|
||||||
|
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||||
for (i=0, j=0; i<RARRAY(ary)->len; i++) {
|
|
||||||
tmp = RARRAY(ary)->ptr[i];
|
tmp = RARRAY(ary)->ptr[i];
|
||||||
switch (TYPE(tmp)) {
|
switch (TYPE(tmp)) {
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
|
@ -800,11 +784,11 @@ rb_ary_join(ary, sep)
|
||||||
default:
|
default:
|
||||||
tmp = rb_obj_as_string(tmp);
|
tmp = rb_obj_as_string(tmp);
|
||||||
}
|
}
|
||||||
if (i > 0 && !NIL_P(sep)) j = str_cpy(result, j, sep);
|
if (i > 0 && !NIL_P(sep))
|
||||||
j = str_cpy(result, j, tmp);
|
rb_str_buf_append(result, sep);
|
||||||
|
rb_str_buf_append(result, tmp);
|
||||||
if (OBJ_TAINTED(tmp)) taint = 1;
|
if (OBJ_TAINTED(tmp)) taint = 1;
|
||||||
}
|
}
|
||||||
rb_str_resize(result, j);
|
|
||||||
|
|
||||||
if (taint) OBJ_TAINT(result);
|
if (taint) OBJ_TAINT(result);
|
||||||
return result;
|
return result;
|
||||||
|
@ -909,16 +893,14 @@ inspect_ary(ary)
|
||||||
long i = 0;
|
long i = 0;
|
||||||
VALUE s, str;
|
VALUE s, str;
|
||||||
|
|
||||||
str = rb_str_new2("[");
|
str = rb_str_buf_new2("[");
|
||||||
|
|
||||||
for (i=0; i<RARRAY(ary)->len; i++) {
|
for (i=0; i<RARRAY(ary)->len; i++) {
|
||||||
s = rb_inspect(RARRAY(ary)->ptr[i]);
|
s = rb_inspect(RARRAY(ary)->ptr[i]);
|
||||||
tainted = OBJ_TAINTED(s);
|
if (OBJ_TAINTED(s)) tainted = 1;
|
||||||
if (i > 0) rb_str_cat2(str, ", ");
|
if (i > 0) rb_str_buf_cat2(str, ", ");
|
||||||
rb_str_append(str, s);
|
rb_str_buf_append(str, s);
|
||||||
}
|
}
|
||||||
rb_str_cat(str, "]", 1);
|
rb_str_buf_cat2(str, "]");
|
||||||
|
|
||||||
if (tainted) OBJ_TAINT(str);
|
if (tainted) OBJ_TAINT(str);
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
12
class.c
12
class.c
|
@ -484,19 +484,29 @@ rb_class_private_instance_methods(argc, argv, mod)
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_obj_singleton_methods(obj)
|
rb_obj_singleton_methods(argc, argv, obj)
|
||||||
|
int argc;
|
||||||
|
VALUE *argv;
|
||||||
VALUE obj;
|
VALUE obj;
|
||||||
{
|
{
|
||||||
|
VALUE all;
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
VALUE klass;
|
VALUE klass;
|
||||||
VALUE *p, *q, *pend;
|
VALUE *p, *q, *pend;
|
||||||
|
|
||||||
|
rb_scan_args(argc, argv, "01", &all);
|
||||||
ary = rb_ary_new();
|
ary = rb_ary_new();
|
||||||
klass = CLASS_OF(obj);
|
klass = CLASS_OF(obj);
|
||||||
while (klass && FL_TEST(klass, FL_SINGLETON)) {
|
while (klass && FL_TEST(klass, FL_SINGLETON)) {
|
||||||
st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
|
st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
|
||||||
klass = RCLASS(klass)->super;
|
klass = RCLASS(klass)->super;
|
||||||
}
|
}
|
||||||
|
if (RTEST(all)) {
|
||||||
|
while (klass && TYPE(klass) == T_ICLASS) {
|
||||||
|
st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
|
||||||
|
klass = RCLASS(klass)->super;
|
||||||
|
}
|
||||||
|
}
|
||||||
p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
|
p = q = RARRAY(ary)->ptr; pend = p + RARRAY(ary)->len;
|
||||||
while (p < pend) {
|
while (p < pend) {
|
||||||
if (*p == Qnil) {
|
if (*p == Qnil) {
|
||||||
|
|
15
dln.c
15
dln.c
|
@ -50,6 +50,10 @@ void *xrealloc();
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#ifndef S_ISDIR
|
||||||
|
# define S_ISDIR(m) ((m & S_IFMT) == S_IFDIR)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SYS_PARAM_H
|
#ifdef HAVE_SYS_PARAM_H
|
||||||
# include <sys/param.h>
|
# include <sys/param.h>
|
||||||
#else
|
#else
|
||||||
|
@ -1582,9 +1586,8 @@ dln_find_1(fname, path, exe_flag)
|
||||||
register char *dp;
|
register char *dp;
|
||||||
register char *ep;
|
register char *ep;
|
||||||
register char *bp;
|
register char *bp;
|
||||||
#ifndef __MACOS__
|
|
||||||
struct stat st;
|
struct stat st;
|
||||||
#else
|
#ifdef __MACOS__
|
||||||
const char* mac_fullpath;
|
const char* mac_fullpath;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1669,13 +1672,17 @@ dln_find_1(fname, path, exe_flag)
|
||||||
if (stat(fbuf, &st) == 0) {
|
if (stat(fbuf, &st) == 0) {
|
||||||
if (exe_flag == 0) return fbuf;
|
if (exe_flag == 0) return fbuf;
|
||||||
/* looking for executable */
|
/* looking for executable */
|
||||||
if (eaccess(fbuf, X_OK) == 0) return fbuf;
|
if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0)
|
||||||
|
return fbuf;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) {
|
if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) {
|
||||||
if (exe_flag == 0) return mac_fullpath;
|
if (exe_flag == 0) return mac_fullpath;
|
||||||
/* looking for executable */
|
/* looking for executable */
|
||||||
if (eaccess(mac_fullpath, X_OK) == 0) return mac_fullpath;
|
if (stat(mac_fullpath, &st) == 0) {
|
||||||
|
if (!S_ISDIR(st.st_mode) && eaccess(mac_fullpath, X_OK) == 0)
|
||||||
|
return mac_fullpath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if defined(MSDOS) || defined(NT) || defined(__human68k__) || defined(__EMX__)
|
#if defined(MSDOS) || defined(NT) || defined(__human68k__) || defined(__EMX__)
|
||||||
|
|
10
error.c
10
error.c
|
@ -359,12 +359,12 @@ exc_inspect(exc)
|
||||||
return rb_str_dup(rb_class_path(klass));
|
return rb_str_dup(rb_class_path(klass));
|
||||||
}
|
}
|
||||||
|
|
||||||
str = rb_str_new2("#<");
|
str = rb_str_buf_new2("#<");
|
||||||
klass = rb_class_path(klass);
|
klass = rb_class_path(klass);
|
||||||
rb_str_append(str, klass);
|
rb_str_buf_append(str, klass);
|
||||||
rb_str_cat(str, ": ", 2);
|
rb_str_buf_cat(str, ": ", 2);
|
||||||
rb_str_append(str, exc);
|
rb_str_buf_append(str, exc);
|
||||||
rb_str_cat(str, ">", 1);
|
rb_str_buf_cat(str, ">", 1);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
33
eval.c
33
eval.c
|
@ -15,6 +15,7 @@
|
||||||
#include "ruby.h"
|
#include "ruby.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
|
#include "util.h"
|
||||||
#include "rubysig.h"
|
#include "rubysig.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
@ -1213,14 +1214,14 @@ compile_error(at)
|
||||||
VALUE str;
|
VALUE str;
|
||||||
|
|
||||||
ruby_nerrs = 0;
|
ruby_nerrs = 0;
|
||||||
str = rb_str_new2("compile error");
|
str = rb_str_buf_new2("compile error");
|
||||||
if (at) {
|
if (at) {
|
||||||
rb_str_cat2(str, " in ");
|
rb_str_buf_cat2(str, " in ");
|
||||||
rb_str_cat2(str, at);
|
rb_str_buf_cat2(str, at);
|
||||||
}
|
}
|
||||||
rb_str_cat(str, "\n", 1);
|
rb_str_buf_cat(str, "\n", 1);
|
||||||
if (!NIL_P(ruby_errinfo)) {
|
if (!NIL_P(ruby_errinfo)) {
|
||||||
rb_str_concat(str, ruby_errinfo);
|
rb_str_append(str, ruby_errinfo);
|
||||||
}
|
}
|
||||||
rb_exc_raise(rb_exc_new3(rb_eSyntaxError, str));
|
rb_exc_raise(rb_exc_new3(rb_eSyntaxError, str));
|
||||||
}
|
}
|
||||||
|
@ -2351,9 +2352,7 @@ rb_eval(self, n)
|
||||||
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 &&
|
if (nd_type(node->nd_stts) == NODE_RESTARGS && RARRAY(result)->len == 1) {
|
||||||
RARRAY(result)->len == 1)
|
|
||||||
{
|
|
||||||
result = RARRAY(result)->ptr[0];
|
result = RARRAY(result)->ptr[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6752,19 +6751,19 @@ method_inspect(method)
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
||||||
Data_Get_Struct(method, struct METHOD, data);
|
Data_Get_Struct(method, struct METHOD, data);
|
||||||
str = rb_str_new2("#<");
|
str = rb_str_buf_new2("#<");
|
||||||
s = rb_class2name(CLASS_OF(method));
|
s = rb_class2name(CLASS_OF(method));
|
||||||
rb_str_cat2(str, s);
|
rb_str_buf_cat2(str, s);
|
||||||
rb_str_cat2(str, ": ");
|
rb_str_buf_cat2(str, ": ");
|
||||||
s = rb_class2name(data->oklass);
|
s = rb_class2name(data->oklass);
|
||||||
rb_str_cat2(str, s);
|
rb_str_buf_cat2(str, s);
|
||||||
rb_str_cat2(str, "(");
|
rb_str_buf_cat2(str, "(");
|
||||||
s = rb_class2name(data->klass);
|
s = rb_class2name(data->klass);
|
||||||
rb_str_cat2(str, s);
|
rb_str_buf_cat2(str, s);
|
||||||
rb_str_cat2(str, ")#");
|
rb_str_buf_cat2(str, ")#");
|
||||||
s = rb_id2name(data->oid);
|
s = rb_id2name(data->oid);
|
||||||
rb_str_cat2(str, s);
|
rb_str_buf_cat2(str, s);
|
||||||
rb_str_cat2(str, ">");
|
rb_str_buf_cat2(str, ">");
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
16
file.c
16
file.c
|
@ -281,22 +281,22 @@ rb_stat_inspect(self)
|
||||||
{"ctime", rb_stat_ctime},
|
{"ctime", rb_stat_ctime},
|
||||||
};
|
};
|
||||||
|
|
||||||
str = rb_str_new2("#<");
|
str = rb_str_buf_new2("#<");
|
||||||
rb_str_cat2(str, rb_class2name(CLASS_OF(self)));
|
rb_str_buf_cat2(str, rb_class2name(CLASS_OF(self)));
|
||||||
rb_str_cat2(str, " ");
|
rb_str_buf_cat2(str, " ");
|
||||||
|
|
||||||
for (i = 0; i < sizeof(member)/sizeof(member[0]); i++) {
|
for (i = 0; i < sizeof(member)/sizeof(member[0]); i++) {
|
||||||
VALUE str2;
|
VALUE str2;
|
||||||
|
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
rb_str_cat2(str, ", ");
|
rb_str_buf_cat2(str, ", ");
|
||||||
}
|
}
|
||||||
rb_str_cat2(str, member[i].name);
|
rb_str_buf_cat2(str, member[i].name);
|
||||||
rb_str_cat2(str, "=");
|
rb_str_buf_cat2(str, "=");
|
||||||
str2 = rb_inspect((*member[i].func)(self));
|
str2 = rb_inspect((*member[i].func)(self));
|
||||||
rb_str_append(str, str2);
|
rb_str_append(str, str2);
|
||||||
}
|
}
|
||||||
rb_str_cat2(str, ">");
|
rb_str_buf_cat2(str, ">");
|
||||||
OBJ_INFECT(str, self);
|
OBJ_INFECT(str, self);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
|
@ -449,7 +449,7 @@ eaccess(path, mode)
|
||||||
if (st.st_mode & mode) return 0;
|
if (st.st_mode & mode) return 0;
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
#else /* !NT */
|
#else
|
||||||
return access(path, mode);
|
return access(path, mode);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
26
hash.c
26
hash.c
|
@ -634,11 +634,11 @@ inspect_i(key, value, str)
|
||||||
rb_str_cat2(str, ", ");
|
rb_str_cat2(str, ", ");
|
||||||
}
|
}
|
||||||
str2 = rb_inspect(key);
|
str2 = rb_inspect(key);
|
||||||
rb_str_append(str, str2);
|
rb_str_buf_append(str, str2);
|
||||||
OBJ_INFECT(str, str2);
|
OBJ_INFECT(str, str2);
|
||||||
rb_str_cat2(str, "=>");
|
rb_str_buf_cat2(str, "=>");
|
||||||
str2 = rb_inspect(value);
|
str2 = rb_inspect(value);
|
||||||
rb_str_append(str, str2);
|
rb_str_buf_append(str, str2);
|
||||||
OBJ_INFECT(str, str2);
|
OBJ_INFECT(str, str2);
|
||||||
|
|
||||||
return ST_CONTINUE;
|
return ST_CONTINUE;
|
||||||
|
@ -650,11 +650,11 @@ inspect_hash(hash)
|
||||||
{
|
{
|
||||||
VALUE str;
|
VALUE str;
|
||||||
|
|
||||||
str = rb_str_new2("{");
|
str = rb_str_buf_new2("{");
|
||||||
st_foreach(RHASH(hash)->tbl, inspect_i, str);
|
st_foreach(RHASH(hash)->tbl, inspect_i, str);
|
||||||
rb_str_cat2(str, "}");
|
rb_str_buf_cat2(str, "}");
|
||||||
|
|
||||||
OBJ_INFECT(str, hash);
|
OBJ_INFECT(str, hash);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1266,7 +1266,7 @@ static VALUE
|
||||||
env_inspect()
|
env_inspect()
|
||||||
{
|
{
|
||||||
char **env;
|
char **env;
|
||||||
VALUE str = rb_str_new2("{");
|
VALUE str = rb_str_buf_new2("{");
|
||||||
VALUE i;
|
VALUE i;
|
||||||
|
|
||||||
env = environ;
|
env = environ;
|
||||||
|
@ -1274,18 +1274,18 @@ env_inspect()
|
||||||
char *s = strchr(*env, '=');
|
char *s = strchr(*env, '=');
|
||||||
|
|
||||||
if (env != environ) {
|
if (env != environ) {
|
||||||
rb_str_cat2(str, ", ");
|
rb_str_buf_cat2(str, ", ");
|
||||||
}
|
}
|
||||||
if (s) {
|
if (s) {
|
||||||
rb_str_cat2(str, "\"");
|
rb_str_buf_cat2(str, "\"");
|
||||||
rb_str_cat(str, *env, s-*env);
|
rb_str_buf_cat(str, *env, s-*env);
|
||||||
rb_str_cat2(str, "\"=>");
|
rb_str_buf_cat2(str, "\"=>");
|
||||||
i = rb_inspect(rb_str_new2(s+1));
|
i = rb_inspect(rb_str_new2(s+1));
|
||||||
rb_str_append(str, i);
|
rb_str_buf_append(str, i);
|
||||||
}
|
}
|
||||||
env++;
|
env++;
|
||||||
}
|
}
|
||||||
rb_str_cat2(str, "}");
|
rb_str_buf_cat2(str, "}");
|
||||||
OBJ_TAINT(str);
|
OBJ_TAINT(str);
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
|
|
4
intern.h
4
intern.h
|
@ -91,7 +91,7 @@ VALUE rb_mod_ancestors _((VALUE));
|
||||||
VALUE rb_class_instance_methods _((int, VALUE*, VALUE));
|
VALUE rb_class_instance_methods _((int, VALUE*, VALUE));
|
||||||
VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));
|
VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));
|
||||||
VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE));
|
VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE));
|
||||||
VALUE rb_obj_singleton_methods _((VALUE));
|
VALUE rb_obj_singleton_methods _((int, VALUE*, VALUE));
|
||||||
void rb_define_method_id _((VALUE, ID, VALUE (*)(ANYARGS), int));
|
void rb_define_method_id _((VALUE, ID, VALUE (*)(ANYARGS), int));
|
||||||
void rb_frozen_class_p _((VALUE));
|
void rb_frozen_class_p _((VALUE));
|
||||||
void rb_undef _((VALUE, ID));
|
void rb_undef _((VALUE, ID));
|
||||||
|
@ -312,6 +312,8 @@ VALUE rb_str_new3 _((VALUE));
|
||||||
VALUE rb_str_new4 _((VALUE));
|
VALUE rb_str_new4 _((VALUE));
|
||||||
VALUE rb_tainted_str_new _((const char*, long));
|
VALUE rb_tainted_str_new _((const char*, long));
|
||||||
VALUE rb_tainted_str_new2 _((const char*));
|
VALUE rb_tainted_str_new2 _((const char*));
|
||||||
|
VALUE rb_str_buf_new _((long));
|
||||||
|
VALUE rb_str_buf_new2 _((const char*));
|
||||||
VALUE rb_obj_as_string _((VALUE));
|
VALUE rb_obj_as_string _((VALUE));
|
||||||
VALUE rb_str_dup _((VALUE));
|
VALUE rb_str_dup _((VALUE));
|
||||||
VALUE rb_str_plus _((VALUE, VALUE));
|
VALUE rb_str_plus _((VALUE, VALUE));
|
||||||
|
|
2
io.c
2
io.c
|
@ -608,7 +608,7 @@ rb_io_gets_internal(argc, argv, io)
|
||||||
VALUE rs;
|
VALUE rs;
|
||||||
|
|
||||||
if (argc == 0) {
|
if (argc == 0) {
|
||||||
rs = rb_default_rs;
|
rs = rb_rs;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rb_scan_args(argc, argv, "1", &rs);
|
rb_scan_args(argc, argv, "1", &rs);
|
||||||
|
|
|
@ -106,7 +106,7 @@ w_byte(c, arg)
|
||||||
struct dump_arg *arg;
|
struct dump_arg *arg;
|
||||||
{
|
{
|
||||||
if (arg->fp) putc(c, arg->fp);
|
if (arg->fp) putc(c, arg->fp);
|
||||||
else rb_str_cat(arg->str, &c, 1);
|
else rb_str_buf_cat(arg->str, &c, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -540,7 +540,7 @@ marshal_dump(argc, argv)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
arg.fp = 0;
|
arg.fp = 0;
|
||||||
port = rb_str_new(0, 0);
|
port = rb_str_buf_new(0);
|
||||||
arg.str = port;
|
arg.str = port;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
4
object.c
4
object.c
|
@ -809,8 +809,6 @@ rb_obj_methods(obj)
|
||||||
return rb_class_instance_methods(1, argv, CLASS_OF(obj));
|
return rb_class_instance_methods(1, argv, CLASS_OF(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE rb_obj_singleton_methods();
|
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
rb_obj_protected_methods(obj)
|
rb_obj_protected_methods(obj)
|
||||||
VALUE obj;
|
VALUE obj;
|
||||||
|
@ -1179,7 +1177,7 @@ Init_Object()
|
||||||
rb_define_method(rb_mKernel, "inspect", rb_obj_inspect, 0);
|
rb_define_method(rb_mKernel, "inspect", rb_obj_inspect, 0);
|
||||||
rb_define_method(rb_mKernel, "methods", rb_obj_methods, 0);
|
rb_define_method(rb_mKernel, "methods", rb_obj_methods, 0);
|
||||||
rb_define_method(rb_mKernel, "public_methods", rb_obj_methods, 0);
|
rb_define_method(rb_mKernel, "public_methods", rb_obj_methods, 0);
|
||||||
rb_define_method(rb_mKernel, "singleton_methods", rb_obj_singleton_methods, 0);
|
rb_define_method(rb_mKernel, "singleton_methods", rb_obj_singleton_methods, -1);
|
||||||
rb_define_method(rb_mKernel, "protected_methods", rb_obj_protected_methods, 0);
|
rb_define_method(rb_mKernel, "protected_methods", rb_obj_protected_methods, 0);
|
||||||
rb_define_method(rb_mKernel, "private_methods", rb_obj_private_methods, 0);
|
rb_define_method(rb_mKernel, "private_methods", rb_obj_private_methods, 0);
|
||||||
rb_define_method(rb_mKernel, "instance_variables", rb_obj_instance_variables, 0);
|
rb_define_method(rb_mKernel, "instance_variables", rb_obj_instance_variables, 0);
|
||||||
|
|
110
pack.c
110
pack.c
|
@ -331,7 +331,7 @@ pack_pack(ary, fmt)
|
||||||
static char *nul10 = "\0\0\0\0\0\0\0\0\0\0";
|
static char *nul10 = "\0\0\0\0\0\0\0\0\0\0";
|
||||||
static char *spc10 = " ";
|
static char *spc10 = " ";
|
||||||
char *p, *pend;
|
char *p, *pend;
|
||||||
VALUE res, from;
|
VALUE res, from, associates = 0;
|
||||||
char type;
|
char type;
|
||||||
int items, len, idx;
|
int items, len, idx;
|
||||||
char *ptr;
|
char *ptr;
|
||||||
|
@ -343,7 +343,7 @@ pack_pack(ary, fmt)
|
||||||
StringValue(fmt);
|
StringValue(fmt);
|
||||||
p = RSTRING(fmt)->ptr;
|
p = RSTRING(fmt)->ptr;
|
||||||
pend = p + RSTRING(fmt)->len;
|
pend = p + RSTRING(fmt)->len;
|
||||||
res = rb_str_new(0, 0);
|
res = rb_str_buf_new(0);
|
||||||
|
|
||||||
items = RARRAY(ary)->len;
|
items = RARRAY(ary)->len;
|
||||||
idx = 0;
|
idx = 0;
|
||||||
|
@ -405,15 +405,15 @@ pack_pack(ary, fmt)
|
||||||
case 'A':
|
case 'A':
|
||||||
case 'Z':
|
case 'Z':
|
||||||
if (plen >= len)
|
if (plen >= len)
|
||||||
rb_str_cat(res, ptr, len);
|
rb_str_buf_cat(res, ptr, len);
|
||||||
else {
|
else {
|
||||||
rb_str_cat(res, ptr, plen);
|
rb_str_buf_cat(res, ptr, plen);
|
||||||
len -= plen;
|
len -= plen;
|
||||||
while (len >= 10) {
|
while (len >= 10) {
|
||||||
rb_str_cat(res, (type == 'A')?spc10:nul10, 10);
|
rb_str_buf_cat(res, (type == 'A')?spc10:nul10, 10);
|
||||||
len -= 10;
|
len -= 10;
|
||||||
}
|
}
|
||||||
rb_str_cat(res, (type == 'A')?spc10:nul10, len);
|
rb_str_buf_cat(res, (type == 'A')?spc10:nul10, len);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -433,7 +433,7 @@ pack_pack(ary, fmt)
|
||||||
byte >>= 1;
|
byte >>= 1;
|
||||||
else {
|
else {
|
||||||
char c = byte & 0xff;
|
char c = byte & 0xff;
|
||||||
rb_str_cat(res, &c, 1);
|
rb_str_buf_cat(res, &c, 1);
|
||||||
byte = 0;
|
byte = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,11 +441,9 @@ pack_pack(ary, fmt)
|
||||||
char c;
|
char c;
|
||||||
byte >>= 7 - (len & 7);
|
byte >>= 7 - (len & 7);
|
||||||
c = byte & 0xff;
|
c = byte & 0xff;
|
||||||
rb_str_cat(res, &c, 1);
|
rb_str_buf_cat(res, &c, 1);
|
||||||
}
|
}
|
||||||
len = RSTRING(res)->len;
|
rb_str_buf_cat(res, 0, j);
|
||||||
rb_str_resize(res, len+j);
|
|
||||||
MEMZERO(RSTRING(res)->ptr+len, char, j);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -464,7 +462,7 @@ pack_pack(ary, fmt)
|
||||||
byte <<= 1;
|
byte <<= 1;
|
||||||
else {
|
else {
|
||||||
char c = byte & 0xff;
|
char c = byte & 0xff;
|
||||||
rb_str_cat(res, &c, 1);
|
rb_str_buf_cat(res, &c, 1);
|
||||||
byte = 0;
|
byte = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -472,11 +470,9 @@ pack_pack(ary, fmt)
|
||||||
char c;
|
char c;
|
||||||
byte <<= 7 - (len & 7);
|
byte <<= 7 - (len & 7);
|
||||||
c = byte & 0xff;
|
c = byte & 0xff;
|
||||||
rb_str_cat(res, &c, 1);
|
rb_str_buf_cat(res, &c, 1);
|
||||||
}
|
}
|
||||||
len = RSTRING(res)->len;
|
rb_str_buf_cat(res, 0, j);
|
||||||
rb_str_resize(res, len+j);
|
|
||||||
MEMZERO(RSTRING(res)->ptr+len, char, j);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -498,17 +494,15 @@ pack_pack(ary, fmt)
|
||||||
byte >>= 4;
|
byte >>= 4;
|
||||||
else {
|
else {
|
||||||
char c = byte & 0xff;
|
char c = byte & 0xff;
|
||||||
rb_str_cat(res, &c, 1);
|
rb_str_buf_cat(res, &c, 1);
|
||||||
byte = 0;
|
byte = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (len & 1) {
|
if (len & 1) {
|
||||||
char c = byte & 0xff;
|
char c = byte & 0xff;
|
||||||
rb_str_cat(res, &c, 1);
|
rb_str_buf_cat(res, &c, 1);
|
||||||
}
|
}
|
||||||
len = RSTRING(res)->len;
|
rb_str_buf_cat(res, 0, j);
|
||||||
rb_str_resize(res, len+j);
|
|
||||||
MEMZERO(RSTRING(res)->ptr+len, char, j);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -530,17 +524,15 @@ pack_pack(ary, fmt)
|
||||||
byte <<= 4;
|
byte <<= 4;
|
||||||
else {
|
else {
|
||||||
char c = byte & 0xff;
|
char c = byte & 0xff;
|
||||||
rb_str_cat(res, &c, 1);
|
rb_str_buf_cat(res, &c, 1);
|
||||||
byte = 0;
|
byte = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (len & 1) {
|
if (len & 1) {
|
||||||
char c = byte & 0xff;
|
char c = byte & 0xff;
|
||||||
rb_str_cat(res, &c, 1);
|
rb_str_buf_cat(res, &c, 1);
|
||||||
}
|
}
|
||||||
len = RSTRING(res)->len;
|
rb_str_buf_cat(res, 0, j);
|
||||||
rb_str_resize(res, len+j);
|
|
||||||
MEMZERO(RSTRING(res)->ptr+len, char, j);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -556,7 +548,7 @@ pack_pack(ary, fmt)
|
||||||
else {
|
else {
|
||||||
c = NUM2INT(from);
|
c = NUM2INT(from);
|
||||||
}
|
}
|
||||||
rb_str_cat(res, &c, sizeof(char));
|
rb_str_buf_cat(res, &c, sizeof(char));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -570,7 +562,7 @@ pack_pack(ary, fmt)
|
||||||
else {
|
else {
|
||||||
s = NUM2INT(from);
|
s = NUM2INT(from);
|
||||||
}
|
}
|
||||||
rb_str_cat(res, OFF16(&s), NATINT_LEN(short,2));
|
rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -584,7 +576,7 @@ pack_pack(ary, fmt)
|
||||||
else {
|
else {
|
||||||
i = NUM2UINT(from);
|
i = NUM2UINT(from);
|
||||||
}
|
}
|
||||||
rb_str_cat(res, (char*)&i, sizeof(int));
|
rb_str_buf_cat(res, (char*)&i, sizeof(int));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -598,7 +590,7 @@ pack_pack(ary, fmt)
|
||||||
else {
|
else {
|
||||||
l = NATINT_U32(from);
|
l = NATINT_U32(from);
|
||||||
}
|
}
|
||||||
rb_str_cat(res, OFF32(&l), NATINT_LEN(long,4));
|
rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -612,7 +604,7 @@ pack_pack(ary, fmt)
|
||||||
s = NUM2INT(from);
|
s = NUM2INT(from);
|
||||||
}
|
}
|
||||||
s = htons(s);
|
s = htons(s);
|
||||||
rb_str_cat(res, OFF16B(&s), NATINT_LEN(short,2));
|
rb_str_buf_cat(res, OFF16B(&s), NATINT_LEN(short,2));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -626,7 +618,7 @@ pack_pack(ary, fmt)
|
||||||
l = NATINT_U32(from);
|
l = NATINT_U32(from);
|
||||||
}
|
}
|
||||||
l = htonl(l);
|
l = htonl(l);
|
||||||
rb_str_cat(res, OFF32B(&l), NATINT_LEN(long,4));
|
rb_str_buf_cat(res, OFF32B(&l), NATINT_LEN(long,4));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -640,7 +632,7 @@ pack_pack(ary, fmt)
|
||||||
s = NUM2INT(from);
|
s = NUM2INT(from);
|
||||||
}
|
}
|
||||||
s = htovs(s);
|
s = htovs(s);
|
||||||
rb_str_cat(res, OFF16(&s), NATINT_LEN(short,2));
|
rb_str_buf_cat(res, OFF16(&s), NATINT_LEN(short,2));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -654,7 +646,7 @@ pack_pack(ary, fmt)
|
||||||
l = NATINT_U32(from);
|
l = NATINT_U32(from);
|
||||||
}
|
}
|
||||||
l = htovl(l);
|
l = htovl(l);
|
||||||
rb_str_cat(res, OFF32(&l), NATINT_LEN(long,4));
|
rb_str_buf_cat(res, OFF32(&l), NATINT_LEN(long,4));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -674,7 +666,7 @@ pack_pack(ary, fmt)
|
||||||
f = (float)NUM2INT(from);
|
f = (float)NUM2INT(from);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rb_str_cat(res, (char*)&f, sizeof(float));
|
rb_str_buf_cat(res, (char*)&f, sizeof(float));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -695,7 +687,7 @@ pack_pack(ary, fmt)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
f = HTOVF(f,ftmp);
|
f = HTOVF(f,ftmp);
|
||||||
rb_str_cat(res, (char*)&f, sizeof(float));
|
rb_str_buf_cat(res, (char*)&f, sizeof(float));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -716,7 +708,7 @@ pack_pack(ary, fmt)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
d = HTOVD(d,dtmp);
|
d = HTOVD(d,dtmp);
|
||||||
rb_str_cat(res, (char*)&d, sizeof(double));
|
rb_str_buf_cat(res, (char*)&d, sizeof(double));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -736,7 +728,7 @@ pack_pack(ary, fmt)
|
||||||
d = (double)NUM2INT(from);
|
d = (double)NUM2INT(from);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
rb_str_cat(res, (char*)&d, sizeof(double));
|
rb_str_buf_cat(res, (char*)&d, sizeof(double));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -757,7 +749,7 @@ pack_pack(ary, fmt)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
f = HTONF(f,ftmp);
|
f = HTONF(f,ftmp);
|
||||||
rb_str_cat(res, (char*)&f, sizeof(float));
|
rb_str_buf_cat(res, (char*)&f, sizeof(float));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -778,25 +770,26 @@ pack_pack(ary, fmt)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
d = HTOND(d,dtmp);
|
d = HTOND(d,dtmp);
|
||||||
rb_str_cat(res, (char*)&d, sizeof(double));
|
rb_str_buf_cat(res, (char*)&d, sizeof(double));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
grow:
|
grow:
|
||||||
while (len >= 10) {
|
while (len >= 10) {
|
||||||
rb_str_cat(res, nul10, 10);
|
rb_str_buf_cat(res, nul10, 10);
|
||||||
len -= 10;
|
len -= 10;
|
||||||
}
|
}
|
||||||
rb_str_cat(res, nul10, len);
|
rb_str_buf_cat(res, nul10, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'X':
|
case 'X':
|
||||||
shrink:
|
shrink:
|
||||||
if (RSTRING(res)->len < len)
|
plen = RSTRING(res)->len;
|
||||||
|
if (plen < len)
|
||||||
rb_raise(rb_eArgError, "X outside of string");
|
rb_raise(rb_eArgError, "X outside of string");
|
||||||
RSTRING(res)->len -= len;
|
RSTRING(res)->len = plen - len;
|
||||||
RSTRING(res)->ptr[RSTRING(res)->len] = '\0';
|
RSTRING(res)->ptr[plen - len] = '\0';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '@':
|
case '@':
|
||||||
|
@ -822,7 +815,7 @@ pack_pack(ary, fmt)
|
||||||
l = NUM2ULONG(from);
|
l = NUM2ULONG(from);
|
||||||
}
|
}
|
||||||
le = uv_to_utf8(buf, l);
|
le = uv_to_utf8(buf, l);
|
||||||
rb_str_cat(res, (char*)buf, le);
|
rb_str_buf_cat(res, (char*)buf, le);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -879,8 +872,11 @@ pack_pack(ary, fmt)
|
||||||
StringValue(from);
|
StringValue(from);
|
||||||
t = RSTRING(from)->ptr;
|
t = RSTRING(from)->ptr;
|
||||||
}
|
}
|
||||||
rb_str_associate(res, from);
|
if (!associates) {
|
||||||
rb_str_cat(res, (char*)&t, sizeof(char*));
|
associates = rb_ary_new();
|
||||||
|
}
|
||||||
|
rb_ary_push(associates, from);
|
||||||
|
rb_str_buf_cat(res, (char*)&t, sizeof(char*));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -891,13 +887,12 @@ pack_pack(ary, fmt)
|
||||||
char c, *bufs, *bufe;
|
char c, *bufs, *bufe;
|
||||||
|
|
||||||
from = NEXTFROM;
|
from = NEXTFROM;
|
||||||
|
|
||||||
if (TYPE(from) == T_BIGNUM) {
|
if (TYPE(from) == T_BIGNUM) {
|
||||||
VALUE big128 = rb_uint2big(128);
|
VALUE big128 = rb_uint2big(128);
|
||||||
while (TYPE(from) == T_BIGNUM) {
|
while (TYPE(from) == T_BIGNUM) {
|
||||||
from = rb_big_divmod(from, big128);
|
from = rb_big_divmod(from, big128);
|
||||||
c = NUM2INT(RARRAY(from)->ptr[1]) | 0x80; /* mod */
|
c = NUM2INT(RARRAY(from)->ptr[1]) | 0x80; /* mod */
|
||||||
rb_str_cat(buf, &c, sizeof(char));
|
rb_str_buf_cat(buf, &c, sizeof(char));
|
||||||
from = RARRAY(from)->ptr[0]; /* div */
|
from = RARRAY(from)->ptr[0]; /* div */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -909,7 +904,7 @@ pack_pack(ary, fmt)
|
||||||
|
|
||||||
while (ul) {
|
while (ul) {
|
||||||
c = ((ul & 0x7f) | 0x80);
|
c = ((ul & 0x7f) | 0x80);
|
||||||
rb_str_cat(buf, &c, sizeof(char));
|
rb_str_buf_cat(buf, &c, sizeof(char));
|
||||||
ul >>= 7;
|
ul >>= 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -922,11 +917,11 @@ pack_pack(ary, fmt)
|
||||||
*bufs++ = *bufe;
|
*bufs++ = *bufe;
|
||||||
*bufe-- = c;
|
*bufe-- = c;
|
||||||
}
|
}
|
||||||
rb_str_cat(res, RSTRING(buf)->ptr, RSTRING(buf)->len);
|
rb_str_buf_cat(res, RSTRING(buf)->ptr, RSTRING(buf)->len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c = 0;
|
c = 0;
|
||||||
rb_str_cat(res, &c, sizeof(char));
|
rb_str_buf_cat(res, &c, sizeof(char));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -936,6 +931,9 @@ pack_pack(ary, fmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (associates) {
|
||||||
|
rb_str_associate(res, associates);
|
||||||
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,7 +982,7 @@ encodes(str, s, len, type)
|
||||||
buff[i++] = padding;
|
buff[i++] = padding;
|
||||||
}
|
}
|
||||||
buff[i++] = '\n';
|
buff[i++] = '\n';
|
||||||
rb_str_cat(str, buff, i);
|
rb_str_buf_cat(str, buff, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char hex_table[] = "0123456789ABCDEF";
|
static char hex_table[] = "0123456789ABCDEF";
|
||||||
|
@ -1030,7 +1028,7 @@ qpencode(str, from, len)
|
||||||
prev = '\n';
|
prev = '\n';
|
||||||
}
|
}
|
||||||
if (i > 1024 - 5) {
|
if (i > 1024 - 5) {
|
||||||
rb_str_cat(str, buff, i);
|
rb_str_buf_cat(str, buff, i);
|
||||||
i = 0;
|
i = 0;
|
||||||
}
|
}
|
||||||
s++;
|
s++;
|
||||||
|
@ -1040,7 +1038,7 @@ qpencode(str, from, len)
|
||||||
buff[i++] = '\n';
|
buff[i++] = '\n';
|
||||||
}
|
}
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
rb_str_cat(str, buff, i);
|
rb_str_buf_cat(str, buff, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
308
parse.y
308
parse.y
|
@ -51,6 +51,7 @@ static enum lex_state {
|
||||||
EXPR_BEG, /* ignore newline, +/- is a sign. */
|
EXPR_BEG, /* ignore newline, +/- is a sign. */
|
||||||
EXPR_END, /* newline significant, +/- is a operator. */
|
EXPR_END, /* newline significant, +/- is a operator. */
|
||||||
EXPR_ARG, /* newline significant, +/- is a operator. */
|
EXPR_ARG, /* newline significant, +/- is a operator. */
|
||||||
|
EXPR_CMDARG, /* newline significant, +/- is a operator. */
|
||||||
EXPR_MID, /* newline significant, +/- is a operator. */
|
EXPR_MID, /* newline significant, +/- is a operator. */
|
||||||
EXPR_FNAME, /* ignore newline, no reserved words. */
|
EXPR_FNAME, /* ignore newline, no reserved words. */
|
||||||
EXPR_DOT, /* right after `.' or `::', no reserved words. */
|
EXPR_DOT, /* right after `.' or `::', no reserved words. */
|
||||||
|
@ -63,32 +64,40 @@ typedef unsigned LONG_LONG stack_type;
|
||||||
typedef unsigned long stack_type;
|
typedef unsigned long stack_type;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int cond_nest = 0;
|
|
||||||
static stack_type cond_stack = 0;
|
static stack_type cond_stack = 0;
|
||||||
#define COND_PUSH do {\
|
#define COND_PUSH(n) do {\
|
||||||
cond_nest++;\
|
cond_stack = (cond_stack<<1)|((n)&1);\
|
||||||
cond_stack = (cond_stack<<1)|1;\
|
|
||||||
} while(0)
|
} while(0)
|
||||||
#define COND_POP do {\
|
#define COND_POP() do {\
|
||||||
cond_nest--;\
|
|
||||||
cond_stack >>= 1;\
|
cond_stack >>= 1;\
|
||||||
} while (0)
|
} while (0)
|
||||||
#define COND_P() (cond_nest > 0 && (cond_stack&1))
|
#define COND_LEXPOP() do {\
|
||||||
|
int last = COND_P();\
|
||||||
|
cond_stack >>= 1;\
|
||||||
|
if (last) cond_stack |= 1;\
|
||||||
|
} while (0)
|
||||||
|
#define COND_P() (cond_stack&1)
|
||||||
|
|
||||||
static stack_type cmdarg_stack = 0;
|
static stack_type cmdarg_stack = 0;
|
||||||
#define CMDARG_PUSH do {\
|
#define CMDARG_PUSH(n) do {\
|
||||||
cmdarg_stack = (cmdarg_stack<<1)|1;\
|
cmdarg_stack = (cmdarg_stack<<1)|((n)&1);\
|
||||||
} while(0)
|
} while(0)
|
||||||
#define CMDARG_POP do {\
|
#define CMDARG_POP() do {\
|
||||||
cmdarg_stack >>= 1;\
|
cmdarg_stack >>= 1;\
|
||||||
} while (0)
|
} while (0)
|
||||||
#define CMDARG_P() (cmdarg_stack && (cmdarg_stack&1))
|
#define CMDARG_LEXPOP() do {\
|
||||||
|
int last = CMDARG_P();\
|
||||||
|
cmdarg_stack >>= 1;\
|
||||||
|
if (last) cmdarg_stack |= 1;\
|
||||||
|
} while (0)
|
||||||
|
#define CMDARG_P() (cmdarg_stack&1)
|
||||||
|
|
||||||
static int class_nest = 0;
|
static int class_nest = 0;
|
||||||
static int in_single = 0;
|
static int in_single = 0;
|
||||||
static int in_def = 0;
|
static int in_def = 0;
|
||||||
static int compile_for_eval = 0;
|
static int compile_for_eval = 0;
|
||||||
static ID cur_mid = 0;
|
static ID cur_mid = 0;
|
||||||
|
static ID last_id = 0;
|
||||||
|
|
||||||
static NODE *cond();
|
static NODE *cond();
|
||||||
static NODE *logop();
|
static NODE *logop();
|
||||||
|
@ -104,9 +113,11 @@ static NODE *block_append();
|
||||||
static NODE *list_append();
|
static NODE *list_append();
|
||||||
static NODE *list_concat();
|
static NODE *list_concat();
|
||||||
static NODE *arg_concat();
|
static NODE *arg_concat();
|
||||||
|
static NODE *arg_prepend();
|
||||||
static NODE *call_op();
|
static NODE *call_op();
|
||||||
static int in_defined = 0;
|
static int in_defined = 0;
|
||||||
|
|
||||||
|
static NODE *ret_args();
|
||||||
static NODE *arg_blk_pass();
|
static NODE *arg_blk_pass();
|
||||||
static NODE *new_call();
|
static NODE *new_call();
|
||||||
static NODE *new_fcall();
|
static NODE *new_fcall();
|
||||||
|
@ -133,6 +144,7 @@ static int dyna_in_block();
|
||||||
|
|
||||||
static void top_local_init();
|
static void top_local_init();
|
||||||
static void top_local_setup();
|
static void top_local_setup();
|
||||||
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
|
@ -199,7 +211,7 @@ static void top_local_setup();
|
||||||
%type <val> literal numeric
|
%type <val> literal numeric
|
||||||
%type <node> compstmt stmts stmt expr arg primary command command_call method_call
|
%type <node> compstmt stmts stmt expr arg primary command command_call method_call
|
||||||
%type <node> if_tail opt_else case_body cases rescue exc_list exc_var ensure
|
%type <node> if_tail opt_else case_body cases rescue exc_list exc_var ensure
|
||||||
%type <node> args ret_args when_args call_args paren_args opt_paren_args
|
%type <node> args when_args call_args call_args2 open_args paren_args opt_paren_args
|
||||||
%type <node> command_args aref_args opt_block_arg block_arg var_ref
|
%type <node> command_args aref_args opt_block_arg block_arg var_ref
|
||||||
%type <node> mrhs mrhs_basic superclass block_call block_command
|
%type <node> mrhs mrhs_basic superclass block_call block_command
|
||||||
%type <node> f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg
|
%type <node> f_arglist f_args f_optarg f_opt f_block_arg opt_f_block_arg
|
||||||
|
@ -228,9 +240,11 @@ static void top_local_setup();
|
||||||
%token <id> tOP_ASGN /* +=, -= etc. */
|
%token <id> tOP_ASGN /* +=, -= etc. */
|
||||||
%token tASSOC /* => */
|
%token tASSOC /* => */
|
||||||
%token tLPAREN /* ( */
|
%token tLPAREN /* ( */
|
||||||
|
%token tLPAREN_ARG /* ( */
|
||||||
%token tRPAREN /* ) */
|
%token tRPAREN /* ) */
|
||||||
%token tLBRACK /* [ */
|
%token tLBRACK /* [ */
|
||||||
%token tLBRACE /* { */
|
%token tLBRACE /* { */
|
||||||
|
%token tLBRACE_ARG /* { */
|
||||||
%token tSTAR /* * */
|
%token tSTAR /* * */
|
||||||
%token tAMPER /* & */
|
%token tAMPER /* & */
|
||||||
%token tSYMBEG
|
%token tSYMBEG
|
||||||
|
@ -420,19 +434,19 @@ stmt : kALIAS fitem {lex_state = EXPR_FNAME;} fitem
|
||||||
}
|
}
|
||||||
| expr
|
| expr
|
||||||
|
|
||||||
expr : kRETURN ret_args
|
expr : kRETURN call_args
|
||||||
{
|
{
|
||||||
if (!compile_for_eval && !in_def && !in_single)
|
if (!compile_for_eval && !in_def && !in_single)
|
||||||
yyerror("return appeared outside of method");
|
yyerror("return appeared outside of method");
|
||||||
$$ = NEW_RETURN($2);
|
$$ = NEW_RETURN(ret_args($2));
|
||||||
}
|
}
|
||||||
| kBREAK ret_args
|
| kBREAK call_args
|
||||||
{
|
{
|
||||||
$$ = NEW_BREAK($2);
|
$$ = NEW_BREAK(ret_args($2));
|
||||||
}
|
}
|
||||||
| kNEXT ret_args
|
| kNEXT call_args
|
||||||
{
|
{
|
||||||
$$ = NEW_NEXT($2);
|
$$ = NEW_NEXT(ret_args($2));
|
||||||
}
|
}
|
||||||
| command_call
|
| command_call
|
||||||
| expr kAND expr
|
| expr kAND expr
|
||||||
|
@ -493,9 +507,9 @@ command : operation command_args
|
||||||
$$ = new_super($2);
|
$$ = new_super($2);
|
||||||
fixpos($$, $2);
|
fixpos($$, $2);
|
||||||
}
|
}
|
||||||
| kYIELD ret_args
|
| kYIELD call_args
|
||||||
{
|
{
|
||||||
$$ = NEW_YIELD($2);
|
$$ = NEW_YIELD(ret_args($2));
|
||||||
fixpos($$, $2);
|
fixpos($$, $2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1001,9 +1015,90 @@ call_args : command
|
||||||
}
|
}
|
||||||
| block_arg
|
| block_arg
|
||||||
|
|
||||||
command_args : {CMDARG_PUSH;} call_args
|
call_args2 : arg ',' args opt_block_arg
|
||||||
{
|
{
|
||||||
CMDARG_POP;
|
$$ = arg_blk_pass(list_append(NEW_LIST($1),$3), $4);
|
||||||
|
}
|
||||||
|
| arg ',' tSTAR arg opt_block_arg
|
||||||
|
{
|
||||||
|
value_expr($1);
|
||||||
|
value_expr($4);
|
||||||
|
$$ = arg_concat(NEW_LIST($1), $4);
|
||||||
|
$$ = arg_blk_pass($$, $5);
|
||||||
|
}
|
||||||
|
| arg ',' args ',' tSTAR arg opt_block_arg
|
||||||
|
{
|
||||||
|
value_expr($1);
|
||||||
|
value_expr($6);
|
||||||
|
$$ = arg_concat(list_append($1,$3), $6);
|
||||||
|
$$ = arg_blk_pass($$, $7);
|
||||||
|
}
|
||||||
|
| assocs opt_block_arg
|
||||||
|
{
|
||||||
|
$$ = NEW_LIST(NEW_HASH($1));
|
||||||
|
$$ = arg_blk_pass($$, $2);
|
||||||
|
}
|
||||||
|
| assocs ',' tSTAR arg opt_block_arg
|
||||||
|
{
|
||||||
|
value_expr($4);
|
||||||
|
$$ = arg_concat(NEW_LIST(NEW_HASH($1)), $4);
|
||||||
|
$$ = arg_blk_pass($$, $5);
|
||||||
|
}
|
||||||
|
| arg ',' assocs opt_block_arg
|
||||||
|
{
|
||||||
|
$$ = list_append(NEW_LIST($1), NEW_HASH($3));
|
||||||
|
$$ = arg_blk_pass($$, $4);
|
||||||
|
}
|
||||||
|
| arg ',' args ',' assocs opt_block_arg
|
||||||
|
{
|
||||||
|
value_expr($1);
|
||||||
|
value_expr($6);
|
||||||
|
$$ = list_append(list_append($1,$3), NEW_HASH($5));
|
||||||
|
$$ = arg_blk_pass($$, $6);
|
||||||
|
}
|
||||||
|
| arg ',' assocs ',' tSTAR arg opt_block_arg
|
||||||
|
{
|
||||||
|
value_expr($1);
|
||||||
|
value_expr($6);
|
||||||
|
$$ = arg_concat(list_append(NEW_LIST($1), NEW_HASH($3)), $6);
|
||||||
|
$$ = arg_blk_pass($$, $7);
|
||||||
|
}
|
||||||
|
| arg ',' args ',' assocs ',' tSTAR arg opt_block_arg
|
||||||
|
{
|
||||||
|
value_expr($1);
|
||||||
|
value_expr($8);
|
||||||
|
$$ = arg_concat(list_append(list_append(NEW_LIST($1), $3), NEW_HASH($5)), $8);
|
||||||
|
$$ = arg_blk_pass($$, $9);
|
||||||
|
}
|
||||||
|
| tSTAR arg opt_block_arg
|
||||||
|
{
|
||||||
|
value_expr($2);
|
||||||
|
$$ = arg_blk_pass(NEW_RESTARGS($2), $3);
|
||||||
|
}
|
||||||
|
| block_arg
|
||||||
|
|
||||||
|
command_args : {
|
||||||
|
$<num>$ = cmdarg_stack;
|
||||||
|
CMDARG_PUSH(1);
|
||||||
|
}
|
||||||
|
open_args
|
||||||
|
{
|
||||||
|
/* CMDARG_POP() */
|
||||||
|
cmdarg_stack = $<num>1;
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
|
|
||||||
|
open_args : call_args
|
||||||
|
| tLPAREN_ARG ')'
|
||||||
|
{
|
||||||
|
rb_warning("%s (...) interpreted as method call",
|
||||||
|
rb_id2name(last_id));
|
||||||
|
$$ = 0;
|
||||||
|
}
|
||||||
|
| tLPAREN_ARG call_args2 ')'
|
||||||
|
{
|
||||||
|
rb_warning("%s (...) interpreted as method call",
|
||||||
|
rb_id2name(last_id));
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1053,20 +1148,6 @@ mrhs_basic : args ',' arg
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret_args : call_args
|
|
||||||
{
|
|
||||||
$$ = $1;
|
|
||||||
if ($1) {
|
|
||||||
if (nd_type($1) == NODE_ARRAY &&
|
|
||||||
$1->nd_next == 0) {
|
|
||||||
$$ = $1->nd_head;
|
|
||||||
}
|
|
||||||
else if (nd_type($1) == NODE_BLOCK_PASS) {
|
|
||||||
rb_compile_error("block argument should not be given");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
primary : literal
|
primary : literal
|
||||||
{
|
{
|
||||||
$$ = NEW_LIT($1);
|
$$ = NEW_LIT($1);
|
||||||
|
@ -1104,6 +1185,11 @@ primary : literal
|
||||||
}
|
}
|
||||||
fixpos($$, $2);
|
fixpos($$, $2);
|
||||||
}
|
}
|
||||||
|
| tLPAREN_ARG expr ')'
|
||||||
|
{
|
||||||
|
rb_warning("%s (...) interpreted as command call", rb_id2name(last_id));
|
||||||
|
$$ = $2;
|
||||||
|
}
|
||||||
| tLPAREN compstmt ')'
|
| tLPAREN compstmt ')'
|
||||||
{
|
{
|
||||||
$$ = $2;
|
$$ = $2;
|
||||||
|
@ -1140,10 +1226,10 @@ primary : literal
|
||||||
yyerror("return appeared outside of method");
|
yyerror("return appeared outside of method");
|
||||||
$$ = NEW_RETURN(0);
|
$$ = NEW_RETURN(0);
|
||||||
}
|
}
|
||||||
| kYIELD '(' ret_args ')'
|
| kYIELD '(' call_args ')'
|
||||||
{
|
{
|
||||||
value_expr($3);
|
value_expr($3);
|
||||||
$$ = NEW_YIELD($3);
|
$$ = NEW_YIELD(ret_args($3));
|
||||||
}
|
}
|
||||||
| kYIELD '(' ')'
|
| kYIELD '(' ')'
|
||||||
{
|
{
|
||||||
|
@ -1191,7 +1277,7 @@ primary : literal
|
||||||
$$ = NEW_UNLESS(cond($2), $4, $5);
|
$$ = NEW_UNLESS(cond($2), $4, $5);
|
||||||
fixpos($$, $2);
|
fixpos($$, $2);
|
||||||
}
|
}
|
||||||
| kWHILE {COND_PUSH;} expr do {COND_POP;}
|
| kWHILE {COND_PUSH(1);} expr do {COND_POP();}
|
||||||
compstmt
|
compstmt
|
||||||
kEND
|
kEND
|
||||||
{
|
{
|
||||||
|
@ -1199,7 +1285,7 @@ primary : literal
|
||||||
$$ = NEW_WHILE(cond($3), $6, 1);
|
$$ = NEW_WHILE(cond($3), $6, 1);
|
||||||
fixpos($$, $3);
|
fixpos($$, $3);
|
||||||
}
|
}
|
||||||
| kUNTIL {COND_PUSH;} expr do {COND_POP;}
|
| kUNTIL {COND_PUSH(1);} expr do {COND_POP();}
|
||||||
compstmt
|
compstmt
|
||||||
kEND
|
kEND
|
||||||
{
|
{
|
||||||
|
@ -1219,7 +1305,7 @@ primary : literal
|
||||||
{
|
{
|
||||||
$$ = $3;
|
$$ = $3;
|
||||||
}
|
}
|
||||||
| kFOR block_var kIN {COND_PUSH;} expr do {COND_POP;}
|
| kFOR block_var kIN {COND_PUSH(1);} expr do {COND_POP();}
|
||||||
compstmt
|
compstmt
|
||||||
kEND
|
kEND
|
||||||
{
|
{
|
||||||
|
@ -1407,6 +1493,16 @@ do_block : kDO_BLOCK
|
||||||
fixpos($$, $3?$3:$4);
|
fixpos($$, $3?$3:$4);
|
||||||
dyna_pop($<vars>2);
|
dyna_pop($<vars>2);
|
||||||
}
|
}
|
||||||
|
| tLBRACE_ARG {$<vars>$ = dyna_push();}
|
||||||
|
opt_block_var
|
||||||
|
compstmt
|
||||||
|
'}'
|
||||||
|
{
|
||||||
|
$$ = NEW_ITER($3, 0, $4);
|
||||||
|
fixpos($$, $3?$3:$4);
|
||||||
|
dyna_pop($<vars>2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
block_call : command do_block
|
block_call : command do_block
|
||||||
{
|
{
|
||||||
|
@ -1913,6 +2009,7 @@ yyerror(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int heredoc_end;
|
static int heredoc_end;
|
||||||
|
static int command_start = Qtrue;
|
||||||
|
|
||||||
int ruby_in_compile = 0;
|
int ruby_in_compile = 0;
|
||||||
int ruby__end__seen;
|
int ruby__end__seen;
|
||||||
|
@ -1958,9 +2055,9 @@ yycompile(f, line)
|
||||||
ruby_debug_lines = 0;
|
ruby_debug_lines = 0;
|
||||||
compile_for_eval = 0;
|
compile_for_eval = 0;
|
||||||
ruby_in_compile = 0;
|
ruby_in_compile = 0;
|
||||||
cond_nest = 0;
|
|
||||||
cond_stack = 0;
|
cond_stack = 0;
|
||||||
cmdarg_stack = 0;
|
cmdarg_stack = 0;
|
||||||
|
command_start = 1;
|
||||||
class_nest = 0;
|
class_nest = 0;
|
||||||
in_single = 0;
|
in_single = 0;
|
||||||
in_def = 0;
|
in_def = 0;
|
||||||
|
@ -2711,13 +2808,6 @@ here_document(term, indent)
|
||||||
|
|
||||||
lex_pbeg = lex_p = RSTRING(line)->ptr;
|
lex_pbeg = lex_p = RSTRING(line)->ptr;
|
||||||
lex_pend = lex_p + RSTRING(line)->len;
|
lex_pend = lex_p + RSTRING(line)->len;
|
||||||
#if 0
|
|
||||||
if (indent) {
|
|
||||||
while (*lex_p && *lex_p == '\t') {
|
|
||||||
lex_p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
retry:
|
retry:
|
||||||
switch (parse_string(term, '\n', '\n')) {
|
switch (parse_string(term, '\n', '\n')) {
|
||||||
case tSTRING:
|
case tSTRING:
|
||||||
|
@ -2791,13 +2881,18 @@ arg_ambiguous()
|
||||||
double strtod ();
|
double strtod ();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define IS_ARG() (lex_state == EXPR_ARG || lex_state == EXPR_CMDARG)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
yylex()
|
yylex()
|
||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
int space_seen = 0;
|
int space_seen = 0;
|
||||||
|
int cmd_state;
|
||||||
struct kwtable *kw;
|
struct kwtable *kw;
|
||||||
|
|
||||||
|
cmd_state = command_start;
|
||||||
|
command_start = Qfalse;
|
||||||
retry:
|
retry:
|
||||||
switch (c = nextc()) {
|
switch (c = nextc()) {
|
||||||
case '\0': /* NUL */
|
case '\0': /* NUL */
|
||||||
|
@ -2827,6 +2922,7 @@ yylex()
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
command_start = Qtrue;
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
return '\n';
|
return '\n';
|
||||||
|
|
||||||
|
@ -2846,7 +2942,7 @@ yylex()
|
||||||
return tOP_ASGN;
|
return tOP_ASGN;
|
||||||
}
|
}
|
||||||
pushback(c);
|
pushback(c);
|
||||||
if (lex_state == EXPR_ARG && space_seen && !ISSPACE(c)){
|
if (IS_ARG() && space_seen && !ISSPACE(c)){
|
||||||
rb_warning("`*' interpreted as argument prefix");
|
rb_warning("`*' interpreted as argument prefix");
|
||||||
c = tSTAR;
|
c = tSTAR;
|
||||||
}
|
}
|
||||||
|
@ -2913,7 +3009,7 @@ yylex()
|
||||||
c = nextc();
|
c = nextc();
|
||||||
if (c == '<' &&
|
if (c == '<' &&
|
||||||
lex_state != EXPR_END && lex_state != EXPR_CLASS &&
|
lex_state != EXPR_END && lex_state != EXPR_CLASS &&
|
||||||
(lex_state != EXPR_ARG || space_seen)) {
|
(!IS_ARG() || space_seen)) {
|
||||||
int c2 = nextc();
|
int c2 = nextc();
|
||||||
int indent = 0;
|
int indent = 0;
|
||||||
if (c2 == '-') {
|
if (c2 == '-') {
|
||||||
|
@ -2980,7 +3076,7 @@ yylex()
|
||||||
rb_compile_error("incomplete character syntax");
|
rb_compile_error("incomplete character syntax");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (lex_state == EXPR_ARG && ISSPACE(c)){
|
if (IS_ARG() && ISSPACE(c)){
|
||||||
pushback(c);
|
pushback(c);
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
return '?';
|
return '?';
|
||||||
|
@ -3009,8 +3105,8 @@ yylex()
|
||||||
return tOP_ASGN;
|
return tOP_ASGN;
|
||||||
}
|
}
|
||||||
pushback(c);
|
pushback(c);
|
||||||
if (lex_state == EXPR_ARG && space_seen && !ISSPACE(c)){
|
if (IS_ARG() && space_seen && !ISSPACE(c)){
|
||||||
rb_warning("`&' interpreted as argument prefix");
|
rb_warning("`&' interpeted as argument prefix");
|
||||||
c = tAMPER;
|
c = tAMPER;
|
||||||
}
|
}
|
||||||
else if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
|
else if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
|
||||||
|
@ -3054,8 +3150,8 @@ yylex()
|
||||||
return tOP_ASGN;
|
return tOP_ASGN;
|
||||||
}
|
}
|
||||||
if (lex_state == EXPR_BEG || lex_state == EXPR_MID ||
|
if (lex_state == EXPR_BEG || lex_state == EXPR_MID ||
|
||||||
(lex_state == EXPR_ARG && space_seen && !ISSPACE(c))) {
|
(IS_ARG() && space_seen && !ISSPACE(c))) {
|
||||||
if (lex_state == EXPR_ARG) arg_ambiguous();
|
if (IS_ARG()) arg_ambiguous();
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
pushback(c);
|
pushback(c);
|
||||||
if (ISDIGIT(c)) {
|
if (ISDIGIT(c)) {
|
||||||
|
@ -3083,8 +3179,8 @@ yylex()
|
||||||
return tOP_ASGN;
|
return tOP_ASGN;
|
||||||
}
|
}
|
||||||
if (lex_state == EXPR_BEG || lex_state == EXPR_MID ||
|
if (lex_state == EXPR_BEG || lex_state == EXPR_MID ||
|
||||||
(lex_state == EXPR_ARG && space_seen && !ISSPACE(c))) {
|
(IS_ARG() && space_seen && !ISSPACE(c))) {
|
||||||
if (lex_state == EXPR_ARG) arg_ambiguous();
|
if (IS_ARG()) arg_ambiguous();
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
pushback(c);
|
pushback(c);
|
||||||
if (ISDIGIT(c)) {
|
if (ISDIGIT(c)) {
|
||||||
|
@ -3276,13 +3372,9 @@ yylex()
|
||||||
|
|
||||||
case ']':
|
case ']':
|
||||||
case '}':
|
case '}':
|
||||||
lex_state = EXPR_END;
|
|
||||||
return c;
|
|
||||||
|
|
||||||
case ')':
|
case ')':
|
||||||
if (cond_nest > 0) {
|
COND_LEXPOP();
|
||||||
cond_stack >>= 1;
|
CMDARG_LEXPOP();
|
||||||
}
|
|
||||||
lex_state = EXPR_END;
|
lex_state = EXPR_END;
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
|
@ -3290,7 +3382,7 @@ yylex()
|
||||||
c = nextc();
|
c = nextc();
|
||||||
if (c == ':') {
|
if (c == ':') {
|
||||||
if (lex_state == EXPR_BEG || lex_state == EXPR_MID ||
|
if (lex_state == EXPR_BEG || lex_state == EXPR_MID ||
|
||||||
(lex_state == EXPR_ARG && space_seen)) {
|
(IS_ARG() && space_seen)) {
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
return tCOLON3;
|
return tCOLON3;
|
||||||
}
|
}
|
||||||
|
@ -3315,7 +3407,7 @@ yylex()
|
||||||
return tOP_ASGN;
|
return tOP_ASGN;
|
||||||
}
|
}
|
||||||
pushback(c);
|
pushback(c);
|
||||||
if (lex_state == EXPR_ARG && space_seen) {
|
if (IS_ARG() && space_seen) {
|
||||||
if (!ISSPACE(c)) {
|
if (!ISSPACE(c)) {
|
||||||
arg_ambiguous();
|
arg_ambiguous();
|
||||||
return parse_regx('/', '/');
|
return parse_regx('/', '/');
|
||||||
|
@ -3333,8 +3425,9 @@ yylex()
|
||||||
pushback(c);
|
pushback(c);
|
||||||
return '^';
|
return '^';
|
||||||
|
|
||||||
case ',':
|
|
||||||
case ';':
|
case ';':
|
||||||
|
command_start = Qtrue;
|
||||||
|
case ',':
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
|
@ -3348,15 +3441,21 @@ yylex()
|
||||||
return '~';
|
return '~';
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
if (cond_nest > 0) {
|
command_start = Qtrue;
|
||||||
cond_stack = (cond_stack<<1)|0;
|
|
||||||
}
|
|
||||||
if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
|
if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
|
||||||
c = tLPAREN;
|
c = tLPAREN;
|
||||||
}
|
}
|
||||||
else if (lex_state == EXPR_ARG && space_seen) {
|
else if (space_seen) {
|
||||||
rb_warning("%s (...) interpreted as method call", tok());
|
if (lex_state == EXPR_CMDARG) {
|
||||||
|
c = tLPAREN_ARG;
|
||||||
}
|
}
|
||||||
|
else if (lex_state == EXPR_ARG) {
|
||||||
|
rb_warning("%s (...) interpreted as method call", tok());
|
||||||
|
c = tLPAREN_ARG;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
COND_PUSH(0);
|
||||||
|
CMDARG_PUSH(0);
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
|
@ -3375,15 +3474,23 @@ yylex()
|
||||||
else if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
|
else if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
|
||||||
c = tLBRACK;
|
c = tLBRACK;
|
||||||
}
|
}
|
||||||
else if (lex_state == EXPR_ARG && space_seen) {
|
else if (IS_ARG() && space_seen) {
|
||||||
c = tLBRACK;
|
c = tLBRACK;
|
||||||
}
|
}
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
|
COND_PUSH(0);
|
||||||
|
CMDARG_PUSH(0);
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
case '{':
|
case '{':
|
||||||
if (lex_state != EXPR_END && lex_state != EXPR_ARG)
|
if (!IS_ARG()) {
|
||||||
|
if (lex_state != EXPR_END)
|
||||||
c = tLBRACE;
|
c = tLBRACE;
|
||||||
|
if (space_seen && CMDARG_P())
|
||||||
|
c = tLBRACE_ARG;
|
||||||
|
}
|
||||||
|
COND_PUSH(0);
|
||||||
|
CMDARG_PUSH(0);
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
return c;
|
return c;
|
||||||
|
|
||||||
|
@ -3446,7 +3553,7 @@ yylex()
|
||||||
yylval.id = '%';
|
yylval.id = '%';
|
||||||
return tOP_ASGN;
|
return tOP_ASGN;
|
||||||
}
|
}
|
||||||
if (lex_state == EXPR_ARG && space_seen && !ISSPACE(c)) {
|
if (IS_ARG() && space_seen && !ISSPACE(c)) {
|
||||||
goto quotation;
|
goto quotation;
|
||||||
}
|
}
|
||||||
lex_state = EXPR_BEG;
|
lex_state = EXPR_BEG;
|
||||||
|
@ -3608,7 +3715,8 @@ yylex()
|
||||||
}
|
}
|
||||||
if (kw->id[0] == kDO) {
|
if (kw->id[0] == kDO) {
|
||||||
if (COND_P()) return kDO_COND;
|
if (COND_P()) return kDO_COND;
|
||||||
if (CMDARG_P()) return kDO_BLOCK;
|
if (CMDARG_P() && state != EXPR_CMDARG && state != EXPR_ARG)
|
||||||
|
return kDO_BLOCK;
|
||||||
return kDO;
|
return kDO;
|
||||||
}
|
}
|
||||||
if (state == EXPR_BEG)
|
if (state == EXPR_BEG)
|
||||||
|
@ -3626,12 +3734,8 @@ yylex()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (lex_state == EXPR_FNAME) {
|
if (lex_state == EXPR_FNAME) {
|
||||||
#if 0
|
|
||||||
if ((c = nextc()) == '=' && !peek('=') && !peek('~') && !peek('>')) {
|
|
||||||
#else
|
|
||||||
if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&
|
if ((c = nextc()) == '=' && !peek('~') && !peek('>') &&
|
||||||
(!peek('=') || lex_p + 1 < lex_pend && lex_p[1] == '>')) {
|
(!peek('=') || lex_p + 1 < lex_pend && lex_p[1] == '>')) {
|
||||||
#endif
|
|
||||||
result = tIDENTIFIER;
|
result = tIDENTIFIER;
|
||||||
tokadd(c);
|
tokadd(c);
|
||||||
}
|
}
|
||||||
|
@ -3648,7 +3752,11 @@ yylex()
|
||||||
}
|
}
|
||||||
if (lex_state == EXPR_BEG ||
|
if (lex_state == EXPR_BEG ||
|
||||||
lex_state == EXPR_DOT ||
|
lex_state == EXPR_DOT ||
|
||||||
lex_state == EXPR_ARG) {
|
lex_state == EXPR_ARG ||
|
||||||
|
lex_state == EXPR_CMDARG) {
|
||||||
|
if (cmd_state)
|
||||||
|
lex_state = EXPR_CMDARG;
|
||||||
|
else
|
||||||
lex_state = EXPR_ARG;
|
lex_state = EXPR_ARG;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3656,7 +3764,7 @@ yylex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tokfix();
|
tokfix();
|
||||||
yylval.id = rb_intern(tok());
|
last_id = yylval.id = rb_intern(tok());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4548,6 +4656,21 @@ logop(type, left, right)
|
||||||
return rb_node_newnode(type, cond1(left, 1), cond1(right, 1), 0);
|
return rb_node_newnode(type, cond1(left, 1), cond1(right, 1), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NODE *
|
||||||
|
ret_args(node)
|
||||||
|
NODE *node;
|
||||||
|
{
|
||||||
|
if (node) {
|
||||||
|
if (nd_type(node) == NODE_ARRAY && node->nd_next == 0) {
|
||||||
|
node = node->nd_head;
|
||||||
|
}
|
||||||
|
else if (nd_type(node) == NODE_BLOCK_PASS) {
|
||||||
|
rb_compile_error("block argument should not be given");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
static NODE *
|
static NODE *
|
||||||
arg_blk_pass(node1, node2)
|
arg_blk_pass(node1, node2)
|
||||||
NODE *node1;
|
NODE *node1;
|
||||||
|
@ -4560,6 +4683,27 @@ arg_blk_pass(node1, node2)
|
||||||
return node1;
|
return node1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static NODE*
|
||||||
|
arg_prepend(node1, node2)
|
||||||
|
NODE *node1, *node2;
|
||||||
|
{
|
||||||
|
switch (nodetype(node2)) {
|
||||||
|
case NODE_ARRAY:
|
||||||
|
return list_concat(NEW_LIST(node1), node2);
|
||||||
|
|
||||||
|
case NODE_RESTARGS:
|
||||||
|
return arg_concat(node1, node2->nd_head);
|
||||||
|
|
||||||
|
case NODE_BLOCK_PASS:
|
||||||
|
node2->nd_body = arg_prepend(node1, node2->nd_body);
|
||||||
|
return node2;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rb_bug("unknown nodetype(%d) for arg_prepend");
|
||||||
|
}
|
||||||
|
return 0; /* not reached */
|
||||||
|
}
|
||||||
|
|
||||||
static NODE*
|
static NODE*
|
||||||
new_call(r,m,a)
|
new_call(r,m,a)
|
||||||
NODE *r;
|
NODE *r;
|
||||||
|
|
95
range.c
95
range.c
|
@ -13,7 +13,7 @@
|
||||||
#include "ruby.h"
|
#include "ruby.h"
|
||||||
|
|
||||||
VALUE rb_cRange;
|
VALUE rb_cRange;
|
||||||
static ID id_cmp, id_beg, id_end, id_excl;
|
static ID id_cmp, id_succ, id_beg, id_end, id_excl;
|
||||||
|
|
||||||
#define EXCL(r) RTEST(rb_ivar_get((r), id_excl))
|
#define EXCL(r) RTEST(rb_ivar_get((r), id_excl))
|
||||||
#define SET_EXCL(r,v) rb_ivar_set((r), id_excl, (v)?Qtrue:Qfalse)
|
#define SET_EXCL(r,v) rb_ivar_set((r), id_excl, (v)?Qtrue:Qfalse)
|
||||||
|
@ -23,6 +23,9 @@ range_check(args)
|
||||||
VALUE *args;
|
VALUE *args;
|
||||||
{
|
{
|
||||||
rb_funcall(args[0], id_cmp, 1, args[1]);
|
rb_funcall(args[0], id_cmp, 1, args[1]);
|
||||||
|
if (!FIXNUM_P(args[0]) && !rb_obj_is_kind_of(args[0], rb_cNumeric)) {
|
||||||
|
rb_funcall(args[0], id_succ, 0, 0);
|
||||||
|
}
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +106,49 @@ range_eq(range, obj)
|
||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
r_eq(a,b)
|
||||||
|
VALUE a, b;
|
||||||
|
{
|
||||||
|
VALUE r;
|
||||||
|
|
||||||
|
if (a == b) return Qtrue;
|
||||||
|
|
||||||
|
if (rb_funcall(a, id_cmp, 1, b) == INT2FIX(0))
|
||||||
|
return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
r_lt(a,b)
|
||||||
|
VALUE a, b;
|
||||||
|
{
|
||||||
|
VALUE r = rb_funcall(a, id_cmp, 1, b);
|
||||||
|
|
||||||
|
if (NUM2LONG(r) < 0) return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
r_le(a,b)
|
||||||
|
VALUE a, b;
|
||||||
|
{
|
||||||
|
VALUE r = rb_funcall(a, id_cmp, 1, b);
|
||||||
|
|
||||||
|
if (NUM2LONG(r) <= 0) return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
r_gt(a,b)
|
||||||
|
VALUE a, b;
|
||||||
|
{
|
||||||
|
VALUE r = rb_funcall(a, id_cmp, 1, b);
|
||||||
|
|
||||||
|
if (NUM2LONG(r) > 0) return Qtrue;
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
range_eqq(range, obj)
|
range_eqq(range, obj)
|
||||||
VALUE range, obj;
|
VALUE range, obj;
|
||||||
|
@ -123,14 +169,12 @@ range_eqq(range, obj)
|
||||||
}
|
}
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
else if (RTEST(rb_funcall(beg, rb_intern("<="), 1, obj))) {
|
else if (r_le(beg, obj)) {
|
||||||
if (EXCL(range)) {
|
if (EXCL(range)) {
|
||||||
if (RTEST(rb_funcall(end, rb_intern(">"), 1, obj)))
|
if (r_lt(obj, end)) return Qtrue;
|
||||||
return Qtrue;
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (RTEST(rb_funcall(end, rb_intern(">="), 1, obj)))
|
if (r_le(obj, end)) return Qtrue;
|
||||||
return Qtrue;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
|
@ -169,22 +213,19 @@ range_each(range)
|
||||||
}
|
}
|
||||||
else { /* generic each */
|
else { /* generic each */
|
||||||
VALUE v = b;
|
VALUE v = b;
|
||||||
ID succ = rb_intern("succ");
|
|
||||||
|
|
||||||
if (EXCL(range)) {
|
if (EXCL(range)) {
|
||||||
while (RTEST(rb_funcall(v, '<', 1, e))) {
|
while (r_lt(v, e)) {
|
||||||
if (rb_equal(v, e)) break;
|
if (r_eq(v, e)) break;
|
||||||
rb_yield(v);
|
rb_yield(v);
|
||||||
v = rb_funcall(v, succ, 0, 0);
|
v = rb_funcall(v, id_succ, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ID le = rb_intern("<=");
|
while (r_le(v, e)) {
|
||||||
|
|
||||||
while (RTEST(rb_funcall(v, le, 1, e))) {
|
|
||||||
rb_yield(v);
|
rb_yield(v);
|
||||||
if (rb_equal(v, e)) break;
|
if (r_eq(v, e)) break;
|
||||||
v = rb_funcall(v, succ, 0, 0);
|
v = rb_funcall(v, id_succ, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,7 +365,7 @@ range_length(range)
|
||||||
beg = rb_ivar_get(range, id_beg);
|
beg = rb_ivar_get(range, id_beg);
|
||||||
end = rb_ivar_get(range, id_end);
|
end = rb_ivar_get(range, id_end);
|
||||||
|
|
||||||
if (RTEST(rb_funcall(beg, '>', 1, end))) {
|
if (r_gt(beg, end)) {
|
||||||
return INT2FIX(0);
|
return INT2FIX(0);
|
||||||
}
|
}
|
||||||
if (FIXNUM_P(beg) && FIXNUM_P(end)) {
|
if (FIXNUM_P(beg) && FIXNUM_P(end)) {
|
||||||
|
@ -349,6 +390,25 @@ range_length(range)
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
range_member(range, val)
|
||||||
|
VALUE range, val;
|
||||||
|
{
|
||||||
|
VALUE beg, end;
|
||||||
|
|
||||||
|
beg = rb_ivar_get(range, id_beg);
|
||||||
|
end = rb_ivar_get(range, id_end);
|
||||||
|
|
||||||
|
if (r_lt(beg, val)) return Qtrue;
|
||||||
|
if (EXCL(range)) {
|
||||||
|
if (r_lt(val, end)) return Qtrue;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (r_le(val, end)) return Qtrue;
|
||||||
|
}
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Init_Range()
|
Init_Range()
|
||||||
{
|
{
|
||||||
|
@ -369,8 +429,11 @@ Init_Range()
|
||||||
|
|
||||||
rb_define_method(rb_cRange, "length", range_length, 0);
|
rb_define_method(rb_cRange, "length", range_length, 0);
|
||||||
rb_define_method(rb_cRange, "size", range_length, 0);
|
rb_define_method(rb_cRange, "size", range_length, 0);
|
||||||
|
rb_define_method(rb_cRange, "member?", range_member, 1);
|
||||||
|
rb_define_method(rb_cRange, "include?", range_member, 1);
|
||||||
|
|
||||||
id_cmp = rb_intern("<=>");
|
id_cmp = rb_intern("<=>");
|
||||||
|
id_succ = rb_intern("succ");
|
||||||
id_beg = rb_intern("begin");
|
id_beg = rb_intern("begin");
|
||||||
id_end = rb_intern("end");
|
id_end = rb_intern("end");
|
||||||
id_excl = rb_intern("excl");
|
id_excl = rb_intern("excl");
|
||||||
|
|
74
re.c
74
re.c
|
@ -224,51 +224,51 @@ rb_reg_expr_str(str, s, len)
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
if (!need_escape) {
|
if (!need_escape) {
|
||||||
rb_str_cat(str, s, len);
|
rb_str_buf_cat(str, s, len);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
p = s;
|
p = s;
|
||||||
while (p<pend) {
|
while (p<pend) {
|
||||||
if (*p == '/') {
|
if (*p == '/') {
|
||||||
char c = '\\';
|
char c = '\\';
|
||||||
rb_str_cat(str, &c, 1);
|
rb_str_buf_cat(str, &c, 1);
|
||||||
rb_str_cat(str, p, 1);
|
rb_str_buf_cat(str, p, 1);
|
||||||
}
|
}
|
||||||
else if (ismbchar(*p)) {
|
else if (ismbchar(*p)) {
|
||||||
rb_str_cat(str, p, mbclen(*p));
|
rb_str_buf_cat(str, p, mbclen(*p));
|
||||||
p += mbclen(*p);
|
p += mbclen(*p);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else if (ISPRINT(*p)) {
|
else if (ISPRINT(*p)) {
|
||||||
rb_str_cat(str, p, 1);
|
rb_str_buf_cat(str, p, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
char b[8];
|
char b[8];
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
case '\r':
|
case '\r':
|
||||||
rb_str_cat(str, "\\r", 2);
|
rb_str_buf_cat(str, "\\r", 2);
|
||||||
break;
|
break;
|
||||||
case '\n':
|
case '\n':
|
||||||
rb_str_cat(str, "\\n", 2);
|
rb_str_buf_cat(str, "\\n", 2);
|
||||||
break;
|
break;
|
||||||
case '\t':
|
case '\t':
|
||||||
rb_str_cat(str, "\\t", 2);
|
rb_str_buf_cat(str, "\\t", 2);
|
||||||
break;
|
break;
|
||||||
case '\f':
|
case '\f':
|
||||||
rb_str_cat(str, "\\f", 2);
|
rb_str_buf_cat(str, "\\f", 2);
|
||||||
break;
|
break;
|
||||||
case 007:
|
case 007:
|
||||||
rb_str_cat(str, "\\a", 2);
|
rb_str_buf_cat(str, "\\a", 2);
|
||||||
break;
|
break;
|
||||||
case 013:
|
case 013:
|
||||||
rb_str_cat(str, "\\v", 2);
|
rb_str_buf_cat(str, "\\v", 2);
|
||||||
break;
|
break;
|
||||||
case 033:
|
case 033:
|
||||||
rb_str_cat(str, "\\e", 2);
|
rb_str_buf_cat(str, "\\e", 2);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
sprintf(b, "\\%03o", *p & 0377);
|
sprintf(b, "\\%03o", *p & 0377);
|
||||||
rb_str_cat(str, b, 4);
|
rb_str_buf_cat(str, b, 4);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,35 +283,35 @@ rb_reg_desc(s, len, re)
|
||||||
int len;
|
int len;
|
||||||
VALUE re;
|
VALUE re;
|
||||||
{
|
{
|
||||||
VALUE str = rb_str_new2("/");
|
VALUE str = rb_str_buf_new2("/");
|
||||||
|
|
||||||
rb_reg_expr_str(str, s, len);
|
rb_reg_expr_str(str, s, len);
|
||||||
rb_str_cat2(str, "/");
|
rb_str_buf_cat2(str, "/");
|
||||||
if (re) {
|
if (re) {
|
||||||
rb_reg_check(re);
|
rb_reg_check(re);
|
||||||
/* /p is obsolete; to be removed */
|
/* /p is obsolete; to be removed */
|
||||||
if ((RREGEXP(re)->ptr->options & RE_OPTION_POSIXLINE) == RE_OPTION_POSIXLINE)
|
if ((RREGEXP(re)->ptr->options & RE_OPTION_POSIXLINE) == RE_OPTION_POSIXLINE)
|
||||||
rb_str_cat2(str, "p");
|
rb_str_buf_cat2(str, "p");
|
||||||
else if (RREGEXP(re)->ptr->options & RE_OPTION_MULTILINE)
|
else if (RREGEXP(re)->ptr->options & RE_OPTION_MULTILINE)
|
||||||
rb_str_cat2(str, "m");
|
rb_str_buf_cat2(str, "m");
|
||||||
if (RREGEXP(re)->ptr->options & RE_OPTION_IGNORECASE)
|
if (RREGEXP(re)->ptr->options & RE_OPTION_IGNORECASE)
|
||||||
rb_str_cat2(str, "i");
|
rb_str_buf_cat2(str, "i");
|
||||||
if (RREGEXP(re)->ptr->options & RE_OPTION_EXTENDED)
|
if (RREGEXP(re)->ptr->options & RE_OPTION_EXTENDED)
|
||||||
rb_str_cat2(str, "x");
|
rb_str_buf_cat2(str, "x");
|
||||||
|
|
||||||
if (FL_TEST(re, KCODE_FIXED)) {
|
if (FL_TEST(re, KCODE_FIXED)) {
|
||||||
switch ((RBASIC(re)->flags & KCODE_MASK)) {
|
switch ((RBASIC(re)->flags & KCODE_MASK)) {
|
||||||
case KCODE_NONE:
|
case KCODE_NONE:
|
||||||
rb_str_cat2(str, "n");
|
rb_str_buf_cat2(str, "n");
|
||||||
break;
|
break;
|
||||||
case KCODE_EUC:
|
case KCODE_EUC:
|
||||||
rb_str_cat2(str, "e");
|
rb_str_buf_cat2(str, "e");
|
||||||
break;
|
break;
|
||||||
case KCODE_SJIS:
|
case KCODE_SJIS:
|
||||||
rb_str_cat2(str, "s");
|
rb_str_buf_cat2(str, "s");
|
||||||
break;
|
break;
|
||||||
case KCODE_UTF8:
|
case KCODE_UTF8:
|
||||||
rb_str_cat2(str, "u");
|
rb_str_buf_cat2(str, "u");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1171,8 +1171,13 @@ rb_reg_regsub(str, src, regs)
|
||||||
}
|
}
|
||||||
if (c != '\\' || s == e) continue;
|
if (c != '\\' || s == e) continue;
|
||||||
|
|
||||||
if (!val) val = rb_str_new(p, ss-p);
|
if (!val) {
|
||||||
else rb_str_cat(val, p, ss-p);
|
val = rb_str_buf_new(ss-p);
|
||||||
|
rb_str_buf_cat(val, p, ss-p);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_str_buf_cat(val, p, ss-p);
|
||||||
|
}
|
||||||
|
|
||||||
c = *s++;
|
c = *s++;
|
||||||
p = s;
|
p = s;
|
||||||
|
@ -1186,11 +1191,11 @@ rb_reg_regsub(str, src, regs)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '`':
|
case '`':
|
||||||
rb_str_cat(val, RSTRING(src)->ptr, BEG(0));
|
rb_str_buf_cat(val, RSTRING(src)->ptr, BEG(0));
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '\'':
|
case '\'':
|
||||||
rb_str_cat(val, RSTRING(src)->ptr+END(0), RSTRING(src)->len-END(0));
|
rb_str_buf_cat(val, RSTRING(src)->ptr+END(0), RSTRING(src)->len-END(0));
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case '+':
|
case '+':
|
||||||
|
@ -1200,24 +1205,29 @@ rb_reg_regsub(str, src, regs)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case '\\':
|
case '\\':
|
||||||
rb_str_cat(val, s-1, 1);
|
rb_str_buf_cat(val, s-1, 1);
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
rb_str_cat(val, s-2, 2);
|
rb_str_buf_cat(val, s-2, 2);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (no >= 0) {
|
if (no >= 0) {
|
||||||
if (no >= regs->num_regs) continue;
|
if (no >= regs->num_regs) continue;
|
||||||
if (BEG(no) == -1) continue;
|
if (BEG(no) == -1) continue;
|
||||||
rb_str_cat(val, RSTRING(src)->ptr+BEG(no), END(no)-BEG(no));
|
rb_str_buf_cat(val, RSTRING(src)->ptr+BEG(no), END(no)-BEG(no));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p < e) {
|
if (p < e) {
|
||||||
if (!val) val = rb_str_new(p, e-p);
|
if (!val) {
|
||||||
else rb_str_cat(val, p, e-p);
|
val = rb_str_buf_new(e-p);
|
||||||
|
rb_str_buf_cat(val, p, e-p);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
rb_str_buf_cat(val, p, e-p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!val) return str;
|
if (!val) return str;
|
||||||
|
|
||||||
|
|
29
regex.c
29
regex.c
|
@ -370,6 +370,7 @@ enum regexpcode
|
||||||
duplicate, /* Match a duplicate of something remembered.
|
duplicate, /* Match a duplicate of something remembered.
|
||||||
Followed by one byte containing the index of the memory
|
Followed by one byte containing the index of the memory
|
||||||
register. */
|
register. */
|
||||||
|
fail, /* always fails. */
|
||||||
wordchar, /* Matches any word-constituent character. */
|
wordchar, /* Matches any word-constituent character. */
|
||||||
notwordchar, /* Matches any char that is not a word-constituent. */
|
notwordchar, /* Matches any char that is not a word-constituent. */
|
||||||
wordbeg, /* Succeeds if at word beginning. */
|
wordbeg, /* Succeeds if at word beginning. */
|
||||||
|
@ -2246,32 +2247,23 @@ re_compile_pattern(pattern, size, bufp)
|
||||||
case '1': case '2': case '3':
|
case '1': case '2': case '3':
|
||||||
case '4': case '5': case '6':
|
case '4': case '5': case '6':
|
||||||
case '7': case '8': case '9':
|
case '7': case '8': case '9':
|
||||||
{
|
|
||||||
const char *p_save;
|
|
||||||
|
|
||||||
PATUNFETCH;
|
PATUNFETCH;
|
||||||
p_save = p;
|
p0 = p;
|
||||||
|
|
||||||
had_mbchar = 0;
|
had_mbchar = 0;
|
||||||
c1 = 0;
|
c1 = 0;
|
||||||
GET_UNSIGNED_NUMBER(c1);
|
GET_UNSIGNED_NUMBER(c1);
|
||||||
if (!ISDIGIT(c)) PATUNFETCH;
|
if (!ISDIGIT(c)) PATUNFETCH;
|
||||||
|
|
||||||
if (c1 >= regnum) {
|
if (9 < c1 && c1 >= regnum) {
|
||||||
/* need to get octal */
|
/* need to get octal */
|
||||||
p = p_save;
|
c = scan_oct(p0, 3, &numlen) & 0xff;
|
||||||
c = scan_oct(p_save, 3, &numlen) & 0xff;
|
p = p0 + numlen;
|
||||||
p = p_save + numlen;
|
|
||||||
c1 = 0;
|
c1 = 0;
|
||||||
had_num_literal = 1;
|
had_num_literal = 1;
|
||||||
goto numeric_char;
|
goto numeric_char;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Can't back reference to a subexpression if inside of it. */
|
|
||||||
for (stackt = stackp - 2; stackt > stackb; stackt -= 5)
|
|
||||||
if (*stackt == c1)
|
|
||||||
goto normal_char;
|
|
||||||
laststart = b;
|
laststart = b;
|
||||||
BUFPUSH(duplicate);
|
BUFPUSH(duplicate);
|
||||||
BUFPUSH(c1);
|
BUFPUSH(c1);
|
||||||
|
@ -3736,11 +3728,16 @@ re_match(bufp, string_arg, size, pos, regs)
|
||||||
int regno = *p++; /* Get which register to match against */
|
int regno = *p++; /* Get which register to match against */
|
||||||
register unsigned char *d2, *dend2;
|
register unsigned char *d2, *dend2;
|
||||||
|
|
||||||
if (IS_ACTIVE(reg_info[regno])) break;
|
#if 0
|
||||||
|
/* Check if corresponding group is still open */
|
||||||
|
if (IS_ACTIVE(reg_info[regno])) goto fail;
|
||||||
|
|
||||||
/* Where in input to try to start matching. */
|
/* Where in input to try to start matching. */
|
||||||
d2 = regstart[regno];
|
d2 = regstart[regno];
|
||||||
if (REG_UNSET(d2)) break;
|
#else
|
||||||
|
d2 = IS_ACTIVE(reg_info[regno])?old_regstart[regno]:regstart[regno];
|
||||||
|
#endif
|
||||||
|
if (REG_UNSET(d2)) goto fail;
|
||||||
|
|
||||||
/* Where to stop matching; if both the place to start and
|
/* Where to stop matching; if both the place to start and
|
||||||
the place to stop matching are in the same string, then
|
the place to stop matching are in the same string, then
|
||||||
|
@ -3748,7 +3745,7 @@ re_match(bufp, string_arg, size, pos, regs)
|
||||||
the end of the first string. */
|
the end of the first string. */
|
||||||
|
|
||||||
dend2 = regend[regno];
|
dend2 = regend[regno];
|
||||||
if (REG_UNSET(dend2)) break;
|
if (REG_UNSET(dend2)) goto fail;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* At end of register contents => success */
|
/* At end of register contents => success */
|
||||||
if (d2 == dend2) break;
|
if (d2 == dend2) break;
|
||||||
|
|
10
ruby.c
10
ruby.c
|
@ -681,6 +681,11 @@ proc_options(argc, argv)
|
||||||
ruby_show_copyright();
|
ruby_show_copyright();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rb_safe_level() >= 4) {
|
||||||
|
OBJ_TAINT(rb_argv);
|
||||||
|
OBJ_TAINT(rb_load_path);
|
||||||
|
}
|
||||||
|
|
||||||
if (!e_script && argc == 0) { /* no more args */
|
if (!e_script && argc == 0) { /* no more args */
|
||||||
if (verbose) exit(0);
|
if (verbose) exit(0);
|
||||||
script = "-";
|
script = "-";
|
||||||
|
@ -726,6 +731,11 @@ proc_options(argc, argv)
|
||||||
|
|
||||||
process_sflag();
|
process_sflag();
|
||||||
xflag = 0;
|
xflag = 0;
|
||||||
|
|
||||||
|
if (rb_safe_level() >= 4) {
|
||||||
|
FL_UNSET(rb_argv, FL_TAINT);
|
||||||
|
FL_UNSET(rb_load_path, FL_TAINT);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int ruby__end__seen;
|
extern int ruby__end__seen;
|
||||||
|
|
1
ruby.h
1
ruby.h
|
@ -111,6 +111,7 @@ typedef unsigned long ID;
|
||||||
|
|
||||||
#define FIXNUM_FLAG 0x01
|
#define FIXNUM_FLAG 0x01
|
||||||
#define INT2FIX(i) ((VALUE)(((long)(i))<<1 | FIXNUM_FLAG))
|
#define INT2FIX(i) ((VALUE)(((long)(i))<<1 | FIXNUM_FLAG))
|
||||||
|
#define LONG2FIX(i) INT2FIX(i)
|
||||||
#define rb_fix_new(v) INT2FIX(v)
|
#define rb_fix_new(v) INT2FIX(v)
|
||||||
VALUE rb_int2inum _((long));
|
VALUE rb_int2inum _((long));
|
||||||
#define INT2NUM(v) rb_int2inum(v)
|
#define INT2NUM(v) rb_int2inum(v)
|
||||||
|
|
186
string.c
186
string.c
|
@ -28,6 +28,7 @@
|
||||||
VALUE rb_cString;
|
VALUE rb_cString;
|
||||||
|
|
||||||
#define STR_NO_ORIG FL_USER2
|
#define STR_NO_ORIG FL_USER2
|
||||||
|
#define STR_ASSOC FL_USER3
|
||||||
|
|
||||||
VALUE rb_fs;
|
VALUE rb_fs;
|
||||||
|
|
||||||
|
@ -132,6 +133,40 @@ rb_str_new4(orig)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define STR_BUF_MIN_SIZE 128
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_str_buf_new(capa)
|
||||||
|
long capa;
|
||||||
|
{
|
||||||
|
NEWOBJ(str, struct RString);
|
||||||
|
OBJSETUP(str, rb_cString, T_STRING);
|
||||||
|
|
||||||
|
FL_SET(str, STR_NO_ORIG);
|
||||||
|
if (capa < STR_BUF_MIN_SIZE)
|
||||||
|
capa = STR_BUF_MIN_SIZE;
|
||||||
|
str->ptr = 0;
|
||||||
|
str->len = 0;
|
||||||
|
str->orig = LONG2FIX(capa);
|
||||||
|
str->ptr = ALLOC_N(char, capa+1);
|
||||||
|
str->ptr[0] = '\0';
|
||||||
|
|
||||||
|
return (VALUE)str;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_str_buf_new2(ptr)
|
||||||
|
const char *ptr;
|
||||||
|
{
|
||||||
|
VALUE str;
|
||||||
|
long len = strlen(ptr);
|
||||||
|
|
||||||
|
str = rb_str_buf_new(len + STR_BUF_MIN_SIZE);
|
||||||
|
rb_str_cat(str, ptr, len);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_str_to_str(str)
|
rb_str_to_str(str)
|
||||||
VALUE str;
|
VALUE str;
|
||||||
|
@ -176,7 +211,7 @@ rb_str_associate(str, add)
|
||||||
rb_str_modify(str);
|
rb_str_modify(str);
|
||||||
}
|
}
|
||||||
RSTRING(str)->orig = rb_ary_new();
|
RSTRING(str)->orig = rb_ary_new();
|
||||||
FL_SET(str, STR_NO_ORIG);
|
FL_SET(str, STR_NO_ORIG|STR_ASSOC);
|
||||||
}
|
}
|
||||||
rb_ary_push(RSTRING(str)->orig, add);
|
rb_ary_push(RSTRING(str)->orig, add);
|
||||||
}
|
}
|
||||||
|
@ -185,7 +220,7 @@ VALUE
|
||||||
rb_str_associated(str)
|
rb_str_associated(str)
|
||||||
VALUE str;
|
VALUE str;
|
||||||
{
|
{
|
||||||
if (!FL_TEST(str, STR_NO_ORIG)) {
|
if (!FL_TEST(str, STR_NO_ORIG|STR_ASSOC)) {
|
||||||
return Qfalse;
|
return Qfalse;
|
||||||
}
|
}
|
||||||
return RSTRING(str)->orig;
|
return RSTRING(str)->orig;
|
||||||
|
@ -442,28 +477,70 @@ rb_str_resize(str, len)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_str_buf_cat(str, ptr, len)
|
||||||
|
VALUE str;
|
||||||
|
const char *ptr;
|
||||||
|
long len;
|
||||||
|
{
|
||||||
|
long i, capa, total;
|
||||||
|
|
||||||
|
if (RSTRING(str)->orig == 0) {
|
||||||
|
capa = RSTRING(str)->len;
|
||||||
|
FL_SET(str, STR_NO_ORIG);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
capa = FIX2LONG(RSTRING(str)->orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
total = RSTRING(str)->len+len;
|
||||||
|
if (capa <= total) {
|
||||||
|
while (total > capa) {
|
||||||
|
capa = (capa + 1) * 2;
|
||||||
|
}
|
||||||
|
REALLOC_N(RSTRING(str)->ptr, char, capa+1);
|
||||||
|
RSTRING(str)->orig = LONG2FIX(capa);
|
||||||
|
}
|
||||||
|
memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);
|
||||||
|
RSTRING(str)->len = total;
|
||||||
|
RSTRING(str)->ptr[total] = '\0'; /* sentinel */
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_str_buf_cat2(str, ptr)
|
||||||
|
VALUE str;
|
||||||
|
const char *ptr;
|
||||||
|
{
|
||||||
|
return rb_str_buf_cat(str, ptr, strlen(ptr));
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_str_cat(str, ptr, len)
|
rb_str_cat(str, ptr, len)
|
||||||
VALUE str;
|
VALUE str;
|
||||||
const char *ptr;
|
const char *ptr;
|
||||||
long len;
|
long len;
|
||||||
{
|
{
|
||||||
if (len > 0) {
|
long i, capa;
|
||||||
int poffset = -1;
|
|
||||||
|
|
||||||
rb_str_modify(str);
|
rb_str_modify(str);
|
||||||
if (RSTRING(str)->ptr <= ptr &&
|
if (len > 0) {
|
||||||
ptr < RSTRING(str)->ptr + RSTRING(str)->len) {
|
if (RSTRING(str)->orig == 0 ||
|
||||||
poffset = ptr - RSTRING(str)->ptr;
|
(FL_TEST(str, STR_NO_ORIG) && !FL_TEST(str, STR_ASSOC))) {
|
||||||
|
return rb_str_buf_cat(str, ptr, len);
|
||||||
}
|
}
|
||||||
REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len + len + 1);
|
REALLOC_N(RSTRING(str)->ptr, char, RSTRING(str)->len+1);
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
if (poffset >= 0) ptr = RSTRING(str)->ptr + poffset;
|
|
||||||
memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);
|
memcpy(RSTRING(str)->ptr + RSTRING(str)->len, ptr, len);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
MEMZERO(RSTRING(str)->ptr + RSTRING(str)->len, char, len);
|
||||||
|
}
|
||||||
RSTRING(str)->len += len;
|
RSTRING(str)->len += len;
|
||||||
RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */
|
RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */
|
||||||
}
|
}
|
||||||
|
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,14 +553,61 @@ rb_str_cat2(str, ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_str_append(str1, str2)
|
rb_str_buf_append(str, str2)
|
||||||
VALUE str1, str2;
|
VALUE str, str2;
|
||||||
{
|
{
|
||||||
StringValue(str2);
|
long i, capa, len;
|
||||||
str1 = rb_str_cat(str1, RSTRING(str2)->ptr, RSTRING(str2)->len);
|
|
||||||
OBJ_INFECT(str1, str2);
|
|
||||||
|
|
||||||
return str1;
|
if (RSTRING(str)->orig == 0) {
|
||||||
|
capa = RSTRING(str)->len;
|
||||||
|
FL_SET(str, STR_NO_ORIG);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
capa = FIX2LONG(RSTRING(str)->orig);
|
||||||
|
}
|
||||||
|
|
||||||
|
len = RSTRING(str)->len+RSTRING(str2)->len;
|
||||||
|
if (capa <= len) {
|
||||||
|
while (len > capa) {
|
||||||
|
capa = (capa + 1) * 2;
|
||||||
|
}
|
||||||
|
REALLOC_N(RSTRING(str)->ptr, char, capa+1);
|
||||||
|
RSTRING(str)->orig = LONG2FIX(capa);
|
||||||
|
}
|
||||||
|
memcpy(RSTRING(str)->ptr + RSTRING(str)->len,
|
||||||
|
RSTRING(str2)->ptr, RSTRING(str2)->len);
|
||||||
|
RSTRING(str)->len += RSTRING(str2)->len;
|
||||||
|
RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_str_append(str, str2)
|
||||||
|
VALUE str, str2;
|
||||||
|
{
|
||||||
|
long i, capa, len;
|
||||||
|
|
||||||
|
StringValue(str2);
|
||||||
|
rb_str_modify(str);
|
||||||
|
len = RSTRING(str)->len+RSTRING(str2)->len;
|
||||||
|
if (len > 0) {
|
||||||
|
if (RSTRING(str)->orig == 0 ||
|
||||||
|
(FL_TEST(str, STR_NO_ORIG) && !FL_TEST(str, STR_ASSOC))) {
|
||||||
|
rb_str_buf_append(str, str2);
|
||||||
|
OBJ_INFECT(str, str2);
|
||||||
|
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
REALLOC_N(RSTRING(str)->ptr, char, len+1);
|
||||||
|
memcpy(RSTRING(str)->ptr + RSTRING(str)->len,
|
||||||
|
RSTRING(str2)->ptr, RSTRING(str2)->len);
|
||||||
|
RSTRING(str)->len += RSTRING(str2)->len;
|
||||||
|
RSTRING(str)->ptr[RSTRING(str)->len] = '\0'; /* sentinel */
|
||||||
|
}
|
||||||
|
OBJ_INFECT(str, str2);
|
||||||
|
|
||||||
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
|
@ -998,6 +1122,7 @@ rb_str_update(str, beg, len, val)
|
||||||
}
|
}
|
||||||
RSTRING(str)->len += RSTRING(val)->len - len;
|
RSTRING(str)->len += RSTRING(val)->len - len;
|
||||||
RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
|
RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
|
||||||
|
OBJ_INFECT(str, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE rb_str_sub_bang _((int, VALUE*, VALUE));
|
static VALUE rb_str_sub_bang _((int, VALUE*, VALUE));
|
||||||
|
@ -1518,7 +1643,7 @@ rb_str_inspect(str)
|
||||||
VALUE str;
|
VALUE str;
|
||||||
{
|
{
|
||||||
char *p, *pend;
|
char *p, *pend;
|
||||||
VALUE result = rb_str_new2("\"");
|
VALUE result = rb_str_buf_new2("\"");
|
||||||
char s[5];
|
char s[5];
|
||||||
|
|
||||||
p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len;
|
p = RSTRING(str)->ptr; pend = p + RSTRING(str)->len;
|
||||||
|
@ -1526,51 +1651,51 @@ rb_str_inspect(str)
|
||||||
char c = *p++;
|
char c = *p++;
|
||||||
if (ismbchar(c) && p < pend) {
|
if (ismbchar(c) && p < pend) {
|
||||||
int len = mbclen(c);
|
int len = mbclen(c);
|
||||||
rb_str_cat(result, p - 1, len);
|
rb_str_buf_cat(result, p - 1, len);
|
||||||
p += len - 1;
|
p += len - 1;
|
||||||
}
|
}
|
||||||
else if (c == '"'|| c == '\\') {
|
else if (c == '"'|| c == '\\') {
|
||||||
s[0] = '\\'; s[1] = c;
|
s[0] = '\\'; s[1] = c;
|
||||||
rb_str_cat(result, s, 2);
|
rb_str_buf_cat(result, s, 2);
|
||||||
}
|
}
|
||||||
else if (ISPRINT(c)) {
|
else if (ISPRINT(c)) {
|
||||||
s[0] = c;
|
s[0] = c;
|
||||||
rb_str_cat(result, s, 1);
|
rb_str_buf_cat(result, s, 1);
|
||||||
}
|
}
|
||||||
else if (c == '\n') {
|
else if (c == '\n') {
|
||||||
s[0] = '\\'; s[1] = 'n';
|
s[0] = '\\'; s[1] = 'n';
|
||||||
rb_str_cat(result, s, 2);
|
rb_str_buf_cat(result, s, 2);
|
||||||
}
|
}
|
||||||
else if (c == '\r') {
|
else if (c == '\r') {
|
||||||
s[0] = '\\'; s[1] = 'r';
|
s[0] = '\\'; s[1] = 'r';
|
||||||
rb_str_cat(result, s, 2);
|
rb_str_buf_cat(result, s, 2);
|
||||||
}
|
}
|
||||||
else if (c == '\t') {
|
else if (c == '\t') {
|
||||||
s[0] = '\\'; s[1] = 't';
|
s[0] = '\\'; s[1] = 't';
|
||||||
rb_str_cat(result, s, 2);
|
rb_str_buf_cat(result, s, 2);
|
||||||
}
|
}
|
||||||
else if (c == '\f') {
|
else if (c == '\f') {
|
||||||
s[0] = '\\'; s[1] = 'f';
|
s[0] = '\\'; s[1] = 'f';
|
||||||
rb_str_cat(result, s, 2);
|
rb_str_buf_cat(result, s, 2);
|
||||||
}
|
}
|
||||||
else if (c == '\013') {
|
else if (c == '\013') {
|
||||||
s[0] = '\\'; s[1] = 'v';
|
s[0] = '\\'; s[1] = 'v';
|
||||||
rb_str_cat(result, s, 2);
|
rb_str_buf_cat(result, s, 2);
|
||||||
}
|
}
|
||||||
else if (c == '\007') {
|
else if (c == '\007') {
|
||||||
s[0] = '\\'; s[1] = 'a';
|
s[0] = '\\'; s[1] = 'a';
|
||||||
rb_str_cat(result, s, 2);
|
rb_str_buf_cat(result, s, 2);
|
||||||
}
|
}
|
||||||
else if (c == 033) {
|
else if (c == 033) {
|
||||||
s[0] = '\\'; s[1] = 'e';
|
s[0] = '\\'; s[1] = 'e';
|
||||||
rb_str_cat(result, s, 2);
|
rb_str_buf_cat(result, s, 2);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sprintf(s, "\\%03o", c & 0377);
|
sprintf(s, "\\%03o", c & 0377);
|
||||||
rb_str_cat2(result, s);
|
rb_str_buf_cat2(result, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rb_str_cat2(result, "\"");
|
rb_str_buf_cat2(result, "\"");
|
||||||
|
|
||||||
OBJ_INFECT(result, str);
|
OBJ_INFECT(result, str);
|
||||||
return result;
|
return result;
|
||||||
|
@ -2661,7 +2786,7 @@ rb_str_crypt(str, salt)
|
||||||
StringValue(salt);
|
StringValue(salt);
|
||||||
if (RSTRING(salt)->len < 2)
|
if (RSTRING(salt)->len < 2)
|
||||||
rb_raise(rb_eArgError, "salt too short(need >=2 bytes)");
|
rb_raise(rb_eArgError, "salt too short(need >=2 bytes)");
|
||||||
return rb_str_new2(crypt(RSTRING(str)->ptr, RSTRING(salt)->ptr));
|
return rb_tainted_str_new2(crypt(RSTRING(str)->ptr, RSTRING(salt)->ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -2738,6 +2863,7 @@ rb_str_ljust(str, w)
|
||||||
while (p < pend) {
|
while (p < pend) {
|
||||||
*p++ = ' ';
|
*p++ = ' ';
|
||||||
}
|
}
|
||||||
|
OBJ_INFECT(res, str);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2757,6 +2883,7 @@ rb_str_rjust(str, w)
|
||||||
*p++ = ' ';
|
*p++ = ' ';
|
||||||
}
|
}
|
||||||
memcpy(pend, RSTRING(str)->ptr, RSTRING(str)->len);
|
memcpy(pend, RSTRING(str)->ptr, RSTRING(str)->len);
|
||||||
|
OBJ_INFECT(res, str);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2782,6 +2909,7 @@ rb_str_center(str, w)
|
||||||
while (p < pend) {
|
while (p < pend) {
|
||||||
*p++ = ' ';
|
*p++ = ' ';
|
||||||
}
|
}
|
||||||
|
OBJ_INFECT(res, str);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
struct.c
2
struct.c
|
@ -358,7 +358,7 @@ inspect_struct(s)
|
||||||
rb_bug("non-initialized struct");
|
rb_bug("non-initialized struct");
|
||||||
}
|
}
|
||||||
|
|
||||||
str = rb_str_new2("#<");
|
str = rb_str_buf_new2("#<");
|
||||||
rb_str_cat2(str, cname);
|
rb_str_cat2(str, cname);
|
||||||
rb_str_cat2(str, " ");
|
rb_str_cat2(str, " ");
|
||||||
for (i=0; i<RSTRUCT(s)->len; i++) {
|
for (i=0; i<RSTRUCT(s)->len; i++) {
|
||||||
|
|
240
time.c
240
time.c
|
@ -314,7 +314,10 @@ make_time_t(tptr, utc_p)
|
||||||
{
|
{
|
||||||
time_t guess, guess_lo, guess_hi;
|
time_t guess, guess_lo, guess_hi;
|
||||||
struct tm *tm, tm_lo, tm_hi;
|
struct tm *tm, tm_lo, tm_hi;
|
||||||
int d;
|
int d, have_guess;
|
||||||
|
int find_dst;
|
||||||
|
|
||||||
|
find_dst = 1;
|
||||||
|
|
||||||
#ifdef NEGATIVE_TIME_T
|
#ifdef NEGATIVE_TIME_T
|
||||||
guess_lo = 1 << (8 * sizeof(time_t) - 1);
|
guess_lo = 1 << (8 * sizeof(time_t) - 1);
|
||||||
|
@ -322,7 +325,7 @@ make_time_t(tptr, utc_p)
|
||||||
guess_lo = 0;
|
guess_lo = 0;
|
||||||
#endif
|
#endif
|
||||||
guess_hi = ((time_t)-1) < ((time_t)0) ?
|
guess_hi = ((time_t)-1) < ((time_t)0) ?
|
||||||
(1U << (8 * sizeof(time_t) - 1)) - 1 :
|
(1UL << (8 * sizeof(time_t) - 1)) - 1 :
|
||||||
~(time_t)0;
|
~(time_t)0;
|
||||||
|
|
||||||
tm = (utc_p ? gmtime : localtime)(&guess_lo);
|
tm = (utc_p ? gmtime : localtime)(&guess_lo);
|
||||||
|
@ -339,62 +342,87 @@ make_time_t(tptr, utc_p)
|
||||||
if (d == 0) return guess_hi;
|
if (d == 0) return guess_hi;
|
||||||
tm_hi = *tm;
|
tm_hi = *tm;
|
||||||
|
|
||||||
while (guess_lo + 1 < guess_hi) { /* there is a gap between lo and hi. */
|
have_guess = 0;
|
||||||
unsigned long range;
|
|
||||||
|
while (guess_lo + 1 < guess_hi) {
|
||||||
|
/* there is a gap between guess_lo and guess_hi. */
|
||||||
|
unsigned long range = 0;
|
||||||
|
if (!have_guess) {
|
||||||
int a, b;
|
int a, b;
|
||||||
/*
|
/*
|
||||||
Try precious guess by a linear interpolation at first.
|
Try precious guess by a linear interpolation at first.
|
||||||
`a' and `b' is a coefficient of guess_lo and guess_hi.
|
`a' and `b' is a coefficient of guess_lo and guess_hi as:
|
||||||
`range' is approximation of maximum error by the interpolation.
|
|
||||||
(a + b)**2 should be less than 2**31 to avoid overflow.
|
guess = (guess_lo * a + guess_hi * b) / (a + b)
|
||||||
When these parameter is wrong, binary search is used.
|
|
||||||
|
However this causes overflow in most cases, following assignment
|
||||||
|
is used instead:
|
||||||
|
|
||||||
|
guess = guess_lo / d * a + (guess_lo % d) * a / d
|
||||||
|
+ guess_hi / d * b + (guess_hi % d) * b / d
|
||||||
|
where d = a + b
|
||||||
|
|
||||||
|
To avoid overflow in this assignment, `d' is restricted to less than
|
||||||
|
sqrt(2**31). By this restriction and other reasons, the guess is
|
||||||
|
not accurate and some error is expected. `range' approximates
|
||||||
|
the maximum error.
|
||||||
|
|
||||||
|
When these parameters are not suitable, i.e. guess is not within
|
||||||
|
guess_lo and guess_hi, simple guess by binary search is used.
|
||||||
*/
|
*/
|
||||||
|
range = 366 * 24 * 60 * 60;
|
||||||
a = (tm_hi.tm_year - tptr->tm_year);
|
a = (tm_hi.tm_year - tptr->tm_year);
|
||||||
b = (tptr->tm_year - tm_lo.tm_year);
|
b = (tptr->tm_year - tm_lo.tm_year);
|
||||||
range = 366 * 24 * 3600;
|
|
||||||
if (a + b < 46000 / 366) {
|
|
||||||
/* 46000 is selected as `some big number less than sqrt(2**31)'. */
|
/* 46000 is selected as `some big number less than sqrt(2**31)'. */
|
||||||
/* The distinction between leap/non-leap year is not important here. */
|
if (a + b <= 46000 / 12) {
|
||||||
static int days[] = {
|
range = 31 * 24 * 60 * 60;
|
||||||
0,
|
a *= 12;
|
||||||
0 + 31,
|
b *= 12;
|
||||||
0 + 31 + 29,
|
a += tm_hi.tm_mon - tptr->tm_mon;
|
||||||
0 + 31 + 29 + 31,
|
b += tptr->tm_mon - tm_lo.tm_mon;
|
||||||
0 + 31 + 29 + 31 + 30,
|
if (a + b <= 46000 / 31) {
|
||||||
0 + 31 + 29 + 31 + 30 + 31,
|
range = 24 * 60 * 60;
|
||||||
0 + 31 + 29 + 31 + 30 + 31 + 30,
|
a *= 31;
|
||||||
0 + 31 + 29 + 31 + 30 + 31 + 30 + 31,
|
b *= 31;
|
||||||
0 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
|
a += tm_hi.tm_mday - tptr->tm_mday;
|
||||||
0 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30,
|
b += tptr->tm_mday - tm_lo.tm_mday;
|
||||||
0 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31,
|
if (a + b <= 46000 / 24) {
|
||||||
0 + 31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30
|
range = 60 * 60;
|
||||||
/* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov */
|
a *= 24;
|
||||||
};
|
b *= 24;
|
||||||
a *= 366;
|
a += tm_hi.tm_hour - tptr->tm_hour;
|
||||||
b *= 366;
|
b += tptr->tm_hour - tm_lo.tm_hour;
|
||||||
d = days[tptr->tm_mon] + tptr->tm_mday;
|
if (a + b <= 46000 / 60) {
|
||||||
a += days[tm_hi.tm_mon] + tm_hi.tm_mday - d;
|
range = 60;
|
||||||
b += d - (days[tm_lo.tm_mon] + tm_lo.tm_mday);
|
a *= 60;
|
||||||
range = 2 * 24 * 3600;
|
b *= 60;
|
||||||
|
a += tm_hi.tm_min - tptr->tm_min;
|
||||||
|
b += tptr->tm_min - tm_lo.tm_min;
|
||||||
|
if (a + b <= 46000 / 60) {
|
||||||
|
range = 1;
|
||||||
|
a *= 60;
|
||||||
|
b *= 60;
|
||||||
|
a += tm_hi.tm_sec - tptr->tm_sec;
|
||||||
|
b += tptr->tm_sec - tm_lo.tm_sec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (a + b <= 1) {
|
|
||||||
range = 2;
|
|
||||||
a *= 24 * 3600;
|
|
||||||
b *= 24 * 3600;
|
|
||||||
d = tptr->tm_hour * 3600 + tptr->tm_min * 60 + tptr->tm_sec;
|
|
||||||
a += tm_hi.tm_hour * 3600 + tm_hi.tm_min * 60 + tm_hi.tm_sec - d;
|
|
||||||
b += d - (tm_lo.tm_hour * 3600 + tm_lo.tm_min * 60 + tm_lo.tm_sec);
|
|
||||||
}
|
}
|
||||||
if (a <= 0) a = 1;
|
if (a <= 0) a = 1;
|
||||||
if (b <= 0) b = 1;
|
if (b <= 0) b = 1;
|
||||||
d = a + b;
|
d = a + b;
|
||||||
guess = guess_lo / d * a + guess_hi / d * b;
|
/*
|
||||||
/* Although `%' may not work with negative value,
|
Although `/' and `%' may produce unexpected result with negative
|
||||||
it doesn't cause serious problem because there is a fail safe. */
|
argument, it doesn't cause serious problem because there is a
|
||||||
guess += ((guess_lo % d) * a + (guess_hi % d) * b) / d;
|
fail safe.
|
||||||
|
*/
|
||||||
|
guess = guess_lo / d * a + (guess_lo % d) * a / d
|
||||||
|
+ guess_hi / d * b + (guess_hi % d) * b / d;
|
||||||
|
have_guess = 1;
|
||||||
|
}
|
||||||
|
|
||||||
fixguess:
|
if (guess <= guess_lo || guess_hi <= guess) {
|
||||||
if (guess <= guess_lo || guess >= guess_hi) {
|
|
||||||
/* Precious guess is invalid. try binary search. */
|
/* Precious guess is invalid. try binary search. */
|
||||||
guess = guess_lo / 2 + guess_hi / 2;
|
guess = guess_lo / 2 + guess_hi / 2;
|
||||||
if (guess <= guess_lo)
|
if (guess <= guess_lo)
|
||||||
|
@ -406,53 +434,99 @@ make_time_t(tptr, utc_p)
|
||||||
|
|
||||||
tm = (utc_p ? gmtime : localtime)(&guess);
|
tm = (utc_p ? gmtime : localtime)(&guess);
|
||||||
if (!tm) goto error;
|
if (!tm) goto error;
|
||||||
|
have_guess = 0;
|
||||||
|
|
||||||
d = tmcmp(tptr, tm);
|
d = tmcmp(tptr, tm);
|
||||||
if (d == 0) {
|
if (d < 0) {
|
||||||
if (!utc_p && !tm->tm_isdst) {
|
guess_hi = guess;
|
||||||
/* When leaving DST, there may be two time corresponding to given
|
tm_hi = *tm;
|
||||||
argument. make_time_t returns DST in such cases. */
|
if (range) {
|
||||||
/* xxx this assumes a difference in time as 3600 seconds. */
|
guess = guess - range;
|
||||||
time_t guess2 = guess - 3600;
|
range = 0;
|
||||||
|
if (guess_lo < guess && guess < guess_hi)
|
||||||
|
have_guess = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (d > 0) {
|
||||||
|
guess_lo = guess;
|
||||||
|
tm_lo = *tm;
|
||||||
|
if (range) {
|
||||||
|
guess = guess + range;
|
||||||
|
range = 0;
|
||||||
|
if (guess_lo < guess && guess < guess_hi)
|
||||||
|
have_guess = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!utc_p) {
|
||||||
|
/* If localtime is nonmonotonic, another result may exist. */
|
||||||
|
time_t guess2;
|
||||||
|
if (find_dst) {
|
||||||
|
guess2 = guess - 2 * 60 * 60;
|
||||||
tm = localtime(&guess2);
|
tm = localtime(&guess2);
|
||||||
if (!tm) return guess;
|
if (tm) {
|
||||||
if (tmcmp(tptr, tm) == 0)
|
if (tptr->tm_hour != (tm->tm_hour + 2) % 24 ||
|
||||||
|
tptr->tm_min != tm->tm_min ||
|
||||||
|
tptr->tm_sec != tm->tm_sec) {
|
||||||
|
guess2 -= (tm->tm_hour - tptr->tm_hour) * 60 * 60 +
|
||||||
|
(tm->tm_min - tptr->tm_min) * 60 +
|
||||||
|
(tm->tm_sec - tptr->tm_sec);
|
||||||
|
if (tptr->tm_mday != tm->tm_mday)
|
||||||
|
guess2 += 24 * 60 * 60;
|
||||||
|
if (guess != guess2) {
|
||||||
|
tm = localtime(&guess2);
|
||||||
|
if (tmcmp(tptr, tm) == 0) {
|
||||||
|
if (guess < guess2)
|
||||||
|
return guess;
|
||||||
|
else
|
||||||
return guess2;
|
return guess2;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
guess2 = guess + 2 * 60 * 60;
|
||||||
|
tm = localtime(&guess2);
|
||||||
|
if (tm) {
|
||||||
|
if ((tptr->tm_hour + 2) % 24 != tm->tm_hour ||
|
||||||
|
tptr->tm_min != tm->tm_min ||
|
||||||
|
tptr->tm_sec != tm->tm_sec) {
|
||||||
|
guess2 -= (tm->tm_hour - tptr->tm_hour) * 60 * 60 +
|
||||||
|
(tm->tm_min - tptr->tm_min) * 60 +
|
||||||
|
(tm->tm_sec - tptr->tm_sec);
|
||||||
|
if (tptr->tm_mday != tm->tm_mday)
|
||||||
|
guess2 -= 24 * 60 * 60;
|
||||||
|
if (guess != guess2) {
|
||||||
|
tm = localtime(&guess2);
|
||||||
|
if (tmcmp(tptr, tm) == 0) {
|
||||||
|
if (guess < guess2)
|
||||||
|
return guess2;
|
||||||
|
else
|
||||||
|
return guess;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return guess;
|
return guess;
|
||||||
}
|
}
|
||||||
else if (d < 0) {
|
|
||||||
guess_hi = guess;
|
|
||||||
tm_hi = *tm;
|
|
||||||
if (range && range < (unsigned long)(guess_hi - guess_lo)) {
|
|
||||||
guess = guess - range;
|
|
||||||
range = 0;
|
|
||||||
goto fixguess;
|
|
||||||
}
|
}
|
||||||
|
/* Given argument has no corresponding time_t. Let's outerpolation. */
|
||||||
|
if (tm_lo.tm_year == tptr->tm_year && tm_lo.tm_mon == tptr->tm_mon) {
|
||||||
|
return guess_lo +
|
||||||
|
(tptr->tm_mday - tm_lo.tm_mday) * 24 * 60 * 60 +
|
||||||
|
(tptr->tm_hour - tm_lo.tm_hour) * 60 * 60 +
|
||||||
|
(tptr->tm_min - tm_lo.tm_min) * 60 +
|
||||||
|
(tptr->tm_sec - tm_lo.tm_sec);
|
||||||
}
|
}
|
||||||
else {
|
else if (tm_hi.tm_year == tptr->tm_year && tm_hi.tm_mon == tptr->tm_mon) {
|
||||||
guess_lo = guess;
|
return guess_hi +
|
||||||
tm_lo = *tm;
|
(tptr->tm_mday - tm_hi.tm_mday) * 24 * 60 * 60 +
|
||||||
if (range && range < (unsigned long)(guess_hi - guess_lo)) {
|
(tptr->tm_hour - tm_hi.tm_hour) * 60 * 60 +
|
||||||
guess = guess + range;
|
(tptr->tm_min - tm_hi.tm_min) * 60 +
|
||||||
range = 0;
|
(tptr->tm_sec - tm_hi.tm_sec);
|
||||||
goto fixguess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* given time is not found. */
|
|
||||||
if (guess_lo + 1 == guess_hi) {
|
|
||||||
/* given argument is invalid: 04/29 at non-leap year for example. */
|
|
||||||
return guess_hi;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* given argument is in a gap. When it enters DST, for example. */
|
|
||||||
d = tptr->tm_sec - tm_lo.tm_sec;
|
|
||||||
d += (tptr->tm_min - tm_lo.tm_min) * 60;
|
|
||||||
d += (tptr->tm_hour - tm_lo.tm_hour) * 3600;
|
|
||||||
if (d < 0)
|
|
||||||
d += 24 * 3600;
|
|
||||||
return guess_hi + d - 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
out_of_range:
|
out_of_range:
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include "env.h"
|
#include "env.h"
|
||||||
#include "node.h"
|
#include "node.h"
|
||||||
#include "st.h"
|
#include "st.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
static st_table *rb_global_tbl;
|
static st_table *rb_global_tbl;
|
||||||
st_table *rb_class_tbl;
|
st_table *rb_class_tbl;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#define RUBY_VERSION "1.7.0"
|
#define RUBY_VERSION "1.7.1"
|
||||||
#define RUBY_RELEASE_DATE "2001-05-28"
|
#define RUBY_RELEASE_DATE "2001-05-30"
|
||||||
#define RUBY_VERSION_CODE 170
|
#define RUBY_VERSION_CODE 171
|
||||||
#define RUBY_RELEASE_CODE 20010528
|
#define RUBY_RELEASE_CODE 20010530
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue