mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* configure.in (FILE_READPTR): new. for IO#gets improvement.
* io.c (READ_DATA_PENDING_PTR): ditto. * io.c (remain_size): separated from read_all(). * io.c (read_all): argument chagend. * io.c (appendline): new. get a line and append to string. * io.c (swallow): new. swallow continuous line delimiters. * io.c (rb_io_getline_fast): add delimiter argument. * io.c (rb_io_getline): performance improvement. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2276 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
45ca4d69aa
commit
dfaf41d759
3 changed files with 239 additions and 161 deletions
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
||||||
|
Mon Mar 25 23:39:25 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
|
||||||
|
|
||||||
|
* configure.in (FILE_READPTR): new. for IO#gets improvement.
|
||||||
|
|
||||||
|
* io.c (READ_DATA_PENDING_PTR): ditto.
|
||||||
|
|
||||||
|
* io.c (remain_size): separated from read_all().
|
||||||
|
|
||||||
|
* io.c (read_all): argument chagend.
|
||||||
|
|
||||||
|
* io.c (appendline): new. get a line and append to string.
|
||||||
|
|
||||||
|
* io.c (swallow): new. swallow continuous line delimiters.
|
||||||
|
|
||||||
|
* io.c (rb_io_getline_fast): add delimiter argument.
|
||||||
|
|
||||||
|
* io.c (rb_io_getline): performance improvement.
|
||||||
|
|
||||||
Mon Mar 25 19:30:25 2002 WATANABE Hirofumi <eban@ruby-lang.org>
|
Mon Mar 25 19:30:25 2002 WATANABE Hirofumi <eban@ruby-lang.org>
|
||||||
|
|
||||||
* ext/extmk.rb.in (arg_config): get rid of single quotes
|
* ext/extmk.rb.in (arg_config): get rid of single quotes
|
||||||
|
|
78
configure.in
78
configure.in
|
@ -453,29 +453,21 @@ else
|
||||||
AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>y) : (x)>>y))
|
AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>y) : (x)>>y))
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_MSG_CHECKING(count field in FILE structures)
|
AC_MSG_CHECKING(read count field in FILE structures)
|
||||||
AC_CACHE_VAL(rb_cv_fcnt,
|
AC_CACHE_VAL(rb_cv_fcnt,
|
||||||
[AC_TRY_COMPILE([#include <stdio.h>],
|
[for fcnt in dnl
|
||||||
[FILE *f = stdin; f->_cnt = 0;], rb_cv_fcnt="_cnt", )
|
_cnt dnl
|
||||||
if test "$rb_cv_fcnt" = ""; then
|
__cnt dnl
|
||||||
AC_TRY_COMPILE([#include <stdio.h>],
|
_r dnl
|
||||||
[FILE *f = stdin; f->__cnt = 0;], rb_cv_fcnt="__cnt", )
|
readCount dnl
|
||||||
fi
|
_rcount dnl for emx0.9c
|
||||||
if test "$rb_cv_fcnt" = ""; then
|
; do
|
||||||
AC_TRY_COMPILE([#include <stdio.h>],
|
AC_TRY_COMPILE([#include <stdio.h>
|
||||||
[FILE *f = stdin; f->_r = 0;], rb_cv_fcnt="_r", )
|
],
|
||||||
fi
|
[FILE *f = stdin; f->$fcnt = 0;],
|
||||||
if test "$rb_cv_fcnt" = ""; then
|
rb_cv_fcnt="$fcnt"; break,
|
||||||
AC_TRY_COMPILE([#include <stdio.h>],
|
rb_cv_fcnt="not found")
|
||||||
[FILE *f = stdin; f->readCount = 0;],
|
done])
|
||||||
rb_cv_fcnt="readCount", )
|
|
||||||
fi
|
|
||||||
dnl for emx0.9c
|
|
||||||
if test "$rb_cv_fcnt" = ""; then
|
|
||||||
AC_TRY_COMPILE([#include <stdio.h>],
|
|
||||||
[FILE *f = stdin; f->_rcount = 0;],
|
|
||||||
rb_cv_fcnt="_rcount", rb_cv_fcnt="not found")
|
|
||||||
fi])
|
|
||||||
if test "$rb_cv_fcnt" = "not found"; then
|
if test "$rb_cv_fcnt" = "not found"; then
|
||||||
AC_MSG_RESULT([not found(OK if using GNU libc)])
|
AC_MSG_RESULT([not found(OK if using GNU libc)])
|
||||||
else
|
else
|
||||||
|
@ -483,6 +475,48 @@ else
|
||||||
AC_DEFINE_UNQUOTED(FILE_COUNT, $rb_cv_fcnt)
|
AC_DEFINE_UNQUOTED(FILE_COUNT, $rb_cv_fcnt)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
AC_MSG_CHECKING(read buffer ptr field in FILE structures)
|
||||||
|
AC_CACHE_VAL(rb_cv_frptr,
|
||||||
|
[for frptr in dnl
|
||||||
|
_IO_read_ptr dnl
|
||||||
|
_ptr dnl
|
||||||
|
__ptr dnl
|
||||||
|
bufpos dnl
|
||||||
|
; do
|
||||||
|
AC_TRY_COMPILE([#include <stdio.h>
|
||||||
|
],
|
||||||
|
[FILE *f = stdin; char buf[256]; f->$frptr = buf;],
|
||||||
|
rb_cv_frptr="$frptr"; break,
|
||||||
|
rb_cv_frptr="not found")
|
||||||
|
done])
|
||||||
|
if test "$rb_cv_frptr" = "not found"; then
|
||||||
|
AC_MSG_RESULT([not found])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT($rb_cv_frptr)
|
||||||
|
AC_DEFINE_UNQUOTED(FILE_READPTR, $rb_cv_frptr)
|
||||||
|
|
||||||
|
if test "$rb_cv_fcnt" = "not found"; then
|
||||||
|
AC_MSG_CHECKING(read buffer end field in FILE structures)
|
||||||
|
AC_CACHE_VAL(rb_cv_frend,
|
||||||
|
[for frend in dnl
|
||||||
|
_IO_read_end dnl
|
||||||
|
bufend dnl
|
||||||
|
; do
|
||||||
|
AC_TRY_COMPILE([#include <stdio.h>
|
||||||
|
],
|
||||||
|
[FILE *f = stdin; char buf[256]; f->$frend = buf;],
|
||||||
|
rb_cv_frend="$frend"; break,
|
||||||
|
rb_cv_frend="not found")
|
||||||
|
done])
|
||||||
|
if test "$rb_cv_frend" = "not found"; then
|
||||||
|
AC_MSG_RESULT([not found])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT($rb_cv_frend)
|
||||||
|
AC_DEFINE_UNQUOTED(FILE_READEND, $rb_cv_frend)
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
dnl default value for $KANJI
|
dnl default value for $KANJI
|
||||||
DEFAULT_KCODE="KCODE_NONE"
|
DEFAULT_KCODE="KCODE_NONE"
|
||||||
|
|
||||||
|
|
304
io.c
304
io.c
|
@ -125,17 +125,24 @@ static VALUE lineno;
|
||||||
# ifdef _IO_fpos_t
|
# ifdef _IO_fpos_t
|
||||||
# define READ_DATA_PENDING(fp) ((fp)->_IO_read_ptr != (fp)->_IO_read_end)
|
# define READ_DATA_PENDING(fp) ((fp)->_IO_read_ptr != (fp)->_IO_read_end)
|
||||||
# define READ_DATA_PENDING_COUNT(fp) ((fp)->_IO_read_end - (fp)->_IO_read_ptr)
|
# define READ_DATA_PENDING_COUNT(fp) ((fp)->_IO_read_end - (fp)->_IO_read_ptr)
|
||||||
|
# define READ_DATA_PENDING_PTR(fp) ((fp)->_IO_read_ptr)
|
||||||
# else
|
# else
|
||||||
# define READ_DATA_PENDING(fp) ((fp)->_gptr < (fp)->_egptr)
|
# define READ_DATA_PENDING(fp) ((fp)->_gptr < (fp)->_egptr)
|
||||||
# define READ_DATA_PENDING_COUNT(fp) ((fp)->_egptr - (fp)->_gptr)
|
# define READ_DATA_PENDING_COUNT(fp) ((fp)->_egptr - (fp)->_gptr)
|
||||||
|
# define READ_DATA_PENDING_PTR(fp) ((fp)->_gptr)
|
||||||
# endif
|
# endif
|
||||||
#elif defined(FILE_COUNT)
|
#elif defined(FILE_COUNT)
|
||||||
# define READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0)
|
# define READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0)
|
||||||
# define READ_DATA_PENDING_COUNT(fp) ((fp)->FILE_COUNT)
|
# define READ_DATA_PENDING_COUNT(fp) ((fp)->FILE_COUNT)
|
||||||
|
#elif defined(FILE_READEND)
|
||||||
|
# define READ_DATA_PENDING(fp) ((fp)->FILE_READPTR < (fp)->FILE_READEND)
|
||||||
|
# define READ_DATA_PENDING_COUNT(fp) ((fp)->FILE_READEND - (fp)->FILE_READPTR)
|
||||||
#elif defined(__BEOS__)
|
#elif defined(__BEOS__)
|
||||||
# define READ_DATA_PENDING(fp) (fp->_state._eof == 0)
|
# define READ_DATA_PENDING(fp) (fp->_state._eof == 0)
|
||||||
#elif defined(__UCLIBC__)
|
#elif defined(__UCLIBC__)
|
||||||
# define READ_DATA_PENDING(fp) ((fp)->bufpos < (fp)->bufend)
|
# define READ_DATA_PENDING(fp) ((fp)->bufpos < (fp)->bufend)
|
||||||
|
# define READ_DATA_PENDING_COUNT(fp) ((fp)->bufend - (fp)->bufpos)
|
||||||
|
# define READ_DATA_PENDING_PTR(fp) ((fp)->bufpos)
|
||||||
#elif defined(__VMS)
|
#elif defined(__VMS)
|
||||||
# define READ_DATA_PENDING(fp) (((unsigned int)((*(fp))->_flag) & _IOEOF) == 0)
|
# define READ_DATA_PENDING(fp) (((unsigned int)((*(fp))->_flag) & _IOEOF) == 0)
|
||||||
#else
|
#else
|
||||||
|
@ -143,6 +150,11 @@ static VALUE lineno;
|
||||||
extern int ReadDataPending();
|
extern int ReadDataPending();
|
||||||
# define READ_DATA_PENDING(fp) ReadDataPending(fp)
|
# define READ_DATA_PENDING(fp) ReadDataPending(fp)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef READ_DATA_PENDING_PTR
|
||||||
|
# ifdef FILE_READPTR
|
||||||
|
# define READ_DATA_PENDING_PTR(fp) ((fp)->FILE_READPTR)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#define READ_CHECK(fp) do {\
|
#define READ_CHECK(fp) do {\
|
||||||
if (!READ_DATA_PENDING(fp)) {\
|
if (!READ_DATA_PENDING(fp)) {\
|
||||||
|
@ -605,21 +617,16 @@ io_fread(ptr, len, f)
|
||||||
|
|
||||||
#define SMALLBUF 100
|
#define SMALLBUF 100
|
||||||
|
|
||||||
static VALUE
|
static long
|
||||||
read_all(port)
|
remain_size(fptr)
|
||||||
VALUE port;
|
|
||||||
{
|
|
||||||
OpenFile *fptr;
|
OpenFile *fptr;
|
||||||
VALUE str = Qnil;
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
off_t siz = BUFSIZ;
|
off_t siz = BUFSIZ;
|
||||||
long bytes = 0;
|
long bytes = 0;
|
||||||
int n;
|
int n;
|
||||||
|
|
||||||
GetOpenFile(port, fptr);
|
if (feof(fptr->f)) return 0;
|
||||||
rb_io_check_readable(fptr);
|
|
||||||
|
|
||||||
if (feof(fptr->f)) return Qnil;
|
|
||||||
if (fstat(fileno(fptr->f), &st) == 0 && S_ISREG(st.st_mode)
|
if (fstat(fileno(fptr->f), &st) == 0 && S_ISREG(st.st_mode)
|
||||||
#ifdef __BEOS__
|
#ifdef __BEOS__
|
||||||
&& (st.st_dev > 3)
|
&& (st.st_dev > 3)
|
||||||
|
@ -629,12 +636,7 @@ read_all(port)
|
||||||
off_t pos;
|
off_t pos;
|
||||||
|
|
||||||
if (st.st_size == 0) {
|
if (st.st_size == 0) {
|
||||||
int c = getc(fptr->f);
|
return 1; /* force EOF */
|
||||||
|
|
||||||
if (c == EOF) {
|
|
||||||
return rb_str_new(0, 0);
|
|
||||||
}
|
|
||||||
ungetc(c, fptr->f);
|
|
||||||
}
|
}
|
||||||
pos = ftello(fptr->f);
|
pos = ftello(fptr->f);
|
||||||
if (st.st_size > pos && pos >= 0) {
|
if (st.st_size > pos && pos >= 0) {
|
||||||
|
@ -644,8 +646,22 @@ read_all(port)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
str = rb_tainted_str_new(0, (long)siz);
|
return (long)siz;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
read_all(fptr, siz)
|
||||||
|
OpenFile *fptr;
|
||||||
|
long siz;
|
||||||
|
{
|
||||||
|
VALUE str;
|
||||||
|
long bytes = 0;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
if (feof(fptr->f)) return Qnil;
|
||||||
READ_CHECK(fptr->f);
|
READ_CHECK(fptr->f);
|
||||||
|
if (!siz) siz = BUFSIZ;
|
||||||
|
str = rb_tainted_str_new(0, siz);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
n = io_fread(RSTRING(str)->ptr+bytes, (long)siz-bytes, fptr->f);
|
n = io_fread(RSTRING(str)->ptr+bytes, (long)siz-bytes, fptr->f);
|
||||||
if (n == 0 && bytes == 0) {
|
if (n == 0 && bytes == 0) {
|
||||||
|
@ -674,16 +690,17 @@ io_read(argc, argv, io)
|
||||||
VALUE length, str;
|
VALUE length, str;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "01", &length);
|
rb_scan_args(argc, argv, "01", &length);
|
||||||
|
|
||||||
|
GetOpenFile(io, fptr);
|
||||||
|
rb_io_check_readable(fptr);
|
||||||
if (NIL_P(length)) {
|
if (NIL_P(length)) {
|
||||||
return read_all(io);
|
return read_all(fptr, remain_size(fptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
len = NUM2INT(length);
|
len = NUM2INT(length);
|
||||||
if (len < 0) {
|
if (len < 0) {
|
||||||
rb_raise(rb_eArgError, "negative length %d given", len);
|
rb_raise(rb_eArgError, "negative length %d given", len);
|
||||||
}
|
}
|
||||||
GetOpenFile(io, fptr);
|
|
||||||
rb_io_check_readable(fptr);
|
|
||||||
|
|
||||||
if (feof(fptr->f)) return Qnil;
|
if (feof(fptr->f)) return Qnil;
|
||||||
str = rb_str_new(0, len);
|
str = rb_str_new(0, len);
|
||||||
|
@ -702,22 +719,47 @@ io_read(argc, argv, io)
|
||||||
return str;
|
return str;
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static int
|
||||||
rb_io_getline_fast(fptr)
|
appendline(fptr, delim, strp)
|
||||||
OpenFile *fptr;
|
OpenFile *fptr;
|
||||||
|
int delim;
|
||||||
|
VALUE *strp;
|
||||||
{
|
{
|
||||||
FILE *f = fptr->f;
|
FILE *f = fptr->f;
|
||||||
VALUE str = Qnil;
|
VALUE str = *strp;
|
||||||
int c;
|
int c = EOF;
|
||||||
|
#ifndef READ_DATA_PENDING_PTR
|
||||||
char buf[8192];
|
char buf[8192];
|
||||||
char *bp, *bpe = buf + sizeof buf - 3;
|
char *bp = buf, *bpe = buf + sizeof buf - 3;
|
||||||
int cnt;
|
int cnt;
|
||||||
int append = 0;
|
#endif
|
||||||
|
|
||||||
again:
|
do {
|
||||||
bp = buf;
|
#ifdef READ_DATA_PENDING_PTR
|
||||||
for (;;) {
|
int pending = READ_DATA_PENDING_COUNT(f);
|
||||||
|
if (pending > 0) {
|
||||||
|
const char *p = READ_DATA_PENDING_PTR(f);
|
||||||
|
const char *e = memchr(p, delim, pending);
|
||||||
|
long last = 0;
|
||||||
|
if (e) pending = e - p + 1;
|
||||||
|
if (!NIL_P(str)) {
|
||||||
|
last = RSTRING(str)->len;
|
||||||
|
rb_str_resize(str, last + (c != EOF) + pending);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*strp = str = rb_str_new(0, (c != EOF) + pending);
|
||||||
|
}
|
||||||
|
if (c != EOF) {
|
||||||
|
RSTRING(str)->ptr[last++] = c;
|
||||||
|
}
|
||||||
|
fread(RSTRING(str)->ptr + last, 1, pending, f); /* must not fail */
|
||||||
|
if (e) return delim;
|
||||||
|
}
|
||||||
|
rb_thread_wait_fd(fileno(f));
|
||||||
|
rb_io_check_closed(fptr);
|
||||||
|
#else
|
||||||
READ_CHECK(f);
|
READ_CHECK(f);
|
||||||
|
#endif
|
||||||
TRAP_BEG;
|
TRAP_BEG;
|
||||||
c = getc(f);
|
c = getc(f);
|
||||||
TRAP_END;
|
TRAP_END;
|
||||||
|
@ -726,29 +768,86 @@ rb_io_getline_fast(fptr)
|
||||||
if (errno == EINTR) continue;
|
if (errno == EINTR) continue;
|
||||||
rb_sys_fail(fptr->path);
|
rb_sys_fail(fptr->path);
|
||||||
}
|
}
|
||||||
break;
|
return c;
|
||||||
|
}
|
||||||
|
#ifndef READ_DATA_PENDING_PTR
|
||||||
|
if ((*bp++ = c) == delim || bp == bpe) {
|
||||||
|
cnt = bp - buf;
|
||||||
|
|
||||||
|
if (cnt > 0) {
|
||||||
|
if (!NIL_P(str))
|
||||||
|
rb_str_cat(str, buf, cnt);
|
||||||
|
else
|
||||||
|
*strp = str = rb_str_new(buf, cnt);
|
||||||
|
}
|
||||||
|
bp = buf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} while (c != delim);
|
||||||
|
|
||||||
|
#ifdef READ_DATA_PENDING_PTR
|
||||||
|
{
|
||||||
|
char ch = c;
|
||||||
|
if (!NIL_P(str)) {
|
||||||
|
rb_str_cat(str, &ch, 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*strp = str = rb_str_new(&ch, 1);
|
||||||
}
|
}
|
||||||
if ((*bp++ = c) == '\n') break;
|
|
||||||
if (bp == bpe) break;
|
|
||||||
}
|
}
|
||||||
cnt = bp - buf;
|
#endif
|
||||||
|
|
||||||
if (c == EOF && !append && cnt == 0) {
|
return c;
|
||||||
str = Qnil;
|
}
|
||||||
goto return_gets;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (append)
|
static inline int
|
||||||
rb_str_cat(str, buf, cnt);
|
swallow(fptr, term)
|
||||||
else
|
OpenFile *fptr;
|
||||||
str = rb_str_new(buf, cnt);
|
int term;
|
||||||
|
{
|
||||||
|
FILE *f = fptr->f;
|
||||||
|
int c;
|
||||||
|
|
||||||
if (c != EOF && RSTRING(str)->ptr[RSTRING(str)->len-1] != '\n') {
|
do {
|
||||||
append = 1;
|
#ifdef READ_DATA_PENDING_PTR
|
||||||
goto again;
|
int cnt;
|
||||||
}
|
while ((cnt = READ_DATA_PENDING_COUNT(f)) > 0) {
|
||||||
|
char buf[1024];
|
||||||
|
const char *p = READ_DATA_PENDING_PTR(f);
|
||||||
|
int i;
|
||||||
|
if (cnt > sizeof buf) cnt = sizeof buf;
|
||||||
|
if (*p != term) return Qtrue;
|
||||||
|
i = cnt;
|
||||||
|
while (--i && *++p == term);
|
||||||
|
if (!fread(buf, 1, cnt - i, f)) /* must not fail */
|
||||||
|
rb_sys_fail(fptr->path);
|
||||||
|
}
|
||||||
|
rb_thread_wait_fd(fileno(f));
|
||||||
|
rb_io_check_closed(fptr);
|
||||||
|
#else
|
||||||
|
READ_CHECK(f);
|
||||||
|
#endif
|
||||||
|
TRAP_BEG;
|
||||||
|
c = getc(f);
|
||||||
|
TRAP_END;
|
||||||
|
if (c != term) {
|
||||||
|
ungetc(c, f);
|
||||||
|
return Qtrue;
|
||||||
|
}
|
||||||
|
} while (c != EOF);
|
||||||
|
return Qfalse;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_io_getline_fast(fptr, delim)
|
||||||
|
OpenFile *fptr;
|
||||||
|
int delim;
|
||||||
|
{
|
||||||
|
VALUE str = Qnil;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
while ((c = appendline(fptr, delim, &str)) != EOF && c != delim);
|
||||||
|
|
||||||
return_gets:
|
|
||||||
if (!NIL_P(str)) {
|
if (!NIL_P(str)) {
|
||||||
fptr->lineno++;
|
fptr->lineno++;
|
||||||
lineno = INT2FIX(fptr->lineno);
|
lineno = INT2FIX(fptr->lineno);
|
||||||
|
@ -763,118 +862,42 @@ rb_io_getline(rs, fptr)
|
||||||
VALUE rs;
|
VALUE rs;
|
||||||
OpenFile *fptr;
|
OpenFile *fptr;
|
||||||
{
|
{
|
||||||
FILE *f;
|
|
||||||
VALUE str = Qnil;
|
VALUE str = Qnil;
|
||||||
int c, newline;
|
|
||||||
char *rsptr;
|
|
||||||
int rslen, rspara = 0;
|
|
||||||
|
|
||||||
if (NIL_P(rs)) {
|
if (NIL_P(rs)) {
|
||||||
rsptr = 0;
|
str = read_all(fptr, 0);
|
||||||
rslen = 0;
|
|
||||||
}
|
}
|
||||||
else if (rs == rb_default_rs) {
|
else if (rs == rb_default_rs) {
|
||||||
return rb_io_getline_fast(fptr);
|
return rb_io_getline_fast(fptr, '\n');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
int c, newline;
|
||||||
|
char *rsptr;
|
||||||
|
int rslen, rspara = 0;
|
||||||
|
|
||||||
StringValue(rs);
|
StringValue(rs);
|
||||||
rslen = RSTRING(rs)->len;
|
rslen = RSTRING(rs)->len;
|
||||||
if (rslen == 0) {
|
if (rslen == 0) {
|
||||||
rsptr = "\n\n";
|
rsptr = "\n\n";
|
||||||
rslen = 2;
|
rslen = 2;
|
||||||
rspara = 1;
|
rspara = 1;
|
||||||
|
swallow(fptr, '\n');
|
||||||
}
|
}
|
||||||
else if (rslen == 1 && RSTRING(rs)->ptr[0] == '\n') {
|
else if (rslen == 1) {
|
||||||
return rb_io_getline_fast(fptr);
|
return rb_io_getline_fast(fptr, RSTRING(rs)->ptr[0]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rsptr = RSTRING(rs)->ptr;
|
rsptr = RSTRING(rs)->ptr;
|
||||||
}
|
}
|
||||||
}
|
newline = rsptr[rslen - 1];
|
||||||
|
|
||||||
f = fptr->f;
|
while ((c = appendline(fptr, newline, &str)) != EOF &&
|
||||||
if (rspara) {
|
(c != newline || RSTRING(str)->len < rslen ||
|
||||||
do {
|
memcmp(RSTRING(str)->ptr+RSTRING(str)->len-rslen,rsptr,rslen)));
|
||||||
READ_CHECK(f);
|
|
||||||
TRAP_BEG;
|
|
||||||
c = getc(f);
|
|
||||||
TRAP_END;
|
|
||||||
if (c != '\n') {
|
|
||||||
ungetc(c,f);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (c != EOF);
|
|
||||||
}
|
|
||||||
|
|
||||||
newline = rslen ? rsptr[rslen - 1] : 0777;
|
if (rspara) {
|
||||||
{
|
if (c != EOF) {
|
||||||
char buf[8192];
|
swallow(fptr, '\n');
|
||||||
char *bp, *bpe = buf + sizeof buf - 3;
|
|
||||||
int cnt;
|
|
||||||
int append = 0;
|
|
||||||
|
|
||||||
again:
|
|
||||||
bp = buf;
|
|
||||||
|
|
||||||
if (rslen) {
|
|
||||||
for (;;) {
|
|
||||||
READ_CHECK(f);
|
|
||||||
TRAP_BEG;
|
|
||||||
c = getc(f);
|
|
||||||
TRAP_END;
|
|
||||||
if (c == EOF) {
|
|
||||||
if (ferror(f)) {
|
|
||||||
if (errno == EINTR) continue;
|
|
||||||
rb_sys_fail(fptr->path);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ((*bp++ = c) == newline) break;
|
|
||||||
if (bp == bpe) break;
|
|
||||||
}
|
|
||||||
cnt = bp - buf;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
READ_CHECK(f);
|
|
||||||
cnt = io_fread(buf, sizeof(buf), f);
|
|
||||||
if (cnt == 0) {
|
|
||||||
if (ferror(f)) rb_sys_fail(fptr->path);
|
|
||||||
c = EOF;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
c = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c == EOF && !append && cnt == 0) {
|
|
||||||
str = Qnil;
|
|
||||||
goto return_gets;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (append)
|
|
||||||
rb_str_cat(str, buf, cnt);
|
|
||||||
else
|
|
||||||
str = rb_str_new(buf, cnt);
|
|
||||||
|
|
||||||
if (c != EOF &&
|
|
||||||
(!rslen ||
|
|
||||||
RSTRING(str)->len < rslen ||
|
|
||||||
memcmp(RSTRING(str)->ptr+RSTRING(str)->len-rslen,rsptr,rslen))) {
|
|
||||||
append = 1;
|
|
||||||
goto again;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return_gets:
|
|
||||||
if (rspara) {
|
|
||||||
while (c != EOF) {
|
|
||||||
READ_CHECK(f);
|
|
||||||
TRAP_BEG;
|
|
||||||
c = getc(f);
|
|
||||||
TRAP_END;
|
|
||||||
if (c != '\n') {
|
|
||||||
ungetc(c, f);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -896,7 +919,7 @@ rb_io_gets(io)
|
||||||
|
|
||||||
GetOpenFile(io, fptr);
|
GetOpenFile(io, fptr);
|
||||||
rb_io_check_readable(fptr);
|
rb_io_check_readable(fptr);
|
||||||
return rb_io_getline_fast(fptr);
|
return rb_io_getline_fast(fptr, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
|
@ -2871,11 +2894,14 @@ rb_f_backquote(obj, str)
|
||||||
VALUE obj, str;
|
VALUE obj, str;
|
||||||
{
|
{
|
||||||
VALUE port, result;
|
VALUE port, result;
|
||||||
|
OpenFile *fptr;
|
||||||
|
|
||||||
SafeStringValue(str);
|
SafeStringValue(str);
|
||||||
port = pipe_open(RSTRING(str)->ptr, "r");
|
port = pipe_open(RSTRING(str)->ptr, "r");
|
||||||
if (NIL_P(port)) return rb_str_new(0,0);
|
if (NIL_P(port)) return rb_str_new(0,0);
|
||||||
result = read_all(port);
|
|
||||||
|
GetOpenFile(port, fptr);
|
||||||
|
result = read_all(fptr, remain_size(fptr));
|
||||||
|
|
||||||
rb_io_close(port);
|
rb_io_close(port);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue