summaryrefslogtreecommitdiff
path: root/io.c
diff options
context:
space:
mode:
authorYukihiro Matsumoto <matz@ruby-lang.org>1994-08-10 15:54:46 +0900
committerTakashi Kokubun <takashikkbn@gmail.com>2019-08-17 22:09:30 +0900
commit6e3090413652b6592346556149fed1e9aec5495d (patch)
treebac97139bbeedc8cb67cb2e451a22ed4ddb2b2d4 /io.c
parent200e0ee2fd3c1c006c528874a88f684447215524 (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.c166
1 files changed, 114 insertions, 52 deletions
diff --git a/io.c b/io.c
index b3ed236..4b3c03a 100644
--- a/io.c
+++ b/io.c
@@ -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);