[#30220] schedule for Ruby 1.8.6 — "Akinori MUSHA" <knu@...>

 ruby-core を読んでいない人もいると思うので、ここでもアナウンス

20 messages 2007/01/30

[ruby-dev:30121] file name and line number of parser error/warning

From: nobu@...
Date: 2007-01-11 15:04:45 UTC
List: ruby-dev #30121
なかだです。

YARVになってから、syntax errorやparse時の警告でソースファイル名
や行番号が出なくなっています。

当初、err_position()を実行時用とparser用に分ければいいかと思っ
たんですが、どうせならruby_sourcefile/ruby_sourcelineをripper同
様parser_paramsに移してparser_warn()などで処理するようにしては
どうかという気もします。

どちらにするにしても、シグナルで呼ばれる可能性のあるrb_bug()は
単純にどちらか一方にはできそうにないという問題があります。どう
したもんでしょうか。

一応、最初の案で試してみたパッチをつけておきます。


Index: parse.y
===================================================================
--- parse.y	(revision 11525)
+++ parse.y	(working copy)
@@ -500,9 +500,9 @@ static VALUE ripper_id2sym(ID);
 
 #ifndef RIPPER
-# define rb_warn0(fmt)    rb_warn(fmt)
-# define rb_warnI(fmt,a)  rb_warn(fmt,a)
-# define rb_warnS(fmt,a)  rb_warn(fmt,a)
-# define rb_warning0(fmt) rb_warning(fmt)
-# define rb_warningS(fmt,a) rb_warning(fmt,a)
+# define rb_warn0(fmt)    rb_compile_warn(fmt)
+# define rb_warnI(fmt,a)  rb_compile_warn(fmt,a)
+# define rb_warnS(fmt,a)  rb_compile_warn(fmt,a)
+# define rb_warning0(fmt) rb_compile_warning(fmt)
+# define rb_warningS(fmt,a) rb_compile_warning(fmt,a)
 #else
 # define rb_warn0(fmt)    ripper_warn0(parser, fmt)
@@ -739,5 +739,5 @@ bodystmt	: compstmt
 			}
 			else if ($3) {
-			    rb_warn("else without rescue is useless");
+			    rb_warn0("else without rescue is useless");
 			    $$ = block_append($$, $3);
 			}
@@ -2234,5 +2234,5 @@ opt_call_args   : none
 call_args	: command
 		    {
-		        rb_warn("parenthesize argument(s) for future version");
+		        rb_warn0("parenthesize argument(s) for future version");
 		    /*%%%*/
 			$$ = NEW_LIST($1);
@@ -6987,5 +6987,5 @@ parser_warn(NODE *node, const char *mesg
     int line = ruby_sourceline;
     ruby_sourceline = nd_line(node);
-    rb_warn("%s", mesg);
+    rb_warnS("%s", mesg);
     ruby_sourceline = line;
 }
@@ -7593,5 +7593,5 @@ void_expr_gen(struct parser_params *pars
 
 	ruby_sourceline = nd_line(node);
-	rb_warn("useless use of %s in void context", useless);
+	rb_warnS("useless use of %s in void context", useless);
 	ruby_sourceline = line;
     }
@@ -7788,5 +7788,5 @@ cond0(struct parser_params *parser, NODE
       case NODE_EVSTR:
       case NODE_STR:
-	rb_warn("string literal in condition");
+	rb_warn0("string literal in condition");
 	break;
 
Index: error.c
===================================================================
--- error.c	(revision 11525)
+++ error.c	(working copy)
@@ -31,18 +31,30 @@ int rb_sourceline();
 
 static int
-err_position(char *buf, long len)
+err_position_0(char *buf, long len, const char *file, long line)
 {
-    ruby_set_current_source();
-    if (!rb_sourcefile()) {
+    if (!file) {
 	return 0;
     }
-    else if (rb_sourceline() == 0) {
-	return snprintf(buf, len, "%s: ", rb_sourcefile());
+    else if (line == 0) {
+	return snprintf(buf, len, "%s: ", file);
     }
     else {
-	return snprintf(buf, len, "%s:%d: ", rb_sourcefile(), rb_sourceline());
+	return snprintf(buf, len, "%s:%d: ", file, line);
     }
 }
 
+static int
+err_position(char *buf, long len)
+{
+    return err_position_0(buf, len, rb_sourcefile(), rb_sourceline());
+}
+
+static int
+compile_position(char *buf, long len)
+{
+    ruby_set_current_source();
+    return err_position_0(buf, len, ruby_sourcefile, ruby_sourceline);
+}
+
 static void
 err_snprintf(char *buf, long len, const char *fmt, va_list args)
@@ -56,21 +68,27 @@ err_snprintf(char *buf, long len, const 
 }
 
-static void err_append(const char*);
 static void
-err_print(const char *fmt, va_list args)
+compile_snprintf(char *buf, long len, const char *fmt, va_list args)
 {
-    char buf[BUFSIZ];
+    long n;
 
-    err_snprintf(buf, BUFSIZ, fmt, args);
-    err_append(buf);
+    n = compile_position(buf, len);
+    if (len > n) {
+	vsnprintf((char*)buf+n, len-n, fmt, args);
+    }
 }
 
+static void err_append(const char*);
+
 void
 rb_compile_error(const char *fmt, ...)
 {
     va_list args;
+    char buf[BUFSIZ];
+
     va_start(args, fmt);
-    err_print(fmt, args);
+    compile_snprintf(buf, BUFSIZ, fmt, args);
     va_end(args);
+    err_append(buf);
     ruby_nerrs++;
 }
@@ -89,4 +107,47 @@ rb_compile_error_append(const char *fmt,
 
 static void
+compile_warn_print(const char *fmt, va_list args)
+{
+    char buf[BUFSIZ];
+    int len;
+
+    compile_snprintf(buf, BUFSIZ, fmt, args);
+    len = strlen(buf);
+    buf[len++] = '\n';
+    rb_write_error2(buf, len);
+}
+
+void
+rb_compile_warn(const char *fmt, ...)
+{
+    char buf[BUFSIZ];
+    va_list args;
+
+    if (NIL_P(ruby_verbose)) return;
+
+    snprintf(buf, BUFSIZ, "warning: %s", fmt);
+
+    va_start(args, fmt);
+    compile_warn_print(buf, args);
+    va_end(args);
+}
+
+/* rb_compile_warning() reports only in verbose mode */
+void
+rb_compile_warning(const char *fmt, ...)
+{
+    char buf[BUFSIZ];
+    va_list args;
+
+    if (!RTEST(ruby_verbose)) return;
+
+    snprintf(buf, BUFSIZ, "warning: %s", fmt);
+
+    va_start(args, fmt);
+    compile_warn_print(buf, args);
+    va_end(args);
+}
+
+static void
 warn_print(const char *fmt, va_list args)
 {
Index: ruby.h
===================================================================
--- ruby.h	(revision 11525)
+++ ruby.h	(working copy)
@@ -632,8 +632,10 @@ NORETURN(void rb_notimplement(void));
 /* reports if `-w' specified */
 PRINTF_ARGS(void rb_warning(const char*, ...), 1, 2);
+PRINTF_ARGS(void rb_compile_warning(const char*, ...), 1, 2);
 /* reports if `-w' specified */
 PRINTF_ARGS(void rb_sys_warning(const char*, ...), 1, 2);
 /* reports always */
 PRINTF_ARGS(void rb_warn(const char*, ...), 1, 2);
+PRINTF_ARGS(void rb_compile_warn(const char*, ...), 1, 2);
 
 VALUE rb_each(VALUE);


-- 
--- 僕の前にBugはない。
--- 僕の後ろにBugはできる。
    中田 伸悦

In This Thread

Prev Next