ruby-changes:49574
From: mame <ko1@a...>
Date: Mon, 8 Jan 2018 21:57:03 +0900 (JST)
Subject: [ruby-changes:49574] mame:r61690 (trunk): parse.y: Make consistent with the terms about code ranges and locations
mame 2018-01-08 21:56:58 +0900 (Mon, 08 Jan 2018) New Revision: 61690 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61690 Log: parse.y: Make consistent with the terms about code ranges and locations "loc" was ambiguous; it might refer both a location and a code range. This change uses "loc" for a location, and "crange" or "cr" for a code range. A location (abbr. loc) is a point in a program and consists of line number and column number. A code range (abbr. crange and cr) is a range within a program and consists of a pair of locations which is the first and the last. Modified files: trunk/iseq.c trunk/node.c trunk/node.h trunk/parse.y Index: iseq.c =================================================================== --- iseq.c (revision 61689) +++ iseq.c (revision 61690) @@ -525,7 +525,7 @@ rb_iseq_new_with_opt(const rb_ast_body_t https://github.com/ruby/ruby/blob/trunk/iseq.c#L525 new_opt = option ? *option : COMPILE_OPTION_DEFAULT; if (ast && ast->compile_option) rb_iseq_make_compile_option(&new_opt, ast->compile_option); - prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_loc : NULL, parent, type, &new_opt); + prepare_iseq_build(iseq, name, path, realpath, first_lineno, node ? &node->nd_crange : NULL, parent, type, &new_opt); rb_iseq_compile_node(iseq, node); finish_iseq_build(iseq); Index: parse.y =================================================================== --- parse.y (revision 61689) +++ parse.y (revision 61690) @@ -63,11 +63,11 @@ https://github.com/ruby/ruby/blob/trunk/parse.y#L63 while (0) #define RUBY_SET_YYLLOC_FROM_STRTERM_HEREDOC(Current) \ - rb_parser_set_location_from_strterm_heredoc(parser, &lex_strterm->u.heredoc, &(Current)) + rb_parser_set_code_range_from_strterm_heredoc(parser, &lex_strterm->u.heredoc, &(Current)) #define RUBY_SET_YYLLOC_OF_NONE(Current) \ - rb_parser_set_location_of_none(parser, &(Current)) + rb_parser_set_code_range_of_none(parser, &(Current)) #define RUBY_SET_YYLLOC(Current) \ - rb_parser_set_location(parser, &(Current)) + rb_parser_set_code_range(parser, &(Current)) #undef malloc #undef realloc @@ -294,7 +294,7 @@ struct parser_params { https://github.com/ruby/ruby/blob/trunk/parse.y#L294 static int parser_yyerror(struct parser_params*, const YYLTYPE *yylloc, const char*); #define yyerror0(msg) parser_yyerror(parser, NULL, (msg)) -#define yyerror1(loc, msg) parser_yyerror(parser, (loc), (msg)) +#define yyerror1(cr, msg) parser_yyerror(parser, (cr), (msg)) #define yyerror(yylloc, parser, msg) parser_yyerror(parser, yylloc, msg) #define token_flush(p) ((p)->lex.ptok = (p)->lex.pcur) @@ -349,7 +349,7 @@ static int parser_yyerror(struct parser_ https://github.com/ruby/ruby/blob/trunk/parse.y#L349 #define CALL_Q_P(q) ((q) == TOKEN2VAL(tANDDOT)) #define NODE_CALL_Q(q) (CALL_Q_P(q) ? NODE_QCALL : NODE_CALL) -#define NEW_QCALL(q,r,m,a,loc) NEW_NODE(NODE_CALL_Q(q),r,m,a,loc) +#define NEW_QCALL(q,r,m,a,cr) NEW_NODE(NODE_CALL_Q(q),r,m,a,cr) #define lambda_beginning_p() (lpar_beg && lpar_beg == paren_nest) @@ -379,9 +379,9 @@ add_mark_object_gen(struct parser_params https://github.com/ruby/ruby/blob/trunk/parse.y#L379 #define add_mark_object(obj) add_mark_object_gen(parser, (obj)) static NODE* node_newnode(struct parser_params *, enum node_type, VALUE, VALUE, VALUE, const rb_code_range_t*); -#define rb_node_newnode(type, a1, a2, a3, loc) node_newnode(parser, (type), (a1), (a2), (a3), (loc)) +#define rb_node_newnode(type, a1, a2, a3, cr) node_newnode(parser, (type), (a1), (a2), (a3), (cr)) -static NODE *nd_set_loc(NODE *nd, const YYLTYPE *location); +static NODE *nd_set_crange(NODE *nd, const YYLTYPE *cr); #ifndef RIPPER static inline void @@ -398,17 +398,17 @@ set_line_body(NODE *body, int line) https://github.com/ruby/ruby/blob/trunk/parse.y#L398 #define yyparse ruby_yyparse static NODE *cond_gen(struct parser_params*,NODE*,int,const YYLTYPE*); -#define cond(node,location) cond_gen(parser, (node), FALSE, location) -#define method_cond(node,location) cond_gen(parser, (node), TRUE, location) -#define new_nil(location) NEW_NIL(location) +#define cond(node,cr) cond_gen(parser, (node), FALSE, cr) +#define method_cond(node,cr) cond_gen(parser, (node), TRUE, cr) +#define new_nil(cr) NEW_NIL(cr) static NODE *new_if_gen(struct parser_params*,NODE*,NODE*,NODE*,const YYLTYPE*); -#define new_if(cc,left,right,location) new_if_gen(parser, (cc), (left), (right), (location)) +#define new_if(cc,left,right,cr) new_if_gen(parser, (cc), (left), (right), (cr)) static NODE *new_unless_gen(struct parser_params*,NODE*,NODE*,NODE*,const YYLTYPE*); -#define new_unless(cc,left,right,location) new_unless_gen(parser, (cc), (left), (right), (location)) +#define new_unless(cc,left,right,cr) new_unless_gen(parser, (cc), (left), (right), (cr)) static NODE *logop_gen(struct parser_params*,enum node_type,NODE*,NODE*,const YYLTYPE*,const YYLTYPE*); -#define logop(id,node1,node2,op_loc,location) \ +#define logop(id,node1,node2,op_cr,cr) \ logop_gen(parser, ((id)==idAND||(id)==idANDOP)?NODE_AND:NODE_OR, \ - (node1), (node2), (op_loc), (location)) + (node1), (node2), (op_cr), (cr)) static NODE *newline_node(NODE*); static void fixpos(NODE*,NODE*); @@ -433,36 +433,36 @@ static NODE *list_append_gen(struct pars https://github.com/ruby/ruby/blob/trunk/parse.y#L433 #define list_append(l,i) list_append_gen(parser,(l),(i)) static NODE *list_concat(NODE*,NODE*); static NODE *arg_append_gen(struct parser_params*,NODE*,NODE*,const YYLTYPE*); -#define arg_append(h,t,location) arg_append_gen(parser,(h),(t),(location)) +#define arg_append(h,t,cr) arg_append_gen(parser,(h),(t),(cr)) static NODE *arg_concat_gen(struct parser_params*,NODE*,NODE*,const YYLTYPE*); -#define arg_concat(h,t,location) arg_concat_gen(parser,(h),(t),(location)) +#define arg_concat(h,t,cr) arg_concat_gen(parser,(h),(t),(cr)) static NODE *literal_concat_gen(struct parser_params*,NODE*,NODE*,const YYLTYPE*); -#define literal_concat(h,t,location) literal_concat_gen(parser,(h),(t),(location)) +#define literal_concat(h,t,cr) literal_concat_gen(parser,(h),(t),(cr)) static int literal_concat0(struct parser_params *, VALUE, VALUE); static NODE *new_evstr_gen(struct parser_params*,NODE*,const YYLTYPE*); -#define new_evstr(n, location) new_evstr_gen(parser,(n),(location)) +#define new_evstr(n, cr) new_evstr_gen(parser,(n),(cr)) static NODE *evstr2dstr_gen(struct parser_params*,NODE*); #define evstr2dstr(n) evstr2dstr_gen(parser,(n)) static NODE *splat_array(NODE*); static NODE *call_bin_op_gen(struct parser_params*,NODE*,ID,NODE*,const YYLTYPE*,const YYLTYPE*); -#define call_bin_op(recv,id,arg1,op_loc,location) call_bin_op_gen(parser, (recv),(id),(arg1),(op_loc),(location)) +#define call_bin_op(recv,id,arg1,op_cr,cr) call_bin_op_gen(parser, (recv),(id),(arg1),(op_cr),(cr)) static NODE *call_uni_op_gen(struct parser_params*,NODE*,ID,const YYLTYPE*,const YYLTYPE*); -#define call_uni_op(recv,id,op_loc,location) call_uni_op_gen(parser, (recv),(id),(op_loc),(location)) -static NODE *new_qcall_gen(struct parser_params* parser, ID atype, NODE *recv, ID mid, NODE *args, const YYLTYPE *op_loc, const YYLTYPE *location); -#define new_qcall(q,r,m,a,op_loc,location) new_qcall_gen(parser,q,r,m,a,op_loc,location) -#define new_command_qcall(q,r,m,a,op_loc,location) new_qcall_gen(parser,q,r,m,a,op_loc,location) +#define call_uni_op(recv,id,op_cr,cr) call_uni_op_gen(parser, (recv),(id),(op_cr),(cr)) +static NODE *new_qcall_gen(struct parser_params* parser, ID atype, NODE *recv, ID mid, NODE *args, const YYLTYPE *op_cr, const YYLTYPE *cr); +#define new_qcall(q,r,m,a,op_cr,cr) new_qcall_gen(parser,q,r,m,a,op_cr,cr) +#define new_command_qcall(q,r,m,a,op_cr,cr) new_qcall_gen(parser,q,r,m,a,op_cr,cr) static NODE *new_command_gen(struct parser_params*parser, NODE *m, NODE *a) {m->nd_args = a; return m;} #define new_command(m,a) new_command_gen(parser, m, a) -static NODE *method_add_block_gen(struct parser_params*parser, NODE *m, NODE *b, const YYLTYPE *location) {b->nd_iter = m; b->nd_loc = *location; return b;} -#define method_add_block(m,b,location) method_add_block_gen(parser, m, b, location) +static NODE *method_add_block_gen(struct parser_params*parser, NODE *m, NODE *b, const YYLTYPE *cr) {b->nd_iter = m; b->nd_crange = *cr; return b;} +#define method_add_block(m,b,cr) method_add_block_gen(parser, m, b, cr) static NODE *new_args_gen(struct parser_params*,NODE*,NODE*,ID,NODE*,NODE*,const YYLTYPE*); -#define new_args(f,o,r,p,t,location) new_args_gen(parser, (f),(o),(r),(p),(t),(location)) +#define new_args(f,o,r,p,t,cr) new_args_gen(parser, (f),(o),(r),(p),(t),(cr)) static NODE *new_args_tail_gen(struct parser_params*,NODE*,ID,ID,const YYLTYPE*); -#define new_args_tail(k,kr,b,location) new_args_tail_gen(parser, (k),(kr),(b),(location)) -static NODE *new_kw_arg_gen(struct parser_params *parser, NODE *k, const YYLTYPE *location); -#define new_kw_arg(k,location) new_kw_arg_gen(parser, k, location) +#define new_args_tail(k,kr,b,cr) new_args_tail_gen(parser, (k),(kr),(b),(cr)) +static NODE *new_kw_arg_gen(struct parser_params *parser, NODE *k, const YYLTYPE *cr); +#define new_kw_arg(k,cr) new_kw_arg_gen(parser, k, cr) static VALUE negate_lit_gen(struct parser_params*, VALUE); #define negate_lit(lit) negate_lit_gen(parser, lit) @@ -470,31 +470,31 @@ static NODE *ret_args_gen(struct parser_ https://github.com/ruby/ruby/blob/trunk/parse.y#L470 #define ret_args(node) ret_args_gen(parser, (node)) static NODE *arg_blk_pass(NODE*,NODE*); static NODE *new_yield_gen(struct parser_params*,NODE*,const YYLTYPE*); -#define new_yield(node,location) new_yield_gen(parser, (node), (location)) +#define new_yield(node,cr) new_yield_gen(parser, (node), (cr)) static NODE *dsym_node_gen(struct parser_params*,NODE*,const YYLTYPE*); -#define dsym_node(node,location) dsym_node_gen(parser, (node), (location)) +#define dsym_node(node,cr) dsym_node_gen(parser, (node), (cr)) static NODE *gettable_gen(struct parser_params*,ID,const YYLTYPE*); -#define gettable(id,location) gettable_gen(parser,(id),(location)) +#define gettable(id,cr) gettable_gen(parser,(id),(cr)) static NODE *assignable_gen(struct parser_params*,ID,NODE*,const YYLTYPE*); -#define assignable(id,node,location) assignable_gen(parser, (id), (node), (location)) +#define assignable(id,node,cr) assignable_gen(parser, (id), (node), (cr)) static NODE *aryset_gen(struct parser_params*,NODE*,NODE*,const YYLTYPE*); -#define aryset(node1,node2,location) aryset_gen(parser, (node1), (node2), (location)) +#define aryset(node1,node2,cr) aryset_gen(parser, (node1), (node2), (cr)) static NODE *attrset_gen(struct parser_params*,NODE*,ID,ID,const YYLTYPE*); -#define attrset(node,q,id,location) attrset_gen(parser, (node), (q), (id), (location)) +#define attrset(node,q,id,cr) attrset_gen(parser, (node), (q), (id), (cr)) static void rb_backref_error_gen(struct parser_params*,NODE*); #define rb_backref_error(n) rb_backref_error_gen(parser,(n)) static NODE *node_assign_gen(struct parser_params*,NODE*,NODE*,const YYLTYPE*); -#define node_assign(node1, node2, location) node_assign_gen(parser, (node1), (node2), (location)) +#define node_assign(node1, node2, cr) node_assign_gen(parser, (node1), (node2), (cr)) -static NODE *new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs, const YYLTYPE *location); -#define new_op_assign(lhs, op, rhs, location) new_op_assign_gen(parser, (lhs), (op), (rhs), (location)) -static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID atype, ID attr, ID op, NODE *rhs, const YYLTYPE *location); -#define new_attr_op_assign(lhs, type, attr, op, rhs, location) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs), (location)) -static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs, const YYLTYPE *location); -#define new_const_op_assign(lhs, op, rhs, location) new_const_op_assign_gen(parser, (lhs), (op), (rhs), (location)) +static NODE *new_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs, const YYLTYPE *cr); +#define new_op_assign(lhs, op, rhs, cr) new_op_assign_gen(parser, (lhs), (op), (rhs), (cr)) +static NODE *new_attr_op_assign_gen(struct parser_params *parser, NODE *lhs, ID atype, ID attr, ID op, NODE *rhs, const YYLTYPE *cr); +#define new_attr_op_assign(lhs, type, attr, op, rhs, cr) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs), (cr)) +static NODE *new_const_op_assign_gen(struct parser_params *parser, NODE *lhs, ID op, NODE *rhs, const YYLTYPE *cr); +#define new_const_op_assign(lhs, op, rhs, cr) new_const_op_assign_gen(parser, (lhs), (op), (rhs), (cr)) static ID change_shortcut_operator_id(ID id) { if (id == tOROP) return 0; @@ -502,39 +502,39 @@ static ID change_shortcut_operator_id(ID https://github.com/ruby/ruby/blob/trunk/parse.y#L502 return id; } -static NODE *const_path_field_gen(struct parser_params *parser, NODE *head, ID mid, const YYLTYPE *location); -#define const_path_field(w, n, location) const_path_field_gen(parser, w, n, location) -#define top_const_field(n,loc) NEW_COLON3(n,loc) -static NODE *const_decl_gen(struct parser_params *parser, NODE* path, const YYLTYPE *location); -#define const_decl(path, location) const_decl_gen(parser, path, location) +static NODE *const_path_field_gen(struct parser_params *parser, NODE *head, ID mid, const YYLTYPE *cr); +#define const_path_field(w, n, cr) const_path_field_gen(parser, w, n, cr) +#define top_const_field(n,cr) NEW_COLON3(n,cr) +static NODE *const_decl_gen(struct parser_params *parser, NODE* path, const YYLTYPE *cr); +#define const_decl(path, cr) const_decl_gen(parser, path, cr) #define var_field(n) (n) -#define backref_assign_error(n, a, location) (rb_backref_error(n), NEW_BEGIN(0, location)) +#define backref_assign_error(n, a, cr) (rb_backref_error(n), NEW_BEGIN(0, cr)) static NODE *opt_arg_append(NODE*, NODE*); static NODE *kwd_append(NODE*, NODE*); -static NODE *new_hash_gen(struct parser_params *parser, NODE *hash, const YYLTYPE *location); -#define new_hash(hash, location) new_hash_gen(parser, (hash), location) +static NODE *new_hash_gen(struct parser_params *parser, NODE *hash, const YYLTYPE *cr); +#define new_hash(hash, cr) new_hash_gen(parser, (hash), cr) -static NODE *new_defined_gen(struct parser_params *parser, NODE *expr, const YYLTYPE *location); -#define new_defined(expr, location) new_defined_gen(parser, expr, location) +static NODE *new_defined_gen(struct parser_params *parser, NODE *expr, const YYLTYPE *cr); +#define new_defined(expr, cr) new_defined_gen(parser, expr, cr) static NODE *new_regexp_gen(struct parser_params *, NODE *, int, const YYLTYPE *); -#define new_regexp(node, opt, location) new_regexp_gen(parser, node, opt, location) +#define new_regexp(node, opt, cr) new_regexp_gen(parser, node, opt, cr) -#define make_array(ary, location) ((ary) ? (nd_set_loc(ary, location), ary) : NEW_ZARRAY(location)) +#define make_array(ary, cr) ((ary) ? (nd_set_crange(ary, cr), ary) : NEW_ZARRAY(cr)) -static NODE *new_xstring_gen(struct parser_params *, NODE *, const YYLTYPE *location); -#define new_xstring(node, location) new_xstring_gen(parser, node, location) +static NODE *new_xstring_gen(struct parser_params *, NODE *, const YYLTYPE *cr); +#define new_xstring(node, cr) new_xstring_gen(parser, node, cr) #define new_string1(str) (str) -static NODE *new_body_gen(struct parser_params *parser, NODE *param, NODE *stmt, const YYLTYPE *location); -#define new_brace_body(param, stmt, location) new_body_gen(parser, param, stmt, location) -#define new_do_body(param, stmt, location) new_body_gen(parser, param, stmt, location) +static NODE *new_body_gen(struct parser_params *parser, NODE *param, NODE *stmt, const YYLTYPE *cr); +#define new_brace_body(param, stmt, cr) new_body_gen(parser, param, stmt, cr) +#define new_do_body(param, stmt, cr) new_body_gen(parser, param, stmt, cr) static NODE *match_op_gen(struct parser_params*,NODE*,NODE*,const YYLTYPE*,const YYLTYPE*); -#define match_op(node1,node2,op_loc,location) match_op_gen(parser, (node1), (node2), (op_loc), (location)) +#define match_op(node1,node2,op_cr,cr) match_op_gen(parser, (node1), (node2), (op_cr), (cr)) static ID *local_tbl_gen(struct parser_params*); #define local_tbl() local_tbl_gen(parser) @@ -545,8 +545,8 @@ static void reg_fragment_setenc_gen(stru https://github.com/ruby/ruby/blob/trunk/parse.y#L545 #define reg_fragment_setenc(str,options) reg_fragment_setenc_gen(parser, (str), (options)) static int reg_fragment_check_gen(struct parser_params*, VALUE, int); #define reg_fragment_check(str,options) reg_fragment_check_gen(parser, (str), (options)) -static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, const YYLTYPE *location); -#define reg_named_capture_assign(regexp,location) reg_named_capture_assign_gen(parser,(regexp),location) +static NODE *reg_named_capture_assign_gen(struct parser_params* parser, VALUE regexp, const YYLTYPE *cr); +#define reg_named_capture_assign(regexp,cr) reg_named_capture_assign_gen(parser,(regexp),cr) static NODE *parser_heredoc_dedent(struct parser_params*,NODE*); # define heredoc_dedent(str) parser_heredoc_dedent(parser, (str)) @@ -580,48 +580,48 @@ static ID ripper_get_id(VALUE); https://github.com/ruby/ruby/blob/trunk/parse.y#L580 static VALUE ripper_get_value(VALUE); #define get_value(val) ripper_get_value(val) static VALUE assignable_gen(struct parser_params*,VALUE); -#define assignable(lhs,node,location) assignable_gen(parser, (lhs)) +#define assignable(lhs,node,cr) assignable_gen(parser, (lhs)) static int id_is_var_gen(struct parser_params *parser, ID id); #define id_is_var(id) id_is_var_gen(parser, (id)) -#define method_cond(node,location) (node) -#define call_bin_op(recv,id,arg1,op_loc,location) dispatch3(binary, (recv), STATIC_ID2SYM(id), (arg1)) -#define match_op(node1,node2,op_loc,location) call_bin_op((node1), idEqTilde, (node2), op_loc, location) -#define call_uni_op(recv,id,op_loc,location) dispatch2(unary, STATIC_ID2SYM(id), (recv)) -#define logop(id,node1,node2,op_loc,location) call_bin_op((node1), (id), (node2), op_loc, location) -#define node_assign(node1, node2, location) dispatch2(assign, (node1), (node2)) +#define method_cond(node,cr) (node) +#define call_bin_op(recv,id,arg1,op_cr,cr) dispatch3(binary, (recv), STATIC_ID2SYM(id), (arg1)) +#define match_op(node1,node2,op_cr,cr) call_bin_op((node1), idEqTilde, (node2), op_cr, cr) +#define call_uni_op(recv,id,op_cr,cr) dispatch2(unary, STATIC_ID2SYM(id), (recv)) +#define logop(id,node1,node2,op_cr,cr) call_bin_op((node1), (id), (node2), op_cr, cr) +#define node_assign(node1, node2, cr) dispatch2(assign, (node1), (node2)) static VALUE new_qcall_gen(struct parser_params *parser, VALUE q, VALUE r, VALUE m, VALUE a); -#define new_qcall(q,r,m,a,op_loc,location) new_qcall_gen(parser, (r), (q), (m), (a)) -#define new_command_qcall(q,r,m,a,op_loc,location) dispatch4(command_call, (r), (q), (m), (a)) +#define new_qcall(q,r,m,a,op_cr,cr) new_qcall_gen(parser, (r), (q), (m), (a)) +#define new_command_qcall(q,r,m,a,op_cr,cr) dispatch4(command_call, (r), (q), (m), (a)) #define new_command(m,a) dispatch2(command, (m), (a)); -#define new_nil(location) Qnil +#define new_nil(cr) Qnil static VALUE new_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE op, VALUE rhs); -#define new_op_assign(lhs, op, rhs, location) new_op_assign_gen(parser, (lhs), (op), (rhs)) +#define new_op_assign(lhs, op, rhs, cr) new_op_assign_gen(parser, (lhs), (op), (rhs)) static VALUE new_attr_op_assign_gen(struct parser_params *parser, VALUE lhs, VALUE type, VALUE attr, VALUE op, VALUE rhs); -#define new_attr_op_assign(lhs, type, attr, op, rhs, location) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs)) -#define new_const_op_assign(lhs, op, rhs, location) new_op_assign(lhs, op, rhs, location) +#define new_attr_op_assign(lhs, type, attr, op, rhs, cr) new_attr_op_assign_gen(parser, (lhs), (type), (attr), (op), (rhs)) +#define new_const_op_assign(lhs, op, rhs, cr) new_op_assign(lhs, op, rhs, cr) static VALUE new_regexp_gen(struct parser_params *, VALUE, VALUE); -#define new_regexp(node, opt, location) new_regexp_gen(parser, node, opt) +#define new_regexp(node, opt, cr) new_regexp_gen(parser, node, opt) static VALUE new_xstring_gen(struct parser_params *, VALUE); -#define new_xstring(str, location) new_xstring_gen(parser, str) +#define new_xstring(str, c (... truncated) -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/