diff options
Diffstat (limited to 'Source')
-rw-r--r-- | Source/CMakeLists.txt | 1 | ||||
-rw-r--r-- | Source/CTest/cmCTestBuildHandler.cxx | 453 | ||||
-rw-r--r-- | Source/CTest/cmCTestBuildHandler.h | 81 | ||||
-rw-r--r-- | Source/cmCTest.cxx | 401 | ||||
-rw-r--r-- | Source/cmCTest.h | 33 |
5 files changed, 549 insertions, 420 deletions
diff --git a/Source/CMakeLists.txt b/Source/CMakeLists.txt index d7372ac..8b51866 100644 --- a/Source/CMakeLists.txt +++ b/Source/CMakeLists.txt @@ -110,6 +110,7 @@ ADD_EXECUTABLE(cmake cmakemain.cxx) ADD_EXECUTABLE(DumpDocumentation cmDumpDocumentation) SET(CMTEST_SRCS ctest.cxx cmCTest.cxx + CTest/cmCTestBuildHandler.cxx CTest/cmCTestScriptHandler.cxx CTest/cmCTestUpdateHandler.cxx CTest/cmCTestConfigureHandler.cxx diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx new file mode 100644 index 0000000..38d19ad --- /dev/null +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -0,0 +1,453 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#include "cmCTestBuildHandler.h" + +#include "cmCTest.h" +#include "cmake.h" +#include "cmMakefile.h" +#include "cmLocalGenerator.h" +#include "cmGlobalGenerator.h" + +//#include <cmsys/RegularExpression.hxx> +#include <cmsys/Process.h> + +// used for sleep +#ifdef _WIN32 +#include "windows.h" +#endif + +#include <stdlib.h> +#include <time.h> +#include <math.h> +#include <float.h> + + +//---------------------------------------------------------------------- +cmCTestBuildHandler::cmCTestBuildHandler() +{ + m_Verbose = false; + m_CTest = 0; +} + +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]+):", + "^Fatal", + "^Error: ", + "^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:", + "^Unresolved:", + "Undefined symbols:", + "^Undefined[ \\t]+first referenced", + "^CMake Error:", + ":[ \\t]cannot find", + ":[ \\t]can't find", + ": \\*\\*\\* No rule to make target \\`.*\\'. Stop", + ": Invalid loader fixup for symbol", + ": internal link edit command failed", + ": Unrecognized option \\`.*\\'", + "\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\([^W]\\)", + "ld: 0706-006 Cannot find or open library file: -l ", + "ild: \\(argument error\\) can't find library argument ::", + "^could not be found and will not be loaded.", + "s:616 string too big", + "make: Fatal error: ", + "ld: 0711-993 Error occurred while writing to the output file:", + "make: \\*\\*\\*.*Error", + 0 +}; + +static const char* cmCTestErrorExceptions[] = { + "instantiated from ", + "candidates are:", + ": warning", + "makefile:", + "Makefile:", + ":[ \\t]+Where:", + "([^ :]+):([0-9]+): Warning", + 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", + "([^:]+): warning", + "\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\(W\\)", + "^cxx: Warning:", + ".*file: .* has no symbols", + "([^ :]+):([0-9]+): 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 [^ \\t]+ discarded by .OPT:REF", + "ld32: WARNING 85: definition of dataKey in", + "cc: warning 422: Unknown option \"\\+b", + "_with_warning_C", + 0 +}; + + +//---------------------------------------------------------------------- +void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile *mf) +{ + cmCTest::PopulateCustomVector(mf, "CTEST_CUSTOM_ERROR_MATCH", + m_CustomErrorMatches); + cmCTest::PopulateCustomVector(mf, "CTEST_CUSTOM_ERROR_EXCEPTION", + m_CustomErrorExceptions); + cmCTest::PopulateCustomVector(mf, "CTEST_CUSTOM_WARNING_MATCH", + m_CustomWarningMatches); + cmCTest::PopulateCustomVector(mf, "CTEST_CUSTOM_WARNING_EXCEPTION", + m_CustomWarningExceptions); +} + +//---------------------------------------------------------------------- +//clearly it would be nice if this were broken up into a few smaller +//functions and commented... +int cmCTestBuildHandler::BuildDirectory(cmCTest *ctest_inst) +{ + m_CTest = ctest_inst; + + std::cout << "Build project" << std::endl; + std::string makeCommand = m_CTest->GetDartConfiguration("MakeCommand"); + if ( makeCommand.size() == 0 ) + { + std::cerr << "Cannot find MakeCommand key in the DartConfiguration.tcl" << std::endl; + return 1; + } + std::string buildDirectory = m_CTest->GetDartConfiguration("BuildDirectory"); + if ( buildDirectory.size() == 0 ) + { + std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl; + return 1; + } + + std::ofstream ofs; + double elapsed_time_start = cmSystemTools::GetTime(); + if ( !m_CTest->OpenOutputFile("Temporary", "LastBuild.log", ofs) ) + { + std::cerr << "Cannot create LastBuild.log file" << std::endl; + } + m_StartBuild = m_CTest->CurrentTime(); + std::string output; + int retVal = 0; + int res = cmsysProcess_State_Exited; + if ( !m_CTest->GetShowOnly() ) + { + res = m_CTest->RunMakeCommand(makeCommand.c_str(), &output, + &retVal, buildDirectory.c_str(), + m_Verbose, 0, ofs); + } + else + { + std::cout << "Build with command: " << makeCommand << std::endl; + } + m_EndBuild = m_CTest->CurrentTime(); + double elapsed_build_time = cmSystemTools::GetTime() - elapsed_time_start; + if (res != cmsysProcess_State_Exited || retVal ) + { + std::cerr << "Error(s) when building project" << std::endl; + } + if ( ofs ) + { + ofs.close(); + } + + std::vector<cmStdString>::size_type cc; + if ( m_CTest->GetDartConfiguration("SourceDirectory").size() > 20 || + m_CTest->GetDartConfiguration("BuildDirectory").size() > 20 ) + { + std::string srcdir = m_CTest->GetDartConfiguration("SourceDirectory") + "/"; + std::string bindir = m_CTest->GetDartConfiguration("BuildDirectory") + "/"; + std::string srcdirrep; + std::string bindirrep; + for ( cc = srcdir.size()-2; cc > 0; cc -- ) + { + if ( srcdir[cc] == '/' ) + { + srcdirrep = srcdir.c_str() + cc; + srcdirrep = "/..." + srcdirrep; + srcdir = srcdir.substr(0, cc+1); + break; + } + } + for ( cc = bindir.size()-2; cc > 0; cc -- ) + { + if ( bindir[cc] == '/' ) + { + bindirrep = bindir.c_str() + cc; + bindirrep = "/..." + bindirrep; + bindir = bindir.substr(0, cc+1); + break; + } + } + + cmSystemTools::ReplaceString(output, srcdir.c_str(), "/.../"); //srcdirrep.c_str()); + cmSystemTools::ReplaceString(output, bindir.c_str(), "/.../"); //bindirrep.c_str()); + } + + // Parsing of output for errors and warnings. + + std::vector<cmStdString> lines; + cmSystemTools::Split(output.c_str(), lines); + + + // Lines are marked: + // 0 - nothing + // 1 - error + // > 1 - warning + std::vector<int> markedLines(lines.size(), 0); + + // Errors + for ( cc = 0; cmCTestErrorMatches[cc]; cc ++ ) + { + m_CustomErrorMatches.push_back(cmCTestErrorMatches[cc]); + } + for ( cc = 0; cmCTestErrorExceptions[cc]; cc ++ ) + { + m_CustomErrorExceptions.push_back(cmCTestErrorExceptions[cc]); + } + for ( cc = 0; cmCTestWarningMatches[cc]; cc ++ ) + { + m_CustomWarningMatches.push_back(cmCTestWarningMatches[cc]); + } + for ( cc = 0; cmCTestWarningExceptions[cc]; cc ++ ) + { + m_CustomWarningExceptions.push_back(cmCTestWarningExceptions[cc]); + } + + for ( cc = 0; cc < m_CustomErrorMatches.size(); cc ++ ) + { + cmsys::RegularExpression re(m_CustomErrorMatches[cc].c_str()); + std::vector<cmStdString>::size_type kk; + for ( kk = 0; kk < lines.size(); kk ++ ) + { + if ( re.find(lines[kk]) ) + { + markedLines[kk] = 1; + } + } + } + // Warnings + for ( cc = 0; cc < m_CustomWarningMatches.size(); cc ++ ) + { + cmsys::RegularExpression re(m_CustomWarningMatches[cc].c_str()); + std::vector<cmStdString>::size_type kk; + for ( kk = 0; kk < lines.size(); kk ++ ) + { + if ( re.find(lines[kk]) ) + { + markedLines[kk] += 2; + } + } + } + // Errors exceptions + for ( cc = 0; cc < m_CustomErrorExceptions.size(); cc ++ ) + { + cmsys::RegularExpression re(m_CustomErrorExceptions[cc].c_str()); + std::vector<int>::size_type kk; + for ( kk =0; kk < markedLines.size(); kk ++ ) + { + if ( markedLines[kk] == 1 ) + { + if ( re.find(lines[kk]) ) + { + markedLines[kk] = 0; + } + } + } + } + // Warning exceptions + for ( cc = 0; cc < m_CustomWarningExceptions.size(); cc ++ ) + { + cmsys::RegularExpression re(m_CustomWarningExceptions[cc].c_str()); + std::vector<int>::size_type kk; + for ( kk =0; kk < markedLines.size(); kk ++ ) + { + if ( markedLines[kk] > 1 ) + { + if ( re.find(lines[kk]) ) + { + markedLines[kk] = 0; + } + } + } + } + std::vector<cmCTestBuildErrorWarning> errorsWarnings; + + int errors = 0; + int warnings = 0; + + std::vector<int>::size_type kk; + cmCTestBuildErrorWarning errorwarning; + for ( kk =0; kk < markedLines.size(); kk ++ ) + { + errorwarning.m_LineNumber = -1; + 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 = static_cast<int>(kk+1); + errorwarning.m_Text = lines[kk]; + errorwarning.m_PreContext = ""; + errorwarning.m_PostContext = ""; + std::vector<int>::size_type jj; + std::vector<int>::size_type ll = 0; + if ( kk > 6 ) + { + ll = kk - 6; + } + for ( jj = kk-1; + jj > 0 && jj > ll && markedLines[jj] != markedLines[kk]; + jj -- ); + while ( markedLines[jj] == markedLines[kk] && jj < kk ) + { + jj ++; + } + for (; jj < kk; jj ++ ) + { + errorwarning.m_PreContext += lines[jj] + "\n"; + } + for ( jj = kk+1; + jj < lines.size() && jj < kk + 7 && markedLines[jj] != markedLines[kk]; + jj ++ ) + { + errorwarning.m_PostContext += lines[jj] + "\n"; + } + errorsWarnings.push_back(errorwarning); + if ( errorwarning.m_Error ) + { + errors ++; + } + else + { + warnings ++; + } + } + } + + std::cout << " " << errors << " Compiler errors" << std::endl; + std::cout << " " << warnings << " Compiler warnings" << std::endl; + + if( !m_CTest->OpenOutputFile(m_CTest->GetCurrentTag(), "Build.xml", ofs) ) + { + std::cerr << "Cannot create build XML file" << std::endl; + return 1; + } + this->GenerateDartBuildOutput(ofs, errorsWarnings, elapsed_build_time); + return 0; +} + + +void cmCTestBuildHandler::GenerateDartBuildOutput( + std::ostream& os, + std::vector<cmCTestBuildErrorWarning> ew, + double elapsed_build_time) +{ + m_CTest->StartXML(os); + os << "<Build>\n" + << "\t<StartDateTime>" << m_StartBuild << "</StartDateTime>\n" + << "<BuildCommand>" + << m_CTest->MakeXMLSafe(m_CTest->GetDartConfiguration("MakeCommand")) + << "</BuildCommand>" << std::endl; + + std::vector<cmCTestBuildErrorWarning>::iterator it; + for ( it = ew.begin(); it != ew.end(); it++ ) + { + cmCTestBuildErrorWarning *cm = &(*it); + os << "\t<" << (cm->m_Error ? "Error" : "Warning") << ">\n" + << "\t\t<BuildLogLine>" << cm->m_LogLine << "</BuildLogLine>\n" + << "\t\t<Text>" << m_CTest->MakeXMLSafe(cm->m_Text) + << "\n</Text>" << std::endl; + if ( cm->m_SourceFile.size() > 0 ) + { + os << "\t\t<SourceFile>" << cm->m_SourceFile << "</SourceFile>" + << std::endl; + } + if ( cm->m_SourceFileTail.size() > 0 ) + { + os << "\t\t<SourceFileTail>" << cm->m_SourceFileTail + << "</SourceFileTail>" << std::endl; + } + if ( cm->m_LineNumber >= 0 ) + { + os << "\t\t<SourceLineNumber>" << cm->m_LineNumber + << "</SourceLineNumber>" << std::endl; + } + os << "\t\t<PreContext>" << m_CTest->MakeXMLSafe(cm->m_PreContext) + << "</PreContext>\n" + << "\t\t<PostContext>" << m_CTest->MakeXMLSafe(cm->m_PostContext) + << "</PostContext>\n" + << "\t\t<RepeatCount>0</RepeatCount>\n" + << "</" << (cm->m_Error ? "Error" : "Warning") << ">\n\n" + << std::endl; + } + os << "\t<Log Encoding=\"base64\" Compression=\"/bin/gzip\">\n\t</Log>\n" + << "\t<EndDateTime>" << m_EndBuild << "</EndDateTime>\n" + << "<ElapsedMinutes>" << static_cast<int>(elapsed_build_time/6)/10.0 + << "</ElapsedMinutes>" + << "</Build>" << std::endl; + m_CTest->EndXML(os); +} + diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h new file mode 100644 index 0000000..ec4c14f --- /dev/null +++ b/Source/CTest/cmCTestBuildHandler.h @@ -0,0 +1,81 @@ +/*========================================================================= + + Program: CMake - Cross-Platform Makefile Generator + Module: $RCSfile$ + Language: C++ + Date: $Date$ + Version: $Revision$ + + Copyright (c) 2002 Kitware, Inc. All rights reserved. + See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details. + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ + +#ifndef cmCTestBuildHandler_h +#define cmCTestBuildHandler_h + + +#include "cmStandardIncludes.h" +#include "cmListFileCache.h" + +class cmCTest; +class cmMakefile; + +/** \class cmCTestBuildHandler + * \brief A class that handles ctest -S invocations + * + */ +class cmCTestBuildHandler +{ +public: + + /* + * The main entry point for this class + */ + int BuildDirectory(cmCTest *); + + /* + * If verbose then more informaiton is printed out + */ + void SetVerbose(bool val) { m_Verbose = val; } + + cmCTestBuildHandler(); + + void PopulateCustomVectors(cmMakefile *mf); + +private: + 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; + }; + + // generate the XML output + void GenerateDartBuildOutput(std::ostream& os, + std::vector<cmCTestBuildErrorWarning>, + double elapsed_time); + + + bool m_Verbose; + cmCTest *m_CTest; + + std::string m_StartBuild; + std::string m_EndBuild; + + std::vector<cmStdString> m_CustomErrorMatches; + std::vector<cmStdString> m_CustomErrorExceptions; + std::vector<cmStdString> m_CustomWarningMatches; + std::vector<cmStdString> m_CustomWarningExceptions; +}; + +#endif diff --git a/Source/cmCTest.cxx b/Source/cmCTest.cxx index 1f721ed..dab3d49 100644 --- a/Source/cmCTest.cxx +++ b/Source/cmCTest.cxx @@ -23,6 +23,7 @@ #include "cmGlob.h" #include "cmDynamicLoader.h" +#include "cmcTestBuildHandler.h" #include "cmcTestScriptHandler.h" #include "cmcTestUpdateHandler.h" #include "cmcTestConfigureHandler.h" @@ -145,98 +146,6 @@ std::string cmCTest::CurrentTime() return cmCTest::MakeXMLSafe(::CleanString(current_time)); } -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]+):", - "^Fatal", - "^Error: ", - "^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:", - "^Unresolved:", - "Undefined symbols:", - "^Undefined[ \\t]+first referenced", - "^CMake Error:", - ":[ \\t]cannot find", - ":[ \\t]can't find", - ": \\*\\*\\* No rule to make target \\`.*\\'. Stop", - ": Invalid loader fixup for symbol", - ": internal link edit command failed", - ": Unrecognized option \\`.*\\'", - "\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\([^W]\\)", - "ld: 0706-006 Cannot find or open library file: -l ", - "ild: \\(argument error\\) can't find library argument ::", - "^could not be found and will not be loaded.", - "s:616 string too big", - "make: Fatal error: ", - "ld: 0711-993 Error occurred while writing to the output file:", - "make: \\*\\*\\*.*Error", - 0 -}; - -static const char* cmCTestErrorExceptions[] = { - "instantiated from ", - "candidates are:", - ": warning", - "makefile:", - "Makefile:", - ":[ \\t]+Where:", - "([^ :]+):([0-9]+): Warning", - 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", - "([^:]+): warning", - "\", line [0-9]+\\.[0-9]+: [0-9]+-[0-9]+ \\(W\\)", - "^cxx: Warning:", - ".*file: .* has no symbols", - "([^ :]+):([0-9]+): 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 [^ \\t]+ discarded by .OPT:REF", - "ld32: WARNING 85: definition of dataKey in", - "cc: warning 422: Unknown option \"\\+b", - "_with_warning_C", - 0 -}; static const char* cmCTestMemCheckResultStrings[] = { "ABR", @@ -414,13 +323,15 @@ cmCTest::cmCTest() m_MaximumPassedTestResultSize = 100 * 1024; m_MaximumFailedTestResultSize = 200 * 1024; - this->ScriptHandler = new cmCTestScriptHandler; - this->UpdateHandler = new cmCTestUpdateHandler; + this->BuildHandler = new cmCTestBuildHandler; + this->ScriptHandler = new cmCTestScriptHandler; + this->UpdateHandler = new cmCTestUpdateHandler; this->ConfigureHandler = new cmCTestConfigureHandler; } cmCTest::~cmCTest() { + delete this->BuildHandler; delete this->ScriptHandler; delete this->UpdateHandler; delete this->ConfigureHandler; @@ -720,248 +631,6 @@ std::string cmCTest::FindTheExecutable(const char *exe) } -int cmCTest::BuildDirectory() -{ - std::cout << "Build project" << std::endl; - std::string makeCommand = m_DartConfiguration["MakeCommand"]; - if ( makeCommand.size() == 0 ) - { - std::cerr << "Cannot find MakeCommand key in the DartConfiguration.tcl" << std::endl; - return 1; - } - std::string buildDirectory = m_DartConfiguration["BuildDirectory"]; - if ( buildDirectory.size() == 0 ) - { - std::cerr << "Cannot find BuildDirectory key in the DartConfiguration.tcl" << std::endl; - return 1; - } - - std::ofstream ofs; - double elapsed_time_start = cmSystemTools::GetTime(); - if ( !this->OpenOutputFile("Temporary", "LastBuild.log", ofs) ) - { - std::cerr << "Cannot create LastBuild.log file" << std::endl; - } - m_StartBuild = this->CurrentTime(); - std::string output; - int retVal = 0; - int res = cmsysProcess_State_Exited; - if ( !m_ShowOnly ) - { - res = this->RunMakeCommand(makeCommand.c_str(), &output, - &retVal, buildDirectory.c_str(), - m_Verbose, 0, ofs); - } - else - { - std::cout << "Build with command: " << makeCommand << std::endl; - } - m_EndBuild = this->CurrentTime(); - double elapsed_build_time = cmSystemTools::GetTime() - elapsed_time_start; - if (res != cmsysProcess_State_Exited || retVal ) - { - std::cerr << "Error(s) when building project" << std::endl; - } - if ( ofs ) - { - ofs.close(); - } - - tm_VectorOfStrings::size_type cc; - if ( m_DartConfiguration["SourceDirectory"].size() > 20 || - m_DartConfiguration["BuildDirectory"].size() > 20 ) - { - std::string srcdir = m_DartConfiguration["SourceDirectory"] + "/"; - std::string bindir = m_DartConfiguration["BuildDirectory"] + "/"; - std::string srcdirrep; - std::string bindirrep; - for ( cc = srcdir.size()-2; cc > 0; cc -- ) - { - if ( srcdir[cc] == '/' ) - { - srcdirrep = srcdir.c_str() + cc; - srcdirrep = "/..." + srcdirrep; - srcdir = srcdir.substr(0, cc+1); - break; - } - } - for ( cc = bindir.size()-2; cc > 0; cc -- ) - { - if ( bindir[cc] == '/' ) - { - bindirrep = bindir.c_str() + cc; - bindirrep = "/..." + bindirrep; - bindir = bindir.substr(0, cc+1); - break; - } - } - - cmSystemTools::ReplaceString(output, srcdir.c_str(), "/.../"); //srcdirrep.c_str()); - cmSystemTools::ReplaceString(output, bindir.c_str(), "/.../"); //bindirrep.c_str()); - } - - // Parsing of output for errors and warnings. - - std::vector<cmStdString> lines; - cmSystemTools::Split(output.c_str(), lines); - - - // Lines are marked: - // 0 - nothing - // 1 - error - // > 1 - warning - std::vector<int> markedLines(lines.size(), 0); - - // Errors - for ( cc = 0; cmCTestErrorMatches[cc]; cc ++ ) - { - m_CustomErrorMatches.push_back(cmCTestErrorMatches[cc]); - } - for ( cc = 0; cmCTestErrorExceptions[cc]; cc ++ ) - { - m_CustomErrorExceptions.push_back(cmCTestErrorExceptions[cc]); - } - for ( cc = 0; cmCTestWarningMatches[cc]; cc ++ ) - { - m_CustomWarningMatches.push_back(cmCTestWarningMatches[cc]); - } - for ( cc = 0; cmCTestWarningExceptions[cc]; cc ++ ) - { - m_CustomWarningExceptions.push_back(cmCTestWarningExceptions[cc]); - } - - for ( cc = 0; cc < m_CustomErrorMatches.size(); cc ++ ) - { - cmsys::RegularExpression re(m_CustomErrorMatches[cc].c_str()); - cmCTest::tm_VectorOfStrings::size_type kk; - for ( kk = 0; kk < lines.size(); kk ++ ) - { - if ( re.find(lines[kk]) ) - { - markedLines[kk] = 1; - } - } - } - // Warnings - for ( cc = 0; cc < m_CustomWarningMatches.size(); cc ++ ) - { - cmsys::RegularExpression re(m_CustomWarningMatches[cc].c_str()); - cmCTest::tm_VectorOfStrings::size_type kk; - for ( kk = 0; kk < lines.size(); kk ++ ) - { - if ( re.find(lines[kk]) ) - { - markedLines[kk] += 2; - } - } - } - // Errors exceptions - for ( cc = 0; cc < m_CustomErrorExceptions.size(); cc ++ ) - { - cmsys::RegularExpression re(m_CustomErrorExceptions[cc].c_str()); - std::vector<int>::size_type kk; - for ( kk =0; kk < markedLines.size(); kk ++ ) - { - if ( markedLines[kk] == 1 ) - { - if ( re.find(lines[kk]) ) - { - markedLines[kk] = 0; - } - } - } - } - // Warning exceptions - for ( cc = 0; cc < m_CustomWarningExceptions.size(); cc ++ ) - { - cmsys::RegularExpression re(m_CustomWarningExceptions[cc].c_str()); - std::vector<int>::size_type kk; - for ( kk =0; kk < markedLines.size(); kk ++ ) - { - if ( markedLines[kk] > 1 ) - { - if ( re.find(lines[kk]) ) - { - markedLines[kk] = 0; - } - } - } - } - std::vector<cmCTestBuildErrorWarning> errorsWarnings; - - int errors = 0; - int warnings = 0; - - std::vector<int>::size_type kk; - cmCTestBuildErrorWarning errorwarning; - for ( kk =0; kk < markedLines.size(); kk ++ ) - { - errorwarning.m_LineNumber = -1; - 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 = static_cast<int>(kk+1); - errorwarning.m_Text = lines[kk]; - errorwarning.m_PreContext = ""; - errorwarning.m_PostContext = ""; - std::vector<int>::size_type jj; - std::vector<int>::size_type ll = 0; - if ( kk > 6 ) - { - ll = kk - 6; - } - for ( jj = kk-1; - jj > 0 && jj > ll && markedLines[jj] != markedLines[kk]; - jj -- ); - while ( markedLines[jj] == markedLines[kk] && jj < kk ) - { - jj ++; - } - for (; jj < kk; jj ++ ) - { - errorwarning.m_PreContext += lines[jj] + "\n"; - } - for ( jj = kk+1; - jj < lines.size() && jj < kk + 7 && markedLines[jj] != markedLines[kk]; - jj ++ ) - { - errorwarning.m_PostContext += lines[jj] + "\n"; - } - errorsWarnings.push_back(errorwarning); - if ( errorwarning.m_Error ) - { - errors ++; - } - else - { - warnings ++; - } - } - } - - std::cout << " " << errors << " Compiler errors" << std::endl; - std::cout << " " << warnings << " Compiler warnings" << std::endl; - - if( !this->OpenOutputFile(m_CurrentTag, "Build.xml", ofs) ) - { - std::cerr << "Cannot create build XML file" << std::endl; - return 1; - } - this->GenerateDartBuildOutput(ofs, errorsWarnings, elapsed_build_time); - return 0; -} int cmCTest::CoverageDirectory() { @@ -1538,56 +1207,6 @@ bool cmCTest::OpenOutputFile(const std::string& path, return true; } -void cmCTest::GenerateDartBuildOutput(std::ostream& os, - std::vector<cmCTestBuildErrorWarning> ew, - double elapsed_build_time) -{ - this->StartXML(os); - os << "<Build>\n" - << "\t<StartDateTime>" << m_StartBuild << "</StartDateTime>\n" - << "<BuildCommand>" - << this->MakeXMLSafe(m_DartConfiguration["MakeCommand"]) - << "</BuildCommand>" << std::endl; - - std::vector<cmCTestBuildErrorWarning>::iterator it; - for ( it = ew.begin(); it != ew.end(); it++ ) - { - cmCTestBuildErrorWarning *cm = &(*it); - os << "\t<" << (cm->m_Error ? "Error" : "Warning") << ">\n" - << "\t\t<BuildLogLine>" << cm->m_LogLine << "</BuildLogLine>\n" - << "\t\t<Text>" << this->MakeXMLSafe(cm->m_Text) - << "\n</Text>" << std::endl; - if ( cm->m_SourceFile.size() > 0 ) - { - os << "\t\t<SourceFile>" << cm->m_SourceFile << "</SourceFile>" - << std::endl; - } - if ( cm->m_SourceFileTail.size() > 0 ) - { - os << "\t\t<SourceFileTail>" << cm->m_SourceFileTail - << "</SourceFileTail>" << std::endl; - } - if ( cm->m_LineNumber >= 0 ) - { - os << "\t\t<SourceLineNumber>" << cm->m_LineNumber - << "</SourceLineNumber>" << std::endl; - } - os << "\t\t<PreContext>" << this->MakeXMLSafe(cm->m_PreContext) - << "</PreContext>\n" - << "\t\t<PostContext>" << this->MakeXMLSafe(cm->m_PostContext) - << "</PostContext>\n" - << "\t\t<RepeatCount>0</RepeatCount>\n" - << "</" << (cm->m_Error ? "Error" : "Warning") << ">\n\n" - << std::endl; - } - os << "\t<Log Encoding=\"base64\" Compression=\"/bin/gzip\">\n\t</Log>\n" - << "\t<EndDateTime>" << m_EndBuild << "</EndDateTime>\n" - << "<ElapsedMinutes>" << static_cast<int>(elapsed_build_time/6)/10.0 - << "</ElapsedMinutes>" - << "</Build>" << std::endl; - this->EndXML(os); -} - void cmCTest::GetListOfTests(tm_ListOfTests* testlist, bool memcheck) { // does the DartTestfile.txt exist ? @@ -2669,7 +2288,7 @@ int cmCTest::ProcessTests() if ( m_Tests[BUILD_TEST] || m_Tests[ALL_TEST] ) { this->UpdateCTestConfiguration(); - if (this->BuildDirectory()) + if (this->BuildHandler->BuildDirectory(this)) { res |= cmCTest::BUILD_ERRORS; } @@ -3459,6 +3078,7 @@ int cmCTest::Run(std::vector<std::string>const& args, std::string* output) if( arg.find("-V",0) == 0 || arg.find("--verbose",0) == 0 ) { this->m_Verbose = true; + this->BuildHandler->SetVerbose(this->m_Verbose); this->ScriptHandler->SetVerbose(this->m_Verbose); this->UpdateHandler->SetVerbose(this->m_Verbose); this->ConfigureHandler->SetVerbose(this->m_Verbose); @@ -4396,11 +4016,8 @@ int cmCTest::ReadCustomConfigurationFileTree(const char* dir) dirs.insert(dirs.end(), ndirs.begin(), ndirs.end()); } - this->PopulateCustomVector(mf, "CTEST_CUSTOM_ERROR_MATCH", m_CustomErrorMatches); - this->PopulateCustomVector(mf, "CTEST_CUSTOM_ERROR_EXCEPTION", m_CustomErrorExceptions); - this->PopulateCustomVector(mf, "CTEST_CUSTOM_WARNING_MATCH", m_CustomWarningMatches); - this->PopulateCustomVector(mf, "CTEST_CUSTOM_WARNING_EXCEPTION", m_CustomWarningExceptions); - + this->BuildHandler->PopulateCustomVectors(mf); + this->PopulateCustomVector(mf, "CTEST_CUSTOM_TESTS_IGNORE", m_CustomTestsIgnore); this->PopulateCustomVector(mf, "CTEST_CUSTOM_MEMCHECK_IGNORE", m_CustomMemCheckIgnore); diff --git a/Source/cmCTest.h b/Source/cmCTest.h index 07d6bfb..5ec5b45 100644 --- a/Source/cmCTest.h +++ b/Source/cmCTest.h @@ -23,6 +23,7 @@ #include "cmListFileCache.h" class cmMakefile; +class cmCTestBuildHandler; class cmCTestScriptHandler; class cmCTestUpdateHandler; class cmCTestConfigureHandler; @@ -67,11 +68,6 @@ public: bool GetTomorrowTag() { return m_TomorrowTag; }; /** - * Try to build the project - */ - int BuildDirectory(); - - /** * Try to run tests of the project */ int TestDirectory(bool memcheck); @@ -189,8 +185,12 @@ public: int* retVal, const char* dir, bool verbose, int timeout, std::ofstream& ofs); + static void PopulateCustomVector(cmMakefile* mf, const char* definition, + tm_VectorOfStrings& vec); + private: // these are helper classes + cmCTestBuildHandler *BuildHandler; cmCTestScriptHandler *ScriptHandler; cmCTestUpdateHandler *UpdateHandler; cmCTestConfigureHandler *ConfigureHandler; @@ -277,18 +277,6 @@ private: int m_TestCount; }; - 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; - }; - struct cmCTestTestProperties { cmStdString m_Name; @@ -333,8 +321,6 @@ private: std::string m_CurrentTag; bool m_TomorrowTag; - std::string m_StartBuild; - std::string m_EndBuild; std::string m_StartTest; std::string m_EndTest; double m_ElapsedTestingTime; @@ -374,12 +360,6 @@ private: int ReadCustomConfigurationFileTree(const char* dir); - void PopulateCustomVector(cmMakefile* mf, const char* definition, tm_VectorOfStrings& vec); - - tm_VectorOfStrings m_CustomErrorMatches; - tm_VectorOfStrings m_CustomErrorExceptions; - tm_VectorOfStrings m_CustomWarningMatches; - tm_VectorOfStrings m_CustomWarningExceptions; tm_VectorOfStrings m_CustomTestsIgnore; tm_VectorOfStrings m_CustomMemCheckIgnore; @@ -409,9 +389,6 @@ private: */ void GenerateDartTestOutput(std::ostream& os); void GenerateDartMemCheckOutput(std::ostream& os); - void GenerateDartBuildOutput(std::ostream& os, - std::vector<cmCTestBuildErrorWarning>, - double elapsed_time); //! Run command specialized for tests. Returns process status and retVal is // return value or exception. |