なかだです。

At Mon, 16 Feb 2004 15:17:20 +0900,
Yukihiro Matsumoto wrote in [ruby-dev:22904]:
> |> |systemはどっちのがいいのかな。
> |> 
> |> 例外が出た方が良いと思います、ってそういう意味じゃない?
> |
> |そういう意味です。
> 
> ぜんぶコミットしてくださいな。よろしく。

openやIO.foreachなど、"|command..."を受け付けるもの全部こうする
というのはやりすぎでしょうか。


* io.c (pipe_open): accept a generic argument not only a string.

* io.c (rb_f_open, rb_io_open): allow generic argument.

Index: io.c =================================================================== RCS file: /cvs/ruby/src/ruby/io.c,v retrieving revision 1.259 diff -u -2 -p -d -r1.259 io.c --- io.c 16 Feb 2004 06:45:31 -0000 1.259 +++ io.c 20 Feb 2004 01:02:56 -0000 @@ -2591,9 +2591,11 @@ popen_exec(p) static VALUE -pipe_open(argc, argv, pname, mode) +pipe_open(args, mode, pipemode) + VALUE args; + char *mode; + int pipemode; +{ int argc; VALUE *argv; - char *pname, *mode; -{ int modef = rb_io_mode_flags(mode); int pid = 0; @@ -2601,17 +2603,27 @@ pipe_open(argc, argv, pname, mode) FILE *fpr, *fpw; VALUE port, arg0; + char *pname; #if defined(HAVE_FORK) int status; struct popen_arg arg; - volatile int doexec; + int doexec; #elif defined(_WIN32) int openmode = rb_io_mode_modenum(mode); - char *cmd = pname, *prog = NULL; + char *cmd, *prog = NULL; #endif - if (!pname) { + if (!NIL_P(arg0 = rb_check_array_type(args))) { + argc = RARRAY(arg0)->len; + argv = ALLOCA_N(VALUE, argc); + MEMCPY(argv, RARRAY(arg0)->ptr, VALUE, argc); arg0 = rb_check_argv(argc, argv); if (arg0) pname = StringValuePtr(arg0); } + else { + SafeStringValue(args); + pname = RSTRING(args)->ptr; + if (!pipemode && pname[0] != '|') return 0; + argc = 0; + } #if defined(HAVE_FORK) @@ -2661,4 +2673,5 @@ pipe_open(argc, argv, pname, mode) #define PIPE_FDOPEN(i) (rb_fdopen((i?arg.pw:arg.pr)[i], i?"w":"r")) #elif defined(_WIN32) + cmd = pname; if (argc) { char **args = ALLOC_N(char *, argc+1); @@ -2720,43 +2733,4 @@ pipe_open(argc, argv, pname, mode) } -static VALUE -rb_io_popen(str, argc, argv, klass) - char *str; - int argc; - VALUE *argv; - VALUE klass; -{ - char *mode; - VALUE pname, pmode, port; - char mbuf[4]; - - if (rb_scan_args(argc, argv, "11", &pname, &pmode) == 1) { - mode = "r"; - } - else if (FIXNUM_P(pmode)) { - mode = rb_io_modenum_mode(FIX2INT(pmode), mbuf); - } - else { - mode = StringValuePtr(pmode); - } - SafeStringValue(pname); - port = pipe_open(0, 0, str, mode); - if (NIL_P(port)) { - /* child */ - if (rb_block_given_p()) { - rb_yield(Qnil); - fflush(stdout); - fflush(stderr); - _exit(0); - } - return Qnil; - } - RBASIC(port)->klass = klass; - if (rb_block_given_p()) { - return rb_ensure(rb_yield, port, io_close, port); - } - return port; -} - /* * call-seq: @@ -2807,5 +2781,5 @@ rb_io_s_popen(argc, argv, klass) { char *mode; - VALUE pname, pmode, port, tmp; + VALUE pname, pmode, port; char mbuf[4]; @@ -2819,25 +2793,14 @@ rb_io_s_popen(argc, argv, klass) mode = StringValuePtr(pmode); } - tmp = rb_check_array_type(pname); - if (!NIL_P(tmp)) { - long argc = RARRAY(tmp)->len; - VALUE *argv = ALLOCA_N(VALUE, argc); - - MEMCPY(argv, RARRAY(tmp)->ptr, VALUE, argc); - port = pipe_open(argc, argv, 0, mode); - } - else { - SafeStringValue(pname); - port = pipe_open(0, 0, RSTRING(pname)->ptr, mode); - if (NIL_P(port)) { - /* child */ - if (rb_block_given_p()) { - rb_yield(Qnil); - fflush(stdout); - fflush(stderr); - _exit(0); - } - return Qnil; + port = pipe_open(pname, mode, Qtrue); + if (NIL_P(port)) { + /* child */ + if (rb_block_given_p()) { + rb_yield(Qnil); + fflush(stdout); + fflush(stderr); + _exit(0); } + return Qnil; } RBASIC(port)->klass = klass; @@ -3031,24 +2994,49 @@ rb_f_open(argc, argv) VALUE *argv; { + VALUE port = 0; + if (argc >= 1) { - char *str = StringValuePtr(argv[0]); + char mbuf[4], *mode, *str; + VALUE pname, pmode; - if (str[0] == '|') { - return rb_io_popen(str+1, argc, argv, rb_cIO); + if (rb_scan_args(argc, argv, "11", &pname, &pmode) == 1) { + mode = "r"; + } + else if (FIXNUM_P(pmode)) { + mode = rb_io_modenum_mode(FIX2INT(pmode), mbuf); + } + else { + mode = StringValuePtr(pmode); + } + port = pipe_open(pname, mode, Qfalse); + if (NIL_P(port)) { + /* child */ + if (rb_block_given_p()) { + rb_yield(Qnil); + fflush(stdout); + fflush(stderr); + _exit(0); + } + return Qnil; } } - return rb_io_s_open(argc, argv, rb_cFile); + if (!port) { + port = rb_class_new_instance(argc, argv, rb_cFile); + } + if (rb_block_given_p()) { + return rb_ensure(rb_yield, port, io_close, port); + } + return port; } static VALUE -rb_io_open(fname, mode) - char *fname, *mode; +rb_io_open(name, mode) + VALUE name; + char *mode; { - if (fname[0] == '|') { - return pipe_open(0, 0, fname+1, mode); - } - else { - return rb_file_open(fname, mode); - } + VALUE port = pipe_open(name, mode, Qfalse); + + if (port) return port; + return rb_file_open(RSTRING(name)->ptr, mode); } @@ -4240,5 +4228,5 @@ rb_f_backquote(obj, str) SafeStringValue(str); - port = pipe_open(0, 0, RSTRING(str)->ptr, "r"); + port = pipe_open(str, "r", Qtrue); if (NIL_P(port)) return rb_str_new(0,0); @@ -4807,10 +4795,8 @@ rb_io_s_foreach(argc, argv) rb_scan_args(argc, argv, "11", &fname, &arg.sep); - SafeStringValue(fname); - if (argc == 1) { arg.sep = rb_default_rs; } - io = rb_io_open(RSTRING(fname)->ptr, "r"); + io = rb_io_open(fname, "r"); if (NIL_P(io)) return Qnil; GetOpenFile(io, fptr); @@ -4850,8 +4836,6 @@ rb_io_s_readlines(argc, argv, io) rb_scan_args(argc, argv, "11", &fname, &arg.sep); - SafeStringValue(fname); - arg.argc = argc - 1; - arg.io = rb_io_open(RSTRING(fname)->ptr, "r"); + arg.io = rb_io_open(fname, "r"); if (NIL_P(arg.io)) return Qnil; return rb_ensure(io_s_readlines, (VALUE)&arg, rb_io_close, arg.io); @@ -4888,8 +4872,6 @@ rb_io_s_read(argc, argv, io) rb_scan_args(argc, argv, "12", &fname, &arg.sep, &offset); - SafeStringValue(fname); - arg.argc = argc ? 1 : 0; - arg.io = rb_io_open(RSTRING(fname)->ptr, "r"); + arg.io = rb_io_open(fname, "r"); if (NIL_P(arg.io)) return Qnil; if (!NIL_P(offset)) {
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦