ruby-changes:41206
From: nobu <ko1@a...>
Date: Thu, 24 Dec 2015 17:25:59 +0900 (JST)
Subject: [ruby-changes:41206] nobu:r53278 (trunk): preserve source file name encoding
nobu 2015-12-24 17:25:44 +0900 (Thu, 24 Dec 2015) New Revision: 53278 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=53278 Log: preserve source file name encoding * compile.c (append_compile_error), parse.y (compile_error): preserve encoding of source file name in exceptions. * error.c (rb_compile_error_str, rb_compile_bug_str): add. Modified files: trunk/ChangeLog trunk/compile.c trunk/error.c trunk/internal.h trunk/parse.y Index: ChangeLog =================================================================== --- ChangeLog (revision 53277) +++ ChangeLog (revision 53278) @@ -1,3 +1,10 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu Dec 24 17:25:42 2015 Nobuyoshi Nakada <nobu@r...> + + * compile.c (append_compile_error), parse.y (compile_error): + preserve encoding of source file name in exceptions. + + * error.c (rb_compile_error_str, rb_compile_bug_str): add. + Thu Dec 24 16:17:47 2015 NARUSE, Yui <naruse@r...> * common.mk (fake.rb): $(arch)-fake.rb must depend miniruby because Index: compile.c =================================================================== --- compile.c (revision 53277) +++ compile.c (revision 53278) @@ -295,10 +295,10 @@ r_value(VALUE value) https://github.com/ruby/ruby/blob/trunk/compile.c#L295 (((INSN*)(insn))->insn_id) /* error */ -typedef void (*compile_error_func)(const char *, int, const char *, ...); +typedef void (*compile_error_func)(VALUE, int, const char *, ...); static void -append_compile_error(const char *file, int line, const char *fmt, ...) +append_compile_error(VALUE file, int line, const char *fmt, ...) { VALUE err_info = rb_errinfo(); VALUE str = rb_attr_get(err_info, idMesg); @@ -306,7 +306,7 @@ append_compile_error(const char *file, i https://github.com/ruby/ruby/blob/trunk/compile.c#L306 if (RSTRING_LEN(str)) rb_str_cat2(str, "\n"); if (file) { - rb_str_cat2(str, file); + rb_str_concat(str, file); if (line) rb_str_catf(str, ":%d", line); rb_str_cat2(str, ": "); } @@ -321,7 +321,7 @@ static compile_error_func https://github.com/ruby/ruby/blob/trunk/compile.c#L321 prepare_compile_error(rb_iseq_t *iseq) { VALUE err_info = ISEQ_COMPILE_DATA(iseq)->err_info; - if (compile_debug) return rb_compile_bug; + if (compile_debug) return rb_compile_bug_str; if (NIL_P(err_info)) { err_info = rb_exc_new_cstr(rb_eSyntaxError, ""); RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->err_info, err_info); @@ -332,7 +332,7 @@ prepare_compile_error(rb_iseq_t *iseq) https://github.com/ruby/ruby/blob/trunk/compile.c#L332 #define COMPILE_ERROR prepare_compile_error(iseq) -#define ERROR_ARGS_AT(n) ruby_sourcefile, nd_line(n), +#define ERROR_ARGS_AT(n) ruby_sourcefile_string, nd_line(n), #define ERROR_ARGS ERROR_ARGS_AT(node) #define EXPECT_NODE(prefix, node, ndtype) \ @@ -340,23 +340,23 @@ do { \ https://github.com/ruby/ruby/blob/trunk/compile.c#L340 NODE *error_node = (node); \ enum node_type error_type = nd_type(error_node); \ if (error_type != (ndtype)) { \ - rb_compile_bug(ERROR_ARGS_AT(error_node) \ - prefix ": " #ndtype " is expected, but %s", \ - ruby_node_name(error_type)); \ + rb_compile_bug_str(ERROR_ARGS_AT(error_node) \ + prefix ": " #ndtype " is expected, but %s", \ + ruby_node_name(error_type)); \ } \ } while (0) #define EXPECT_NODE_NONULL(prefix, parent, ndtype) \ do { \ - rb_compile_bug(ERROR_ARGS_AT(parent) \ - prefix ": must be " #ndtype ", but 0"); \ + rb_compile_bug_str(ERROR_ARGS_AT(parent) \ + prefix ": must be " #ndtype ", but 0"); \ } while (0) #define UNKNOWN_NODE(prefix, node) \ do { \ NODE *error_node = (node); \ - rb_compile_bug(ERROR_ARGS_AT(error_node) prefix ": unknown node (%s)", \ - ruby_node_name(nd_type(error_node))); \ + rb_compile_bug_str(ERROR_ARGS_AT(error_node) prefix ": unknown node (%s)", \ + ruby_node_name(nd_type(error_node))); \ } while (0) #define COMPILE_OK 1 @@ -494,6 +494,7 @@ iseq_add_mark_object(const rb_iseq_t *is https://github.com/ruby/ruby/blob/trunk/compile.c#L494 return COMPILE_OK; } +#define ruby_sourcefile_string (iseq->body->location.path) #define ruby_sourcefile RSTRING_PTR(iseq->body->location.path) static int @@ -512,7 +513,7 @@ validate_label(st_data_t name, st_data_t https://github.com/ruby/ruby/blob/trunk/compile.c#L513 LABEL *lobj = (LABEL *)label; if (!lobj->link.next) { do { - COMPILE_ERROR(ruby_sourcefile, lobj->position, + COMPILE_ERROR(ruby_sourcefile_string, lobj->position, "%"PRIsVALUE": undefined label", rb_id2str((ID)name)); } while (0); @@ -611,7 +612,7 @@ rb_iseq_compile_node(rb_iseq_t *iseq, NO https://github.com/ruby/ruby/blob/trunk/compile.c#L612 COMPILE(ret, "defined guard", node); break; default: - rb_compile_bug(ERROR_ARGS "unknown scope"); + rb_compile_bug_str(ERROR_ARGS "unknown scope"); } } @@ -1559,7 +1560,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L1560 default: dump_disasm_list(FIRST_ELEMENT(anchor)); dump_disasm_list(list); - COMPILE_ERROR(ruby_sourcefile, line, "error: set_sequence"); + COMPILE_ERROR(ruby_sourcefile_string, line, "error: set_sequence"); return COMPILE_NG; } list = list->next; @@ -1606,7 +1607,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L1607 dump_disasm_list(list); xfree(generated_iseq); xfree(line_info_table); - COMPILE_ERROR(ruby_sourcefile, iobj->line_no, + COMPILE_ERROR(ruby_sourcefile_string, iobj->line_no, "operand size miss! (%d for %d)", iobj->operand_size, len - 1); return COMPILE_NG; @@ -1621,7 +1622,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L1622 /* label(destination position) */ LABEL *lobj = (LABEL *)operands[j]; if (!lobj->set) { - COMPILE_ERROR(ruby_sourcefile, iobj->line_no, + COMPILE_ERROR(ruby_sourcefile_string, iobj->line_no, "unknown label"); return COMPILE_NG; } @@ -1716,7 +1717,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L1717 default: xfree(generated_iseq); xfree(line_info_table); - COMPILE_ERROR(ruby_sourcefile, iobj->line_no, + COMPILE_ERROR(ruby_sourcefile_string, iobj->line_no, "unknown operand type: %c", type); return COMPILE_NG; } @@ -1773,8 +1774,8 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L1774 generated_iseq[code_index++] = BIN(nop); } else { - rb_compile_bug(ruby_sourcefile, adjust->line_no, - "iseq_set_sequence: adjust bug %d < %d", orig_sp, sp); + rb_compile_bug_str(ruby_sourcefile_string, adjust->line_no, + "iseq_set_sequence: adjust bug %d < %d", orig_sp, sp); } } break; @@ -2454,7 +2455,7 @@ insn_set_sc_state(rb_iseq_t *iseq, INSN https://github.com/ruby/ruby/blob/trunk/compile.c#L2455 dump_disasm_list((LINK_ELEMENT *)iobj); dump_disasm_list((LINK_ELEMENT *)lobj); printf("\n-- %d, %d\n", lobj->sc_state, nstate); - COMPILE_ERROR(ruby_sourcefile, iobj->line_no, + COMPILE_ERROR(ruby_sourcefile_string, iobj->line_no, "insn_set_sc_state error\n"); return COMPILE_NG; } @@ -2556,7 +2557,7 @@ iseq_set_sequence_stackcaching(rb_iseq_t https://github.com/ruby/ruby/blob/trunk/compile.c#L2557 case SCS_XX: goto normal_insn; default: - COMPILE_ERROR(ruby_sourcefile, iobj->line_no, + COMPILE_ERROR(ruby_sourcefile_string, iobj->line_no, "unreachable"); return COMPILE_NG; } @@ -2600,8 +2601,8 @@ compile_dstr_fragments(rb_iseq_t *iseq, https://github.com/ruby/ruby/blob/trunk/compile.c#L2601 if (!NIL_P(lit)) { cnt++; if (!RB_TYPE_P(lit, T_STRING)) { - rb_compile_bug(ERROR_ARGS "dstr: must be string: %s", - rb_builtin_type_name(TYPE(lit))); + rb_compile_bug_str(ERROR_ARGS "dstr: must be string: %s", + rb_builtin_type_name(TYPE(lit))); } lit = node->nd_lit = rb_fstring(lit); ADD_INSN1(ret, nd_line(node), putobject, lit); @@ -2947,7 +2948,8 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR * https://github.com/ruby/ruby/blob/trunk/compile.c#L2948 } else { if (rb_hash_lookup(literals, lit) != Qnil) { - rb_compile_warning(ruby_sourcefile, nd_line(val), "duplicated when clause is ignored"); + rb_compile_warning(ruby_sourcefile, nd_line(val), + "duplicated when clause is ignored"); } else { rb_hash_aset(literals, lit, (VALUE)(l1) | 1); @@ -3823,7 +3825,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L3825 vals = node->nd_head; if (!vals) { - rb_compile_bug(ERROR_ARGS "NODE_WHEN: must be NODE_ARRAY, but 0"); + rb_compile_bug_str(ERROR_ARGS "NODE_WHEN: must be NODE_ARRAY, but 0"); } switch (nd_type(vals)) { case NODE_ARRAY: @@ -3917,7 +3919,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L3919 if (node->nd_state == Qundef) { /* ADD_INSN(ret, line, putundef); */ - rb_compile_bug(ERROR_ARGS "unsupported: putundef"); + rb_compile_bug_str(ERROR_ARGS "unsupported: putundef"); } else { ADD_INSN(ret, line, putnil); @@ -4391,7 +4393,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4393 idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls); if (idx < 0) { - rb_compile_bug(ERROR_ARGS "NODE_DASGN(_CURR): unknown id (%"PRIsVALUE")", rb_id2str(node->nd_vid)); + rb_compile_bug_str(ERROR_ARGS "NODE_DASGN(_CURR): unknown id (%"PRIsVALUE")", rb_id2str(node->nd_vid)); } ADD_INSN2(ret, line, setlocal, INT2FIX(ls - idx), INT2FIX(lv)); @@ -5115,8 +5117,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L5117 break; default: - rb_compile_bug(ERROR_ARGS_AT(node->nd_head) "can't make hash with this node: %s", - ruby_node_name(type)); + rb_compile_bug_str(ERROR_ARGS_AT(node->nd_head) "can't make hash with this node: %s", + ruby_node_name(type)); } if (poped) { @@ -5206,7 +5208,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L5208 if (!poped) { idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls); if (idx < 0) { - rb_compile_bug(ERROR_ARGS "unknown dvar (%"PRIsVALUE")", rb_id2str(node->nd_vid)); + rb_compile_bug_str(ERROR_ARGS "unknown dvar (%"PRIsVALUE")", rb_id2str(node->nd_vid)); } ADD_INSN2(ret, line, getlocal, INT2FIX(ls - idx), INT2FIX(lv)); } @@ -5800,13 +5802,13 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L5802 if (default_value == (NODE *)-1) { /* required argument. do nothing */ - rb_compile_bug(ERROR_ARGS "unreachable"); + rb_compile_bug_str(ERROR_ARGS "unreachable"); } else if (nd_type(default_value) == NODE_LIT || nd_type(default_value) == NODE_NIL || nd_type(default_value) == NODE_TRUE || nd_type(default_value) == NODE_FALSE) { - rb_compile_bug(ERROR_ARGS "unreachable"); + rb_compile_bug_str(ERROR_ARGS "unreachable"); } else { /* if keywordcheck(_kw_bits, nth_keyword) @@ -6347,14 +6349,14 @@ iseq_build_from_ary_body(rb_iseq_t *iseq https://github.com/ruby/ruby/blob/trunk/compile.c#L6349 insn = (argc < 0) ? Qnil : RARRAY_AREF(obj, 0); if (st_lookup(insn_table, (st_data_t)insn, &insn_id) == 0) { /* TODO: exception */ - COMPILE_ERROR(ruby_sourcefile, line_no, + COMPILE_ERROR(ruby_sourcefile_string, line_no, "unknown instruction: %+"PRIsVALUE, insn); ret = COMPILE_NG; break; } if (argc != insn_len((VALUE)insn_id)-1) { - COMPILE_ERROR(ruby_sourcefile, line_no, + COMPILE_ERROR(ruby_sourcefile_string, line_no, "operand size mismatch"); ret = COMPILE_NG; break; Index: parse.y =================================================================== --- parse.y (revision 53277) +++ parse.y (revision 53278) @@ -741,15 +741,15 @@ static void ripper_compile_error(struct https://github.com/ruby/ruby/blob/trunk/parse.y#L741 # define WARN_S(s) s # define WARN_I(i) i # define PRIsWARN PRIsVALUE -# define WARN_ARGS(fmt,n) ruby_sourcefile, ruby_sourceline, (fmt) +# define WARN_ARGS(fmt,n) WARN_ARGS_L(ruby_sourceline,fmt,n) # define WARN_ARGS_L(l,fmt,n) ruby_sourcefile, (l), (fmt) # define WARN_CALL rb_compile_warn # define WARNING_ARGS(fmt,n) WARN_ARGS(fmt,n) # define WARNING_ARGS_L(l,fmt,n) WARN_ARGS_L(l,fmt,n) # define WARNING_CALL rb_compile_warning -# define rb_compile_error rb_compile_error_with_enc -# define compile_error (parser->error_p = 1),rb_compile_error_with_enc -# define PARSER_ARG ruby_sourcefile, ruby_sourceline, (void *)current_enc, +# define rb_compile_error rb_compile_error_str +# define compile_error (parser->error_p = 1),rb_compile_error_str +# define PARSER_ARG ruby_sourcefile_string, ruby_sourceline, (void *)current_enc, #endif /* Older versions of Yacc set YYMAXDEPTH to a very low value by default (150, @@ -7020,7 +7020,7 @@ parser_set_encode(struct parser_params * https://github.com/ruby/ruby/blob/trunk/parse.y#L7020 error: excargs[0] = rb_eArgError; excargs[2] = rb_make_backtrace(); - rb_ary_unshift(excargs[2], rb_sprintf("%s:%d", ruby_sourcefile, ruby_sourceline)); + rb_ary_unshift(excargs[2], rb_sprintf("%"PRIsVALUE":%d", ruby_sourcefile_string, ruby_sourceline)); rb_exc_raise(rb_make_exception(3, excargs)); } enc = rb_enc_from_index(idx); Index: error.c =================================================================== --- error.c (revision 53277) +++ error.c (revision 53278) @@ -152,6 +152,20 @@ rb_compile_error(const char *file, int l https://github.com/ruby/ruby/blob/trunk/error.c#L152 } void +rb_compile_error_str(VALUE file, int line, void *enc, const char *fmt, ...) +{ + va_list args; + VALUE str; + + va_start(args, fmt); + str = compile_snprintf(enc, NULL, + NIL_P(file) ? NULL : RSTRING_PTR(file), line, + fmt, args); + va_end(args); + compile_err_append(str); +} + +void rb_compile_error_append(const char *fmt, ...) { va_list args; @@ -476,6 +490,14 @@ rb_compile_bug(const char *file, int lin https://github.com/ruby/ruby/blob/trunk/error.c#L490 abort(); } + +void +rb_compile_bug_str(VALUE file, int line, const char *fmt, ...) +{ + report_bug(RSTRING_PTR(file), line, fmt, NULL); + + abort(); +} static const char builtin_types[][10] = { "", /* 0x00, */ Index: internal.h =================================================================== --- internal.h (revision 53277) +++ internal.h (revision 53278) @@ -736,6 +736,8 @@ extern VALUE rb_eEAGAIN; https://github.com/ruby/ruby/blob/trunk/internal.h#L736 extern VALUE rb_eEWOULDBLOCK; extern VALUE rb_eEINPROGRESS; NORETURN(PRINTF_ARGS(void rb_compile_bug(const char*, int, const char*, ...), 3, 4)); +NORETURN(PRINTF_ARGS(void rb_compile_bug_str(VALUE file, int line, const char *fmt, ...), 3, 4)); +PRINTF_ARGS(void rb_compile_error_str(VALUE file, int line, void *enc, const char *fmt, ...), 4, 5); VALUE rb_check_backtrace(VALUE); NORETURN(void rb_async_bug_errno(const char *,int)); const char *rb_builtin_type_name(int t); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/