diff options
author | Andy Cedilnik <andy.cedilnik@kitware.com> | 2002-10-09 02:00:11 (GMT) |
---|---|---|
committer | Andy Cedilnik <andy.cedilnik@kitware.com> | 2002-10-09 02:00:11 (GMT) |
commit | 8f63293056dd670849dcf205a6de56f48dfafe0d (patch) | |
tree | a62cc918b0a16766f94b22197ca21dbd91428b22 /Source/ctest.cxx | |
parent | 350eeeab4e3833ee12385dfacef34b8513b81fa5 (diff) | |
download | CMake-8f63293056dd670849dcf205a6de56f48dfafe0d.zip CMake-8f63293056dd670849dcf205a6de56f48dfafe0d.tar.gz CMake-8f63293056dd670849dcf205a6de56f48dfafe0d.tar.bz2 |
Add parsing of warnings and errors
Diffstat (limited to 'Source/ctest.cxx')
-rw-r--r-- | Source/ctest.cxx | 261 |
1 files changed, 259 insertions, 2 deletions
diff --git a/Source/ctest.cxx b/Source/ctest.cxx index 85d5a21..4a79b5e 100644 --- a/Source/ctest.cxx +++ b/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,8 +423,200 @@ 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, std::vector<std::string> &failed) { @@ -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 ++ ) |