summaryrefslogtreecommitdiff
path: root/ext/stringio/stringio.c
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-11-08 08:48:43 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-11-08 08:48:43 +0000
commitecdd96c58d715baa34290d140fc2b58e95f335b3 (patch)
tree06c3a71f07406c7dc131a0e6b310fc1fd31112ce /ext/stringio/stringio.c
parentef1e9185f4d05fbc27be3946def78e77c9ec0f15 (diff)
* ext/stringio/stringio.c (strio_ungetc): should allow ungetc at
the top of the buffer. ref #701 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@20151 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'ext/stringio/stringio.c')
-rw-r--r--ext/stringio/stringio.c25
1 files changed, 17 insertions, 8 deletions
diff --git a/ext/stringio/stringio.c b/ext/stringio/stringio.c
index 7838c51aa2..3ed7d6b1af 100644
--- a/ext/stringio/stringio.c
+++ b/ext/stringio/stringio.c
@@ -781,15 +781,24 @@ strio_ungetc(self, ch)
int cc = NUM2INT(ch);
long len, pos = ptr->pos;
- if (cc != EOF && pos > 0) {
- if ((len = RSTRING(ptr->string)->len) < pos-- ||
- (unsigned char)RSTRING(ptr->string)->ptr[pos] !=
- (unsigned char)cc) {
- strio_extend(ptr, pos, 1);
- RSTRING(ptr->string)->ptr[pos] = cc;
- OBJ_INFECT(ptr->string, self);
+ if (cc != EOF) {
+ len = RSTRING(ptr->string)->len;
+ if (pos == 0) {
+ char *p;
+ rb_str_resize(ptr->string, len + 1);
+ p = RSTRING(ptr->string)->ptr;
+ memmove(p + 1, p, len);
+ }
+ else {
+ if (len < pos-- ||
+ (unsigned char)RSTRING(ptr->string)->ptr[pos] !=
+ (unsigned char)cc) {
+ strio_extend(ptr, pos, 1);
+ }
+ --ptr->pos;
}
- --ptr->pos;
+ RSTRING(ptr->string)->ptr[pos] = cc;
+ OBJ_INFECT(ptr->string, self);
ptr->flags &= ~STRIO_EOF;
}
return Qnil;