From d8ef032e421c7485c8b2216ead65e5e23cab6b12 Mon Sep 17 00:00:00 2001 From: "Frank Ch. Eigler" Date: Thu, 23 Apr 2015 21:33:18 -0400 Subject: [PATCH] session.cxx: improve parse error token colorization Previous code had imperfect heuristics about cutting apart parts of erroneous source lines, with a colorized token in the middle. It could occur that the token was synthetic, or cmd-line $/@ based, in which case the srcline-cutting arithmetic could go off-end and cause a basic_string::substr: exception. New code dabbles less in heuristics and confirms that the token content actually matches the srcline content. In case of a mismatch, the original srcline around the token's location is transcribed verbatim (with ellipses). --- session.cxx | 35 +++++++++++++++++++++++------------ 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/session.cxx b/session.cxx index 587c77f1b..3753445cb 100644 --- a/session.cxx +++ b/session.cxx @@ -2117,18 +2117,29 @@ systemtap_session::print_error_source (std::ostream& message, //TRANSLATORS: Here we are printing the source string of the error message << align << _("source: "); string srcline = file_contents.substr(start_pos, end_pos-start_pos-1); - if (color_errors && - // Only colorize tokens whose content is known to match the source - // content. e.g. tok_string doesn't qualify because of the double-quotes. - // tok_embedded lacks the %{ %}. tok_junk is just junky. - (tok->type == tok_number || - tok->type == tok_identifier || - tok->type == tok_operator)) { - // Split into before token, token, and after token - string tok_content = tok->content; - message << srcline.substr(0, col-1); - message << colorize(tok_content, "token"); - message << srcline.substr(col+tok_content.size()-1) << endl; + if (color_errors) { + // before token: + message << srcline.substr(0, col-1); + // token: + // after token: + // ... hold it - the token might have been synthetic, + // or expanded from a $@ command line argument, or ... + // so tok->content may have nothing in common with the + // contents of srcline at the same point. + string srcline_rest = srcline.substr(col-1); + string srcline_tokenish = srcline_rest.substr(0, tok->content.size()); + if (srcline_tokenish == tok->content) { // oh good + message << colorize(tok->content, "token"); + message << srcline_rest.substr(tok->content.size()); + message << endl; + } + else { // oh bad + message << " ... "; + col += 5; // line up with the caret + message << colorize(tok->content, "token"); + message << " ... " << srcline_rest; + message << endl; + } } else message << srcline << endl; message << align << " "; -- 2.43.5