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

* ext/stringio/stringio.c: fixed frozen string bug. ungetc no

longer raises on readonly stream unless modifies actually.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@2198 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
nobu 2002-03-14 03:35:52 +00:00
parent bce7601f73
commit 4f0870f74b
2 changed files with 51 additions and 14 deletions

View file

@ -1,3 +1,8 @@
Thu Mar 14 12:32:59 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* ext/stringio/stringio.c: fixed frozen string bug. ungetc no
longer raises on readonly stream unless modifies actually.
Thu Mar 14 08:57:41 2002 Nobuyoshi Nakada <nobu.nakada@nifty.ne.jp>
* dir.c (rb_push_glob): avoid SEGV when a block given.

View file

@ -4,6 +4,7 @@
$Author$
$Date$
$RoughId: stringio.c,v 1.13 2002/03/14 03:24:18 nobu Exp $
created at: Tue Feb 19 04:10:38 JST 2002
All the files in this distribution are covered under the Ruby's
@ -89,11 +90,15 @@ get_strio(self)
#define StringIO(obj) get_strio(obj)
#define CLOSED(ptr) NIL_P((ptr)->string)
#define READABLE(ptr) (!CLOSED(ptr) && ((ptr)->flags & FMODE_READABLE))
#define WRITABLE(ptr) (!CLOSED(ptr) && ((ptr)->flags & FMODE_WRITABLE))
static struct StringIO*
readable(ptr)
struct StringIO *ptr;
{
if (NIL_P(ptr->string) || !(ptr->flags & FMODE_READABLE)) {
if (!READABLE(ptr)) {
rb_raise(rb_eIOError, "not opened for reading");
}
return ptr;
@ -103,7 +108,7 @@ static struct StringIO*
writable(ptr)
struct StringIO *ptr;
{
if (NIL_P(ptr->string) || !(ptr->flags & FMODE_WRITABLE)) {
if (!WRITABLE(ptr)) {
rb_raise(rb_eIOError, "not opened for writing");
}
if (!OBJ_TAINTED(ptr->string)) {
@ -112,6 +117,16 @@ writable(ptr)
return ptr;
}
static struct StringIO*
check_modifiable(ptr)
struct StringIO *ptr;
{
if (OBJ_FROZEN(ptr->string)) {
rb_raise(rb_eIOError, "not modifiable string");
}
rb_str_modify(ptr->string);
}
static VALUE strio_s_allocate _((VALUE));
static VALUE strio_s_open _((int, VALUE *, VALUE));
static VALUE strio_initialize _((int, VALUE *, VALUE));
@ -199,6 +214,10 @@ strio_initialize(argc, argv, self)
StringValue(mode);
StringValue(string);
ptr->flags = rb_io_mode_flags(RSTRING(mode)->ptr);
if (ptr->flags & FMODE_WRITABLE && OBJ_FROZEN(string)) {
errno = EACCES;
rb_sys_fail(0);
}
switch (*RSTRING(mode)->ptr) {
case 'a':
ptr->flags |= STRIO_APPEND;
@ -210,7 +229,7 @@ strio_initialize(argc, argv, self)
break;
case 1:
StringValue(string);
ptr->flags = FMODE_READWRITE;
ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
break;
case 0:
string = rb_str_new("", 0);
@ -310,7 +329,7 @@ strio_close(self)
VALUE self;
{
struct StringIO *ptr = StringIO(self);
if (NIL_P(ptr->string)) {
if (CLOSED(ptr)) {
rb_raise(rb_eIOError, "closed stream");
}
ptr->string = Qnil;
@ -322,7 +341,10 @@ static VALUE
strio_close_read(self)
VALUE self;
{
struct StringIO *ptr = readable(StringIO(self));
struct StringIO *ptr = StringIO(self);
if (!READABLE(ptr)) {
rb_raise(rb_eIOError, "closing non-duplex IO for reading");
}
if (!((ptr->flags &= ~FMODE_READABLE) & FMODE_READWRITE)) {
ptr->string = Qnil;
}
@ -333,7 +355,10 @@ static VALUE
strio_close_write(self)
VALUE self;
{
struct StringIO *ptr = writable(StringIO(self));
struct StringIO *ptr = StringIO(self);
if (!WRITABLE(ptr)) {
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
}
if (!((ptr->flags &= ~FMODE_WRITABLE) & FMODE_READWRITE)) {
ptr->string = Qnil;
}
@ -345,7 +370,7 @@ strio_closed(self)
VALUE self;
{
struct StringIO *ptr = StringIO(self);
if (!NIL_P(ptr->string)) return Qfalse;
if (!CLOSED(ptr)) return Qfalse;
return Qtrue;
}
@ -354,7 +379,7 @@ strio_closed_read(self)
VALUE self;
{
struct StringIO *ptr = StringIO(self);
if (ptr->flags & FMODE_READABLE) return Qfalse;
if (READABLE(ptr)) return Qfalse;
return Qtrue;
}
@ -363,7 +388,7 @@ strio_closed_write(self)
VALUE self;
{
struct StringIO *ptr = StringIO(self);
if (ptr->flags & FMODE_WRITABLE) return Qfalse;
if (WRITABLE(ptr)) return Qfalse;
return Qtrue;
}
@ -371,9 +396,7 @@ static VALUE
strio_eof(self)
VALUE self;
{
struct StringIO *ptr = StringIO(self);
if (!(ptr->flags & FMODE_READABLE)) return Qtrue;
if (NIL_P(ptr->string)) return Qtrue;
struct StringIO *ptr = readable(StringIO(self));
if (ptr->pos < RSTRING(ptr->string)->len) return Qfalse;
return Qtrue;
}
@ -521,8 +544,11 @@ strio_ungetc(self, ch)
int cc = NUM2INT(ch);
if (cc != EOF && ptr->pos > 0) {
rb_str_modify(ptr->string);
RSTRING(ptr->string)->ptr[--ptr->pos] = cc;
if ((unsigned char)RSTRING(ptr->string)->ptr[--ptr->pos] !=
(unsigned char)cc) {
check_modifiable(ptr);
RSTRING(ptr->string)->ptr[ptr->pos] = cc;
}
}
return Qnil;
}
@ -708,6 +734,8 @@ strio_write(self, str)
if (TYPE(str) != T_STRING)
str = rb_obj_as_string(str);
len = RSTRING(str)->len;
if (!len) return INT2FIX(0);
check_modifiable(ptr);
if (ptr->flags & STRIO_APPEND) {
ptr->pos = RSTRING(ptr->string)->len;
}
@ -732,6 +760,10 @@ strio_putc(self, ch)
struct StringIO *ptr = writable(StringIO(self));
int c = NUM2CHR(ch);
check_modifiable(ptr);
if (ptr->flags & STRIO_APPEND) {
ptr->pos = RSTRING(ptr->string)->len;
}
if (ptr->pos >= RSTRING(ptr->string)->len) {
rb_str_resize(ptr->string, ptr->pos + 1);
}