From: nobu@... Date: 2007-01-12T00:04:45+09:00 Subject: [ruby-dev:30121] file name and line number of parser error/warning なかだです。 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はできる。 中田 伸悦