aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-03-14 05:32:30 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-03-14 05:32:30 +0000
commitccc933d4a6873d9be359c8ab04b1f242ed64c1e5 (patch)
treed71a903579684914e0da97b60afe919a888c0370
parent86c5806c6a3452a0b81595f8a306ec5c421a16a8 (diff)
downloadruby-ccc933d4a6873d9be359c8ab04b1f242ed64c1e5.tar.gz
Hoisted out ruby_show_error_line
* parse.y (ruby_show_error_line): hoisted out from parser_yyerror. * parse.y (regx_options): revert r67226 and show the error line separately. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67250 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--parse.y140
1 files changed, 86 insertions, 54 deletions
diff --git a/parse.y b/parse.y
index d1e6166f8c..898f9fb02d 100644
--- a/parse.y
+++ b/parse.y
@@ -4664,81 +4664,110 @@ parser_precise_mbclen(struct parser_params *p, const char *ptr)
return len;
}
+#ifndef RIPPER
+static void ruby_show_error_line(VALUE errbuf, const YYLTYPE *yylloc, int lineno, VALUE str);
+
+static inline void
+parser_show_error_line(struct parser_params *p, const YYLTYPE *yylloc)
+{
+ ruby_show_error_line(p->error_buffer, yylloc, p->ruby_sourceline, p->lex.lastline);
+}
+
static int
parser_yyerror(struct parser_params *p, const YYLTYPE *yylloc, const char *msg)
{
-#ifndef RIPPER
- const int max_line_margin = 30;
- const char *ptr, *ptr_end, *pt, *pb;
- const char *pre = "", *post = "", *pend;
- const char *code = "", *caret = "";
- const char *lim;
- char *buf;
- long len;
- int i;
YYLTYPE current;
if (!yylloc) {
yylloc = RUBY_SET_YYLLOC(current);
- token_flush(p);
}
else if ((p->ruby_sourceline != yylloc->beg_pos.lineno &&
p->ruby_sourceline != yylloc->end_pos.lineno) ||
(yylloc->beg_pos.lineno == yylloc->end_pos.lineno &&
yylloc->beg_pos.column == yylloc->end_pos.column)) {
- compile_error(p, "%s", msg);
- return 0;
+ yylloc = 0;
+ }
+ compile_error(p, "%s", msg);
+ parser_show_error_line(p, yylloc);
+ return 0;
+}
+
+static void
+ruby_show_error_line(VALUE errbuf, const YYLTYPE *yylloc, int lineno, VALUE str)
+{
+ VALUE mesg;
+ const int max_line_margin = 30;
+ const char *ptr, *ptr_end, *pt, *pb;
+ const char *pre = "", *post = "", *pend;
+ const char *code = "", *caret = "";
+ const char *lim;
+ const char *const pbeg = RSTRING_PTR(str);
+ char *buf;
+ long len;
+ int i;
+
+ if (!yylloc) return;
+ pend = RSTRING_END(str);
+ if (pend > pbeg && pend[-1] == '\n') {
+ if (--pend > pbeg && pend[-1] == '\r') --pend;
}
- pend = p->lex.pend;
- if (pend > p->lex.pbeg && pend[-1] == '\n') {
- if (--pend > p->lex.pbeg && pend[-1] == '\r') --pend;
+ pt = pend;
+ if (lineno == yylloc->end_pos.lineno &&
+ (pend - pbeg) > yylloc->end_pos.column) {
+ pt = pbeg + yylloc->end_pos.column;
}
- pt = (p->ruby_sourceline == yylloc->end_pos.lineno) ?
- p->lex.pbeg + yylloc->end_pos.column : p->lex.pend;
- if ((p->lex.pbeg < pt) && (*(pt-1) == '\n')) pt--;
- ptr = ptr_end = pt < pend ? pt : pend;
- lim = ptr - p->lex.pbeg > max_line_margin ? ptr - max_line_margin : p->lex.pbeg;
+ ptr = ptr_end = pt;
+ lim = ptr - pbeg > max_line_margin ? ptr - max_line_margin : pbeg;
while ((lim < ptr) && (*(ptr-1) != '\n')) ptr--;
lim = pend - ptr_end > max_line_margin ? ptr_end + max_line_margin : pend;
- while ((ptr_end < lim) && (*ptr_end != '\n')) ptr_end++;
+ while ((ptr_end < lim) && (*ptr_end != '\n') && (*ptr_end != '\r')) ptr_end++;
len = ptr_end - ptr;
if (len > 4) {
- if (ptr > p->lex.pbeg) {
- ptr = rb_enc_prev_char(p->lex.pbeg, ptr, pt, rb_enc_get(p->lex.lastline));
- if (ptr > p->lex.pbeg) pre = "...";
+ if (ptr > pbeg) {
+ ptr = rb_enc_prev_char(pbeg, ptr, pt, rb_enc_get(str));
+ if (ptr > pbeg) pre = "...";
}
if (ptr_end < pend) {
- ptr_end = rb_enc_prev_char(pt, ptr_end, pend, rb_enc_get(p->lex.lastline));
+ ptr_end = rb_enc_prev_char(pt, ptr_end, pend, rb_enc_get(str));
if (ptr_end < pend) post = "...";
}
}
- pb = p->lex.pbeg;
- if (p->ruby_sourceline == yylloc->beg_pos.lineno) {
+ pb = pbeg;
+ if (lineno == yylloc->beg_pos.lineno) {
pb += yylloc->beg_pos.column;
if (pb > pt) pb = pt;
}
if (pb < ptr) pb = ptr;
if (len <= 4 && yylloc->beg_pos.lineno == yylloc->end_pos.lineno) {
- compile_error(p, "%s", msg);
+ return;
+ }
+ if (RTEST(errbuf)) {
+ mesg = rb_attr_get(errbuf, idMesg);
+ if (RSTRING_LEN(mesg) > 0 && *(RSTRING_END(mesg)-1) != '\n')
+ rb_str_cat_cstr(mesg, "\n");
}
- else if (!p->error_buffer && rb_stderr_tty_p()) {
+ else {
+ mesg = rb_enc_str_new(0, 0, rb_enc_get(str));
+ }
+ if (!errbuf && rb_stderr_tty_p()) {
#define CSI_BEGIN "\033["
#define CSI_SGR "m"
- compile_error(p, "%s\n"
- CSI_BEGIN""CSI_SGR"%s" /* pre */
- CSI_BEGIN"1"CSI_SGR"%.*s"
- CSI_BEGIN"1;4"CSI_SGR"%.*s"
- CSI_BEGIN";1"CSI_SGR"%.*s"
- CSI_BEGIN""CSI_SGR"%s" /* post */,
- msg, pre,
- (int)(pb - ptr), ptr,
- (int)(pt - pb), pb,
- (int)(ptr_end - pt), pt,
- post);
+ rb_str_catf(mesg,
+ CSI_BEGIN""CSI_SGR"%s" /* pre */
+ CSI_BEGIN"1"CSI_SGR"%.*s"
+ CSI_BEGIN"1;4"CSI_SGR"%.*s"
+ CSI_BEGIN";1"CSI_SGR"%.*s"
+ CSI_BEGIN""CSI_SGR"%s" /* post */
+ "\n",
+ pre,
+ (int)(pb - ptr), ptr,
+ (int)(pt - pb), pb,
+ (int)(ptr_end - pt), pt,
+ post);
}
else {
char *p2;
@@ -4761,19 +4790,28 @@ parser_yyerror(struct parser_params *p, const YYLTYPE *yylloc, const char *msg)
p2 += (lim - ptr);
}
*p2 = '\0';
- compile_error(p, "%s\n""%s%.*s%s\n""%s%s",
- msg,
- pre, (int)len, code, post,
- pre, caret);
+ rb_str_catf(mesg, "%s%.*s%s\n""%s%s",
+ pre, (int)len, code, post,
+ pre, caret);
}
+ if (!errbuf) rb_write_error_str(mesg);
+}
#else
+static int
+parser_yyerror(struct parser_params *p, const YYLTYPE *yylloc, const char *msg)
+{
dispatch1(parse_error, STR_NEW2(msg));
ripper_error(p);
token_flush(p);
-#endif /* !RIPPER */
return 0;
}
+static inline void
+parser_show_error_line(struct parser_params *p, const YYLTYPE *yylloc)
+{
+}
+#endif /* !RIPPER */
+
static int
vtable_size(const struct vtable *tbl)
{
@@ -5636,17 +5674,11 @@ regx_options(struct parser_params *p)
options |= kopt;
pushback(p, c);
if (toklen(p)) {
- static const char mesg[] = "unknown regexp options";
- static const char sep[] = " - ";
- const int mlen = (int)(sizeof(mesg) - 1 - (toklen(p) == 1));
- const int seplen = (int)(sizeof(sep) - 1);
YYLTYPE loc = RUBY_INIT_YYLLOC();
tokfix(p);
- tokspace(p, toklen(p) + mlen + seplen);
- memmove(tok(p) + mlen + seplen, tok(p), toklen(p) + 1);
- memcpy(tok(p), mesg, mlen);
- memcpy(tok(p) + mlen, sep, seplen);
- yyerror1(&loc, tok(p));
+ compile_error(p, "unknown regexp option%s - %*s",
+ toklen(p) > 1 ? "s" : "", toklen(p), tok(p));
+ parser_show_error_line(p, &loc);
}
return options | RE_OPTION_ENCODING(kcode);
}