summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorknu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-05-27 06:39:47 +0000
committerknu <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-05-27 06:39:47 +0000
commit1906045a8f81f8a30d63e494f4ce24808f764922 (patch)
tree85ce7d321730666333dc2bdfc2994335788f2d37
parent42187cffa2b7b4e89c92a91650d8b89a0d2a9197 (diff)
* io.c (rb_io_each_char, argf_each_char, Init_IO):
Add {IO#,ARGF.}{each_char,chars}. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_8@16629 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog7
-rw-r--r--NEWS4
-rw-r--r--io.c86
3 files changed, 96 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 8ace7f8628..1a7e552485 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Tue May 27 15:36:37 2008 Akinori MUSHA <knu@iDaemons.org>
+
+ * io.c (rb_io_each_char, argf_each_char, Init_IO):
+ Add {IO#,ARGF.}{each_char,chars}.
+
Tue May 27 13:46:52 2008 Akinori MUSHA <knu@iDaemons.org>
* ext/stringio/stringio.c (Init_stringio): Define
@@ -5,7 +10,7 @@ Tue May 27 13:46:52 2008 Akinori MUSHA <knu@iDaemons.org>
Tue May 27 13:38:51 2008 Akinori MUSHA <knu@iDaemons.org>
- * io.c (Init_IO): Define {IO,ARGF}#{getbyte,readbyte}.
+ * io.c (Init_IO): Define {IO#,ARGF.}{getbyte,readbyte}.
Tue May 27 13:26:15 2008 Akinori MUSHA <knu@iDaemons.org>
diff --git a/NEWS b/NEWS
index 301ebbc964..2bac745bd9 100644
--- a/NEWS
+++ b/NEWS
@@ -179,10 +179,14 @@ with all sufficient information, see the ChangeLog file.
Return an enumerator if no block is given.
* IO#bytes
+ * IO#chars
+ * IO#each_char
* IO#getbyte
* IO#lines
* IO#readbyte
* ARGF.bytes
+ * ARGF.chars
+ * ARGF.each_char
* ARGF.getbyte
* ARGF.lines
* ARGF.readbyte
diff --git a/io.c b/io.c
index 7242e1f3f1..ab5fb9d75c 100644
--- a/io.c
+++ b/io.c
@@ -21,6 +21,7 @@
#include "rubyio.h"
#include "rubysig.h"
#include "env.h"
+#include "re.h"
#include <ctype.h>
#include <errno.h>
@@ -2026,6 +2027,51 @@ rb_io_each_byte(io)
return io;
}
+VALUE rb_io_getc _((VALUE));
+
+/*
+ * call-seq:
+ * ios.each_char {|c| block } => ios
+ *
+ * Calls the given block once for each character in <em>ios</em>,
+ * passing the character as an argument. The stream must be opened for
+ * reading or an <code>IOError</code> will be raised. Multibyte
+ * characters are dealt with according to $KCODE.
+ *
+ * f = File.new("testfile")
+ * f.each_char {|c| print c, ' ' } #=> #<File:testfile>
+ */
+
+static VALUE
+rb_io_each_char(io)
+ VALUE io;
+{
+ VALUE ch;
+
+ RETURN_ENUMERATOR(io, 0, 0);
+
+ while (!NIL_P(ch = rb_io_getc(io))) {
+ unsigned char c;
+ int n;
+ VALUE str;
+
+ c= FIX2INT(ch);
+ n = mbclen(c);
+ str = rb_tainted_str_new((const char *)&c, 1);
+
+ while (--n > 0) {
+ if (NIL_P(ch = rb_io_getc(io))) {
+ rb_yield(str);
+ return io;
+ }
+ c = FIX2INT(ch);
+ rb_str_cat(str, (const char *)&c, 1);
+ }
+ rb_yield(str);
+ }
+ return io;
+}
+
/*
* call-seq:
* ios.lines(sep=$/) => anEnumerator
@@ -5613,6 +5659,42 @@ argf_each_byte(argf)
}
static VALUE
+argf_each_char(argf)
+ VALUE argf;
+{
+ VALUE ch;
+
+ RETURN_ENUMERATOR(argf, 0, 0);
+
+ while (!NIL_P(ch = argf_getc())) {
+ unsigned char c;
+ int n;
+ VALUE str, file;
+
+ first_char:
+ c = FIX2INT(ch);
+ n = mbclen(c);
+ str = rb_tainted_str_new((const char *)&c, 1);
+ file = current_file;
+
+ while (--n > 0) {
+ if (NIL_P(ch = argf_getc())) {
+ rb_yield(str);
+ return argf;
+ }
+ if (current_file != file) {
+ rb_yield(str);
+ goto first_char;
+ }
+ c = FIX2INT(ch);
+ rb_str_cat(str, (const char *)&c, 1);
+ }
+ rb_yield(str);
+ }
+ return argf;
+}
+
+static VALUE
argf_filename()
{
next_argv();
@@ -5854,8 +5936,10 @@ Init_IO()
rb_define_method(rb_cIO, "each", rb_io_each_line, -1);
rb_define_method(rb_cIO, "each_line", rb_io_each_line, -1);
rb_define_method(rb_cIO, "each_byte", rb_io_each_byte, 0);
+ rb_define_method(rb_cIO, "each_char", rb_io_each_char, 0);
rb_define_method(rb_cIO, "lines", rb_io_lines, -1);
rb_define_method(rb_cIO, "bytes", rb_io_bytes, 0);
+ rb_define_method(rb_cIO, "chars", rb_io_each_char, 0);
rb_define_method(rb_cIO, "syswrite", rb_io_syswrite, 1);
rb_define_method(rb_cIO, "sysread", rb_io_sysread, -1);
@@ -5945,8 +6029,10 @@ Init_IO()
rb_define_singleton_method(argf, "each", argf_each_line, -1);
rb_define_singleton_method(argf, "each_line", argf_each_line, -1);
rb_define_singleton_method(argf, "each_byte", argf_each_byte, 0);
+ rb_define_singleton_method(argf, "each_char", argf_each_char, 0);
rb_define_singleton_method(argf, "lines", argf_each_line, -1);
rb_define_singleton_method(argf, "bytes", argf_each_byte, 0);
+ rb_define_singleton_method(argf, "chars", argf_each_char, 0);
rb_define_singleton_method(argf, "read", argf_read, -1);
rb_define_singleton_method(argf, "readlines", rb_f_readlines, -1);