@@ -444,15 +444,15 @@ static std::string readCode(const std::string &file, unsigned int linenr, unsign
444444 const std::string::size_type endPos = line.find_last_not_of (" \r\n\t " );
445445 if (endPos + 1 < line.size ())
446446 line.erase (endPos + 1 );
447- return line + endl + std::string (column, ' ' ) + ' ^' ;
447+ return line + endl + std::string (( column> 0 ? column- 1 : column), ' ' ) + ' ^' ;
448448}
449449
450- std::string ErrorLogger::ErrorMessage::toString (bool verbose, const std::string &outputFormat ) const
450+ std::string ErrorLogger::ErrorMessage::toString (bool verbose, const std::string &templateFormat, const std::string &templateLocation ) const
451451{
452452 // Save this ErrorMessage in plain text.
453453
454454 // No template is given
455- if (outputFormat .empty ()) {
455+ if (templateFormat .empty ()) {
456456 std::ostringstream text;
457457 if (!_callStack.empty ())
458458 text << callStackToString (_callStack) << " : " ;
@@ -466,76 +466,77 @@ std::string ErrorLogger::ErrorMessage::toString(bool verbose, const std::string
466466 return text.str ();
467467 }
468468
469- else if (outputFormat == " daca2" ) {
470- // This is a clang-like output format for daca2
471- std::ostringstream text;
472- if (_callStack.empty ()) {
473- text << " nofile:0:0: " ;
474- } else {
475- const ErrorLogger::ErrorMessage::FileLocation &loc = _callStack.back ();
476- text << loc.getfile () << ' :' << loc.line << ' :' << loc.col << " : " ;
469+ // template is given. Reformat the output according to it
470+ std::string result = templateFormat;
471+ // Support a few special characters to allow to specific formatting, see http://sourceforge.net/apps/phpbb/cppcheck/viewtopic.php?f=4&t=494&sid=21715d362c0dbafd3791da4d9522f814
472+ // Substitution should be done first so messages from cppcheck never get translated.
473+ findAndReplace (result, " \\ b" , " \b " );
474+ findAndReplace (result, " \\ n" , " \n " );
475+ findAndReplace (result, " \\ r" , " \r " );
476+ findAndReplace (result, " \\ t" , " \t " );
477+
478+ findAndReplace (result, " {id}" , _id);
479+ if (result.find (" {inconclusive:" ) != std::string::npos) {
480+ const std::string::size_type pos1 = result.find (" {inconclusive:" );
481+ const std::string::size_type pos2 = result.find (" }" , pos1+1 );
482+ const std::string replaceFrom = result.substr (pos1,pos2-pos1+1 );
483+ const std::string replaceWith = result.substr (pos1+14 , pos2-pos1-14 );
484+ findAndReplace (result, replaceFrom, replaceWith);
485+ }
486+ findAndReplace (result, " {severity}" , Severity::toString (_severity));
487+ findAndReplace (result, " {message}" , verbose ? _verboseMessage : _shortMessage);
488+ findAndReplace (result, " {callstack}" , _callStack.empty () ? emptyString : callStackToString (_callStack));
489+ if (!_callStack.empty ()) {
490+ findAndReplace (result, " {file}" , _callStack.back ().getfile ());
491+ findAndReplace (result, " {line}" , MathLib::toString (_callStack.back ().line ));
492+ findAndReplace (result, " {column}" , MathLib::toString (_callStack.back ().col ));
493+ if (result.find (" {code}" ) != std::string::npos) {
494+ const std::string::size_type pos = result.find (" \r " );
495+ const char *endl;
496+ if (pos == std::string::npos)
497+ endl = " \n " ;
498+ else if (pos+1 < result.size () && result[pos+1 ] == ' \n ' )
499+ endl = " \r\n " ;
500+ else
501+ endl = " \r " ;
502+ findAndReplace (result, " {code}" , readCode (_callStack.back ().getfile (), _callStack.back ().line , _callStack.back ().col , endl));
477503 }
478-
479- if (_inconclusive)
480- text << " inconclusive " ;
481- text << Severity::toString (_severity) << " : " ;
482-
483- text << (verbose ? _verboseMessage : _shortMessage)
484- << " [" << _id << ' ]' ;
485-
486- if (_callStack.size () <= 1U )
487- return text.str ();
488-
489- for (std::list<FileLocation>::const_iterator loc = _callStack.begin (); loc != _callStack.end (); ++loc)
490- text << std::endl
491- << loc->getfile ()
492- << ' :'
493- << loc->line
494- << ' :'
495- << loc->col
496- << " : note: "
497- << (loc->getinfo ().empty () ? _shortMessage : loc->getinfo ());
498- return text.str ();
504+ } else {
505+ findAndReplace (result, " {file}" , " nofile" );
506+ findAndReplace (result, " {line}" , " 0" );
507+ findAndReplace (result, " {column}" , " 0" );
508+ findAndReplace (result, " {code}" , emptyString);
499509 }
500510
501- // template is given. Reformat the output according to it
502- else {
503- std::string result = outputFormat;
504- // Support a few special characters to allow to specific formatting, see http://sourceforge.net/apps/phpbb/cppcheck/viewtopic.php?f=4&t=494&sid=21715d362c0dbafd3791da4d9522f814
505- // Substitution should be done first so messages from cppcheck never get translated.
506- findAndReplace (result, " \\ b" , " \b " );
507- findAndReplace (result, " \\ n" , " \n " );
508- findAndReplace (result, " \\ r" , " \r " );
509- findAndReplace (result, " \\ t" , " \t " );
510-
511- findAndReplace (result, " {id}" , _id);
512- findAndReplace (result, " {severity}" , Severity::toString (_severity));
513- findAndReplace (result, " {message}" , verbose ? _verboseMessage : _shortMessage);
514- findAndReplace (result, " {callstack}" , _callStack.empty () ? emptyString : callStackToString (_callStack));
515- if (!_callStack.empty ()) {
516- findAndReplace (result, " {file}" , _callStack.back ().getfile ());
517- findAndReplace (result, " {line}" , MathLib::toString (_callStack.back ().line ));
518- findAndReplace (result, " {column}" , MathLib::toString (_callStack.back ().col ));
519- if (result.find (" {code}" ) != std::string::npos) {
520- const std::string::size_type pos = result.find (" \r " );
511+ if (!templateLocation.empty () && _callStack.size () >= 2U ) {
512+ for (const FileLocation &fileLocation : _callStack) {
513+ std::string text = templateLocation;
514+
515+ findAndReplace (text, " \\ b" , " \b " );
516+ findAndReplace (text, " \\ n" , " \n " );
517+ findAndReplace (text, " \\ r" , " \r " );
518+ findAndReplace (text, " \\ t" , " \t " );
519+
520+ findAndReplace (text, " {file}" , fileLocation.getfile ());
521+ findAndReplace (text, " {line}" , MathLib::toString (fileLocation.line ));
522+ findAndReplace (text, " {column}" , MathLib::toString (fileLocation.col ));
523+ findAndReplace (text, " {info}" , fileLocation.getinfo ().empty () ? _shortMessage : fileLocation.getinfo ());
524+ if (text.find (" {code}" ) != std::string::npos) {
525+ const std::string::size_type pos = text.find (" \r " );
521526 const char *endl;
522527 if (pos == std::string::npos)
523528 endl = " \n " ;
524- else if (pos+1 < result .size () && result [pos+1 ] == ' \n ' )
529+ else if (pos+1 < text .size () && text [pos+1 ] == ' \n ' )
525530 endl = " \r\n " ;
526531 else
527532 endl = " \r " ;
528- findAndReplace (result , " {code}" , readCode (_callStack. back (). getfile (), _callStack. back (). line , _callStack. back () .col , endl));
533+ findAndReplace (text , " {code}" , readCode (fileLocation. getfile (), fileLocation. line , fileLocation .col , endl));
529534 }
530- } else {
531- findAndReplace (result, " {file}" , emptyString);
532- findAndReplace (result, " {line}" , emptyString);
533- findAndReplace (result, " {column}" , emptyString);
534- findAndReplace (result, " {code}" , emptyString);
535+ result += ' \n ' + text;
535536 }
536-
537- return result;
538537 }
538+
539+ return result;
539540}
540541
541542void ErrorLogger::reportUnmatchedSuppressions (const std::list<Suppressions::Suppression> &unmatched)
0 commit comments