Add parsing of warnings and errors
This commit is contained in:
parent
350eeeab4e
commit
8f63293056
261
Source/ctest.cxx
261
Source/ctest.cxx
|
@ -18,6 +18,8 @@
|
|||
#include "cmRegularExpression.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
#include <strstream>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
|
@ -42,6 +44,70 @@ static std::string CurrentTime()
|
|||
return ::CleanString(ctime(¤ttime));
|
||||
}
|
||||
|
||||
static const char* cmCTestErrorMatches[] = {
|
||||
"^[Bb]us [Ee]rror",
|
||||
"^[Ss]egmentation [Vv]iolation",
|
||||
"^[Ss]egmentation [Ff]ault",
|
||||
"([^ :]+):([0-9]+): ([^ \\t])",
|
||||
"([^:]+): error[ \\t]*[0-9]+[ \\t]*:",
|
||||
"^Error ([0-9]+):",
|
||||
"^Error ",
|
||||
"^\"[^\"]+\", line [0-9]+: [^Ww]",
|
||||
"^cc[^C]*CC: ERROR File = ([^,]+), Line = ([0-9]+)",
|
||||
"^ld([^:])*:([ \\t])*ERROR([^:])*:",
|
||||
"^ild:([ \\t])*\\(undefined symbol\\)",
|
||||
"([^ :]+) : (error|fatal error|catastrophic error)",
|
||||
"([^:]+): (Error:|error|undefined reference|multiply defined)",
|
||||
"([^:]+)\\(([^\\)]+)\\) : (error|fatal error|catastrophic error)",
|
||||
"^fatal error C[0-9]+:",
|
||||
": syntax error ",
|
||||
"^collect2: ld returned 1 exit status",
|
||||
"Unsatisfied symbols:",
|
||||
"Undefined symbols:",
|
||||
"^Undefined[ \\t]+first referenced",
|
||||
"^CMake Error:",
|
||||
":[ \\t]cannot find",
|
||||
0
|
||||
};
|
||||
|
||||
static const char* cmCTestErrorExceptions[] = {
|
||||
0
|
||||
};
|
||||
|
||||
static const char* cmCTestWarningMatches[] = {
|
||||
"([^ :]+):([0-9]+): warning:",
|
||||
"^cc[^C]*CC: WARNING File = ([^,]+), Line = ([0-9]+)",
|
||||
"^ld([^:])*:([ \\t])*WARNING([^:])*:",
|
||||
"([^:]+): warning ([0-9]+):",
|
||||
"^\"[^\"]+\", line [0-9]+: [Ww]arning",
|
||||
"([^:]+): warning[ \\t]*[0-9]+[ \\t]*:",
|
||||
"^Warning ([0-9]+):",
|
||||
"^Warning ",
|
||||
"([^ :]+) : warning",
|
||||
"([^:]+): warning",
|
||||
0
|
||||
};
|
||||
|
||||
static const char* cmCTestWarningExceptions[] = {
|
||||
"/usr/openwin/include/X11/Xlib\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
|
||||
"/usr/openwin/include/X11/Xutil\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
|
||||
"/usr/openwin/include/X11/XResource\\.h:[0-9]+: warning: ANSI C\\+\\+ forbids declaration",
|
||||
"WARNING 84 :",
|
||||
"WARNING 47 :",
|
||||
"makefile:",
|
||||
"Makefile:",
|
||||
"warning: Clock skew detected. Your build may be incomplete.",
|
||||
"/usr/openwin/include/GL/[^:]+:",
|
||||
"bind_at_load",
|
||||
"XrmQGetResource",
|
||||
"IceFlush",
|
||||
"warning LNK4089: all references to .GDI32.dll. discarded by .OPT:REF",
|
||||
"warning LNK4089: all references to .USER32.dll. discarded by .OPT:REF",
|
||||
"ld32: WARNING 85: definition of dataKey in",
|
||||
0
|
||||
};
|
||||
|
||||
|
||||
bool TryExecutable(const char *dir, const char *file,
|
||||
std::string *fullPath, const char *subdir)
|
||||
{
|
||||
|
@ -357,6 +423,198 @@ void ctest::BuildDirectory()
|
|||
}
|
||||
// To do:
|
||||
// Add parsing of output for errors and warnings.
|
||||
|
||||
cmCTestBuildErrorWarning cerw;
|
||||
char* coutput = new char[ output.size() + 1];
|
||||
memcpy(coutput, output.c_str(), output.size());
|
||||
int cc;
|
||||
|
||||
std::vector<std::string> lines;
|
||||
|
||||
// Lines are marked:
|
||||
// 0 - nothing
|
||||
// 1 - error
|
||||
// > 1 - warning
|
||||
std::vector<int> markedLines;
|
||||
std::istrstream istr(coutput);
|
||||
while(istr)
|
||||
{
|
||||
char buffer[1024];
|
||||
std::string line;
|
||||
while ( istr )
|
||||
{
|
||||
buffer[0] = 0;
|
||||
istr.getline(buffer, 1023);
|
||||
buffer[1023] = 0;
|
||||
line += buffer;
|
||||
if ( strlen(buffer) < 1023 )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
lines.push_back(line);
|
||||
markedLines.push_back(0);
|
||||
//std::cout << "Line [" << line << "]" << std::endl;
|
||||
}
|
||||
|
||||
// Errors
|
||||
for ( cc = 0; cmCTestErrorMatches[cc]; cc ++ )
|
||||
{
|
||||
cmRegularExpression re(cmCTestErrorMatches[cc]);
|
||||
std::vector<std::string>::size_type kk;
|
||||
for ( kk = 0; kk < lines.size(); kk ++ )
|
||||
{
|
||||
if ( re.find(lines[kk]) )
|
||||
{
|
||||
markedLines[kk] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Warnings
|
||||
for ( cc = 0; cmCTestWarningMatches[cc]; cc ++ )
|
||||
{
|
||||
cmRegularExpression re(cmCTestWarningMatches[cc]);
|
||||
std::vector<std::string>::size_type kk;
|
||||
for ( kk = 0; kk < lines.size(); kk ++ )
|
||||
{
|
||||
if ( re.find(lines[kk]) )
|
||||
{
|
||||
markedLines[kk] += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( cc = 0; cmCTestErrorExceptions[cc]; cc ++ )
|
||||
{
|
||||
cmRegularExpression re(cmCTestErrorExceptions[cc]);
|
||||
std::vector<int>::size_type kk;
|
||||
for ( kk =0; kk < markedLines.size(); kk ++ )
|
||||
{
|
||||
if ( markedLines[cc] == 1 )
|
||||
{
|
||||
if ( re.find(lines[kk]) )
|
||||
{
|
||||
markedLines[cc] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for ( cc = 0; cmCTestWarningExceptions[cc]; cc ++ )
|
||||
{
|
||||
cmRegularExpression re(cmCTestWarningExceptions[cc]);
|
||||
std::vector<int>::size_type kk;
|
||||
for ( kk =0; kk < markedLines.size(); kk ++ )
|
||||
{
|
||||
if ( markedLines[cc] > 1 )
|
||||
{
|
||||
if ( re.find(lines[kk]) )
|
||||
{
|
||||
markedLines[cc] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
std::vector<cmCTestBuildErrorWarning> errorsWarnings;
|
||||
|
||||
std::vector<int>::size_type kk;
|
||||
cmCTestBuildErrorWarning errorwarning;
|
||||
for ( kk =0; kk < markedLines.size(); kk ++ )
|
||||
{
|
||||
bool found = false;
|
||||
if ( markedLines[kk] == 1 )
|
||||
{
|
||||
std::cout << "Error: " << lines[kk] << std::endl;
|
||||
errorwarning.m_Error = true;
|
||||
found = true;
|
||||
}
|
||||
else if ( markedLines[kk] > 1 )
|
||||
{
|
||||
std::cout << "Warning: " << lines[kk] << std::endl;
|
||||
errorwarning.m_Error = false;
|
||||
found = true;
|
||||
}
|
||||
if ( found )
|
||||
{
|
||||
errorwarning.m_LogLine = kk;
|
||||
errorwarning.m_Text = lines[kk];
|
||||
errorwarning.m_PreContext = "";
|
||||
errorwarning.m_PostContext = "";
|
||||
std::vector<int>::size_type jj;
|
||||
for ( jj = kk;
|
||||
jj > 0 && jj > kk - 6 /* && markedLines[jj] == 0 */;
|
||||
jj -- );
|
||||
for (; jj < kk; jj ++ )
|
||||
{
|
||||
errorwarning.m_PreContext += lines[jj] + "\n";
|
||||
}
|
||||
for ( jj = kk+1;
|
||||
jj < lines.size() && jj < kk + 6 /* && markedLines[jj] == 0*/;
|
||||
jj ++ )
|
||||
{
|
||||
errorwarning.m_PostContext += lines[jj] + "\n";
|
||||
}
|
||||
errorsWarnings.push_back(errorwarning);
|
||||
}
|
||||
}
|
||||
/*
|
||||
this->GenerateDartBuildOutput(std::cout,
|
||||
errorsWarnings);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void ctest::GenerateDartBuildOutput(std::ostream& os,
|
||||
std::vector<cmCTestBuildErrorWarning> ew)
|
||||
{
|
||||
time_t tctime = time(0);
|
||||
struct tm *lctime = gmtime(&tctime);
|
||||
char datestring[100];
|
||||
sprintf(datestring, "%4d%02d%02d-%d%d",
|
||||
lctime->tm_year + 1900,
|
||||
lctime->tm_mon,
|
||||
lctime->tm_mday,
|
||||
lctime->tm_hour,
|
||||
lctime->tm_min);
|
||||
|
||||
os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
<< "<Site BuildName=\"" << m_DartConfiguration["BuildName"]
|
||||
<< "\" BuildStamp=\"" << datestring << "-Experimental\" Name=\""
|
||||
<< m_DartConfiguration["Site"] << "\">\n"
|
||||
<< "<Build>\n"
|
||||
<< " <StartDateTime>" << ::CurrentTime() << "</StartDateTime>\n"
|
||||
<< " <BuildCommand>" << m_DartConfiguration["MakeCommand"]
|
||||
<< "</BuildCommand>" << std::endl;
|
||||
|
||||
std::vector<cmCTestBuildErrorWarning>::iterator it;
|
||||
for ( it = ew.begin(); it != ew.end(); it++ )
|
||||
{
|
||||
cmCTestBuildErrorWarning *cm = &(*it);
|
||||
os << " <" << (cm->m_Error ? "Error" : "Warning") << ">\n"
|
||||
<< " <BuildLogLine>" << cm->m_LogLine << "</BuildLogLine>\n"
|
||||
<< " <Text>" << cm->m_Text << "</Text>" << std::endl;
|
||||
if ( cm->m_SourceFile.size() > 0 )
|
||||
{
|
||||
os << " <SourceFile>" << cm->m_SourceFile << "</SourceFile>"
|
||||
<< std::endl;
|
||||
}
|
||||
if ( cm->m_SourceFileTail.size() > 0 )
|
||||
{
|
||||
os << " <SourceFileTail>" << cm->m_SourceFileTail
|
||||
<< "</SourceFileTail>" << std::endl;
|
||||
}
|
||||
if ( cm->m_LineNumber >= 0 )
|
||||
{
|
||||
os << " <SourceLineNumber>" << cm->m_LineNumber
|
||||
<< "</SourceLineNumber>" << std::endl;
|
||||
}
|
||||
os << " <PreContext>" << cm->m_PreContext << "</PreContext>\n"
|
||||
<< " <PostContext>" << cm->m_PostContext << "</PostContext>\n"
|
||||
<< " </" << (cm->m_Error ? "Error" : "Warning") << ">"
|
||||
<< std::endl;
|
||||
}
|
||||
os << " <Log Encoding=\"base64\" Compression=\"/bin/gzip\">\n </Log>\n"
|
||||
<< " <EndDateTime>" << ::CurrentTime() << "</EndDateTime>\n"
|
||||
<< "</Build>\n"
|
||||
<< "</Site>" << std::endl;
|
||||
}
|
||||
|
||||
void ctest::ProcessDirectory(std::vector<std::string> &passed,
|
||||
|
@ -547,13 +805,12 @@ void ctest::GenerateDartOutput(std::ostream& os)
|
|||
lctime->tm_hour,
|
||||
lctime->tm_min);
|
||||
|
||||
os << "Try to create dart output file" << std::endl;
|
||||
os << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
|
||||
<< "<Site BuildName=\"" << m_DartConfiguration["BuildName"]
|
||||
<< "\" BuildStamp=\"" << datestring << "-Experimental\" Name=\""
|
||||
<< m_DartConfiguration["Site"] << "\">\n"
|
||||
<< "<Testing>\n"
|
||||
<< " <StartDateTime>" << ::CurrentTime() << " </StartDateTime>\n"
|
||||
<< " <StartDateTime>" << ::CurrentTime() << "</StartDateTime>\n"
|
||||
<< " <TestList>\n";
|
||||
tm_TestResultsVector::size_type cc;
|
||||
for ( cc = 0; cc < m_TestResults.size(); cc ++ )
|
||||
|
|
|
@ -60,11 +60,6 @@ public:
|
|||
void ProcessDirectory(std::vector<std::string> &passed,
|
||||
std::vector<std::string> &failed);
|
||||
|
||||
/**
|
||||
* Generate the Dart compatible output
|
||||
*/
|
||||
void GenerateDartOutput(std::ostream& os);
|
||||
|
||||
/**
|
||||
* Find the executable for a test
|
||||
*/
|
||||
|
@ -115,6 +110,18 @@ private:
|
|||
std::string m_Output;
|
||||
};
|
||||
|
||||
struct cmCTestBuildErrorWarning
|
||||
{
|
||||
bool m_Error;
|
||||
int m_LogLine;
|
||||
std::string m_Text;
|
||||
std::string m_SourceFile;
|
||||
std::string m_SourceFileTail;
|
||||
int m_LineNumber;
|
||||
std::string m_PreContext;
|
||||
std::string m_PostContext;
|
||||
};
|
||||
|
||||
typedef std::vector<cmCTestTestResult> tm_TestResultsVector;
|
||||
typedef std::map<std::string, std::string> tm_DartConfigurationMap;
|
||||
|
||||
|
@ -122,5 +129,14 @@ private:
|
|||
std::string m_ToplevelPath;
|
||||
tm_DartConfigurationMap m_DartConfiguration;
|
||||
int m_Tests[LAST_TEST];
|
||||
|
||||
|
||||
/**
|
||||
* Generate the Dart compatible output
|
||||
*/
|
||||
void GenerateDartOutput(std::ostream& os);
|
||||
void GenerateDartBuildOutput(std::ostream& os,
|
||||
std::vector<cmCTestBuildErrorWarning>);
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue