diff options
author | Yukihiro Matsumoto <matz@ruby-lang.org> | 1994-08-10 15:54:46 +0900 |
---|---|---|
committer | Takashi Kokubun <takashikkbn@gmail.com> | 2019-08-17 22:09:30 +0900 |
commit | 6e3090413652b6592346556149fed1e9aec5495d (patch) | |
tree | bac97139bbeedc8cb67cb2e451a22ed4ddb2b2d4 /io.c | |
parent | 200e0ee2fd3c1c006c528874a88f684447215524 (diff) |
version 0.50v0_50
http://cache.ruby-lang.org/pub/ruby/1.0/ruby-0.50.tar.gz
Wed Aug 10 15:54:46 1994 Yukihiro Matsumoto (matz@ix-02)
* variable.c: -vオプションが指定されている時は初期化されていない,
大域変数, インスタンス変数, ローカル変数を参照した時点でwarning
を出すようにした.
Tue Aug 9 11:50:48 1994 Yukihiro Matsumoto (matz@ix-02)
* bignum.c: 冪乗に関しても多倍長演算を行なうように. 特に浮動小数点
数の範囲を越えた時の処理を的確に行なうように.
* eval.c: メソッド定義後は構文木から, メソッド定義部分を外す. 無駄
な再定義が起こらないようにするためと2重にfree()されないため.
* array.c(Fary_aref): 引数が1つでFixnumの時, Range checkを行なわな
いように修正.
* eval.c: 引数の数をコンパイル時に計算して若干の高速化.
Mon Aug 8 13:06:24 1994 Yukihiro Matsumoto (matz@ix-02)
* object.c: nilによる比較連鎖をなくした.
* parse.y: bit演算子の優先順位を比較演算子よりも強くした. Cとは異
なることになるが, 直観には合致する.
* gc.c: クラスを解放する時, 個々のメソッド毎にキャッシュをクリアす
るのではなく, クラス単位でクリアするように.
Thu Aug 4 18:45:09 1994 Yukihiro Matsumoto (matz@ix-02)
* methods.c(method_free): 解放されたメソッドに関してキャッシュをク
リアしておく必要があった.
* gc.c: Dataクラスのデータ部分をfree()し忘れていた.
Wed Aug 3 09:58:14 1994 Yukihiro Matsumoto (matz@ix-02)
* parse.y: def func .. end形式による関数メソッドの定義はなくなった.
* methods.c: func形式のメソッドをなくした. あっても, あまり意味が
ないので.
* eval.c: $0への代入でps(1)の出力が変化するように.
* io.c(Fsyscall): syscall()を実現.
Mon Aug 1 13:41:11 1994 Yukihiro Matsumoto (matz@ix-02)
* parse.y: ダブルクォートで囲まれた文字列や正規表現中で"#{変数名}"
または"#変数名"という形式で変数の内容を埋め込むことができるよう
になった.
* io.c: 関数メソッドsystem2()はなくなった. 今はバッククォートがあ
るからね.
* parse.y: `cmd`によってコマンドを文字列に展開することができるよう
になった.
* parse.y: __FILE__, __LINE__を追加. それぞれファイル名(文字列),
行番号(整数)を値とする疑似変数.
Fri Jul 29 13:16:07 1994 Yukihiro Matsumoto (matz@ix-02)
* methods.h: メソッドをオブジェクトとして扱うのをやめる. メソッド
のメモリ管理にはリファレンスカウントを使うことにした. これでオブ
ジェクトの数が減ってほんの少しだけGCが速くなる(かな).
* purifyによってメモリ関係のバグを検査した(見つかる,見つかる…).
* gc.c: GCをプログラマが変数をマークする形式から, スタックとレジス
タからマークする方法に変更. 移植性が下がるような気もするが, siod
やscmでも採用されているから多分大丈夫だろう. Linux on i486でも動
作を確認した.
Wed Jul 27 16:13:13 1994 Yukihiro Matsumoto (matz@ix-02)
* eval.c(Eval): トップレベルでは構造木をfreeしないように. どうせ解
放されるから時間の無駄である.
* array.c, dict.c: "=="を構造一致に変更.
Fri Jul 22 10:14:09 1994 Yukihiro Matsumoto (matz@ix-02)
* error.c: 組み込みタイプの名前を登録し忘れていた.
Thu Jul 21 14:06:48 1994 Yukihiro Matsumoto (matz@ix-02)
* parse.y(freenode),eval.c(Eval): 解析木を解放し忘れていた.
Mon Jul 18 10:19:15 1994 Yukihiro Matsumoto (matz@ix-02)
* parse.y: 多重代入を処理するルールにバグがあって, 3要素以上の多重
代入に失敗していた.
* eval.c(rb_eval): 多重代入で, 右辺が配列でない時には`to_a'メソッ
ドで配列に変換して代入するようにした. 今までの仕様だと右辺値が第
1要素にそのまま代入されていたが, structなど配列に変換できるもの
は変換した方が嬉しい気がする.
* dbm.c,dict.c(delete_if): メソッド追加.
* process.c(wait,waitpid): システムコールwaitpidまたはwait4がある
時はそちらを使うように. configureもそれらをチェックするように変更.
* dbm.c, dict.c(clear): メソッド追加.
Diffstat (limited to 'io.c')
-rw-r--r-- | io.c | 166 |
1 files changed, 114 insertions, 52 deletions
@@ -174,9 +174,7 @@ read_all(port) } if (fptr->f == NULL) Fail("closed stream"); - GC_LINK; - GC_PRO3(str, str_new(0, 0)); - + str = str_new(0, 0); for (;;) { n = fread(buf, 1, BUFSIZ, fptr->f); if (n == 0) { @@ -185,8 +183,6 @@ read_all(port) } str_cat(str, buf, n); } - - GC_UNLINK; return str; } @@ -252,9 +248,6 @@ Fio_gets(obj) f = fptr->f; if (f == NULL) Fail("closed stream"); - GC_LINK; - GC_PRO2(str); - if (RS) { rslen = RSTRING(RS)->len; if (rslen == 0) { @@ -329,8 +322,6 @@ Fio_gets(obj) } } - GC_UNLINK; - if (str) { fptr->lineno++; lineno = INT2FIX(fptr->lineno); @@ -345,7 +336,6 @@ Fio_each(obj) { VALUE str; - GC_PRO2(str); while (str = Fio_gets(obj)) { rb_yield(str); } @@ -574,9 +564,7 @@ pipe_open(pname, mode) int pid, pr[2], pw[2]; int doexec; - GC_LINK; - GC_PRO3(port, obj_alloc(C_IO)); - + port = obj_alloc(C_IO); MakeOpenFile(port, fptr); fptr->mode = io_mode_flags(mode); @@ -631,8 +619,6 @@ pipe_open(pname, mode) if (fptr->mode & FMODE_READABLE) fptr->f = rb_fdopen(pr[0], "r"); if (fptr->mode & FMODE_WRITABLE) fptr->f2 = rb_fdopen(pw[1], "w"); - GC_UNLINK; - return port; } @@ -672,13 +658,13 @@ Fprintf(argc, argv) int argc; VALUE argv[]; { - VALUE out, str; + VALUE out; if (argc == 1) return Qnil; if (TYPE(argv[1]) == T_STRING) { out = rb_defout; } - else if (rb_get_method_body(CLASS_OF(argv[1]), id_write, 0, MTH_FUNC)) { + else if (obj_responds_to(argv[1], INT2FIX(id_write))) { out = argv[1]; argv++; argc--; @@ -687,12 +673,7 @@ Fprintf(argc, argv) Fail("output must responds to `write'"); } - GC_LINK; - GC_PRO3(str, Fsprintf(argc, argv)); - - rb_funcall(out, id_write, 1, str); - - GC_UNLINK; + rb_funcall(out, id_write, 1, Fsprintf(argc, argv)); return Qnil; } @@ -740,12 +721,9 @@ prep_stdio(f, mode) VALUE obj = obj_alloc(C_IO); OpenFile *fp; - GC_LINK; - GC_PRO(obj); MakeOpenFile(obj, fp); fp->f = f; fp->mode = mode; - GC_UNLINK; return obj; } @@ -874,15 +852,11 @@ Freadlines(obj) { VALUE line, ary; - GC_LINK; - GC_PRO2(line); - GC_PRO3(ary, ary_new()); - + ary = ary_new(); while (line = Fgets(obj)) { Fary_push(ary, line); } - GC_UNLINK; return ary; } @@ -898,9 +872,8 @@ rb_check_str(val, id) return TRUE; } -static VALUE -Fsystem2(obj, str) - VALUE obj; +VALUE +rb_xstring(str) struct RString *str; { VALUE port, result; @@ -908,10 +881,7 @@ Fsystem2(obj, str) int mask; Check_Type(str, T_STRING); - GC_LINK; - GC_PRO3(port, pipe_open(str->ptr, "r")); - GC_PRO2(result); - + port = pipe_open(str->ptr, "r"); result = read_all(port); GetOpenFile(port, fptr); @@ -919,7 +889,6 @@ Fsystem2(obj, str) fptr->pid = 0; obj_free(port); - GC_UNLINK; return result; } @@ -1026,8 +995,7 @@ Fselect(obj, args) } if (n == 0) return Qnil; - GC_LINK; - GC_PRO3(res, ary_new2(3)); + res = ary_new2(3); RARRAY(res)->ptr[0] = rp?ary_new():Qnil; RARRAY(res)->len++; RARRAY(res)->ptr[1] = wp?ary_new():Qnil; @@ -1075,7 +1043,6 @@ Fselect(obj, args) } } - GC_UNLINK; return res; } @@ -1141,6 +1108,100 @@ Fio_defset(obj, val) return rb_defout = val; } +static VALUE +Fsyscall(argc, argv) + int argc; + VALUE *argv; +{ +#ifdef HAVE_SYSCALL +#ifdef atarist + unsigned long arg[14]; /* yes, we really need that many ! */ +#else + unsigned long arg[8]; +#endif + int retval = -1; + int i = 1; + int items = argc - 2; + + /* This probably won't work on machines where sizeof(long) != sizeof(int) + * or where sizeof(long) != sizeof(char*). But such machines will + * not likely have syscall implemented either, so who cares? + */ + argv++; /* skip SELF */ + arg[0] = NUM2INT(argv[0]); argv++; + while (items--) { + if (FIXNUM_P(*argv)) { + arg[i] = (unsigned long)NUM2INT(*argv); argv++; + } + else { + Check_Type(*argv, T_STRING); + str_modify(*argv); + arg[i] = (unsigned long)RSTRING(*argv)->ptr; argv++; + } + i++; + } + switch (argc-1) { + case 0: + Fail("Too few args to syscall"); + case 1: + retval = syscall(arg[0]); + break; + case 2: + retval = syscall(arg[0],arg[1]); + break; + case 3: + retval = syscall(arg[0],arg[1],arg[2]); + break; + case 4: + retval = syscall(arg[0],arg[1],arg[2],arg[3]); + break; + case 5: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4]); + break; + case 6: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5]); + break; + case 7: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6]); + break; + case 8: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7]); + break; +#ifdef atarist + case 9: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8]); + break; + case 10: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9]); + break; + case 11: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10]); + break; + case 12: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10], arg[11]); + break; + case 13: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10], arg[11], arg[12]); + break; + case 14: + retval = syscall(arg[0],arg[1],arg[2],arg[3],arg[4],arg[5],arg[6], + arg[7], arg[8], arg[9], arg[10], arg[11], arg[12], arg[13]); + break; +#endif /* atarist */ + } + if (retval == -1) rb_sys_fail(0); + return Qnil; +#else + Fail("syscall() unimplemented"); +#endif +} + extern VALUE M_Enumerable; VALUE rb_readonly_hook(); @@ -1148,17 +1209,18 @@ Init_IO() { extern VALUE C_Kernel; - rb_define_func(C_Kernel, "open", Fopen, -2); - rb_define_func(C_Kernel, "printf", Fprintf, -1); + rb_define_method(C_Kernel, "syscall", Fsyscall, -1); + + rb_define_method(C_Kernel, "open", Fopen, -2); + rb_define_method(C_Kernel, "printf", Fprintf, -1); rb_define_method(C_Kernel, "print", Fprint, -1); - rb_define_func(C_Kernel, "gets", Fgets, 0); - rb_define_func(C_Kernel, "eof", Feof, 0); + rb_define_method(C_Kernel, "gets", Fgets, 0); + rb_define_method(C_Kernel, "eof", Feof, 0); rb_define_alias(C_Kernel,"readline", "gets"); - rb_define_func(C_Kernel, "getc", Fgetc, 0); - rb_define_func(C_Kernel, "system2", Fsystem2, 1); - rb_define_func(C_Kernel, "select", Fselect, -2); + rb_define_method(C_Kernel, "getc", Fgetc, 0); + rb_define_method(C_Kernel, "select", Fselect, -2); - rb_define_func(C_Kernel, "readlines", Freadlines, 0); + rb_define_method(C_Kernel, "readlines", Freadlines, 0); C_IO = rb_define_class("IO", C_Object); rb_include_module(C_IO, M_Enumerable); @@ -1191,7 +1253,7 @@ Init_IO() rb_define_method(C_IO, "read", Fio_read, -2); rb_define_method(C_IO, "write", Fio_write, 1); rb_define_method(C_IO, "gets", Fio_gets, 0); - rb_define_alias(C_IO, "readlines", "gets"); + rb_define_alias(C_IO, "readline", "gets"); rb_define_method(C_IO, "getc", Fio_getc, 0); rb_define_method(C_IO, "puts", Fio_puts, 1); rb_define_method(C_IO, "<<", Fio_puts, 1); |