最近の SpiderMonkey には readline() と print() があり、これを使って標準入力から読んで標準出力に書く、いわゆるフィルタ的なものを作ろうと思った。
var ln;
while (ln = readline()) {
print(ln);
}
こんなので cat が出来そうな気がするけど
a
b
こういう空行まじりのファイルを食わせると、空行のところでループから抜けてしまう。なんでかといえば JavaScript では "" == false だから。
じゃあ readline() は EOF のときどうなるのか。こんなプログラムに
for (var i = 0; i < 10; i++) {
var ln = readline();
print(typeof ln + "\t'" + ln + "'");
}
さっきの3行のファイルを食わせてみると
string 'a'
string ''
string 'b'
string ''
string ''
string ''
string ''
string ''
string ''
string ''
EOF 区別できないよ……。しょうがないので SpiderMonkey の js.c に patch 書いた。
Index: js.c
===================================================================
RCS file: /cvsroot/mozilla/js/src/js.c,v
retrieving revision 3.125
diff -p -u -8 -r3.125 js.c
--- js.c 19 Sep 2006 06:48:25 -0000 3.125
+++ js.c 5 Oct 2006 08:48:22 -0000
@@ -639,17 +639,20 @@ ReadLine(JSContext *cx, JSObject *obj, u
}
bufsize *= 2;
buf = tmp;
}
/* Treat the empty string specially. */
if (buflength == 0) {
- *rval = JS_GetEmptyStringValue(cx);
+ if (feof(from))
+ *rval = JSVAL_NULL;
+ else
+ *rval = JS_GetEmptyStringValue(cx);
JS_free(cx, buf);
return JS_TRUE;
}
/* Shrink the buffer to the real size. */
tmp = JS_realloc(cx, buf, buflength);
if (!tmp) {
JS_free(cx, buf);
EOF で null を返すことにしたので、cat はこうなる。
var ln;
while ((ln = readline()) != null) {
print(ln);
}
October 7th, 2006 at 10:43 AM
このパッチは本体に取りこまれそうなのですか? 挙動が変わるとぎゃっと言う人がいるかもしれませんが...
October 7th, 2006 at 05:30 PM
まだ Bugzilla に投げてすらいない状況です。
October 7th, 2006 at 07:05 PM
Bugzilla に送ってみました。 「EOF が区別できないのが仕様」というのも結構ぎゃっとなると思うので、 できれば取りこまれると良いんですが。
October 7th, 2006 at 11:06 PM
であれば,is_eof()(isEof()?)みたいなのがあるとよいのかもしれませんね.