aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog20
-rw-r--r--node.h1
-rw-r--r--parse.y65
-rw-r--r--test/ruby/test_rubyoptions.rb8
-rwxr-xr-xtool/ytab.sed20
5 files changed, 83 insertions, 31 deletions
diff --git a/ChangeLog b/ChangeLog
index 4a3f1a18db..e6711237a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+Sun Dec 13 23:46:10 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (trace_lex_state): trace lex_state changes if yydebug is
+ set, and send the messages to rb_stdout.
+
+ * parse.y (rb_parser_printf): store YYPRINTF messages per lines
+ so that lex_state traces do not mix.
+
+ * tool/ytab.sed: add parser argument to yy_stack_print too.
+
+Sun Dec 13 23:45:19 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * parse.y (trace_lex_state): trace lex_state changes if yydebug is
+ set, and send the messages to rb_stdout.
+
+ * parse.y (rb_parser_printf): store YYPRINTF messages per lines
+ so that lex_state traces do not mix.
+
+ * tool/ytab.sed: add parser argument to yy_stack_print too.
+
Sun Dec 13 20:41:16 2015 Nobuyoshi Nakada <nobu@ruby-lang.org>
* parse.y (build_lex_state_name, trace_lex_state): lex_state is
diff --git a/node.h b/node.h
index 4d632003a9..05c2285a2e 100644
--- a/node.h
+++ b/node.h
@@ -506,6 +506,7 @@ void *rb_parser_malloc(struct parser_params *, size_t);
void *rb_parser_realloc(struct parser_params *, void *, size_t);
void *rb_parser_calloc(struct parser_params *, size_t, size_t);
void rb_parser_free(struct parser_params *, void *);
+void rb_parser_printf(struct parser_params *parser, const char *fmt, ...);
RUBY_SYMBOL_EXPORT_END
diff --git a/parse.y b/parse.y
index 53ff910a89..68ce1044d5 100644
--- a/parse.y
+++ b/parse.y
@@ -44,6 +44,12 @@
#define YYREALLOC(ptr, size) rb_parser_realloc(parser, (ptr), (size))
#define YYCALLOC(nelem, size) rb_parser_calloc(parser, (nelem), (size))
#define YYFREE(ptr) rb_parser_free(parser, (ptr))
+#ifdef HAVE_VA_ARGS_MACRO
+# define YYFPRINTF(f, fmt, ...) rb_parser_printf(parser, fmt, ##__VA_ARGS__)
+#else
+# define YYFPRINTF rb_parser_printf
+# define stderr parser
+#endif
#undef malloc
#undef realloc
#undef calloc
@@ -95,11 +101,9 @@ enum lex_state_e {
# define SET_LEX_STATE(ls) \
(lex_state = trace_lex_state(lex_state, (ls), __LINE__))
-#if PARSER_DEBUG
static enum lex_state_e trace_lex_state(enum lex_state_e from, enum lex_state_e to, int line);
-#else
-# define trace_lex_state(from, to, line) (to)
-#endif
+# define trace_lex_state(from, to, line) \
+ (yydebug ? trace_lex_state(from, to, line) : (to))
typedef VALUE stack_type;
@@ -274,6 +278,8 @@ struct parser_params {
token_info *token_info;
VALUE compile_option;
+ VALUE debug_buffer;
+
ID cur_arg;
int last_cr_line;
@@ -9179,54 +9185,47 @@ id_is_var_gen(struct parser_params *parser, ID id)
}
#endif /* !RIPPER */
-#if PARSER_DEBUG
static const char lex_state_names[][13] = {
"EXPR_BEG", "EXPR_END", "EXPR_ENDARG", "EXPR_ENDFN", "EXPR_ARG",
"EXPR_CMDARG", "EXPR_MID", "EXPR_FNAME", "EXPR_DOT", "EXPR_CLASS",
"EXPR_LABEL", "EXPR_LABELED",
};
-static const char *
-build_lex_state_name(enum lex_state_e state, char *buf, size_t size)
+static VALUE
+append_lex_state_name(enum lex_state_e state, VALUE buf)
{
int i, sep = 0;
- char *p = buf;
unsigned int mask = 1;
- size_t n;
static const char none[] = "EXPR_NONE";
for (i = 0; i < EXPR_MAX_STATE; ++i, mask <<= 1) {
if ((unsigned)state & mask) {
if (sep) {
- if (size < 2) break;
- --size;
- *p++ = '|';
+ rb_str_cat(buf, "|", 1);
}
sep = 1;
- n = strlcpy(p, lex_state_names[i], size);
- if (n >= size) break;
- size -= n;
- p += n;
+ rb_str_cat_cstr(buf, lex_state_names[i]);
}
}
- if (p == buf && size >= sizeof(none)) {
- n = strlcpy(buf, none, size);
- p += n;
+ if (!sep) {
+ rb_str_cat(buf, none, sizeof(none)-1);
}
- *p = '\0';
return buf;
}
+#undef trace_lex_state
static enum lex_state_e
trace_lex_state(enum lex_state_e from, enum lex_state_e to, int line)
{
- char buf1[sizeof(lex_state_names)], buf2[sizeof(lex_state_names)];
- build_lex_state_name(from, buf1, sizeof(buf1));
- build_lex_state_name(to, buf2, sizeof(buf2));
- printf("lex_state: %s -> %s at L%d\n", buf1, buf2, line);
+ VALUE mesg;
+ mesg = rb_str_new_cstr("lex_state: ");
+ append_lex_state_name(from, mesg);
+ rb_str_cat_cstr(mesg, " -> ");
+ append_lex_state_name(to, mesg);
+ rb_str_catf(mesg, " at line %d\n", line);
+ rb_io_write(rb_stdout, mesg);
return to;
}
-#endif
#ifdef RIPPER
static VALUE
@@ -10776,6 +10775,7 @@ parser_initialize(struct parser_params *parser)
parser->result = Qnil;
parser->parsing_thread = Qnil;
#endif
+ parser->debug_buffer = Qnil;
parser->enc = rb_utf8_encoding();
}
@@ -11034,6 +11034,21 @@ rb_parser_free(struct parser_params *parser, void *ptr)
xfree(ptr);
}
#endif
+
+void
+rb_parser_printf(struct parser_params *parser, const char *fmt, ...)
+{
+ va_list ap;
+ VALUE mesg = parser->debug_buffer;
+
+ if (NIL_P(mesg)) parser->debug_buffer = mesg = rb_str_new(0, 0);
+ va_start(ap, fmt);
+ rb_str_vcatf(mesg, fmt, ap);
+ va_end(ap);
+ if (RSTRING_END(mesg)[-1] == '\n') {
+ rb_io_write(rb_stdout, mesg);
+ }
+}
#endif
#ifdef RIPPER
diff --git a/test/ruby/test_rubyoptions.rb b/test/ruby/test_rubyoptions.rb
index b4203284cc..72672292b7 100644
--- a/test/ruby/test_rubyoptions.rb
+++ b/test/ruby/test_rubyoptions.rb
@@ -191,13 +191,13 @@ class TestRubyOptions < Test::Unit::TestCase
def test_yydebug
assert_in_out_err(["-ye", ""]) do |r, e|
- assert_equal([], r)
- assert_not_equal([], e)
+ assert_not_equal([], r)
+ assert_equal([], e)
end
assert_in_out_err(%w(--yydebug -e) + [""]) do |r, e|
- assert_equal([], r)
- assert_not_equal([], e)
+ assert_not_equal([], r)
+ assert_equal([], e)
end
end
diff --git a/tool/ytab.sed b/tool/ytab.sed
index 46317db284..d8fb70016c 100755
--- a/tool/ytab.sed
+++ b/tool/ytab.sed
@@ -14,7 +14,7 @@ a\
/^yydestruct.*yymsg/,/#endif/{
/^yydestruct/{
/parser/!{
- h
+ H
s/^/ruby_parser_&/
s/)$/, parser)/
/\*/s/parser)$/struct parser_params *&/
@@ -22,7 +22,7 @@ a\
}
/^#endif/{
x
- /^./{
+ /yydestruct/{
i\
struct parser_params *parser;
a\
@@ -31,6 +31,22 @@ a\
x
}
}
+/^yy_stack_print/{
+ /parser/!{
+ H
+ s/)$/, parser)/
+ /\*/s/parser)$/struct parser_params *&/
+ }
+}
+/yy_stack_print.*;/{
+ x
+ /yy_stack_print/{
+ x
+ s/\(yy_stack_print *\)(\(.*\));/\1(\2, parser);/
+ x
+ }
+ x
+}
s/^\([ ]*\)\(yyerror[ ]*([ ]*parser,\)/\1parser_\2/
s!^ *extern char \*getenv();!/* & */!
s/^\(#.*\)".*\.tab\.c"/\1"parse.c"/