summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2012-04-22 16:58:19 -0700
committerYukihiro "Matz" Matsumoto <[email protected]>2012-04-22 16:58:19 -0700
commitcf6e7966d3de0de1cf03e8c72dbde474d61d9f7d (patch)
tree4b7522da07ecf6e20b15642e8805281445bda638
parent7feb68eb9030dc15f216479b45533428534b050e (diff)
parent844d7d49b3803f35ee102179e35de283df8e96c2 (diff)
downloadmruby-cf6e7966d3de0de1cf03e8c72dbde474d61d9f7d.tar.gz
mruby-cf6e7966d3de0de1cf03e8c72dbde474d61d9f7d.zip
Merge pull request #35 from fceller/master
simple fix for underflow / capture errors and warnings
-rw-r--r--src/compile.h12
-rw-r--r--src/parse.y62
2 files changed, 68 insertions, 6 deletions
diff --git a/src/compile.h b/src/compile.h
index f0e6b1874..212628deb 100644
--- a/src/compile.h
+++ b/src/compile.h
@@ -25,6 +25,12 @@ enum mrb_lex_state_enum {
EXPR_MAX_STATE
};
+struct mrb_parser_message {
+ int lineno;
+ int column;
+ char* message;
+};
+
struct mrb_parser_state {
mrb_state *mrb;
struct mrb_pool *pool;
@@ -55,14 +61,20 @@ struct mrb_parser_state {
void *ylval;
int nerr;
+ int nwarn;
mrb_ast_node *tree, *begin_tree;
+ int capture_errors;
+ struct mrb_parser_message error_buffer[10];
+ struct mrb_parser_message warn_buffer[10];
+
jmp_buf jmp;
};
struct mrb_parser_state* mrb_parse_file(mrb_state*,FILE*);
struct mrb_parser_state* mrb_parse_string(mrb_state*,char*);
struct mrb_parser_state* mrb_parse_nstring(mrb_state*,char*,size_t);
+struct mrb_parser_state* mrb_parse_nstring_ext(mrb_state*,char*,size_t);
int mrb_generate_code(mrb_state*, mrb_ast_node*);
int mrb_compile_file(mrb_state*,FILE*);
diff --git a/src/parse.y b/src/parse.y
index 2bc78f577..6e2696bd9 100644
--- a/src/parse.y
+++ b/src/parse.y
@@ -2898,8 +2898,21 @@ none : /* none */
static void
yyerror(parser_state *p, const char *s)
{
- fputs(s, stderr);
- fputs("\n", stderr);
+ char* c;
+ size_t n;
+
+ if (! p->capture_errors) {
+ fputs(s, stderr);
+ fputs("\n", stderr);
+ }
+ else if (p->nerr < sizeof(p->error_buffer) / sizeof(p->error_buffer[0])) {
+ n = strlen(s);
+ c = parser_palloc(p, n + 1);
+ memcpy(c, s, n + 1);
+ p->error_buffer[p->nerr].message = c;
+ p->error_buffer[p->nerr].lineno = p->lineno;
+ p->error_buffer[p->nerr].column = p->column;
+ }
p->nerr++;
}
@@ -2915,8 +2928,22 @@ yyerror_i(parser_state *p, const char *fmt, int i)
static void
yywarn(parser_state *p, const char *s)
{
- fputs(s, stderr);
- fputs("\n", stderr);
+ char* c;
+ size_t n;
+
+ if (! p->capture_errors) {
+ fputs(s, stderr);
+ fputs("\n", stderr);
+ }
+ else if (p->nerr < sizeof(p->warn_buffer) / sizeof(p->warn_buffer[0])) {
+ n = strlen(s);
+ c = parser_palloc(p, n + 1);
+ memcpy(c, s, n + 1);
+ p->error_buffer[p->nwarn].message = c;
+ p->error_buffer[p->nwarn].lineno = p->lineno;
+ p->error_buffer[p->nwarn].column = p->column;
+ }
+ p->nwarn++;
}
static void
@@ -2976,8 +3003,13 @@ nextc(parser_state *p)
c = *p->s++;
}
if (c == '\n') {
- p->lineno++;
- p->column = 0;
+ if (p->column < 0) {
+ p->column++; // pushback caused an underflow
+ }
+ else {
+ p->lineno++;
+ p->column = 0;
+ }
// must understand heredoc
}
else {
@@ -4604,6 +4636,8 @@ parser_new(mrb_state *mrb)
p->cmd_start = TRUE;
p->in_def = p->in_single = FALSE;
+ p->capture_errors = NULL;
+
p->lineno = 1;
#if defined(PARSER_TEST) || defined(PARSER_DEBUG)
yydebug = 1;
@@ -4642,6 +4676,22 @@ mrb_parse_nstring(mrb_state *mrb, char *s, size_t len)
}
parser_state*
+mrb_parse_nstring_ext(mrb_state *mrb, char *s, size_t len)
+{
+ parser_state *p;
+
+ p = parser_new(mrb);
+ if (!p) return 0;
+ p->s = s;
+ p->send = s + len;
+ p->f = NULL;
+ p->capture_errors = 1;
+
+ start_parser(p);
+ return p;
+}
+
+parser_state*
mrb_parse_string(mrb_state *mrb, char *s)
{
return mrb_parse_nstring(mrb, s, strlen(s));