2021-03-07 08:39:38 -05:00
|
|
|
/* -*- mode: c; indent-tabs-mode: t -*- */
|
2002-03-11 06:58:07 -05:00
|
|
|
/**********************************************************************
|
|
|
|
|
|
|
|
stringio.c -
|
|
|
|
|
|
|
|
$Author$
|
2002-03-13 22:35:52 -05:00
|
|
|
$RoughId: stringio.c,v 1.13 2002/03/14 03:24:18 nobu Exp $
|
2002-03-11 06:58:07 -05:00
|
|
|
created at: Tue Feb 19 04:10:38 JST 2002
|
|
|
|
|
|
|
|
All the files in this distribution are covered under the Ruby's
|
|
|
|
license (see the file COPYING).
|
|
|
|
|
|
|
|
**********************************************************************/
|
|
|
|
|
2022-05-09 03:47:06 -04:00
|
|
|
#define STRINGIO_VERSION "3.0.3"
|
2019-07-09 12:21:05 -04:00
|
|
|
|
2002-03-11 06:58:07 -05:00
|
|
|
#include "ruby.h"
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
#include "ruby/io.h"
|
2008-10-21 10:14:13 -04:00
|
|
|
#include "ruby/encoding.h"
|
2004-11-17 21:27:00 -05:00
|
|
|
#if defined(HAVE_FCNTL_H) || defined(_WIN32)
|
|
|
|
#include <fcntl.h>
|
|
|
|
#elif defined(HAVE_SYS_FCNTL_H)
|
|
|
|
#include <sys/fcntl.h>
|
|
|
|
#endif
|
2002-03-11 06:58:07 -05:00
|
|
|
|
2017-03-22 09:55:03 -04:00
|
|
|
#ifndef RB_INTEGER_TYPE_P
|
|
|
|
# define RB_INTEGER_TYPE_P(c) (FIXNUM_P(c) || RB_TYPE_P(c, T_BIGNUM))
|
|
|
|
#endif
|
|
|
|
|
2019-09-29 05:06:02 -04:00
|
|
|
#ifndef RB_PASS_CALLED_KEYWORDS
|
|
|
|
# define rb_funcallv_kw(recv, mid, arg, argv, kw_splat) rb_funcallv(recv, mid, arg, argv)
|
|
|
|
# define rb_class_new_instance_kw(argc, argv, klass, kw_splat) rb_class_new_instance(argc, argv, klass)
|
|
|
|
#endif
|
|
|
|
|
2019-08-13 14:02:30 -04:00
|
|
|
#ifndef HAVE_RB_IO_EXTRACT_MODEENC
|
|
|
|
#define rb_io_extract_modeenc strio_extract_modeenc
|
|
|
|
static void
|
|
|
|
strio_extract_modeenc(VALUE *vmode_p, VALUE *vperm_p, VALUE opthash,
|
|
|
|
int *oflags_p, int *fmode_p, struct rb_io_enc_t *convconfig_p)
|
|
|
|
{
|
|
|
|
VALUE mode = *vmode_p;
|
2019-08-13 21:42:14 -04:00
|
|
|
VALUE intmode;
|
2019-08-13 14:02:30 -04:00
|
|
|
int fmode;
|
2019-08-13 21:42:46 -04:00
|
|
|
int has_enc = 0, has_vmode = 0;
|
2019-08-13 14:02:30 -04:00
|
|
|
|
|
|
|
convconfig_p->enc = convconfig_p->enc2 = 0;
|
2019-08-13 21:42:46 -04:00
|
|
|
|
|
|
|
vmode_handle:
|
2019-08-13 14:02:30 -04:00
|
|
|
if (NIL_P(mode)) {
|
|
|
|
fmode = FMODE_READABLE;
|
|
|
|
}
|
2019-08-13 21:42:14 -04:00
|
|
|
else if (!NIL_P(intmode = rb_check_to_integer(mode, "to_int"))) {
|
|
|
|
int flags = NUM2INT(intmode);
|
2019-08-13 14:02:30 -04:00
|
|
|
fmode = rb_io_oflags_fmode(flags);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
const char *m = StringValueCStr(mode), *n, *e;
|
|
|
|
fmode = rb_io_modestr_fmode(m);
|
|
|
|
n = strchr(m, ':');
|
|
|
|
if (n) {
|
|
|
|
long len;
|
|
|
|
char encname[ENCODING_MAXNAMELEN+1];
|
2019-08-13 21:42:46 -04:00
|
|
|
has_enc = 1;
|
2019-08-13 14:02:30 -04:00
|
|
|
if (fmode & FMODE_SETENC_BY_BOM) {
|
|
|
|
n = strchr(n, '|');
|
|
|
|
}
|
|
|
|
e = strchr(++n, ':');
|
2021-07-08 03:38:08 -04:00
|
|
|
len = e ? e - n : (long)strlen(n);
|
2019-08-13 14:02:30 -04:00
|
|
|
if (len > 0 && len <= ENCODING_MAXNAMELEN) {
|
2022-05-30 01:16:03 -04:00
|
|
|
rb_encoding *enc;
|
2019-08-13 14:02:30 -04:00
|
|
|
if (e) {
|
|
|
|
memcpy(encname, n, len);
|
|
|
|
encname[len] = '\0';
|
|
|
|
n = encname;
|
|
|
|
}
|
2022-05-30 01:16:03 -04:00
|
|
|
enc = rb_enc_find(n);
|
|
|
|
if (e)
|
|
|
|
convconfig_p->enc2 = enc;
|
|
|
|
else
|
|
|
|
convconfig_p->enc = enc;
|
2019-08-13 14:02:30 -04:00
|
|
|
}
|
|
|
|
if (e && (len = strlen(++e)) > 0 && len <= ENCODING_MAXNAMELEN) {
|
2022-05-30 01:16:03 -04:00
|
|
|
convconfig_p->enc = rb_enc_find(e);
|
2019-08-13 14:02:30 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!NIL_P(opthash)) {
|
|
|
|
rb_encoding *extenc = 0, *intenc = 0;
|
2019-08-13 21:42:46 -04:00
|
|
|
VALUE v;
|
|
|
|
if (!has_vmode) {
|
|
|
|
ID id_mode;
|
|
|
|
CONST_ID(id_mode, "mode");
|
|
|
|
v = rb_hash_aref(opthash, ID2SYM(id_mode));
|
|
|
|
if (!NIL_P(v)) {
|
|
|
|
if (!NIL_P(mode)) {
|
|
|
|
rb_raise(rb_eArgError, "mode specified twice");
|
|
|
|
}
|
|
|
|
has_vmode = 1;
|
|
|
|
mode = v;
|
|
|
|
goto vmode_handle;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-13 14:02:30 -04:00
|
|
|
if (rb_io_extract_encoding_option(opthash, &extenc, &intenc, &fmode)) {
|
2019-08-13 21:42:46 -04:00
|
|
|
if (has_enc) {
|
2019-08-13 14:02:30 -04:00
|
|
|
rb_raise(rb_eArgError, "encoding specified twice");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
*fmode_p = fmode;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2002-03-11 06:58:07 -05:00
|
|
|
struct StringIO {
|
|
|
|
VALUE string;
|
2015-12-18 02:54:33 -05:00
|
|
|
rb_encoding *enc;
|
2002-03-11 06:58:07 -05:00
|
|
|
long pos;
|
|
|
|
long lineno;
|
|
|
|
int flags;
|
|
|
|
int count;
|
|
|
|
};
|
|
|
|
|
2016-06-09 00:44:32 -04:00
|
|
|
static VALUE strio_init(int, VALUE *, struct StringIO *, VALUE);
|
2015-12-18 01:40:00 -05:00
|
|
|
static VALUE strio_unget_bytes(struct StringIO *, const char *, long);
|
2017-10-23 02:25:39 -04:00
|
|
|
static long strio_write(VALUE self, VALUE str);
|
2002-03-11 06:58:07 -05:00
|
|
|
|
2011-03-29 11:25:25 -04:00
|
|
|
#define IS_STRIO(obj) (rb_typeddata_is_kind_of((obj), &strio_data_type))
|
2015-12-23 03:57:48 -05:00
|
|
|
#define error_inval(msg) (rb_syserr_fail(EINVAL, msg))
|
2015-12-18 02:54:33 -05:00
|
|
|
#define get_enc(ptr) ((ptr)->enc ? (ptr)->enc : rb_enc_get((ptr)->string))
|
2002-03-11 06:58:07 -05:00
|
|
|
|
|
|
|
static struct StringIO *
|
2009-10-27 09:14:52 -04:00
|
|
|
strio_alloc(void)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
struct StringIO *ptr = ALLOC(struct StringIO);
|
|
|
|
ptr->string = Qnil;
|
|
|
|
ptr->pos = 0;
|
|
|
|
ptr->lineno = 0;
|
|
|
|
ptr->flags = 0;
|
|
|
|
ptr->count = 1;
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-10-27 09:14:52 -04:00
|
|
|
strio_mark(void *p)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2009-10-27 09:14:52 -04:00
|
|
|
struct StringIO *ptr = p;
|
2017-03-17 15:59:56 -04:00
|
|
|
|
|
|
|
rb_gc_mark(ptr->string);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2009-10-27 09:14:52 -04:00
|
|
|
strio_free(void *p)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2009-10-27 09:14:52 -04:00
|
|
|
struct StringIO *ptr = p;
|
2002-03-11 06:58:07 -05:00
|
|
|
if (--ptr->count <= 0) {
|
|
|
|
xfree(ptr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-10-27 09:14:52 -04:00
|
|
|
static size_t
|
|
|
|
strio_memsize(const void *p)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2009-10-27 09:14:52 -04:00
|
|
|
return sizeof(struct StringIO);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2009-10-27 09:14:52 -04:00
|
|
|
static const rb_data_type_t strio_data_type = {
|
|
|
|
"strio",
|
2010-07-18 03:31:54 -04:00
|
|
|
{
|
|
|
|
strio_mark,
|
|
|
|
strio_free,
|
|
|
|
strio_memsize,
|
|
|
|
},
|
2014-12-01 01:38:04 -05:00
|
|
|
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
|
2009-10-27 09:14:52 -04:00
|
|
|
};
|
|
|
|
|
2011-03-29 11:25:25 -04:00
|
|
|
#define check_strio(self) ((struct StringIO*)rb_check_typeddata((self), &strio_data_type))
|
2009-10-27 09:14:52 -04:00
|
|
|
|
2002-03-11 06:58:07 -05:00
|
|
|
static struct StringIO*
|
2006-06-20 14:02:17 -04:00
|
|
|
get_strio(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2011-01-05 15:14:43 -05:00
|
|
|
struct StringIO *ptr = check_strio(rb_io_taint_check(self));
|
2002-03-11 06:58:07 -05:00
|
|
|
|
|
|
|
if (!ptr) {
|
|
|
|
rb_raise(rb_eIOError, "uninitialized stream");
|
|
|
|
}
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2016-05-30 01:54:59 -04:00
|
|
|
static VALUE
|
|
|
|
enc_subseq(VALUE str, long pos, long len, rb_encoding *enc)
|
|
|
|
{
|
|
|
|
str = rb_str_subseq(str, pos, len);
|
|
|
|
rb_enc_associate(str, enc);
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
static VALUE
|
2017-08-13 03:31:49 -04:00
|
|
|
strio_substr(struct StringIO *ptr, long pos, long len, rb_encoding *enc)
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
{
|
|
|
|
VALUE str = ptr->string;
|
2009-04-05 21:47:15 -04:00
|
|
|
long rlen = RSTRING_LEN(str) - pos;
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
|
|
|
|
if (len > rlen) len = rlen;
|
|
|
|
if (len < 0) len = 0;
|
2017-08-13 03:31:49 -04:00
|
|
|
if (len == 0) return rb_enc_str_new(0, 0, enc);
|
2016-05-30 01:54:59 -04:00
|
|
|
return enc_subseq(str, pos, len, enc);
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
}
|
|
|
|
|
2002-03-11 06:58:07 -05:00
|
|
|
#define StringIO(obj) get_strio(obj)
|
|
|
|
|
2012-10-29 05:23:02 -04:00
|
|
|
#define STRIO_READABLE FL_USER4
|
|
|
|
#define STRIO_WRITABLE FL_USER5
|
|
|
|
#define STRIO_READWRITE (STRIO_READABLE|STRIO_WRITABLE)
|
|
|
|
typedef char strio_flags_check[(STRIO_READABLE/FMODE_READABLE == STRIO_WRITABLE/FMODE_WRITABLE) * 2 - 1];
|
|
|
|
#define STRIO_MODE_SET_P(strio, mode) \
|
|
|
|
((RBASIC(strio)->flags & STRIO_##mode) && \
|
|
|
|
((struct StringIO*)DATA_PTR(strio))->flags & FMODE_##mode)
|
|
|
|
#define CLOSED(strio) (!STRIO_MODE_SET_P(strio, READWRITE))
|
|
|
|
#define READABLE(strio) STRIO_MODE_SET_P(strio, READABLE)
|
|
|
|
#define WRITABLE(strio) STRIO_MODE_SET_P(strio, WRITABLE)
|
2002-03-13 22:35:52 -05:00
|
|
|
|
2013-08-26 18:41:44 -04:00
|
|
|
static VALUE sym_exception;
|
|
|
|
|
2002-03-11 06:58:07 -05:00
|
|
|
static struct StringIO*
|
2012-10-29 05:23:02 -04:00
|
|
|
readable(VALUE strio)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
struct StringIO *ptr = StringIO(strio);
|
|
|
|
if (!READABLE(strio)) {
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_raise(rb_eIOError, "not opened for reading");
|
|
|
|
}
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct StringIO*
|
2012-10-29 05:23:02 -04:00
|
|
|
writable(VALUE strio)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
struct StringIO *ptr = StringIO(strio);
|
|
|
|
if (!WRITABLE(strio)) {
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_raise(rb_eIOError, "not opened for writing");
|
|
|
|
}
|
|
|
|
return ptr;
|
|
|
|
}
|
|
|
|
|
2002-03-18 08:21:01 -05:00
|
|
|
static void
|
2006-06-20 14:02:17 -04:00
|
|
|
check_modifiable(struct StringIO *ptr)
|
2002-03-13 22:35:52 -05:00
|
|
|
{
|
|
|
|
if (OBJ_FROZEN(ptr->string)) {
|
|
|
|
rb_raise(rb_eIOError, "not modifiable string");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2007-08-14 20:33:33 -04:00
|
|
|
strio_s_allocate(VALUE klass)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2009-10-27 09:14:52 -04:00
|
|
|
return TypedData_Wrap_Struct(klass, &strio_data_type, 0);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq: StringIO.new(string=""[, mode])
|
|
|
|
*
|
|
|
|
* Creates new StringIO instance from with _string_ and _mode_.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_initialize(int argc, VALUE *argv, VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
struct StringIO *ptr = check_strio(self);
|
|
|
|
|
|
|
|
if (!ptr) {
|
|
|
|
DATA_PTR(self) = ptr = strio_alloc();
|
|
|
|
}
|
|
|
|
rb_call_super(0, 0);
|
2016-06-09 00:44:32 -04:00
|
|
|
return strio_init(argc, argv, ptr, self);
|
2007-09-21 16:19:51 -04:00
|
|
|
}
|
|
|
|
|
2019-08-13 21:43:46 -04:00
|
|
|
static int
|
|
|
|
detect_bom(VALUE str, int *bomlen)
|
|
|
|
{
|
|
|
|
const char *p;
|
|
|
|
long len;
|
|
|
|
|
|
|
|
RSTRING_GETMEM(str, p, len);
|
|
|
|
if (len < 1) return 0;
|
|
|
|
switch ((unsigned char)p[0]) {
|
|
|
|
case 0xEF:
|
|
|
|
if (len < 2) break;
|
|
|
|
if ((unsigned char)p[1] == 0xBB && len > 2) {
|
|
|
|
if ((unsigned char)p[2] == 0xBF) {
|
|
|
|
*bomlen = 3;
|
|
|
|
return rb_utf8_encindex();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xFE:
|
|
|
|
if (len < 2) break;
|
|
|
|
if ((unsigned char)p[1] == 0xFF) {
|
|
|
|
*bomlen = 2;
|
|
|
|
return rb_enc_find_index("UTF-16BE");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0xFF:
|
|
|
|
if (len < 2) break;
|
|
|
|
if ((unsigned char)p[1] == 0xFE) {
|
|
|
|
if (len >= 4 && (unsigned char)p[2] == 0 && (unsigned char)p[3] == 0) {
|
|
|
|
*bomlen = 4;
|
|
|
|
return rb_enc_find_index("UTF-32LE");
|
|
|
|
}
|
|
|
|
*bomlen = 2;
|
|
|
|
return rb_enc_find_index("UTF-16LE");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0:
|
|
|
|
if (len < 4) break;
|
2019-08-23 07:43:15 -04:00
|
|
|
if ((unsigned char)p[1] == 0 && (unsigned char)p[2] == 0xFE && (unsigned char)p[3] == 0xFF) {
|
2019-08-13 21:43:46 -04:00
|
|
|
*bomlen = 4;
|
|
|
|
return rb_enc_find_index("UTF-32BE");
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static rb_encoding *
|
|
|
|
set_encoding_by_bom(struct StringIO *ptr)
|
|
|
|
{
|
|
|
|
int bomlen, idx = detect_bom(ptr->string, &bomlen);
|
|
|
|
rb_encoding *extenc = NULL;
|
|
|
|
|
|
|
|
if (idx) {
|
|
|
|
extenc = rb_enc_from_index(idx);
|
|
|
|
ptr->pos = bomlen;
|
|
|
|
if (ptr->flags & FMODE_WRITABLE) {
|
|
|
|
rb_enc_associate_index(ptr->string, idx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ptr->enc = extenc;
|
|
|
|
return extenc;
|
|
|
|
}
|
|
|
|
|
2016-06-09 00:44:32 -04:00
|
|
|
static VALUE
|
2012-10-29 05:23:02 -04:00
|
|
|
strio_init(int argc, VALUE *argv, struct StringIO *ptr, VALUE self)
|
2007-09-21 16:19:51 -04:00
|
|
|
{
|
2016-06-10 01:18:14 -04:00
|
|
|
VALUE string, vmode, opt;
|
|
|
|
int oflags;
|
|
|
|
struct rb_io_enc_t convconfig;
|
|
|
|
|
|
|
|
argc = rb_scan_args(argc, argv, "02:", &string, &vmode, &opt);
|
|
|
|
rb_io_extract_modeenc(&vmode, 0, opt, &oflags, &ptr->flags, &convconfig);
|
|
|
|
if (argc) {
|
2002-03-11 06:58:07 -05:00
|
|
|
StringValue(string);
|
2016-06-10 01:18:14 -04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
string = rb_enc_str_new("", 0, rb_default_external_encoding());
|
|
|
|
}
|
|
|
|
if (OBJ_FROZEN_RAW(string)) {
|
|
|
|
if (ptr->flags & FMODE_WRITABLE) {
|
2015-12-23 03:57:48 -05:00
|
|
|
rb_syserr_fail(EACCES, 0);
|
2002-03-13 22:35:52 -05:00
|
|
|
}
|
2016-06-10 01:18:14 -04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (NIL_P(vmode)) {
|
|
|
|
ptr->flags |= FMODE_WRITABLE;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
2016-06-10 01:18:14 -04:00
|
|
|
}
|
|
|
|
if (ptr->flags & FMODE_TRUNC) {
|
|
|
|
rb_str_resize(string, 0);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
ptr->string = string;
|
2020-03-12 08:55:20 -04:00
|
|
|
if (argc == 1) {
|
|
|
|
ptr->enc = rb_enc_get(string);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ptr->enc = convconfig.enc;
|
|
|
|
}
|
2008-06-11 13:50:03 -04:00
|
|
|
ptr->pos = 0;
|
|
|
|
ptr->lineno = 0;
|
2019-08-13 21:43:46 -04:00
|
|
|
if (ptr->flags & FMODE_SETENC_BY_BOM) set_encoding_by_bom(ptr);
|
2012-10-29 05:23:02 -04:00
|
|
|
RBASIC(self)->flags |= (ptr->flags & FMODE_READWRITE) * (STRIO_READABLE / FMODE_READABLE);
|
2016-06-09 00:44:32 -04:00
|
|
|
return self;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_finalize(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
struct StringIO *ptr = StringIO(self);
|
|
|
|
ptr->string = Qnil;
|
|
|
|
ptr->flags &= ~FMODE_READWRITE;
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2007-08-14 20:33:33 -04:00
|
|
|
/*
|
|
|
|
* call-seq: StringIO.open(string=""[, mode]) {|strio| ...}
|
|
|
|
*
|
|
|
|
* Equivalent to StringIO.new except that when it is called with a block, it
|
|
|
|
* yields with the new instance and closes it, and returns the result which
|
|
|
|
* returned from the block.
|
|
|
|
*/
|
|
|
|
static VALUE
|
|
|
|
strio_s_open(int argc, VALUE *argv, VALUE klass)
|
|
|
|
{
|
Make rb_scan_args handle keywords more similar to Ruby methods (#2460)
Cfuncs that use rb_scan_args with the : entry suffer similar keyword
argument separation issues that Ruby methods suffer if the cfuncs
accept optional or variable arguments.
This makes the following changes to : handling.
* Treats as **kw, prompting keyword argument separation warnings
if called with a positional hash.
* Do not look for an option hash if empty keywords are provided.
For backwards compatibility, treat an empty keyword splat as a empty
mandatory positional hash argument, but emit a a warning, as this
behavior will be removed in Ruby 3. The argument number check
needs to be moved lower so it can correctly handle an empty
positional argument being added.
* If the last argument is nil and it is necessary to treat it as an option
hash in order to make sure all arguments are processed, continue to
treat the last argument as the option hash. Emit a warning in this case,
as this behavior will be removed in Ruby 3.
* If splitting the keyword hash into two hashes, issue a warning, as we
will not be splitting hashes in Ruby 3.
* If the keyword argument is required to fill a mandatory positional
argument, continue to do so, but emit a warning as this behavior will
be going away in Ruby 3.
* If keyword arguments are provided and the last argument is not a hash,
that indicates something wrong. This can happen if a cfunc is calling
rb_scan_args multiple times, and providing arguments that were not
passed to it from Ruby. Callers need to switch to the new
rb_scan_args_kw function, which allows passing of whether keywords
were provided.
This commit fixes all warnings caused by the changes above.
It switches some function calls to *_kw versions with appropriate
kw_splat flags. If delegating arguments, RB_PASS_CALLED_KEYWORDS
is used. If creating new arguments, RB_PASS_KEYWORDS is used if
the last argument is a hash to be treated as keywords.
In open_key_args in io.c, use rb_scan_args_kw.
In this case, the arguments provided come from another C
function, not Ruby. The last argument may or may not be a hash,
so we can't set keyword argument mode. However, if it is a
hash, we don't want to warn when treating it as keywords.
In Ruby files, make sure to appropriately use keyword splats
or literal keywords when calling Cfuncs that now issue keyword
argument separation warnings through rb_scan_args. Also, make
sure not to pass nil in place of an option hash.
Work around Kernel#warn warnings due to problems in the Rubygems
override of the method. There is an open pull request to fix
these issues in Rubygems, but part of the Rubygems tests for
their override fail on ruby-head due to rb_scan_args not
recognizing empty keyword splats, which this commit fixes.
Implementation wise, adding rb_scan_args_kw is kind of a pain,
because rb_scan_args takes a variable number of arguments.
In order to not duplicate all the code, the function internals need
to be split into two functions taking a va_list, and to avoid passing
in a ton of arguments, a single struct argument is used to handle
the variables previously local to the function.
2019-09-25 14:18:49 -04:00
|
|
|
VALUE obj = rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
|
2007-08-14 20:33:33 -04:00
|
|
|
if (!rb_block_given_p()) return obj;
|
|
|
|
return rb_ensure(rb_yield, obj, strio_finalize, obj);
|
|
|
|
}
|
|
|
|
|
2016-04-27 02:47:56 -04:00
|
|
|
/* :nodoc: */
|
|
|
|
static VALUE
|
|
|
|
strio_s_new(int argc, VALUE *argv, VALUE klass)
|
|
|
|
{
|
|
|
|
if (rb_block_given_p()) {
|
|
|
|
VALUE cname = rb_obj_as_string(klass);
|
|
|
|
|
|
|
|
rb_warn("%"PRIsVALUE"::new() does not take block; use %"PRIsVALUE"::open() instead",
|
|
|
|
cname, cname);
|
|
|
|
}
|
Make rb_scan_args handle keywords more similar to Ruby methods (#2460)
Cfuncs that use rb_scan_args with the : entry suffer similar keyword
argument separation issues that Ruby methods suffer if the cfuncs
accept optional or variable arguments.
This makes the following changes to : handling.
* Treats as **kw, prompting keyword argument separation warnings
if called with a positional hash.
* Do not look for an option hash if empty keywords are provided.
For backwards compatibility, treat an empty keyword splat as a empty
mandatory positional hash argument, but emit a a warning, as this
behavior will be removed in Ruby 3. The argument number check
needs to be moved lower so it can correctly handle an empty
positional argument being added.
* If the last argument is nil and it is necessary to treat it as an option
hash in order to make sure all arguments are processed, continue to
treat the last argument as the option hash. Emit a warning in this case,
as this behavior will be removed in Ruby 3.
* If splitting the keyword hash into two hashes, issue a warning, as we
will not be splitting hashes in Ruby 3.
* If the keyword argument is required to fill a mandatory positional
argument, continue to do so, but emit a warning as this behavior will
be going away in Ruby 3.
* If keyword arguments are provided and the last argument is not a hash,
that indicates something wrong. This can happen if a cfunc is calling
rb_scan_args multiple times, and providing arguments that were not
passed to it from Ruby. Callers need to switch to the new
rb_scan_args_kw function, which allows passing of whether keywords
were provided.
This commit fixes all warnings caused by the changes above.
It switches some function calls to *_kw versions with appropriate
kw_splat flags. If delegating arguments, RB_PASS_CALLED_KEYWORDS
is used. If creating new arguments, RB_PASS_KEYWORDS is used if
the last argument is a hash to be treated as keywords.
In open_key_args in io.c, use rb_scan_args_kw.
In this case, the arguments provided come from another C
function, not Ruby. The last argument may or may not be a hash,
so we can't set keyword argument mode. However, if it is a
hash, we don't want to warn when treating it as keywords.
In Ruby files, make sure to appropriately use keyword splats
or literal keywords when calling Cfuncs that now issue keyword
argument separation warnings through rb_scan_args. Also, make
sure not to pass nil in place of an option hash.
Work around Kernel#warn warnings due to problems in the Rubygems
override of the method. There is an open pull request to fix
these issues in Rubygems, but part of the Rubygems tests for
their override fail on ruby-head due to rb_scan_args not
recognizing empty keyword splats, which this commit fixes.
Implementation wise, adding rb_scan_args_kw is kind of a pain,
because rb_scan_args takes a variable number of arguments.
In order to not duplicate all the code, the function internals need
to be split into two functions taking a va_list, and to avoid passing
in a ton of arguments, a single struct argument is used to handle
the variables previously local to the function.
2019-09-25 14:18:49 -04:00
|
|
|
return rb_class_new_instance_kw(argc, argv, klass, RB_PASS_CALLED_KEYWORDS);
|
2016-04-27 02:47:56 -04:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* Returns +false+. Just for compatibility to IO.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_false(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
StringIO(self);
|
|
|
|
return Qfalse;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* Returns +nil+. Just for compatibility to IO.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_nil(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
StringIO(self);
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Returns an object itself. Just for compatibility to IO.
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_self(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
StringIO(self);
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* Returns 0. Just for compatibility to IO.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_0(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
StringIO(self);
|
|
|
|
return INT2FIX(0);
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* Returns the argument unchanged. Just for compatibility to IO.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_first(VALUE self, VALUE arg)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
StringIO(self);
|
|
|
|
return arg;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* Raises NotImplementedError.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_unimpl(int argc, VALUE *argv, VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
StringIO(self);
|
|
|
|
rb_notimplement();
|
2012-04-13 20:36:26 -04:00
|
|
|
|
|
|
|
UNREACHABLE;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq: strio.string -> string
|
|
|
|
*
|
|
|
|
* Returns underlying String object, the subject of IO.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_get_string(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
return StringIO(self)->string;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.string = string -> string
|
|
|
|
*
|
|
|
|
* Changes underlying String object, the subject of IO.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_set_string(VALUE self, VALUE string)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
struct StringIO *ptr = StringIO(self);
|
|
|
|
|
2011-01-05 15:14:43 -05:00
|
|
|
rb_io_taint_check(self);
|
2002-09-08 22:27:01 -04:00
|
|
|
ptr->flags &= ~FMODE_READWRITE;
|
2005-08-13 05:36:12 -04:00
|
|
|
StringValue(string);
|
|
|
|
ptr->flags = OBJ_FROZEN(string) ? FMODE_READABLE : FMODE_READWRITE;
|
2002-09-08 22:27:01 -04:00
|
|
|
ptr->pos = 0;
|
|
|
|
ptr->lineno = 0;
|
2002-03-11 06:58:07 -05:00
|
|
|
return ptr->string = string;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.close -> nil
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Closes a StringIO. The stream is unavailable for any further data
|
2005-03-15 09:52:59 -05:00
|
|
|
* operations; an +IOError+ is raised if such an attempt is made.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_close(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
StringIO(self);
|
|
|
|
RBASIC(self)->flags &= ~STRIO_READWRITE;
|
2005-02-03 09:43:07 -05:00
|
|
|
return Qnil;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.close_read -> nil
|
|
|
|
*
|
|
|
|
* Closes the read end of a StringIO. Will raise an +IOError+ if the
|
2019-10-26 03:03:24 -04:00
|
|
|
* receiver is not readable.
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_close_read(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2015-03-13 02:04:39 -04:00
|
|
|
struct StringIO *ptr = StringIO(self);
|
|
|
|
if (!(ptr->flags & FMODE_READABLE)) {
|
2002-03-13 22:35:52 -05:00
|
|
|
rb_raise(rb_eIOError, "closing non-duplex IO for reading");
|
|
|
|
}
|
2012-10-29 05:23:02 -04:00
|
|
|
RBASIC(self)->flags &= ~STRIO_READABLE;
|
2005-02-03 09:43:07 -05:00
|
|
|
return Qnil;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.close_write -> nil
|
|
|
|
*
|
|
|
|
* Closes the write end of a StringIO. Will raise an +IOError+ if the
|
2019-10-26 03:03:24 -04:00
|
|
|
* receiver is not writeable.
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_close_write(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2015-03-13 02:04:39 -04:00
|
|
|
struct StringIO *ptr = StringIO(self);
|
|
|
|
if (!(ptr->flags & FMODE_WRITABLE)) {
|
2002-03-13 22:35:52 -05:00
|
|
|
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
|
|
|
|
}
|
2012-10-29 05:23:02 -04:00
|
|
|
RBASIC(self)->flags &= ~STRIO_WRITABLE;
|
2005-02-03 09:43:07 -05:00
|
|
|
return Qnil;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.closed? -> true or false
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Returns +true+ if the stream is completely closed, +false+ otherwise.
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_closed(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
StringIO(self);
|
|
|
|
if (!CLOSED(self)) return Qfalse;
|
2002-03-11 06:58:07 -05:00
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.closed_read? -> true or false
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Returns +true+ if the stream is not readable, +false+ otherwise.
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_closed_read(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
StringIO(self);
|
|
|
|
if (READABLE(self)) return Qfalse;
|
2002-03-11 06:58:07 -05:00
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.closed_write? -> true or false
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Returns +true+ if the stream is not writable, +false+ otherwise.
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_closed_write(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
StringIO(self);
|
|
|
|
if (WRITABLE(self)) return Qfalse;
|
2002-03-11 06:58:07 -05:00
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
2021-03-07 08:39:38 -05:00
|
|
|
static struct StringIO *
|
|
|
|
strio_to_read(VALUE self)
|
|
|
|
{
|
|
|
|
struct StringIO *ptr = readable(self);
|
|
|
|
if (ptr->pos < RSTRING_LEN(ptr->string)) return ptr;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.eof -> true or false
|
|
|
|
* strio.eof? -> true or false
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Returns true if the stream is at the end of the data (underlying string).
|
|
|
|
* The stream must be opened for reading or an +IOError+ will be raised.
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_eof(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2021-03-07 08:39:38 -05:00
|
|
|
if (strio_to_read(self)) return Qfalse;
|
2002-03-11 06:58:07 -05:00
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/* :nodoc: */
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
* sprintf.c (rb_str_format): allow %c to print one character
string (e.g. ?x).
* lib/tempfile.rb (Tempfile::make_tmpname): put dot between
basename and pid. [ruby-talk:196272]
* parse.y (do_block): remove -> style block.
* parse.y (parser_yylex): remove tLAMBDA_ARG.
* eval.c (rb_call0): binding for the return event hook should have
consistent scope. [ruby-core:07928]
* eval.c (proc_invoke): return behavior should depend whether it
is surrounded by a lambda or a mere block.
* eval.c (formal_assign): handles post splat arguments.
* eval.c (rb_call0): ditto.
* st.c (strhash): use FNV-1a hash.
* parse.y (parser_yylex): removed experimental ';;' terminator.
* eval.c (rb_node_arity): should be aware of post splat arguments.
* eval.c (rb_proc_arity): ditto.
* parse.y (f_args): syntax rule enhanced to support arguments
after the splat.
* parse.y (block_param): ditto for block parameters.
* parse.y (f_post_arg): mandatory formal arguments after the splat
argument.
* parse.y (new_args_gen): generate nodes for mandatory formal
arguments after the splat argument.
* eval.c (rb_eval): dispatch mandatory formal arguments after the
splat argument.
* parse.y (args): allow more than one splat in the argument list.
* parse.y (method_call): allow aref [] to accept all kind of
method argument, including assocs, splat, and block argument.
* eval.c (SETUP_ARGS0): prepare block argument as well.
* lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931]
* eval.c (error_line): print receivers true/false/nil specially.
* eval.c (rb_proc_yield): handles parameters in yield semantics.
* eval.c (nil_yield): gives LocalJumpError to denote no block
error.
* io.c (rb_io_getc): now takes one-character string.
* string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo
hashing algorithm.
* string.c (rb_str_aref): str[0] now returns 1 character string,
instead of a fixnum. [Ruby2]
* parse.y (parser_yylex): ?c now returns 1 character string,
instead of a fixnum. [Ruby2]
* string.c (rb_str_aset): no longer support fixnum insertion.
* eval.c (umethod_bind): should not update original class.
[ruby-dev:28636]
* eval.c (ev_const_get): should support constant access from
within instance_eval(). [ruby-dev:28327]
* time.c (time_timeval): should round for usec floating
number. [ruby-core:07896]
* time.c (time_add): ditto.
* dir.c (sys_warning): should not call a vararg function
rb_sys_warning() indirectly. [ruby-core:07886]
* numeric.c (flo_divmod): the first element of Float#divmod should
be an integer. [ruby-dev:28589]
* test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder.
* re.c (rb_reg_initialize): should not allow modifying literal
regexps. frozen check moved from rb_reg_initialize_m as well.
* re.c (rb_reg_initialize): should not modify untainted objects in
safe levels higher than 3.
* re.c (rb_memcmp): type change from char* to const void*.
* dir.c (dir_close): should not close untainted dir stream.
* dir.c (GetDIR): add tainted/frozen check for each dir operation.
* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg):
typo fixed. a patch from Florian Gross <florg at florg.net>.
* eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from
event_hooks. no guarantee for arbitrary hook deletion.
[ruby-dev:28632]
* util.c (ruby_strtod): differ addition to minimize error.
[ruby-dev:28619]
* util.c (ruby_strtod): should not raise ERANGE when the input
string does not have any digits. [ruby-dev:28629]
* eval.c (proc_invoke): should restore old ruby_frame->block.
thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833]
also fix [ruby-dev:28614] as well.
* signal.c (trap): sig should be less then NSIG. Coverity found
this bug. a patch from Kevin Tew <tewk at tewk.com>.
[ruby-core:07823]
* math.c (math_log2): add new method inspired by
[ruby-talk:191237].
* math.c (math_log): add optional base argument to Math::log().
[ruby-talk:191308]
* ext/syck/emitter.c (syck_scan_scalar): avoid accessing
uninitialized array element. a patch from Pat Eyler
<rubypate at gmail.com>. [ruby-core:07809]
* array.c (rb_ary_fill): initialize local variables first. a
patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810]
* ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free
type_tag. a patch from Pat Eyler <rubypate at gmail.com>.
[ruby-core:07808]
* ext/socket/socket.c (make_hostent_internal): accept ai_family
check from Sam Roberts <sroberts at uniserve.com>.
[ruby-core:07691]
* util.c (ruby_strtod): should not cut off 18 digits for no
reason. [ruby-core:07796]
* array.c (rb_ary_fill): internalize local variable "beg" to
pacify Coverity. [ruby-core:07770]
* pack.c (pack_unpack): now supports CRLF newlines. a patch from
<tommy at tmtm.org>. [ruby-dev:28601]
* applied code clean-up patch from Stefan Huehner
<stefan at huehner.org>. [ruby-core:07764]
* lib/jcode.rb (String::tr_s): should have translated non
squeezing character sequence (i.e. a character) as well. thanks
to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090]
* ext/socket/socket.c: document update patch from Sam Roberts
<sroberts at uniserve.com>. [ruby-core:07701]
* lib/mathn.rb (Integer): need not to remove gcd2. a patch from
NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570]
* parse.y (arg): too much NEW_LIST()
* eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen.
* eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1.
[ruby-dev:28585]
* parse.y (arg): use NODE_ARGSCAT for placeholder.
* lib/getoptlong.rb (GetoptLong::get): RDoc update patch from
mathew <meta at pobox.com>. [ruby-core:07738]
* variable.c (rb_const_set): raise error when no target klass is
supplied. [ruby-dev:28582]
* prec.c (prec_prec_f): documentation patch from
<gerardo.santana at gmail.com>. [ruby-core:07689]
* bignum.c (rb_big_pow): second operand may be too big even if
it's a Fixnum. [ruby-talk:187984]
* README.EXT: update symbol description. [ruby-talk:188104]
* COPYING: explicitly note GPLv2. [ruby-talk:187922]
* parse.y: remove some obsolete syntax rules (unparenthesized
method calls in argument list).
* eval.c (rb_call0): insecure calling should be checked for non
NODE_SCOPE method invocations too.
* eval.c (rb_alias): should preserve the current safe level as
well as method definition.
* process.c (rb_f_sleep): remove RDoc description about SIGALRM
which is not valid on the current implementation. [ruby-dev:28464]
Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
* eval.c (method_missing): should support argument splat in
super. a bug in combination of super, splat and
method_missing. [ruby-talk:185438]
* configure.in: Solaris SunPro compiler -rapth patch from
<kuwa at labs.fujitsu.com>. [ruby-dev:28443]
* configure.in: remove enable_rpath=no for Solaris.
[ruby-dev:28440]
* ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior
of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby
String object.
* ruby.1: a clarification patch from David Lutterkort
<dlutter at redhat.com>. [ruby-core:7508]
* lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems
directories. a patch from Eric Hodel <drbrain at segment7.net>.
[ruby-core:07423]
* eval.c (rb_clear_cache_by_class): clearing wrong cache.
* ext/extmk.rb: use :remove_destination to install extension libraries
to avoid SEGV. [ruby-dev:28417]
* eval.c (rb_thread_fd_writable): should not re-schedule output
from KILLED thread (must be error printing).
* array.c (rb_ary_flatten_bang): allow specifying recursion
level. [ruby-talk:182170]
* array.c (rb_ary_flatten): ditto.
* gc.c (add_heap): a heap_slots may overflow. a patch from Stefan
Weil <weil at mail.berlios.de>.
* eval.c (rb_call): use separate cache for fcall/vcall
invocation.
* eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local
functions.
* eval.c (rb_mod_local): a new method to specify newly added
visibility "local".
* eval.c (search_method): search for local methods which are
visible only from the current class.
* class.c (rb_class_local_methods): a method to list local methods.
* object.c (Init_Object): add BasicObject class as a top level
BlankSlate class.
* ruby.h (SYM2ID): should not cast to signed long.
[ruby-core:07414]
* class.c (rb_include_module): allow module duplication.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-06-09 17:20:17 -04:00
|
|
|
strio_copy(VALUE copy, VALUE orig)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2002-09-08 22:27:01 -04:00
|
|
|
struct StringIO *ptr;
|
2002-09-03 01:20:14 -04:00
|
|
|
|
2002-09-08 22:27:01 -04:00
|
|
|
orig = rb_convert_type(orig, T_DATA, "StringIO", "to_strio");
|
|
|
|
if (copy == orig) return copy;
|
|
|
|
ptr = StringIO(orig);
|
|
|
|
if (check_strio(copy)) {
|
|
|
|
strio_free(DATA_PTR(copy));
|
2002-09-03 01:20:14 -04:00
|
|
|
}
|
|
|
|
DATA_PTR(copy) = ptr;
|
2012-10-29 05:23:02 -04:00
|
|
|
RBASIC(copy)->flags &= ~STRIO_READWRITE;
|
|
|
|
RBASIC(copy)->flags |= RBASIC(orig)->flags & STRIO_READWRITE;
|
2002-03-11 06:58:07 -05:00
|
|
|
++ptr->count;
|
2002-09-03 01:20:14 -04:00
|
|
|
return copy;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.lineno -> integer
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Returns the current line number. The stream must be
|
2005-03-15 09:52:59 -05:00
|
|
|
* opened for reading. +lineno+ counts the number of times +gets+ is
|
|
|
|
* called, rather than the number of newlines encountered. The two
|
|
|
|
* values will differ if +gets+ is called with a separator other than
|
|
|
|
* newline. See also the <code>$.</code> variable.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_get_lineno(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
return LONG2NUM(StringIO(self)->lineno);
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.lineno = integer -> integer
|
|
|
|
*
|
|
|
|
* Manually sets the current line number to the given value.
|
|
|
|
* <code>$.</code> is updated only on the next read.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_set_lineno(VALUE self, VALUE lineno)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
StringIO(self)->lineno = NUM2LONG(lineno);
|
|
|
|
return lineno;
|
|
|
|
}
|
|
|
|
|
2019-10-26 03:03:24 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.binmode -> stringio
|
|
|
|
*
|
|
|
|
* Puts stream into binary mode. See IO#binmode.
|
|
|
|
*
|
|
|
|
*/
|
2016-01-04 15:45:14 -05:00
|
|
|
static VALUE
|
|
|
|
strio_binmode(VALUE self)
|
|
|
|
{
|
|
|
|
struct StringIO *ptr = StringIO(self);
|
|
|
|
rb_encoding *enc = rb_ascii8bit_encoding();
|
|
|
|
|
|
|
|
ptr->enc = enc;
|
|
|
|
if (WRITABLE(self)) {
|
|
|
|
rb_enc_associate(ptr->string, enc);
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
2002-03-11 06:58:07 -05:00
|
|
|
|
|
|
|
#define strio_fcntl strio_unimpl
|
|
|
|
|
|
|
|
#define strio_flush strio_self
|
|
|
|
|
|
|
|
#define strio_fsync strio_0
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.reopen(other_StrIO) -> strio
|
|
|
|
* strio.reopen(string, mode) -> strio
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Reinitializes the stream with the given <i>other_StrIO</i> or _string_
|
2005-03-15 09:52:59 -05:00
|
|
|
* and _mode_ (see StringIO#new).
|
|
|
|
*/
|
2002-09-08 22:27:01 -04:00
|
|
|
static VALUE
|
* sprintf.c (rb_str_format): allow %c to print one character
string (e.g. ?x).
* lib/tempfile.rb (Tempfile::make_tmpname): put dot between
basename and pid. [ruby-talk:196272]
* parse.y (do_block): remove -> style block.
* parse.y (parser_yylex): remove tLAMBDA_ARG.
* eval.c (rb_call0): binding for the return event hook should have
consistent scope. [ruby-core:07928]
* eval.c (proc_invoke): return behavior should depend whether it
is surrounded by a lambda or a mere block.
* eval.c (formal_assign): handles post splat arguments.
* eval.c (rb_call0): ditto.
* st.c (strhash): use FNV-1a hash.
* parse.y (parser_yylex): removed experimental ';;' terminator.
* eval.c (rb_node_arity): should be aware of post splat arguments.
* eval.c (rb_proc_arity): ditto.
* parse.y (f_args): syntax rule enhanced to support arguments
after the splat.
* parse.y (block_param): ditto for block parameters.
* parse.y (f_post_arg): mandatory formal arguments after the splat
argument.
* parse.y (new_args_gen): generate nodes for mandatory formal
arguments after the splat argument.
* eval.c (rb_eval): dispatch mandatory formal arguments after the
splat argument.
* parse.y (args): allow more than one splat in the argument list.
* parse.y (method_call): allow aref [] to accept all kind of
method argument, including assocs, splat, and block argument.
* eval.c (SETUP_ARGS0): prepare block argument as well.
* lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931]
* eval.c (error_line): print receivers true/false/nil specially.
* eval.c (rb_proc_yield): handles parameters in yield semantics.
* eval.c (nil_yield): gives LocalJumpError to denote no block
error.
* io.c (rb_io_getc): now takes one-character string.
* string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo
hashing algorithm.
* string.c (rb_str_aref): str[0] now returns 1 character string,
instead of a fixnum. [Ruby2]
* parse.y (parser_yylex): ?c now returns 1 character string,
instead of a fixnum. [Ruby2]
* string.c (rb_str_aset): no longer support fixnum insertion.
* eval.c (umethod_bind): should not update original class.
[ruby-dev:28636]
* eval.c (ev_const_get): should support constant access from
within instance_eval(). [ruby-dev:28327]
* time.c (time_timeval): should round for usec floating
number. [ruby-core:07896]
* time.c (time_add): ditto.
* dir.c (sys_warning): should not call a vararg function
rb_sys_warning() indirectly. [ruby-core:07886]
* numeric.c (flo_divmod): the first element of Float#divmod should
be an integer. [ruby-dev:28589]
* test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder.
* re.c (rb_reg_initialize): should not allow modifying literal
regexps. frozen check moved from rb_reg_initialize_m as well.
* re.c (rb_reg_initialize): should not modify untainted objects in
safe levels higher than 3.
* re.c (rb_memcmp): type change from char* to const void*.
* dir.c (dir_close): should not close untainted dir stream.
* dir.c (GetDIR): add tainted/frozen check for each dir operation.
* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg):
typo fixed. a patch from Florian Gross <florg at florg.net>.
* eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from
event_hooks. no guarantee for arbitrary hook deletion.
[ruby-dev:28632]
* util.c (ruby_strtod): differ addition to minimize error.
[ruby-dev:28619]
* util.c (ruby_strtod): should not raise ERANGE when the input
string does not have any digits. [ruby-dev:28629]
* eval.c (proc_invoke): should restore old ruby_frame->block.
thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833]
also fix [ruby-dev:28614] as well.
* signal.c (trap): sig should be less then NSIG. Coverity found
this bug. a patch from Kevin Tew <tewk at tewk.com>.
[ruby-core:07823]
* math.c (math_log2): add new method inspired by
[ruby-talk:191237].
* math.c (math_log): add optional base argument to Math::log().
[ruby-talk:191308]
* ext/syck/emitter.c (syck_scan_scalar): avoid accessing
uninitialized array element. a patch from Pat Eyler
<rubypate at gmail.com>. [ruby-core:07809]
* array.c (rb_ary_fill): initialize local variables first. a
patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810]
* ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free
type_tag. a patch from Pat Eyler <rubypate at gmail.com>.
[ruby-core:07808]
* ext/socket/socket.c (make_hostent_internal): accept ai_family
check from Sam Roberts <sroberts at uniserve.com>.
[ruby-core:07691]
* util.c (ruby_strtod): should not cut off 18 digits for no
reason. [ruby-core:07796]
* array.c (rb_ary_fill): internalize local variable "beg" to
pacify Coverity. [ruby-core:07770]
* pack.c (pack_unpack): now supports CRLF newlines. a patch from
<tommy at tmtm.org>. [ruby-dev:28601]
* applied code clean-up patch from Stefan Huehner
<stefan at huehner.org>. [ruby-core:07764]
* lib/jcode.rb (String::tr_s): should have translated non
squeezing character sequence (i.e. a character) as well. thanks
to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090]
* ext/socket/socket.c: document update patch from Sam Roberts
<sroberts at uniserve.com>. [ruby-core:07701]
* lib/mathn.rb (Integer): need not to remove gcd2. a patch from
NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570]
* parse.y (arg): too much NEW_LIST()
* eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen.
* eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1.
[ruby-dev:28585]
* parse.y (arg): use NODE_ARGSCAT for placeholder.
* lib/getoptlong.rb (GetoptLong::get): RDoc update patch from
mathew <meta at pobox.com>. [ruby-core:07738]
* variable.c (rb_const_set): raise error when no target klass is
supplied. [ruby-dev:28582]
* prec.c (prec_prec_f): documentation patch from
<gerardo.santana at gmail.com>. [ruby-core:07689]
* bignum.c (rb_big_pow): second operand may be too big even if
it's a Fixnum. [ruby-talk:187984]
* README.EXT: update symbol description. [ruby-talk:188104]
* COPYING: explicitly note GPLv2. [ruby-talk:187922]
* parse.y: remove some obsolete syntax rules (unparenthesized
method calls in argument list).
* eval.c (rb_call0): insecure calling should be checked for non
NODE_SCOPE method invocations too.
* eval.c (rb_alias): should preserve the current safe level as
well as method definition.
* process.c (rb_f_sleep): remove RDoc description about SIGALRM
which is not valid on the current implementation. [ruby-dev:28464]
Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
* eval.c (method_missing): should support argument splat in
super. a bug in combination of super, splat and
method_missing. [ruby-talk:185438]
* configure.in: Solaris SunPro compiler -rapth patch from
<kuwa at labs.fujitsu.com>. [ruby-dev:28443]
* configure.in: remove enable_rpath=no for Solaris.
[ruby-dev:28440]
* ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior
of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby
String object.
* ruby.1: a clarification patch from David Lutterkort
<dlutter at redhat.com>. [ruby-core:7508]
* lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems
directories. a patch from Eric Hodel <drbrain at segment7.net>.
[ruby-core:07423]
* eval.c (rb_clear_cache_by_class): clearing wrong cache.
* ext/extmk.rb: use :remove_destination to install extension libraries
to avoid SEGV. [ruby-dev:28417]
* eval.c (rb_thread_fd_writable): should not re-schedule output
from KILLED thread (must be error printing).
* array.c (rb_ary_flatten_bang): allow specifying recursion
level. [ruby-talk:182170]
* array.c (rb_ary_flatten): ditto.
* gc.c (add_heap): a heap_slots may overflow. a patch from Stefan
Weil <weil at mail.berlios.de>.
* eval.c (rb_call): use separate cache for fcall/vcall
invocation.
* eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local
functions.
* eval.c (rb_mod_local): a new method to specify newly added
visibility "local".
* eval.c (search_method): search for local methods which are
visible only from the current class.
* class.c (rb_class_local_methods): a method to list local methods.
* object.c (Init_Object): add BasicObject class as a top level
BlankSlate class.
* ruby.h (SYM2ID): should not cast to signed long.
[ruby-core:07414]
* class.c (rb_include_module): allow module duplication.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-06-09 17:20:17 -04:00
|
|
|
strio_reopen(int argc, VALUE *argv, VALUE self)
|
2002-09-08 22:27:01 -04:00
|
|
|
{
|
2011-01-05 15:14:43 -05:00
|
|
|
rb_io_taint_check(self);
|
2012-05-23 03:13:21 -04:00
|
|
|
if (argc == 1 && !RB_TYPE_P(*argv, T_STRING)) {
|
2002-12-10 21:31:59 -05:00
|
|
|
return strio_copy(self, *argv);
|
2002-09-08 22:27:01 -04:00
|
|
|
}
|
2016-06-09 00:44:32 -04:00
|
|
|
return strio_init(argc, argv, StringIO(self), self);
|
2002-09-08 22:27:01 -04:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.pos -> integer
|
|
|
|
* strio.tell -> integer
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Returns the current offset (in bytes).
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_get_pos(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
return LONG2NUM(StringIO(self)->pos);
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.pos = integer -> integer
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Seeks to the given position (in bytes).
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_set_pos(VALUE self, VALUE pos)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
struct StringIO *ptr = StringIO(self);
|
|
|
|
long p = NUM2LONG(pos);
|
|
|
|
if (p < 0) {
|
|
|
|
error_inval(0);
|
|
|
|
}
|
|
|
|
ptr->pos = p;
|
|
|
|
return pos;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.rewind -> 0
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Positions the stream to the beginning of input, resetting
|
2005-03-15 09:52:59 -05:00
|
|
|
* +lineno+ to zero.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_rewind(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
struct StringIO *ptr = StringIO(self);
|
|
|
|
ptr->pos = 0;
|
|
|
|
ptr->lineno = 0;
|
|
|
|
return INT2FIX(0);
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.seek(amount, whence=SEEK_SET) -> 0
|
|
|
|
*
|
|
|
|
* Seeks to a given offset _amount_ in the stream according to
|
|
|
|
* the value of _whence_ (see IO#seek).
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_seek(int argc, VALUE *argv, VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
VALUE whence;
|
|
|
|
struct StringIO *ptr = StringIO(self);
|
2016-09-26 03:24:55 -04:00
|
|
|
long amount, offset;
|
2002-03-11 06:58:07 -05:00
|
|
|
|
|
|
|
rb_scan_args(argc, argv, "11", NULL, &whence);
|
2016-09-26 03:24:55 -04:00
|
|
|
amount = NUM2LONG(argv[0]);
|
2012-10-29 05:23:02 -04:00
|
|
|
if (CLOSED(self)) {
|
2007-04-16 03:48:50 -04:00
|
|
|
rb_raise(rb_eIOError, "closed stream");
|
|
|
|
}
|
2002-03-11 06:58:07 -05:00
|
|
|
switch (NIL_P(whence) ? 0 : NUM2LONG(whence)) {
|
|
|
|
case 0:
|
2016-09-26 03:24:55 -04:00
|
|
|
offset = 0;
|
2002-03-11 06:58:07 -05:00
|
|
|
break;
|
|
|
|
case 1:
|
2016-09-26 03:24:55 -04:00
|
|
|
offset = ptr->pos;
|
2002-03-11 06:58:07 -05:00
|
|
|
break;
|
|
|
|
case 2:
|
2016-09-26 03:24:55 -04:00
|
|
|
offset = RSTRING_LEN(ptr->string);
|
2002-03-11 06:58:07 -05:00
|
|
|
break;
|
|
|
|
default:
|
2007-04-16 03:48:50 -04:00
|
|
|
error_inval("invalid whence");
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
2016-09-26 03:24:55 -04:00
|
|
|
if (amount > LONG_MAX - offset || amount + offset < 0) {
|
2002-03-11 06:58:07 -05:00
|
|
|
error_inval(0);
|
|
|
|
}
|
2016-09-26 03:24:55 -04:00
|
|
|
ptr->pos = amount + offset;
|
2002-03-11 06:58:07 -05:00
|
|
|
return INT2FIX(0);
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.sync -> true
|
|
|
|
*
|
|
|
|
* Returns +true+ always.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_get_sync(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
StringIO(self);
|
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
#define strio_set_sync strio_first
|
|
|
|
|
|
|
|
#define strio_tell strio_get_pos
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.each_byte {|byte| block } -> strio
|
2010-03-07 05:22:05 -05:00
|
|
|
* strio.each_byte -> anEnumerator
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#each_byte.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_each_byte(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2021-03-07 08:39:38 -05:00
|
|
|
struct StringIO *ptr;
|
* ext/dbm/dbm.c (fdbm_each_value, fdbm_each_key, fdbm_each_pair):
GDBM#{each,each_pair,each_key,each_value}: Return an enumerator
if no block is given.
* ext/gdbm/gdbm.c (fgdbm_each_value, fgdbm_each_key,
fgdbm_each_pair): GDBM#{each,each_pair,each_key,each_value}:
Return an enumerator if no block is given.
* ext/openssl/ossl_config.c (ossl_config_each):
OpenSSL::Config#each: Return an enumerator if no block is given.
* ext/readline/readline.c (hist_each): Readline::HISTORY#each:
Return an enumerator if no block is given.
* ext/sdbm/init.c (fsdbm_each_value, fsdbm_each_key,
fsdbm_each_pair): SDBM#{each,each_pair,each_key,each_value}:
Return an enumerator if no block is given.
* ext/stringio/stringio.c (strio_each_byte, strio_each):
StringIO#{each,each_line,each_byte}: Return an enumerator if no
block is given.
* ext/stringio/stringio.c (Init_stringio): Add #lines and #bytes,
which are aliases to #each_line and #each_byte, respectively.
* ext/win32ole/win32ole.c (fole_each): WIN32OLE#each: Return an
enumerator if no block is given.
* ext/zlib/zlib.c (rb_gzreader_each_byte, rb_gzreader_each):
Zlib::GzipReader#{each,each_line,each_byte}: Return an
enumerator if no block is given.
* ext/zlib/zlib.c (Init_zlib): Add Zlib::GzipReader#lines and
#bytes, which are aliases to #each_line and #each_byte,
respectively.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@16125 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2008-04-21 04:48:33 -04:00
|
|
|
|
|
|
|
RETURN_ENUMERATOR(self, 0, 0);
|
|
|
|
|
2021-03-07 08:39:38 -05:00
|
|
|
while ((ptr = strio_to_read(self)) != NULL) {
|
2006-08-31 06:30:33 -04:00
|
|
|
char c = RSTRING_PTR(ptr->string)[ptr->pos++];
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_yield(CHR2FIX(c));
|
|
|
|
}
|
2008-05-27 04:55:59 -04:00
|
|
|
return self;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
* strio.getc -> string or nil
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#getc.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_getc(VALUE self)
|
2007-08-14 20:33:33 -04:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
struct StringIO *ptr = readable(self);
|
2015-12-18 02:54:33 -05:00
|
|
|
rb_encoding *enc = get_enc(ptr);
|
2016-05-30 01:54:59 -04:00
|
|
|
VALUE str = ptr->string;
|
|
|
|
long pos = ptr->pos;
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
int len;
|
|
|
|
char *p;
|
2007-08-14 20:33:33 -04:00
|
|
|
|
2016-05-30 01:54:59 -04:00
|
|
|
if (pos >= RSTRING_LEN(str)) {
|
2007-08-14 20:33:33 -04:00
|
|
|
return Qnil;
|
|
|
|
}
|
2016-05-30 01:54:59 -04:00
|
|
|
p = RSTRING_PTR(str)+pos;
|
|
|
|
len = rb_enc_mbclen(p, RSTRING_END(str), enc);
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
ptr->pos += len;
|
2016-05-30 01:54:59 -04:00
|
|
|
return enc_subseq(str, pos, len, enc);
|
2007-08-14 20:33:33 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.getbyte -> fixnum or nil
|
|
|
|
*
|
|
|
|
* See IO#getbyte.
|
|
|
|
*/
|
|
|
|
static VALUE
|
|
|
|
strio_getbyte(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
struct StringIO *ptr = readable(self);
|
2002-03-11 06:58:07 -05:00
|
|
|
int c;
|
2006-08-31 06:30:33 -04:00
|
|
|
if (ptr->pos >= RSTRING_LEN(ptr->string)) {
|
2002-03-11 06:58:07 -05:00
|
|
|
return Qnil;
|
|
|
|
}
|
2006-08-31 06:30:33 -04:00
|
|
|
c = RSTRING_PTR(ptr->string)[ptr->pos++];
|
2002-03-11 06:58:07 -05:00
|
|
|
return CHR2FIX(c);
|
|
|
|
}
|
|
|
|
|
2005-02-03 09:43:07 -05:00
|
|
|
static void
|
* sprintf.c (rb_str_format): allow %c to print one character
string (e.g. ?x).
* lib/tempfile.rb (Tempfile::make_tmpname): put dot between
basename and pid. [ruby-talk:196272]
* parse.y (do_block): remove -> style block.
* parse.y (parser_yylex): remove tLAMBDA_ARG.
* eval.c (rb_call0): binding for the return event hook should have
consistent scope. [ruby-core:07928]
* eval.c (proc_invoke): return behavior should depend whether it
is surrounded by a lambda or a mere block.
* eval.c (formal_assign): handles post splat arguments.
* eval.c (rb_call0): ditto.
* st.c (strhash): use FNV-1a hash.
* parse.y (parser_yylex): removed experimental ';;' terminator.
* eval.c (rb_node_arity): should be aware of post splat arguments.
* eval.c (rb_proc_arity): ditto.
* parse.y (f_args): syntax rule enhanced to support arguments
after the splat.
* parse.y (block_param): ditto for block parameters.
* parse.y (f_post_arg): mandatory formal arguments after the splat
argument.
* parse.y (new_args_gen): generate nodes for mandatory formal
arguments after the splat argument.
* eval.c (rb_eval): dispatch mandatory formal arguments after the
splat argument.
* parse.y (args): allow more than one splat in the argument list.
* parse.y (method_call): allow aref [] to accept all kind of
method argument, including assocs, splat, and block argument.
* eval.c (SETUP_ARGS0): prepare block argument as well.
* lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931]
* eval.c (error_line): print receivers true/false/nil specially.
* eval.c (rb_proc_yield): handles parameters in yield semantics.
* eval.c (nil_yield): gives LocalJumpError to denote no block
error.
* io.c (rb_io_getc): now takes one-character string.
* string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo
hashing algorithm.
* string.c (rb_str_aref): str[0] now returns 1 character string,
instead of a fixnum. [Ruby2]
* parse.y (parser_yylex): ?c now returns 1 character string,
instead of a fixnum. [Ruby2]
* string.c (rb_str_aset): no longer support fixnum insertion.
* eval.c (umethod_bind): should not update original class.
[ruby-dev:28636]
* eval.c (ev_const_get): should support constant access from
within instance_eval(). [ruby-dev:28327]
* time.c (time_timeval): should round for usec floating
number. [ruby-core:07896]
* time.c (time_add): ditto.
* dir.c (sys_warning): should not call a vararg function
rb_sys_warning() indirectly. [ruby-core:07886]
* numeric.c (flo_divmod): the first element of Float#divmod should
be an integer. [ruby-dev:28589]
* test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder.
* re.c (rb_reg_initialize): should not allow modifying literal
regexps. frozen check moved from rb_reg_initialize_m as well.
* re.c (rb_reg_initialize): should not modify untainted objects in
safe levels higher than 3.
* re.c (rb_memcmp): type change from char* to const void*.
* dir.c (dir_close): should not close untainted dir stream.
* dir.c (GetDIR): add tainted/frozen check for each dir operation.
* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg):
typo fixed. a patch from Florian Gross <florg at florg.net>.
* eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from
event_hooks. no guarantee for arbitrary hook deletion.
[ruby-dev:28632]
* util.c (ruby_strtod): differ addition to minimize error.
[ruby-dev:28619]
* util.c (ruby_strtod): should not raise ERANGE when the input
string does not have any digits. [ruby-dev:28629]
* eval.c (proc_invoke): should restore old ruby_frame->block.
thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833]
also fix [ruby-dev:28614] as well.
* signal.c (trap): sig should be less then NSIG. Coverity found
this bug. a patch from Kevin Tew <tewk at tewk.com>.
[ruby-core:07823]
* math.c (math_log2): add new method inspired by
[ruby-talk:191237].
* math.c (math_log): add optional base argument to Math::log().
[ruby-talk:191308]
* ext/syck/emitter.c (syck_scan_scalar): avoid accessing
uninitialized array element. a patch from Pat Eyler
<rubypate at gmail.com>. [ruby-core:07809]
* array.c (rb_ary_fill): initialize local variables first. a
patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810]
* ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free
type_tag. a patch from Pat Eyler <rubypate at gmail.com>.
[ruby-core:07808]
* ext/socket/socket.c (make_hostent_internal): accept ai_family
check from Sam Roberts <sroberts at uniserve.com>.
[ruby-core:07691]
* util.c (ruby_strtod): should not cut off 18 digits for no
reason. [ruby-core:07796]
* array.c (rb_ary_fill): internalize local variable "beg" to
pacify Coverity. [ruby-core:07770]
* pack.c (pack_unpack): now supports CRLF newlines. a patch from
<tommy at tmtm.org>. [ruby-dev:28601]
* applied code clean-up patch from Stefan Huehner
<stefan at huehner.org>. [ruby-core:07764]
* lib/jcode.rb (String::tr_s): should have translated non
squeezing character sequence (i.e. a character) as well. thanks
to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090]
* ext/socket/socket.c: document update patch from Sam Roberts
<sroberts at uniserve.com>. [ruby-core:07701]
* lib/mathn.rb (Integer): need not to remove gcd2. a patch from
NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570]
* parse.y (arg): too much NEW_LIST()
* eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen.
* eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1.
[ruby-dev:28585]
* parse.y (arg): use NODE_ARGSCAT for placeholder.
* lib/getoptlong.rb (GetoptLong::get): RDoc update patch from
mathew <meta at pobox.com>. [ruby-core:07738]
* variable.c (rb_const_set): raise error when no target klass is
supplied. [ruby-dev:28582]
* prec.c (prec_prec_f): documentation patch from
<gerardo.santana at gmail.com>. [ruby-core:07689]
* bignum.c (rb_big_pow): second operand may be too big even if
it's a Fixnum. [ruby-talk:187984]
* README.EXT: update symbol description. [ruby-talk:188104]
* COPYING: explicitly note GPLv2. [ruby-talk:187922]
* parse.y: remove some obsolete syntax rules (unparenthesized
method calls in argument list).
* eval.c (rb_call0): insecure calling should be checked for non
NODE_SCOPE method invocations too.
* eval.c (rb_alias): should preserve the current safe level as
well as method definition.
* process.c (rb_f_sleep): remove RDoc description about SIGALRM
which is not valid on the current implementation. [ruby-dev:28464]
Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
* eval.c (method_missing): should support argument splat in
super. a bug in combination of super, splat and
method_missing. [ruby-talk:185438]
* configure.in: Solaris SunPro compiler -rapth patch from
<kuwa at labs.fujitsu.com>. [ruby-dev:28443]
* configure.in: remove enable_rpath=no for Solaris.
[ruby-dev:28440]
* ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior
of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby
String object.
* ruby.1: a clarification patch from David Lutterkort
<dlutter at redhat.com>. [ruby-core:7508]
* lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems
directories. a patch from Eric Hodel <drbrain at segment7.net>.
[ruby-core:07423]
* eval.c (rb_clear_cache_by_class): clearing wrong cache.
* ext/extmk.rb: use :remove_destination to install extension libraries
to avoid SEGV. [ruby-dev:28417]
* eval.c (rb_thread_fd_writable): should not re-schedule output
from KILLED thread (must be error printing).
* array.c (rb_ary_flatten_bang): allow specifying recursion
level. [ruby-talk:182170]
* array.c (rb_ary_flatten): ditto.
* gc.c (add_heap): a heap_slots may overflow. a patch from Stefan
Weil <weil at mail.berlios.de>.
* eval.c (rb_call): use separate cache for fcall/vcall
invocation.
* eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local
functions.
* eval.c (rb_mod_local): a new method to specify newly added
visibility "local".
* eval.c (search_method): search for local methods which are
visible only from the current class.
* class.c (rb_class_local_methods): a method to list local methods.
* object.c (Init_Object): add BasicObject class as a top level
BlankSlate class.
* ruby.h (SYM2ID): should not cast to signed long.
[ruby-core:07414]
* class.c (rb_include_module): allow module duplication.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-06-09 17:20:17 -04:00
|
|
|
strio_extend(struct StringIO *ptr, long pos, long len)
|
2005-02-03 09:43:07 -05:00
|
|
|
{
|
|
|
|
long olen;
|
|
|
|
|
2016-09-26 03:24:55 -04:00
|
|
|
if (len > LONG_MAX - pos)
|
|
|
|
rb_raise(rb_eArgError, "string size too big");
|
|
|
|
|
2005-02-03 09:43:07 -05:00
|
|
|
check_modifiable(ptr);
|
2006-08-31 06:30:33 -04:00
|
|
|
olen = RSTRING_LEN(ptr->string);
|
2005-02-03 09:43:07 -05:00
|
|
|
if (pos + len > olen) {
|
|
|
|
rb_str_resize(ptr->string, pos + len);
|
|
|
|
if (pos > olen)
|
2006-08-31 06:30:33 -04:00
|
|
|
MEMZERO(RSTRING_PTR(ptr->string) + olen, char, pos - olen);
|
2005-02-03 09:43:07 -05:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_str_modify(ptr->string);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2007-08-14 20:33:33 -04:00
|
|
|
* strio.ungetc(string) -> nil
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Pushes back one character (passed as a parameter)
|
2009-12-03 23:14:37 -05:00
|
|
|
* such that a subsequent buffered read will return it. There is no
|
|
|
|
* limitation for multiple pushbacks including pushing back behind the
|
|
|
|
* beginning of the buffer string.
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2007-08-14 20:33:33 -04:00
|
|
|
strio_ungetc(VALUE self, VALUE c)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
struct StringIO *ptr = readable(self);
|
2008-10-21 18:10:49 -04:00
|
|
|
rb_encoding *enc, *enc2;
|
2002-03-11 06:58:07 -05:00
|
|
|
|
2012-12-27 06:43:02 -05:00
|
|
|
check_modifiable(ptr);
|
2015-12-18 01:40:00 -05:00
|
|
|
if (NIL_P(c)) return Qnil;
|
2017-03-20 23:15:57 -04:00
|
|
|
if (RB_INTEGER_TYPE_P(c)) {
|
|
|
|
int len, cc = NUM2INT(c);
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
char buf[16];
|
|
|
|
|
|
|
|
enc = rb_enc_get(ptr->string);
|
2017-03-20 23:15:56 -04:00
|
|
|
len = rb_enc_codelen(cc, enc);
|
|
|
|
if (len <= 0) rb_enc_uint_chr(cc, enc);
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
rb_enc_mbcput(cc, buf, enc);
|
2017-03-20 23:15:56 -04:00
|
|
|
return strio_unget_bytes(ptr, buf, len);
|
2007-08-14 20:33:33 -04:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
SafeStringValue(c);
|
2008-10-21 18:10:49 -04:00
|
|
|
enc = rb_enc_get(ptr->string);
|
|
|
|
enc2 = rb_enc_get(c);
|
|
|
|
if (enc != enc2 && enc != rb_ascii8bit_encoding()) {
|
|
|
|
c = rb_str_conv_enc(c, enc2, enc);
|
|
|
|
}
|
2015-12-18 01:40:00 -05:00
|
|
|
strio_unget_bytes(ptr, RSTRING_PTR(c), RSTRING_LEN(c));
|
|
|
|
RB_GC_GUARD(c);
|
|
|
|
return Qnil;
|
2007-08-14 20:33:33 -04:00
|
|
|
}
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2008-10-21 18:10:49 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.ungetbyte(fixnum) -> nil
|
|
|
|
*
|
|
|
|
* See IO#ungetbyte
|
|
|
|
*/
|
|
|
|
static VALUE
|
|
|
|
strio_ungetbyte(VALUE self, VALUE c)
|
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
struct StringIO *ptr = readable(self);
|
2009-05-14 03:07:55 -04:00
|
|
|
|
2015-12-18 01:40:00 -05:00
|
|
|
check_modifiable(ptr);
|
2019-07-09 14:02:01 -04:00
|
|
|
if (NIL_P(c)) return Qnil;
|
|
|
|
if (RB_INTEGER_TYPE_P(c)) {
|
2019-01-15 07:05:46 -05:00
|
|
|
/* rb_int_and() not visible from exts */
|
|
|
|
VALUE v = rb_funcall(c, '&', 1, INT2FIX(0xff));
|
|
|
|
const char cc = NUM2INT(v) & 0xFF;
|
|
|
|
strio_unget_bytes(ptr, &cc, 1);
|
2009-05-14 03:07:55 -04:00
|
|
|
}
|
2019-07-09 14:02:01 -04:00
|
|
|
else {
|
|
|
|
long cl;
|
|
|
|
SafeStringValue(c);
|
|
|
|
cl = RSTRING_LEN(c);
|
|
|
|
if (cl > 0) {
|
|
|
|
strio_unget_bytes(ptr, RSTRING_PTR(c), cl);
|
|
|
|
RB_GC_GUARD(c);
|
|
|
|
}
|
|
|
|
}
|
2019-01-15 01:41:58 -05:00
|
|
|
return Qnil;
|
2015-12-18 01:40:00 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
strio_unget_bytes(struct StringIO *ptr, const char *cp, long cl)
|
|
|
|
{
|
|
|
|
long pos = ptr->pos, len, rest;
|
|
|
|
VALUE str = ptr->string;
|
|
|
|
char *s;
|
|
|
|
|
2015-12-17 22:09:16 -05:00
|
|
|
len = RSTRING_LEN(str);
|
|
|
|
rest = pos - len;
|
2009-05-14 03:07:55 -04:00
|
|
|
if (cl > pos) {
|
2021-11-16 03:39:32 -05:00
|
|
|
long ex = cl - (rest < 0 ? pos : len);
|
2015-12-17 22:09:16 -05:00
|
|
|
rb_str_modify_expand(str, ex);
|
|
|
|
rb_str_set_len(str, len + ex);
|
2009-05-14 03:07:55 -04:00
|
|
|
s = RSTRING_PTR(str);
|
2015-12-17 22:09:16 -05:00
|
|
|
if (rest < 0) memmove(s + cl, s + pos, -rest);
|
2009-05-14 03:07:55 -04:00
|
|
|
pos = 0;
|
|
|
|
}
|
|
|
|
else {
|
2015-12-17 22:09:16 -05:00
|
|
|
if (rest > 0) {
|
|
|
|
rb_str_modify_expand(str, rest);
|
|
|
|
rb_str_set_len(str, len + rest);
|
|
|
|
}
|
|
|
|
s = RSTRING_PTR(str);
|
|
|
|
if (rest > cl) memset(s + len, 0, rest - cl);
|
2009-05-14 03:07:55 -04:00
|
|
|
pos -= cl;
|
|
|
|
}
|
2015-12-17 22:09:16 -05:00
|
|
|
memcpy(s + pos, cp, cl);
|
2009-05-14 03:07:55 -04:00
|
|
|
ptr->pos = pos;
|
|
|
|
return Qnil;
|
2008-10-21 18:10:49 -04:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2008-12-02 22:22:12 -05:00
|
|
|
* strio.readchar -> string
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#readchar.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_readchar(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2019-09-29 05:02:00 -04:00
|
|
|
VALUE c = rb_funcallv(self, rb_intern("getc"), 0, 0);
|
2002-03-11 06:58:07 -05:00
|
|
|
if (NIL_P(c)) rb_eof_error();
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2007-08-14 20:33:33 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.readbyte -> fixnum
|
|
|
|
*
|
|
|
|
* See IO#readbyte.
|
|
|
|
*/
|
|
|
|
static VALUE
|
|
|
|
strio_readbyte(VALUE self)
|
|
|
|
{
|
2019-09-29 05:02:00 -04:00
|
|
|
VALUE c = rb_funcallv(self, rb_intern("getbyte"), 0, 0);
|
2007-08-14 20:33:33 -04:00
|
|
|
if (NIL_P(c)) rb_eof_error();
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2008-05-27 06:03:23 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.each_char {|char| block } -> strio
|
2010-03-07 05:22:05 -05:00
|
|
|
* strio.each_char -> anEnumerator
|
2008-05-27 06:03:23 -04:00
|
|
|
*
|
|
|
|
* See IO#each_char.
|
|
|
|
*/
|
|
|
|
static VALUE
|
|
|
|
strio_each_char(VALUE self)
|
|
|
|
{
|
|
|
|
VALUE c;
|
|
|
|
|
|
|
|
RETURN_ENUMERATOR(self, 0, 0);
|
|
|
|
|
|
|
|
while (!NIL_P(c = strio_getc(self))) {
|
|
|
|
rb_yield(c);
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2009-06-22 04:23:30 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.each_codepoint {|c| block } -> strio
|
2010-03-07 05:22:05 -05:00
|
|
|
* strio.each_codepoint -> anEnumerator
|
2009-06-22 04:23:30 -04:00
|
|
|
*
|
|
|
|
* See IO#each_codepoint.
|
|
|
|
*/
|
|
|
|
static VALUE
|
|
|
|
strio_each_codepoint(VALUE self)
|
|
|
|
{
|
|
|
|
struct StringIO *ptr;
|
|
|
|
rb_encoding *enc;
|
|
|
|
unsigned int c;
|
|
|
|
int n;
|
|
|
|
|
|
|
|
RETURN_ENUMERATOR(self, 0, 0);
|
|
|
|
|
2012-10-29 05:23:02 -04:00
|
|
|
ptr = readable(self);
|
2015-12-18 02:54:33 -05:00
|
|
|
enc = get_enc(ptr);
|
2021-03-07 08:39:38 -05:00
|
|
|
while ((ptr = strio_to_read(self)) != NULL) {
|
2009-06-22 04:23:30 -04:00
|
|
|
c = rb_enc_codepoint_len(RSTRING_PTR(ptr->string)+ptr->pos,
|
|
|
|
RSTRING_END(ptr->string), &n, enc);
|
|
|
|
ptr->pos += n;
|
2020-08-26 16:46:58 -04:00
|
|
|
rb_yield(UINT2NUM(c));
|
2009-06-22 04:23:30 -04:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2007-08-14 20:33:33 -04:00
|
|
|
/* Boyer-Moore search: copied from regex.c */
|
2002-03-11 06:58:07 -05:00
|
|
|
static void
|
2006-06-20 14:02:17 -04:00
|
|
|
bm_init_skip(long *skip, const char *pat, long m)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
int c;
|
|
|
|
|
|
|
|
for (c = 0; c < (1 << CHAR_BIT); c++) {
|
|
|
|
skip[c] = m;
|
|
|
|
}
|
|
|
|
while (--m) {
|
|
|
|
skip[(unsigned char)*pat++] = m;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static long
|
2006-06-20 14:02:17 -04:00
|
|
|
bm_search(const char *little, long llen, const char *big, long blen, const long *skip)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
long i, j, k;
|
|
|
|
|
|
|
|
i = llen - 1;
|
|
|
|
while (i < blen) {
|
|
|
|
k = i;
|
|
|
|
j = llen - 1;
|
|
|
|
while (j >= 0 && big[k] == little[j]) {
|
|
|
|
k--;
|
|
|
|
j--;
|
|
|
|
}
|
|
|
|
if (j < 0) return k + 1;
|
|
|
|
i += skip[(unsigned char)big[i]];
|
|
|
|
}
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2016-07-11 03:00:58 -04:00
|
|
|
struct getline_arg {
|
|
|
|
VALUE rs;
|
|
|
|
long limit;
|
2016-12-03 06:01:25 -05:00
|
|
|
unsigned int chomp: 1;
|
2016-07-11 03:00:58 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
static struct getline_arg *
|
|
|
|
prepare_getline_args(struct getline_arg *arg, int argc, VALUE *argv)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2016-12-03 06:01:25 -05:00
|
|
|
VALUE str, lim, opts;
|
2016-07-11 03:00:58 -04:00
|
|
|
long limit = -1;
|
2022-05-29 23:56:13 -04:00
|
|
|
int respect_chomp;
|
2002-03-11 06:58:07 -05:00
|
|
|
|
2016-12-03 06:01:25 -05:00
|
|
|
argc = rb_scan_args(argc, argv, "02:", &str, &lim, &opts);
|
2022-05-29 23:56:13 -04:00
|
|
|
respect_chomp = argc == 0 || !NIL_P(str);
|
2011-04-08 03:50:49 -04:00
|
|
|
switch (argc) {
|
|
|
|
case 0:
|
2002-03-11 06:58:07 -05:00
|
|
|
str = rb_rs;
|
2011-04-08 03:50:49 -04:00
|
|
|
break;
|
2006-12-29 14:21:50 -05:00
|
|
|
|
2011-04-08 03:50:49 -04:00
|
|
|
case 1:
|
2012-05-23 03:13:21 -04:00
|
|
|
if (!NIL_P(str) && !RB_TYPE_P(str, T_STRING)) {
|
2011-04-08 03:50:49 -04:00
|
|
|
VALUE tmp = rb_check_string_type(str);
|
2006-12-29 14:21:50 -05:00
|
|
|
if (NIL_P(tmp)) {
|
|
|
|
limit = NUM2LONG(str);
|
|
|
|
str = rb_rs;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
str = tmp;
|
|
|
|
}
|
|
|
|
}
|
2011-04-08 03:50:49 -04:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 2:
|
|
|
|
if (!NIL_P(str)) StringValue(str);
|
2012-12-27 07:21:17 -05:00
|
|
|
if (!NIL_P(lim)) limit = NUM2LONG(lim);
|
2011-04-08 03:50:49 -04:00
|
|
|
break;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
2016-07-11 03:00:58 -04:00
|
|
|
arg->rs = str;
|
|
|
|
arg->limit = limit;
|
2016-12-03 06:01:25 -05:00
|
|
|
arg->chomp = 0;
|
|
|
|
if (!NIL_P(opts)) {
|
|
|
|
static ID keywords[1];
|
|
|
|
VALUE vchomp;
|
|
|
|
if (!keywords[0]) {
|
|
|
|
keywords[0] = rb_intern_const("chomp");
|
|
|
|
}
|
|
|
|
rb_get_kwargs(opts, keywords, 0, 1, &vchomp);
|
2022-05-26 15:17:55 -04:00
|
|
|
if (respect_chomp) {
|
|
|
|
arg->chomp = (vchomp != Qundef) && RTEST(vchomp);
|
|
|
|
}
|
2016-12-03 06:01:25 -05:00
|
|
|
}
|
2016-07-11 03:00:58 -04:00
|
|
|
return arg;
|
|
|
|
}
|
|
|
|
|
2016-12-03 06:01:25 -05:00
|
|
|
static inline int
|
|
|
|
chomp_newline_width(const char *s, const char *e)
|
|
|
|
{
|
|
|
|
if (e > s && *--e == '\n') {
|
2016-12-10 03:54:40 -05:00
|
|
|
if (e > s && *--e == '\r') return 2;
|
2016-12-03 06:01:25 -05:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-07-11 03:00:58 -04:00
|
|
|
static VALUE
|
|
|
|
strio_getline(struct getline_arg *arg, struct StringIO *ptr)
|
|
|
|
{
|
|
|
|
const char *s, *e, *p;
|
|
|
|
long n, limit = arg->limit;
|
|
|
|
VALUE str = arg->rs;
|
2022-05-26 18:22:28 -04:00
|
|
|
long w = 0;
|
2017-08-13 03:31:49 -04:00
|
|
|
rb_encoding *enc = get_enc(ptr);
|
2002-03-11 06:58:07 -05:00
|
|
|
|
2006-08-31 06:30:33 -04:00
|
|
|
if (ptr->pos >= (n = RSTRING_LEN(ptr->string))) {
|
2003-11-18 04:09:41 -05:00
|
|
|
return Qnil;
|
|
|
|
}
|
2006-08-31 06:30:33 -04:00
|
|
|
s = RSTRING_PTR(ptr->string);
|
|
|
|
e = s + RSTRING_LEN(ptr->string);
|
2002-03-11 06:58:07 -05:00
|
|
|
s += ptr->pos;
|
2016-06-17 19:52:48 -04:00
|
|
|
if (limit > 0 && (size_t)limit < (size_t)(e - s)) {
|
2015-12-18 02:54:33 -05:00
|
|
|
e = rb_enc_right_char_head(s, s + limit, e, get_enc(ptr));
|
2006-12-29 14:21:50 -05:00
|
|
|
}
|
2002-03-11 06:58:07 -05:00
|
|
|
if (NIL_P(str)) {
|
2016-12-03 06:01:25 -05:00
|
|
|
if (arg->chomp) {
|
|
|
|
w = chomp_newline_width(s, e);
|
|
|
|
}
|
2017-08-13 03:31:49 -04:00
|
|
|
str = strio_substr(ptr, ptr->pos, e - s - w, enc);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
2006-08-31 06:30:33 -04:00
|
|
|
else if ((n = RSTRING_LEN(str)) == 0) {
|
2022-05-26 18:01:44 -04:00
|
|
|
const char *paragraph_end = NULL;
|
2002-03-11 06:58:07 -05:00
|
|
|
p = s;
|
2016-12-10 03:54:40 -05:00
|
|
|
while (p[(p + 1 < e) && (*p == '\r') && 0] == '\n') {
|
|
|
|
p += *p == '\r';
|
2003-11-18 04:09:41 -05:00
|
|
|
if (++p == e) {
|
|
|
|
return Qnil;
|
|
|
|
}
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
s = p;
|
2005-04-30 00:11:33 -04:00
|
|
|
while ((p = memchr(p, '\n', e - p)) && (p != e)) {
|
2022-05-26 18:01:44 -04:00
|
|
|
p++;
|
|
|
|
if (!((p < e && *p == '\n') ||
|
|
|
|
(p + 1 < e && *p == '\r' && *(p+1) == '\n'))) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
paragraph_end = p - ((*(p-2) == '\r') ? 2 : 1);
|
|
|
|
while ((p < e && *p == '\n') ||
|
|
|
|
(p + 1 < e && *p == '\r' && *(p+1) == '\n')) {
|
|
|
|
p += (*p == '\r') ? 2 : 1;
|
|
|
|
}
|
|
|
|
e = p;
|
|
|
|
break;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
2022-05-26 18:01:44 -04:00
|
|
|
if (arg->chomp && paragraph_end) {
|
|
|
|
w = e - paragraph_end;
|
2016-12-03 06:01:25 -05:00
|
|
|
}
|
2017-08-13 03:31:49 -04:00
|
|
|
str = strio_substr(ptr, s - RSTRING_PTR(ptr->string), e - s - w, enc);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
else if (n == 1) {
|
2006-08-31 06:30:33 -04:00
|
|
|
if ((p = memchr(s, RSTRING_PTR(str)[0], e - s)) != 0) {
|
2002-03-11 06:58:07 -05:00
|
|
|
e = p + 1;
|
2016-12-10 03:54:40 -05:00
|
|
|
w = (arg->chomp ? (p > s && *(p-1) == '\r') + 1 : 0);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
2017-08-13 03:31:49 -04:00
|
|
|
str = strio_substr(ptr, ptr->pos, e - s - w, enc);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
else {
|
2002-07-11 11:04:23 -04:00
|
|
|
if (n < e - s) {
|
|
|
|
if (e - s < 1024) {
|
2002-03-11 06:58:07 -05:00
|
|
|
for (p = s; p + n <= e; ++p) {
|
2006-08-31 06:30:33 -04:00
|
|
|
if (MEMCMP(p, RSTRING_PTR(str), char, n) == 0) {
|
2022-05-26 18:22:28 -04:00
|
|
|
e = p + n;
|
|
|
|
w = (arg->chomp ? n : 0);
|
2002-03-11 06:58:07 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
long skip[1 << CHAR_BIT], pos;
|
2006-08-31 06:30:33 -04:00
|
|
|
p = RSTRING_PTR(str);
|
2002-03-11 06:58:07 -05:00
|
|
|
bm_init_skip(skip, p, n);
|
|
|
|
if ((pos = bm_search(p, n, s, e - s, skip)) >= 0) {
|
2016-12-03 06:01:25 -05:00
|
|
|
e = s + pos + (arg->chomp ? 0 : n);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-08-13 03:31:49 -04:00
|
|
|
str = strio_substr(ptr, ptr->pos, e - s - w, enc);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
2006-08-31 06:30:33 -04:00
|
|
|
ptr->pos = e - RSTRING_PTR(ptr->string);
|
2002-03-11 06:58:07 -05:00
|
|
|
ptr->lineno++;
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2019-10-26 03:03:24 -04:00
|
|
|
* strio.gets(sep=$/, chomp: false) -> string or nil
|
|
|
|
* strio.gets(limit, chomp: false) -> string or nil
|
|
|
|
* strio.gets(sep, limit, chomp: false) -> string or nil
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#gets.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_gets(int argc, VALUE *argv, VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2016-07-11 03:00:58 -04:00
|
|
|
struct getline_arg arg;
|
|
|
|
VALUE str;
|
|
|
|
|
|
|
|
if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
|
2017-08-13 03:21:13 -04:00
|
|
|
struct StringIO *ptr = readable(self);
|
|
|
|
return rb_enc_str_new(0, 0, get_enc(ptr));
|
2016-07-11 03:00:58 -04:00
|
|
|
}
|
* ext/stringio/stringio.c (strio_gets): only "gets" should set $_.
* ext/stringio/stringio.c (strio_getline): should not set $_ here.
* io.c (argf_to_s): argf.to_s returns "ARGF".
* io.c (set_defout_var, set_deferr_var): make $defout and $deferr
obsolete.
* io.c (set_input_var, set_output_var): allow $stdin, $stdout,
$stderr not to be instance of IO.
* io.c (rb_f_readline): forward method to current_file. gets,
readline, readlines, getc, readchar, tell, seek, pos=, rewind,
fileno, to_io, eof, each_line, each_byte, binmode, and closed?
as well.
* io.c (argf_forward): utility function to forward method to
current_file.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4190 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-07-28 03:31:52 -04:00
|
|
|
|
2016-07-11 03:00:58 -04:00
|
|
|
str = strio_getline(&arg, readable(self));
|
* ext/stringio/stringio.c (strio_gets): only "gets" should set $_.
* ext/stringio/stringio.c (strio_getline): should not set $_ here.
* io.c (argf_to_s): argf.to_s returns "ARGF".
* io.c (set_defout_var, set_deferr_var): make $defout and $deferr
obsolete.
* io.c (set_input_var, set_output_var): allow $stdin, $stdout,
$stderr not to be instance of IO.
* io.c (rb_f_readline): forward method to current_file. gets,
readline, readlines, getc, readchar, tell, seek, pos=, rewind,
fileno, to_io, eof, each_line, each_byte, binmode, and closed?
as well.
* io.c (argf_forward): utility function to forward method to
current_file.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4190 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2003-07-28 03:31:52 -04:00
|
|
|
rb_lastline_set(str);
|
|
|
|
return str;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2019-10-26 03:03:24 -04:00
|
|
|
* strio.readline(sep=$/, chomp: false) -> string
|
|
|
|
* strio.readline(limit, chomp: false) -> string or nil
|
|
|
|
* strio.readline(sep, limit, chomp: false) -> string or nil
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#readline.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_readline(int argc, VALUE *argv, VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2019-09-29 05:06:02 -04:00
|
|
|
VALUE line = rb_funcallv_kw(self, rb_intern("gets"), argc, argv, RB_PASS_CALLED_KEYWORDS);
|
2002-03-11 06:58:07 -05:00
|
|
|
if (NIL_P(line)) rb_eof_error();
|
|
|
|
return line;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2019-10-26 03:03:24 -04:00
|
|
|
* strio.each(sep=$/, chomp: false) {|line| block } -> strio
|
|
|
|
* strio.each(limit, chomp: false) {|line| block } -> strio
|
|
|
|
* strio.each(sep, limit, chomp: false) {|line| block } -> strio
|
|
|
|
* strio.each(...) -> anEnumerator
|
2010-03-07 05:22:05 -05:00
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* strio.each_line(sep=$/, chomp: false) {|line| block } -> strio
|
|
|
|
* strio.each_line(limit, chomp: false) {|line| block } -> strio
|
|
|
|
* strio.each_line(sep, limit, chomp: false) {|line| block } -> strio
|
|
|
|
* strio.each_line(...) -> anEnumerator
|
2010-03-07 05:22:05 -05:00
|
|
|
*
|
2005-03-15 09:52:59 -05:00
|
|
|
* See IO#each.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_each(int argc, VALUE *argv, VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
VALUE line;
|
2016-07-11 03:00:58 -04:00
|
|
|
struct getline_arg arg;
|
2002-03-11 06:58:07 -05:00
|
|
|
|
2012-10-29 05:23:02 -04:00
|
|
|
StringIO(self);
|
2011-04-09 10:28:06 -04:00
|
|
|
RETURN_ENUMERATOR(self, argc, argv);
|
|
|
|
|
2016-07-11 03:00:58 -04:00
|
|
|
if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
|
2011-04-09 10:28:06 -04:00
|
|
|
rb_raise(rb_eArgError, "invalid limit: 0 for each_line");
|
2011-04-09 09:01:23 -04:00
|
|
|
}
|
|
|
|
|
2016-07-11 03:00:58 -04:00
|
|
|
while (!NIL_P(line = strio_getline(&arg, readable(self)))) {
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_yield(line);
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2019-10-26 03:03:24 -04:00
|
|
|
* strio.readlines(sep=$/, chomp: false) -> array
|
|
|
|
* strio.readlines(limit, chomp: false) -> array
|
|
|
|
* strio.readlines(sep, limit, chomp: false) -> array
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#readlines.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_readlines(int argc, VALUE *argv, VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
VALUE ary, line;
|
2016-07-11 03:00:58 -04:00
|
|
|
struct getline_arg arg;
|
2011-04-09 09:01:23 -04:00
|
|
|
|
2012-10-29 05:23:02 -04:00
|
|
|
StringIO(self);
|
|
|
|
ary = rb_ary_new();
|
2016-07-11 03:00:58 -04:00
|
|
|
if (prepare_getline_args(&arg, argc, argv)->limit == 0) {
|
2011-04-09 09:01:23 -04:00
|
|
|
rb_raise(rb_eArgError, "invalid limit: 0 for readlines");
|
|
|
|
}
|
|
|
|
|
2016-07-11 03:00:58 -04:00
|
|
|
while (!NIL_P(line = strio_getline(&arg, readable(self)))) {
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_ary_push(ary, line);
|
|
|
|
}
|
|
|
|
return ary;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2017-12-21 22:35:54 -05:00
|
|
|
* strio.write(string, ...) -> integer
|
|
|
|
* strio.syswrite(string) -> integer
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Appends the given string to the underlying buffer string.
|
2005-03-15 09:52:59 -05:00
|
|
|
* The stream must be opened for writing. If the argument is not a
|
|
|
|
* string, it will be converted to a string using <code>to_s</code>.
|
|
|
|
* Returns the number of bytes written. See IO#write.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2017-10-23 02:25:39 -04:00
|
|
|
strio_write_m(int argc, VALUE *argv, VALUE self)
|
|
|
|
{
|
|
|
|
long len = 0;
|
|
|
|
while (argc-- > 0) {
|
|
|
|
/* StringIO can't exceed long limit */
|
|
|
|
len += strio_write(self, *argv++);
|
|
|
|
}
|
|
|
|
return LONG2NUM(len);
|
|
|
|
}
|
|
|
|
|
|
|
|
static long
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_write(VALUE self, VALUE str)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
struct StringIO *ptr = writable(self);
|
2004-09-08 05:44:46 -04:00
|
|
|
long len, olen;
|
2008-10-21 10:14:13 -04:00
|
|
|
rb_encoding *enc, *enc2;
|
2014-09-25 23:52:37 -04:00
|
|
|
rb_encoding *const ascii8bit = rb_ascii8bit_encoding();
|
2020-07-19 03:08:03 -04:00
|
|
|
rb_encoding *usascii = 0;
|
2002-03-11 06:58:07 -05:00
|
|
|
|
2012-05-23 03:13:21 -04:00
|
|
|
if (!RB_TYPE_P(str, T_STRING))
|
2002-03-11 06:58:07 -05:00
|
|
|
str = rb_obj_as_string(str);
|
2015-12-18 02:54:33 -05:00
|
|
|
enc = get_enc(ptr);
|
2008-10-21 10:14:13 -04:00
|
|
|
enc2 = rb_enc_get(str);
|
2020-07-19 03:08:03 -04:00
|
|
|
if (enc != enc2 && enc != ascii8bit && enc != (usascii = rb_usascii_encoding())) {
|
2020-07-18 10:52:27 -04:00
|
|
|
VALUE converted = rb_str_conv_enc(str, enc2, enc);
|
2020-07-19 03:08:03 -04:00
|
|
|
if (converted == str && enc2 != ascii8bit && enc2 != usascii) { /* conversion failed */
|
2020-07-18 10:52:27 -04:00
|
|
|
rb_enc_check(rb_enc_from_encoding(enc), str);
|
|
|
|
}
|
|
|
|
str = converted;
|
2008-10-21 10:14:13 -04:00
|
|
|
}
|
2006-08-31 06:30:33 -04:00
|
|
|
len = RSTRING_LEN(str);
|
2017-10-23 02:25:39 -04:00
|
|
|
if (len == 0) return 0;
|
2002-03-13 22:35:52 -05:00
|
|
|
check_modifiable(ptr);
|
2006-08-31 06:30:33 -04:00
|
|
|
olen = RSTRING_LEN(ptr->string);
|
2004-10-06 13:57:19 -04:00
|
|
|
if (ptr->flags & FMODE_APPEND) {
|
2004-09-08 05:44:46 -04:00
|
|
|
ptr->pos = olen;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
2004-09-08 05:44:46 -04:00
|
|
|
if (ptr->pos == olen) {
|
2014-09-25 23:52:37 -04:00
|
|
|
if (enc == ascii8bit || enc2 == ascii8bit) {
|
2014-04-22 22:03:43 -04:00
|
|
|
rb_enc_str_buf_cat(ptr->string, RSTRING_PTR(str), len, enc);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_str_buf_append(ptr->string, str);
|
|
|
|
}
|
2002-04-08 23:52:39 -04:00
|
|
|
}
|
|
|
|
else {
|
2005-02-03 09:43:07 -05:00
|
|
|
strio_extend(ptr, ptr->pos, len);
|
* encoding.c: provide basic features for M17N.
* parse.y: encoding aware parsing.
* parse.y (pragma_encoding): encoding specification pragma.
* parse.y (rb_intern3): encoding specified symbols.
* string.c (rb_str_length): length based on characters.
for older behavior, bytesize method added.
* string.c (rb_str_index_m): index based on characters. rindex as
well.
* string.c (succ_char): encoding aware succeeding string.
* string.c (rb_str_reverse): reverse based on characters.
* string.c (rb_str_inspect): encoding aware string description.
* string.c (rb_str_upcase_bang): encoding aware case conversion.
downcase, capitalize, swapcase as well.
* string.c (rb_str_tr_bang): tr based on characters. delete,
squeeze, tr_s, count as well.
* string.c (rb_str_split_m): split based on characters.
* string.c (rb_str_each_line): encoding aware each_line.
* string.c (rb_str_each_char): added. iteration based on
characters.
* string.c (rb_str_strip_bang): encoding aware whitespace
stripping. lstrip, rstrip as well.
* string.c (rb_str_justify): encoding aware justifying (ljust,
rjust, center).
* string.c (str_encoding): get encoding attribute from a string.
* re.c (rb_reg_initialize): encoding aware regular expression
* sprintf.c (rb_str_format): formatting (i.e. length count) based
on characters.
* io.c (rb_io_getc): getc to return one-character string.
for older behavior, getbyte method added.
* ext/stringio/stringio.c (strio_getc): ditto.
* io.c (rb_io_ungetc): allow pushing arbitrary string at the
current reading point.
* ext/stringio/stringio.c (strio_ungetc): ditto.
* ext/strscan/strscan.c: encoding support.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@13261 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2007-08-24 23:29:39 -04:00
|
|
|
memmove(RSTRING_PTR(ptr->string)+ptr->pos, RSTRING_PTR(str), len);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
2014-04-22 22:03:35 -04:00
|
|
|
RB_GC_GUARD(str);
|
2002-03-11 06:58:07 -05:00
|
|
|
ptr->pos += len;
|
2017-10-23 02:25:39 -04:00
|
|
|
return len;
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2005-03-15 10:43:29 -05:00
|
|
|
* strio << obj -> strio
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#<<.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
#define strio_addstr rb_io_addstr
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2005-03-15 10:43:29 -05:00
|
|
|
* strio.print() -> nil
|
|
|
|
* strio.print(obj, ...) -> nil
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#print.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
#define strio_print rb_io_print
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2005-03-15 10:43:29 -05:00
|
|
|
* strio.printf(format_string [, obj, ...] ) -> nil
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#printf.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
#define strio_printf rb_io_printf
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2005-03-15 10:43:29 -05:00
|
|
|
* strio.putc(obj) -> obj
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#putc.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_putc(VALUE self, VALUE ch)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
struct StringIO *ptr = writable(self);
|
2014-04-21 01:11:50 -04:00
|
|
|
VALUE str;
|
2002-03-11 06:58:07 -05:00
|
|
|
|
2002-03-13 22:35:52 -05:00
|
|
|
check_modifiable(ptr);
|
2014-04-21 01:11:50 -04:00
|
|
|
if (RB_TYPE_P(ch, T_STRING)) {
|
|
|
|
str = rb_str_substr(ch, 0, 1);
|
2002-04-08 23:52:39 -04:00
|
|
|
}
|
2014-04-21 01:11:50 -04:00
|
|
|
else {
|
|
|
|
char c = NUM2CHR(ch);
|
|
|
|
str = rb_str_new(&c, 1);
|
|
|
|
}
|
|
|
|
strio_write(self, str);
|
2002-03-11 06:58:07 -05:00
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2005-03-15 10:43:29 -05:00
|
|
|
* strio.puts(obj, ...) -> nil
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#puts.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
#define strio_puts rb_io_puts
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2012-04-18 19:48:27 -04:00
|
|
|
* strio.read([length [, outbuf]]) -> string, outbuf, or nil
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* See IO#read.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_read(int argc, VALUE *argv, VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
struct StringIO *ptr = readable(self);
|
2003-12-23 20:29:57 -05:00
|
|
|
VALUE str = Qnil;
|
2009-09-27 21:08:24 -04:00
|
|
|
long len;
|
2011-08-19 21:43:26 -04:00
|
|
|
int binary = 0;
|
2002-03-11 06:58:07 -05:00
|
|
|
|
|
|
|
switch (argc) {
|
2003-12-23 20:29:57 -05:00
|
|
|
case 2:
|
|
|
|
str = argv[1];
|
2011-08-19 21:43:26 -04:00
|
|
|
if (!NIL_P(str)) {
|
|
|
|
StringValue(str);
|
|
|
|
rb_str_modify(str);
|
|
|
|
}
|
2017-08-13 03:53:04 -04:00
|
|
|
/* fall through */
|
2002-03-11 06:58:07 -05:00
|
|
|
case 1:
|
|
|
|
if (!NIL_P(argv[0])) {
|
2009-09-27 21:08:24 -04:00
|
|
|
len = NUM2LONG(argv[0]);
|
2003-11-18 04:09:41 -05:00
|
|
|
if (len < 0) {
|
|
|
|
rb_raise(rb_eArgError, "negative length %ld given", len);
|
|
|
|
}
|
2006-08-31 06:30:33 -04:00
|
|
|
if (len > 0 && ptr->pos >= RSTRING_LEN(ptr->string)) {
|
2003-12-24 00:23:32 -05:00
|
|
|
if (!NIL_P(str)) rb_str_resize(str, 0);
|
2003-11-18 04:23:07 -05:00
|
|
|
return Qnil;
|
|
|
|
}
|
2011-08-19 21:43:26 -04:00
|
|
|
binary = 1;
|
2002-03-11 06:58:07 -05:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
/* fall through */
|
|
|
|
case 0:
|
2006-08-31 06:30:33 -04:00
|
|
|
len = RSTRING_LEN(ptr->string);
|
2003-12-10 05:29:00 -05:00
|
|
|
if (len <= ptr->pos) {
|
2019-07-14 11:19:41 -04:00
|
|
|
rb_encoding *enc = get_enc(ptr);
|
2003-12-23 20:29:57 -05:00
|
|
|
if (NIL_P(str)) {
|
|
|
|
str = rb_str_new(0, 0);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
rb_str_resize(str, 0);
|
|
|
|
}
|
2017-08-11 21:47:09 -04:00
|
|
|
rb_enc_associate(str, enc);
|
2003-12-23 20:29:57 -05:00
|
|
|
return str;
|
2003-12-10 05:29:00 -05:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
len -= ptr->pos;
|
2003-11-18 04:09:41 -05:00
|
|
|
}
|
2002-03-11 06:58:07 -05:00
|
|
|
break;
|
2020-05-22 00:49:08 -04:00
|
|
|
default:
|
|
|
|
rb_error_arity(argc, 0, 2);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
2003-12-23 20:29:57 -05:00
|
|
|
if (NIL_P(str)) {
|
2017-08-13 03:31:49 -04:00
|
|
|
rb_encoding *enc = binary ? rb_ascii8bit_encoding() : get_enc(ptr);
|
|
|
|
str = strio_substr(ptr, ptr->pos, len, enc);
|
2003-12-23 20:29:57 -05:00
|
|
|
}
|
|
|
|
else {
|
2006-08-31 06:30:33 -04:00
|
|
|
long rest = RSTRING_LEN(ptr->string) - ptr->pos;
|
2003-12-23 20:29:57 -05:00
|
|
|
if (len > rest) len = rest;
|
|
|
|
rb_str_resize(str, len);
|
2006-08-31 06:30:33 -04:00
|
|
|
MEMCPY(RSTRING_PTR(str), RSTRING_PTR(ptr->string) + ptr->pos, char, len);
|
2011-08-19 21:43:26 -04:00
|
|
|
if (binary)
|
|
|
|
rb_enc_associate(str, rb_ascii8bit_encoding());
|
|
|
|
else
|
|
|
|
rb_enc_copy(str, ptr->string);
|
2003-12-23 20:29:57 -05:00
|
|
|
}
|
2011-08-19 21:43:26 -04:00
|
|
|
ptr->pos += RSTRING_LEN(str);
|
2002-03-11 06:58:07 -05:00
|
|
|
return str;
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2005-03-15 10:43:29 -05:00
|
|
|
* strio.sysread(integer[, outbuf]) -> string
|
2013-04-15 23:25:50 -04:00
|
|
|
* strio.readpartial(integer[, outbuf]) -> string
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* Similar to #read, but raises +EOFError+ at end of string instead of
|
|
|
|
* returning +nil+, as well as IO#sysread does.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
* sprintf.c (rb_str_format): allow %c to print one character
string (e.g. ?x).
* lib/tempfile.rb (Tempfile::make_tmpname): put dot between
basename and pid. [ruby-talk:196272]
* parse.y (do_block): remove -> style block.
* parse.y (parser_yylex): remove tLAMBDA_ARG.
* eval.c (rb_call0): binding for the return event hook should have
consistent scope. [ruby-core:07928]
* eval.c (proc_invoke): return behavior should depend whether it
is surrounded by a lambda or a mere block.
* eval.c (formal_assign): handles post splat arguments.
* eval.c (rb_call0): ditto.
* st.c (strhash): use FNV-1a hash.
* parse.y (parser_yylex): removed experimental ';;' terminator.
* eval.c (rb_node_arity): should be aware of post splat arguments.
* eval.c (rb_proc_arity): ditto.
* parse.y (f_args): syntax rule enhanced to support arguments
after the splat.
* parse.y (block_param): ditto for block parameters.
* parse.y (f_post_arg): mandatory formal arguments after the splat
argument.
* parse.y (new_args_gen): generate nodes for mandatory formal
arguments after the splat argument.
* eval.c (rb_eval): dispatch mandatory formal arguments after the
splat argument.
* parse.y (args): allow more than one splat in the argument list.
* parse.y (method_call): allow aref [] to accept all kind of
method argument, including assocs, splat, and block argument.
* eval.c (SETUP_ARGS0): prepare block argument as well.
* lib/mathn.rb (Integer): remove Integer#gcd2. [ruby-core:07931]
* eval.c (error_line): print receivers true/false/nil specially.
* eval.c (rb_proc_yield): handles parameters in yield semantics.
* eval.c (nil_yield): gives LocalJumpError to denote no block
error.
* io.c (rb_io_getc): now takes one-character string.
* string.c (rb_str_hash): use FNV-1a hash from Fowler/Noll/Vo
hashing algorithm.
* string.c (rb_str_aref): str[0] now returns 1 character string,
instead of a fixnum. [Ruby2]
* parse.y (parser_yylex): ?c now returns 1 character string,
instead of a fixnum. [Ruby2]
* string.c (rb_str_aset): no longer support fixnum insertion.
* eval.c (umethod_bind): should not update original class.
[ruby-dev:28636]
* eval.c (ev_const_get): should support constant access from
within instance_eval(). [ruby-dev:28327]
* time.c (time_timeval): should round for usec floating
number. [ruby-core:07896]
* time.c (time_add): ditto.
* dir.c (sys_warning): should not call a vararg function
rb_sys_warning() indirectly. [ruby-core:07886]
* numeric.c (flo_divmod): the first element of Float#divmod should
be an integer. [ruby-dev:28589]
* test/ruby/test_float.rb: add tests for divmod, div, modulo and remainder.
* re.c (rb_reg_initialize): should not allow modifying literal
regexps. frozen check moved from rb_reg_initialize_m as well.
* re.c (rb_reg_initialize): should not modify untainted objects in
safe levels higher than 3.
* re.c (rb_memcmp): type change from char* to const void*.
* dir.c (dir_close): should not close untainted dir stream.
* dir.c (GetDIR): add tainted/frozen check for each dir operation.
* lib/rdoc/parsers/parse_rb.rb (RDoc::RubyParser::parse_symbol_arg):
typo fixed. a patch from Florian Gross <florg at florg.net>.
* eval.c (EXEC_EVENT_HOOK): trace_func may remove itself from
event_hooks. no guarantee for arbitrary hook deletion.
[ruby-dev:28632]
* util.c (ruby_strtod): differ addition to minimize error.
[ruby-dev:28619]
* util.c (ruby_strtod): should not raise ERANGE when the input
string does not have any digits. [ruby-dev:28629]
* eval.c (proc_invoke): should restore old ruby_frame->block.
thanks to ts <decoux at moulon.inra.fr>. [ruby-core:07833]
also fix [ruby-dev:28614] as well.
* signal.c (trap): sig should be less then NSIG. Coverity found
this bug. a patch from Kevin Tew <tewk at tewk.com>.
[ruby-core:07823]
* math.c (math_log2): add new method inspired by
[ruby-talk:191237].
* math.c (math_log): add optional base argument to Math::log().
[ruby-talk:191308]
* ext/syck/emitter.c (syck_scan_scalar): avoid accessing
uninitialized array element. a patch from Pat Eyler
<rubypate at gmail.com>. [ruby-core:07809]
* array.c (rb_ary_fill): initialize local variables first. a
patch from Pat Eyler <rubypate at gmail.com>. [ruby-core:07810]
* ext/syck/yaml2byte.c (syck_yaml2byte_handler): need to free
type_tag. a patch from Pat Eyler <rubypate at gmail.com>.
[ruby-core:07808]
* ext/socket/socket.c (make_hostent_internal): accept ai_family
check from Sam Roberts <sroberts at uniserve.com>.
[ruby-core:07691]
* util.c (ruby_strtod): should not cut off 18 digits for no
reason. [ruby-core:07796]
* array.c (rb_ary_fill): internalize local variable "beg" to
pacify Coverity. [ruby-core:07770]
* pack.c (pack_unpack): now supports CRLF newlines. a patch from
<tommy at tmtm.org>. [ruby-dev:28601]
* applied code clean-up patch from Stefan Huehner
<stefan at huehner.org>. [ruby-core:07764]
* lib/jcode.rb (String::tr_s): should have translated non
squeezing character sequence (i.e. a character) as well. thanks
to Hiroshi Ichikawa <gimite at gimite.ddo.jp> [ruby-list:42090]
* ext/socket/socket.c: document update patch from Sam Roberts
<sroberts at uniserve.com>. [ruby-core:07701]
* lib/mathn.rb (Integer): need not to remove gcd2. a patch from
NARUSE, Yui <naruse at airemix.com>. [ruby-dev:28570]
* parse.y (arg): too much NEW_LIST()
* eval.c (SETUP_ARGS0): remove unnecessary access to nd_alen.
* eval.c (rb_eval): use ARGSCAT for NODE_OP_ASGN1.
[ruby-dev:28585]
* parse.y (arg): use NODE_ARGSCAT for placeholder.
* lib/getoptlong.rb (GetoptLong::get): RDoc update patch from
mathew <meta at pobox.com>. [ruby-core:07738]
* variable.c (rb_const_set): raise error when no target klass is
supplied. [ruby-dev:28582]
* prec.c (prec_prec_f): documentation patch from
<gerardo.santana at gmail.com>. [ruby-core:07689]
* bignum.c (rb_big_pow): second operand may be too big even if
it's a Fixnum. [ruby-talk:187984]
* README.EXT: update symbol description. [ruby-talk:188104]
* COPYING: explicitly note GPLv2. [ruby-talk:187922]
* parse.y: remove some obsolete syntax rules (unparenthesized
method calls in argument list).
* eval.c (rb_call0): insecure calling should be checked for non
NODE_SCOPE method invocations too.
* eval.c (rb_alias): should preserve the current safe level as
well as method definition.
* process.c (rb_f_sleep): remove RDoc description about SIGALRM
which is not valid on the current implementation. [ruby-dev:28464]
Thu Mar 23 21:40:47 2006 K.Kosako <sndgk393 AT ybb.ne.jp>
* eval.c (method_missing): should support argument splat in
super. a bug in combination of super, splat and
method_missing. [ruby-talk:185438]
* configure.in: Solaris SunPro compiler -rapth patch from
<kuwa at labs.fujitsu.com>. [ruby-dev:28443]
* configure.in: remove enable_rpath=no for Solaris.
[ruby-dev:28440]
* ext/win32ole/win32ole.c (ole_val2olevariantdata): change behavior
of converting OLE Variant object with VT_ARRAY|VT_UI1 and Ruby
String object.
* ruby.1: a clarification patch from David Lutterkort
<dlutter at redhat.com>. [ruby-core:7508]
* lib/rdoc/ri/ri_paths.rb (RI::Paths): adding paths from rubygems
directories. a patch from Eric Hodel <drbrain at segment7.net>.
[ruby-core:07423]
* eval.c (rb_clear_cache_by_class): clearing wrong cache.
* ext/extmk.rb: use :remove_destination to install extension libraries
to avoid SEGV. [ruby-dev:28417]
* eval.c (rb_thread_fd_writable): should not re-schedule output
from KILLED thread (must be error printing).
* array.c (rb_ary_flatten_bang): allow specifying recursion
level. [ruby-talk:182170]
* array.c (rb_ary_flatten): ditto.
* gc.c (add_heap): a heap_slots may overflow. a patch from Stefan
Weil <weil at mail.berlios.de>.
* eval.c (rb_call): use separate cache for fcall/vcall
invocation.
* eval.c (rb_eval): NODE_FCALL, NODE_VCALL can call local
functions.
* eval.c (rb_mod_local): a new method to specify newly added
visibility "local".
* eval.c (search_method): search for local methods which are
visible only from the current class.
* class.c (rb_class_local_methods): a method to list local methods.
* object.c (Init_Object): add BasicObject class as a top level
BlankSlate class.
* ruby.h (SYM2ID): should not cast to signed long.
[ruby-core:07414]
* class.c (rb_include_module): allow module duplication.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@10235 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2006-06-09 17:20:17 -04:00
|
|
|
strio_sysread(int argc, VALUE *argv, VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2019-09-29 05:06:02 -04:00
|
|
|
VALUE val = rb_funcallv_kw(self, rb_intern("read"), argc, argv, RB_PASS_CALLED_KEYWORDS);
|
2008-06-14 09:52:41 -04:00
|
|
|
if (NIL_P(val)) {
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_eof_error();
|
|
|
|
}
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2013-08-26 18:41:44 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.read_nonblock(integer[, outbuf [, opts]]) -> string
|
|
|
|
*
|
|
|
|
* Similar to #read, but raises +EOFError+ at end of string unless the
|
|
|
|
* +exception: false+ option is passed in.
|
|
|
|
*/
|
|
|
|
static VALUE
|
|
|
|
strio_read_nonblock(int argc, VALUE *argv, VALUE self)
|
|
|
|
{
|
2013-08-27 00:04:33 -04:00
|
|
|
VALUE opts = Qnil, val;
|
2013-08-26 18:41:44 -04:00
|
|
|
|
|
|
|
rb_scan_args(argc, argv, "11:", NULL, NULL, &opts);
|
|
|
|
|
|
|
|
if (!NIL_P(opts)) {
|
|
|
|
argc--;
|
|
|
|
}
|
|
|
|
|
2013-08-27 00:04:33 -04:00
|
|
|
val = strio_read(argc, argv, self);
|
2013-08-26 18:41:44 -04:00
|
|
|
if (NIL_P(val)) {
|
2015-07-02 18:22:14 -04:00
|
|
|
if (!NIL_P(opts) &&
|
|
|
|
rb_hash_lookup2(opts, sym_exception, Qundef) == Qfalse)
|
2013-08-26 18:41:44 -04:00
|
|
|
return Qnil;
|
|
|
|
else
|
|
|
|
rb_eof_error();
|
|
|
|
}
|
|
|
|
|
|
|
|
return val;
|
|
|
|
}
|
|
|
|
|
2012-01-25 13:24:09 -05:00
|
|
|
#define strio_syswrite rb_io_write
|
2002-03-11 06:58:07 -05:00
|
|
|
|
2013-08-26 18:41:44 -04:00
|
|
|
static VALUE
|
|
|
|
strio_syswrite_nonblock(int argc, VALUE *argv, VALUE self)
|
|
|
|
{
|
|
|
|
VALUE str;
|
|
|
|
|
|
|
|
rb_scan_args(argc, argv, "10:", &str, NULL);
|
|
|
|
return strio_syswrite(self, str);
|
|
|
|
}
|
|
|
|
|
2002-03-11 06:58:07 -05:00
|
|
|
#define strio_isatty strio_false
|
|
|
|
|
|
|
|
#define strio_pid strio_nil
|
|
|
|
|
|
|
|
#define strio_fileno strio_nil
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2013-04-15 23:25:50 -04:00
|
|
|
* strio.length -> integer
|
2005-03-15 10:43:29 -05:00
|
|
|
* strio.size -> integer
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
|
|
|
* Returns the size of the buffer string.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_size(VALUE self)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
|
|
|
VALUE string = StringIO(self)->string;
|
|
|
|
if (NIL_P(string)) {
|
|
|
|
rb_raise(rb_eIOError, "not opened");
|
|
|
|
}
|
2006-08-31 06:30:33 -04:00
|
|
|
return ULONG2NUM(RSTRING_LEN(string));
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2005-03-15 10:43:29 -05:00
|
|
|
* strio.truncate(integer) -> 0
|
2005-03-15 09:52:59 -05:00
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Truncates the buffer string to at most _integer_ bytes. The stream
|
2005-03-15 09:52:59 -05:00
|
|
|
* must be opened for writing.
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
static VALUE
|
2006-06-20 14:02:17 -04:00
|
|
|
strio_truncate(VALUE self, VALUE len)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2012-10-29 05:23:02 -04:00
|
|
|
VALUE string = writable(self)->string;
|
2002-03-11 06:58:07 -05:00
|
|
|
long l = NUM2LONG(len);
|
2006-08-31 06:30:33 -04:00
|
|
|
long plen = RSTRING_LEN(string);
|
2002-03-11 06:58:07 -05:00
|
|
|
if (l < 0) {
|
2011-12-12 01:41:05 -05:00
|
|
|
error_inval("negative length");
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
rb_str_resize(string, l);
|
2005-02-02 09:53:36 -05:00
|
|
|
if (plen < l) {
|
2006-08-31 06:30:33 -04:00
|
|
|
MEMZERO(RSTRING_PTR(string) + plen, char, l - plen);
|
2005-02-02 09:53:36 -05:00
|
|
|
}
|
2022-06-30 11:49:36 -04:00
|
|
|
return INT2FIX(0);
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|
|
|
|
|
2008-10-04 05:56:20 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.external_encoding => encoding
|
|
|
|
*
|
|
|
|
* Returns the Encoding object that represents the encoding of the file.
|
2019-10-26 03:03:24 -04:00
|
|
|
* If the stream is write mode and no encoding is specified, returns
|
|
|
|
* +nil+.
|
2008-10-04 05:56:20 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
strio_external_encoding(VALUE self)
|
|
|
|
{
|
2015-12-18 02:54:33 -05:00
|
|
|
struct StringIO *ptr = StringIO(self);
|
|
|
|
return rb_enc_from_encoding(get_enc(ptr));
|
2008-10-04 05:56:20 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.internal_encoding => encoding
|
|
|
|
*
|
|
|
|
* Returns the Encoding of the internal string if conversion is
|
2019-10-26 03:03:24 -04:00
|
|
|
* specified. Otherwise returns +nil+.
|
2008-10-04 05:56:20 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
|
|
|
strio_internal_encoding(VALUE self)
|
|
|
|
{
|
2017-09-27 01:08:53 -04:00
|
|
|
return Qnil;
|
2008-10-04 05:56:20 -04:00
|
|
|
}
|
|
|
|
|
2008-10-05 04:47:01 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
2010-10-10 17:54:22 -04:00
|
|
|
* strio.set_encoding(ext_enc, [int_enc[, opt]]) => strio
|
2008-10-05 04:47:01 -04:00
|
|
|
*
|
2010-10-10 17:54:22 -04:00
|
|
|
* Specify the encoding of the StringIO as <i>ext_enc</i>.
|
|
|
|
* Use the default external encoding if <i>ext_enc</i> is nil.
|
|
|
|
* 2nd argument <i>int_enc</i> and optional hash <i>opt</i> argument
|
|
|
|
* are ignored; they are for API compatibility to IO.
|
2008-10-05 04:47:01 -04:00
|
|
|
*/
|
|
|
|
|
|
|
|
static VALUE
|
2010-10-10 17:54:22 -04:00
|
|
|
strio_set_encoding(int argc, VALUE *argv, VALUE self)
|
2008-10-05 04:47:01 -04:00
|
|
|
{
|
|
|
|
rb_encoding* enc;
|
2015-12-18 02:54:33 -05:00
|
|
|
struct StringIO *ptr = StringIO(self);
|
2010-10-10 17:54:22 -04:00
|
|
|
VALUE ext_enc, int_enc, opt;
|
|
|
|
|
|
|
|
argc = rb_scan_args(argc, argv, "11:", &ext_enc, &int_enc, &opt);
|
|
|
|
|
|
|
|
if (NIL_P(ext_enc)) {
|
|
|
|
enc = rb_default_external_encoding();
|
|
|
|
}
|
|
|
|
else {
|
2022-05-30 00:46:31 -04:00
|
|
|
enc = rb_find_encoding(ext_enc);
|
|
|
|
if (!enc) {
|
|
|
|
struct rb_io_enc_t convconfig;
|
|
|
|
int oflags, fmode;
|
|
|
|
VALUE vmode = rb_str_append(rb_str_new_cstr("r:"), ext_enc);
|
|
|
|
rb_io_extract_modeenc(&vmode, 0, Qnil, &oflags, &fmode, &convconfig);
|
|
|
|
enc = convconfig.enc2;
|
|
|
|
}
|
2010-10-10 17:54:22 -04:00
|
|
|
}
|
2015-12-18 02:54:33 -05:00
|
|
|
ptr->enc = enc;
|
|
|
|
if (WRITABLE(self)) {
|
|
|
|
rb_enc_associate(ptr->string, enc);
|
|
|
|
}
|
|
|
|
|
2008-10-05 04:47:01 -04:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2019-08-13 21:43:46 -04:00
|
|
|
static VALUE
|
|
|
|
strio_set_encoding_by_bom(VALUE self)
|
|
|
|
{
|
|
|
|
struct StringIO *ptr = StringIO(self);
|
|
|
|
|
|
|
|
if (!set_encoding_by_bom(ptr)) return Qnil;
|
|
|
|
return rb_enc_from_encoding(ptr->enc);
|
|
|
|
}
|
|
|
|
|
2005-03-15 09:52:59 -05:00
|
|
|
/*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Pseudo I/O on String object, with interface corresponding to IO.
|
2014-02-05 22:08:38 -05:00
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* Commonly used to simulate <code>$stdio</code> or <code>$stderr</code>
|
2014-02-05 22:08:38 -05:00
|
|
|
*
|
|
|
|
* === Examples
|
|
|
|
*
|
|
|
|
* require 'stringio'
|
|
|
|
*
|
2019-10-26 03:03:24 -04:00
|
|
|
* # Writing stream emulation
|
2014-02-05 22:08:38 -05:00
|
|
|
* io = StringIO.new
|
|
|
|
* io.puts "Hello World"
|
2015-07-11 08:16:37 -04:00
|
|
|
* io.string #=> "Hello World\n"
|
2019-10-26 03:03:24 -04:00
|
|
|
*
|
|
|
|
* # Reading stream emulation
|
|
|
|
* io = StringIO.new "first\nsecond\nlast\n"
|
|
|
|
* io.getc #=> "f"
|
|
|
|
* io.gets #=> "irst\n"
|
|
|
|
* io.read #=> "second\nlast\n"
|
2005-03-15 09:52:59 -05:00
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
void
|
2014-09-30 01:25:32 -04:00
|
|
|
Init_stringio(void)
|
2002-03-11 06:58:07 -05:00
|
|
|
{
|
2018-02-16 03:39:48 -05:00
|
|
|
#undef rb_intern
|
2020-12-16 20:05:07 -05:00
|
|
|
|
|
|
|
#ifdef HAVE_RB_EXT_RACTOR_SAFE
|
|
|
|
rb_ext_ractor_safe(true);
|
|
|
|
#endif
|
|
|
|
|
2020-12-21 11:00:43 -05:00
|
|
|
VALUE StringIO = rb_define_class("StringIO", rb_cObject);
|
2003-07-26 01:14:17 -04:00
|
|
|
|
2019-07-09 12:21:05 -04:00
|
|
|
rb_define_const(StringIO, "VERSION", rb_str_new_cstr(STRINGIO_VERSION));
|
|
|
|
|
2003-07-26 01:14:17 -04:00
|
|
|
rb_include_module(StringIO, rb_mEnumerable);
|
* ext/curses/curses.c, ext/digest/digest.c, ext/dl/handle.c,
ext/dl/ptr.c, ext/dl/sym.c, ext/gdbm/gdbm.c, ext/iconv/iconv.c,
ext/stringio/stringio.c, ext/strscan/strscan.c,
ext/tcltklib/tcltklib.c, ext/win32ole/win32ole.c:
use rb_define_alloc_func().
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@3193 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
2002-12-20 06:23:40 -05:00
|
|
|
rb_define_alloc_func(StringIO, strio_s_allocate);
|
2016-04-27 02:47:56 -04:00
|
|
|
rb_define_singleton_method(StringIO, "new", strio_s_new, -1);
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_singleton_method(StringIO, "open", strio_s_open, -1);
|
|
|
|
rb_define_method(StringIO, "initialize", strio_initialize, -1);
|
2003-09-28 22:44:49 -04:00
|
|
|
rb_define_method(StringIO, "initialize_copy", strio_copy, 1);
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "reopen", strio_reopen, -1);
|
|
|
|
|
|
|
|
rb_define_method(StringIO, "string", strio_get_string, 0);
|
|
|
|
rb_define_method(StringIO, "string=", strio_set_string, 1);
|
|
|
|
rb_define_method(StringIO, "lineno", strio_get_lineno, 0);
|
|
|
|
rb_define_method(StringIO, "lineno=", strio_set_lineno, 1);
|
|
|
|
|
2013-05-19 18:49:29 -04:00
|
|
|
|
|
|
|
/* call-seq: strio.binmode -> true */
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "binmode", strio_binmode, 0);
|
|
|
|
rb_define_method(StringIO, "close", strio_close, 0);
|
|
|
|
rb_define_method(StringIO, "close_read", strio_close_read, 0);
|
|
|
|
rb_define_method(StringIO, "close_write", strio_close_write, 0);
|
|
|
|
rb_define_method(StringIO, "closed?", strio_closed, 0);
|
|
|
|
rb_define_method(StringIO, "closed_read?", strio_closed_read, 0);
|
|
|
|
rb_define_method(StringIO, "closed_write?", strio_closed_write, 0);
|
|
|
|
rb_define_method(StringIO, "eof", strio_eof, 0);
|
|
|
|
rb_define_method(StringIO, "eof?", strio_eof, 0);
|
2013-05-19 18:49:29 -04:00
|
|
|
/* call-seq: strio.fcntl */
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "fcntl", strio_fcntl, -1);
|
2013-05-19 18:49:29 -04:00
|
|
|
/* call-seq: strio.flush -> strio */
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "flush", strio_flush, 0);
|
2013-05-19 18:49:29 -04:00
|
|
|
/* call-seq: strio.fsync -> 0 */
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "fsync", strio_fsync, 0);
|
|
|
|
rb_define_method(StringIO, "pos", strio_get_pos, 0);
|
|
|
|
rb_define_method(StringIO, "pos=", strio_set_pos, 1);
|
|
|
|
rb_define_method(StringIO, "rewind", strio_rewind, 0);
|
|
|
|
rb_define_method(StringIO, "seek", strio_seek, -1);
|
|
|
|
rb_define_method(StringIO, "sync", strio_get_sync, 0);
|
2013-05-19 18:49:29 -04:00
|
|
|
/* call-seq: strio.sync = boolean -> boolean */
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "sync=", strio_set_sync, 1);
|
|
|
|
rb_define_method(StringIO, "tell", strio_tell, 0);
|
|
|
|
|
|
|
|
rb_define_method(StringIO, "each", strio_each, -1);
|
|
|
|
rb_define_method(StringIO, "each_line", strio_each, -1);
|
2008-05-27 06:03:23 -04:00
|
|
|
rb_define_method(StringIO, "each_byte", strio_each_byte, 0);
|
|
|
|
rb_define_method(StringIO, "each_char", strio_each_char, 0);
|
2009-06-22 04:23:30 -04:00
|
|
|
rb_define_method(StringIO, "each_codepoint", strio_each_codepoint, 0);
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "getc", strio_getc, 0);
|
|
|
|
rb_define_method(StringIO, "ungetc", strio_ungetc, 1);
|
2008-10-21 18:10:49 -04:00
|
|
|
rb_define_method(StringIO, "ungetbyte", strio_ungetbyte, 1);
|
2007-08-14 20:33:33 -04:00
|
|
|
rb_define_method(StringIO, "getbyte", strio_getbyte, 0);
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "gets", strio_gets, -1);
|
|
|
|
rb_define_method(StringIO, "readlines", strio_readlines, -1);
|
|
|
|
rb_define_method(StringIO, "read", strio_read, -1);
|
|
|
|
|
2017-10-23 02:25:39 -04:00
|
|
|
rb_define_method(StringIO, "write", strio_write_m, -1);
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "putc", strio_putc, 1);
|
|
|
|
|
2013-05-19 18:49:29 -04:00
|
|
|
/*
|
|
|
|
* call-seq:
|
|
|
|
* strio.isatty -> nil
|
|
|
|
* strio.tty? -> nil
|
|
|
|
*
|
|
|
|
*/
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "isatty", strio_isatty, 0);
|
|
|
|
rb_define_method(StringIO, "tty?", strio_isatty, 0);
|
2013-05-19 18:49:29 -04:00
|
|
|
|
|
|
|
/* call-seq: strio.pid -> nil */
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "pid", strio_pid, 0);
|
2013-05-19 18:49:29 -04:00
|
|
|
|
|
|
|
/* call-seq: strio.fileno -> nil */
|
2002-03-11 06:58:07 -05:00
|
|
|
rb_define_method(StringIO, "fileno", strio_fileno, 0);
|
|
|
|
rb_define_method(StringIO, "size", strio_size, 0);
|
|
|
|
rb_define_method(StringIO, "length", strio_size, 0);
|
|
|
|
rb_define_method(StringIO, "truncate", strio_truncate, 1);
|
2008-10-04 05:56:20 -04:00
|
|
|
|
|
|
|
rb_define_method(StringIO, "external_encoding", strio_external_encoding, 0);
|
|
|
|
rb_define_method(StringIO, "internal_encoding", strio_internal_encoding, 0);
|
2010-10-10 17:54:22 -04:00
|
|
|
rb_define_method(StringIO, "set_encoding", strio_set_encoding, -1);
|
2019-08-13 21:43:46 -04:00
|
|
|
rb_define_method(StringIO, "set_encoding_by_bom", strio_set_encoding_by_bom, 0);
|
2012-01-25 13:24:09 -05:00
|
|
|
|
|
|
|
{
|
2013-05-24 02:54:17 -04:00
|
|
|
VALUE mReadable = rb_define_module_under(rb_cIO, "generic_readable");
|
2012-01-25 13:24:09 -05:00
|
|
|
rb_define_method(mReadable, "readchar", strio_readchar, 0);
|
|
|
|
rb_define_method(mReadable, "readbyte", strio_readbyte, 0);
|
|
|
|
rb_define_method(mReadable, "readline", strio_readline, -1);
|
|
|
|
rb_define_method(mReadable, "sysread", strio_sysread, -1);
|
|
|
|
rb_define_method(mReadable, "readpartial", strio_sysread, -1);
|
2013-08-26 18:41:44 -04:00
|
|
|
rb_define_method(mReadable, "read_nonblock", strio_read_nonblock, -1);
|
2012-01-25 13:24:09 -05:00
|
|
|
rb_include_module(StringIO, mReadable);
|
|
|
|
}
|
|
|
|
{
|
2013-05-24 02:54:17 -04:00
|
|
|
VALUE mWritable = rb_define_module_under(rb_cIO, "generic_writable");
|
2012-01-25 13:24:09 -05:00
|
|
|
rb_define_method(mWritable, "<<", strio_addstr, 1);
|
|
|
|
rb_define_method(mWritable, "print", strio_print, -1);
|
|
|
|
rb_define_method(mWritable, "printf", strio_printf, -1);
|
|
|
|
rb_define_method(mWritable, "puts", strio_puts, -1);
|
|
|
|
rb_define_method(mWritable, "syswrite", strio_syswrite, 1);
|
2013-08-26 18:41:44 -04:00
|
|
|
rb_define_method(mWritable, "write_nonblock", strio_syswrite_nonblock, -1);
|
2012-01-25 13:24:09 -05:00
|
|
|
rb_include_module(StringIO, mWritable);
|
|
|
|
}
|
2013-08-26 18:41:44 -04:00
|
|
|
|
|
|
|
sym_exception = ID2SYM(rb_intern("exception"));
|
2002-03-11 06:58:07 -05:00
|
|
|
}
|