diff options
-rw-r--r-- | Source/CTest/cmCTestBuildHandler.cxx | 551 | ||||
-rw-r--r-- | Source/CTest/cmCTestBuildHandler.h | 42 |
2 files changed, 424 insertions, 169 deletions
diff --git a/Source/CTest/cmCTestBuildHandler.cxx b/Source/CTest/cmCTestBuildHandler.cxx index f2a16dc..70d0974 100644 --- a/Source/CTest/cmCTestBuildHandler.cxx +++ b/Source/CTest/cmCTestBuildHandler.cxx @@ -81,6 +81,7 @@ static const char* cmCTestErrorMatches[] = { "make: \\*\\*\\*.*Error", "\\*\\*\\* Error code", "^Internal error:", + "Makefile:[0-9]+: \\*\\*\\* .* Stop\\.", 0 }; @@ -158,6 +159,8 @@ cmCTestWarningErrorFileLine[] = { //---------------------------------------------------------------------- cmCTestBuildHandler::cmCTestBuildHandler() { + m_MaxPreContext = 6; + m_MaxPostContext = 6; int cc; for ( cc = 0; cmCTestWarningErrorFileLine[cc].m_RegularExpressionString; ++ cc ) { @@ -197,6 +200,8 @@ void cmCTestBuildHandler::PopulateCustomVectors(cmMakefile *mf) int cmCTestBuildHandler::ProcessHandler() { cmCTestLog(m_CTest, HANDLER_OUTPUT, "Build project" << std::endl); + + // Determine build command and build directory const std::string &makeCommand = m_CTest->GetCTestConfiguration("MakeCommand"); if ( makeCommand.size() == 0 ) { @@ -210,6 +215,7 @@ int cmCTestBuildHandler::ProcessHandler() return -1; } + // Create a last build log cmGeneratedFileStream ofs; double elapsed_time_start = cmSystemTools::GetTime(); if ( !m_CTest->OpenOutputFile("Temporary", "LastBuild.log", ofs) ) @@ -217,34 +223,48 @@ int cmCTestBuildHandler::ProcessHandler() cmCTestLog(m_CTest, ERROR_MESSAGE, "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() ) + // Create lists of regular expression strings for errors, error exceptions, + // warnings and warning exceptions. + std::vector<cmStdString>::size_type cc; + for ( cc = 0; cmCTestErrorMatches[cc]; cc ++ ) { - res = m_CTest->RunMakeCommand(makeCommand.c_str(), &output, - &retVal, buildDirectory.c_str(), 0, ofs); + m_CustomErrorMatches.push_back(cmCTestErrorMatches[cc]); } - else + for ( cc = 0; cmCTestErrorExceptions[cc]; cc ++ ) { - cmCTestLog(m_CTest, DEBUG, "Build with command: " << makeCommand << std::endl); + m_CustomErrorExceptions.push_back(cmCTestErrorExceptions[cc]); } - m_EndBuild = m_CTest->CurrentTime(); - double elapsed_build_time = cmSystemTools::GetTime() - elapsed_time_start; - if (res != cmsysProcess_State_Exited || retVal ) + for ( cc = 0; cmCTestWarningMatches[cc]; cc ++ ) { - cmCTestLog(m_CTest, ERROR_MESSAGE, "Error(s) when building project" << std::endl); + m_CustomWarningMatches.push_back(cmCTestWarningMatches[cc]); + } + for ( cc = 0; cmCTestWarningExceptions[cc]; cc ++ ) + { + m_CustomWarningExceptions.push_back(cmCTestWarningExceptions[cc]); } - std::vector<cmStdString>::size_type cc; - if ( m_CTest->GetCTestConfiguration("SourceDirectory").size() > 20 || - m_CTest->GetCTestConfiguration("BuildDirectory").size() > 20 ) + // Pre-compile regular expressions objects for all regular expressions + std::vector<cmStdString>::iterator it; + +#define cmCTestBuildHandlerPopulateRegexVector(strings, regexes) \ + regexes.clear(); \ + for ( it = strings.begin(); it != strings.end(); ++it ) \ + { \ + regexes.push_back(it->c_str()); \ + } + cmCTestBuildHandlerPopulateRegexVector(m_CustomErrorMatches, m_ErrorMatchRegex); + cmCTestBuildHandlerPopulateRegexVector(m_CustomErrorExceptions, m_ErrorExceptionRegex); + cmCTestBuildHandlerPopulateRegexVector(m_CustomWarningMatches, m_WarningMatchRegex); + cmCTestBuildHandlerPopulateRegexVector(m_CustomWarningExceptions, m_WarningExceptionRegex); + + + // Determine source and binary tree substitutions to simplify the output. + m_SimplifySourceDir = ""; + m_SimplifyBuildDir = ""; + if ( m_CTest->GetCTestConfiguration("SourceDirectory").size() > 20 ) { std::string srcdir = m_CTest->GetCTestConfiguration("SourceDirectory") + "/"; - std::string bindir = m_CTest->GetCTestConfiguration("BuildDirectory") + "/"; std::string srcdirrep; - std::string bindirrep; for ( cc = srcdir.size()-2; cc > 0; cc -- ) { if ( srcdir[cc] == '/' ) @@ -255,6 +275,12 @@ int cmCTestBuildHandler::ProcessHandler() break; } } + m_SimplifySourceDir = srcdir; + } + if ( m_CTest->GetCTestConfiguration("BuildDirectory").size() > 20 ) + { + std::string bindir = m_CTest->GetCTestConfiguration("BuildDirectory") + "/"; + std::string bindirrep; for ( cc = bindir.size()-2; cc > 0; cc -- ) { if ( bindir[cc] == '/' ) @@ -265,186 +291,71 @@ int cmCTestBuildHandler::ProcessHandler() break; } } - - cmSystemTools::ReplaceString(output, srcdir.c_str(), "/.../"); //srcdirrep.c_str()); - cmSystemTools::ReplaceString(output, bindir.c_str(), "/.../"); //bindirrep.c_str()); + m_SimplifyBuildDir = bindir; } - // 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); + // Ok, let's do the build - // 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 ++ ) + // Remember start build time + m_StartBuild = m_CTest->CurrentTime(); + int retVal = 0; + int res = cmsysProcess_State_Exited; + if ( !m_CTest->GetShowOnly() ) { - m_CustomWarningMatches.push_back(cmCTestWarningMatches[cc]); + res = this->RunMakeCommand(makeCommand.c_str(), &retVal, buildDirectory.c_str(), 0, ofs); } - for ( cc = 0; cmCTestWarningExceptions[cc]; cc ++ ) + else { - m_CustomWarningExceptions.push_back(cmCTestWarningExceptions[cc]); + cmCTestLog(m_CTest, DEBUG, "Build with command: " << makeCommand << std::endl); } - for ( cc = 0; cc < m_CustomErrorMatches.size(); cc ++ ) - { - cmsys::RegularExpression re(m_CustomErrorMatches[cc].c_str()); - std::vector<cmStdString>::size_type kk; - //cout << "error Line: " << m_CustomErrorMatches[cc] << endl; - for ( kk = 0; kk < lines.size(); kk ++ ) - { - //cout << " Line: " << lines[kk] << endl; - if ( re.find(lines[kk]) ) - { - //cout << "******************************" << endl; - markedLines[kk] = 1; - } - } - } - // Warnings - for ( cc = 0; cc < m_CustomWarningMatches.size(); cc ++ ) + // Remember end build time and calculate elapsed time + m_EndBuild = m_CTest->CurrentTime(); + double elapsed_build_time = cmSystemTools::GetTime() - elapsed_time_start; + if (res != cmsysProcess_State_Exited || retVal ) { - cmsys::RegularExpression re(m_CustomWarningMatches[cc].c_str()); - std::vector<cmStdString>::size_type kk; - //cout << "warning Line: " << m_CustomWarningMatches[cc] << endl; - for ( kk = 0; kk < lines.size(); kk ++ ) - { - //cout << " Line: " << lines[kk] << endl; - if ( re.find(lines[kk]) ) - { - //cout << "******************************" << endl; - markedLines[kk] += 2; - } - } + cmCTestLog(m_CTest, ERROR_MESSAGE, "Error(s) when building project" << std::endl); } - - // the two follwing blocks of code appear wrong to me - Ken - // I belive that the middle if tests should be %2 type tests - // need to close the loop with Andy - - // Errors exceptions - for ( cc = 0; cc < m_CustomErrorExceptions.size(); cc ++ ) + + // Cleanups strings in the errors and warnings list. + t_ErrorsAndWarningsVector::iterator evit; + if ( !m_SimplifySourceDir.empty() ) { - cmsys::RegularExpression re(m_CustomErrorExceptions[cc].c_str()); - std::vector<int>::size_type kk; - for ( kk =0; kk < markedLines.size(); kk ++ ) + for ( evit = m_ErrorsAndWarnings.begin(); evit != m_ErrorsAndWarnings.end(); ++ evit ) { - if ( markedLines[kk] == 1 ) - { - if ( re.find(lines[kk]) ) - { - markedLines[kk] = 0; - } - } + cmSystemTools::ReplaceString(evit->m_Text, m_SimplifySourceDir.c_str(), "/.../"); + cmSystemTools::ReplaceString(evit->m_PreContext, m_SimplifySourceDir.c_str(), "/.../"); + cmSystemTools::ReplaceString(evit->m_PostContext, m_SimplifySourceDir.c_str(), "/.../"); } } - // 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 ++ ) + if ( !m_SimplifyBuildDir.empty() ) { - errorwarning.m_LineNumber = -1; - bool found = false; - if ( markedLines[kk] == 1 ) - { - cmCTestLog(m_CTest, DEBUG, "Error: " << lines[kk] << std::endl); - errorwarning.m_Error = true; - found = true; - } - else if ( markedLines[kk] > 1 ) + for ( evit = m_ErrorsAndWarnings.begin(); evit != m_ErrorsAndWarnings.end(); ++ evit ) { - cmCTestLog(m_CTest, DEBUG, "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 ++; - } + cmSystemTools::ReplaceString(evit->m_Text, m_SimplifyBuildDir.c_str(), "/.../"); + cmSystemTools::ReplaceString(evit->m_PreContext, m_SimplifyBuildDir.c_str(), "/.../"); + cmSystemTools::ReplaceString(evit->m_PostContext, m_SimplifyBuildDir.c_str(), "/.../"); } } - cmCTestLog(m_CTest, HANDLER_OUTPUT, " " << errors << " Compiler errors" << std::endl); - cmCTestLog(m_CTest, HANDLER_OUTPUT, " " << warnings << " Compiler warnings" << std::endl); + // Display message about number of errors and warnings + cmCTestLog(m_CTest, HANDLER_OUTPUT, " " << m_TotalErrors << " Compiler errors" << std::endl); + cmCTestLog(m_CTest, HANDLER_OUTPUT, " " << m_TotalWarnings << " Compiler warnings" << std::endl); + + // Generate XML output cmGeneratedFileStream xofs; if( !m_CTest->OpenOutputFile(m_CTest->GetCurrentTag(), "Build.xml", xofs, true) ) { cmCTestLog(m_CTest, ERROR_MESSAGE, "Cannot create build XML file" << std::endl); return -1; } - this->GenerateDartBuildOutput(xofs, errorsWarnings, elapsed_build_time); + this->GenerateDartBuildOutput(xofs, m_ErrorsAndWarnings, elapsed_build_time); return 0; } - +//---------------------------------------------------------------------- void cmCTestBuildHandler::GenerateDartBuildOutput( std::ostream& os, std::vector<cmCTestBuildErrorWarning> ew, @@ -553,4 +464,306 @@ void cmCTestBuildHandler::GenerateDartBuildOutput( << "</Build>" << std::endl; m_CTest->EndXML(os); } - + +//---------------------------------------------------------------------- +int cmCTestBuildHandler::RunMakeCommand(const char* command, + int* retVal, const char* dir, int timeout, std::ofstream& ofs) +{ + // First generate the command and arguments + std::vector<cmStdString> args = cmSystemTools::ParseArguments(command); + + if(args.size() < 1) + { + return false; + } + + std::vector<const char*> argv; + for(std::vector<cmStdString>::const_iterator a = args.begin(); + a != args.end(); ++a) + { + argv.push_back(a->c_str()); + } + argv.push_back(0); + + // Now create process object + cmsysProcess* cp = cmsysProcess_New(); + cmsysProcess_SetCommand(cp, &*argv.begin()); + cmsysProcess_SetWorkingDirectory(cp, dir); + cmsysProcess_SetOption(cp, cmsysProcess_Option_HideWindow, 1); + cmsysProcess_SetTimeout(cp, timeout); + cmsysProcess_Execute(cp); + + // Initialize tick's + std::string::size_type tick = 0; + const std::string::size_type tick_len = 1024; + + char* data; + int length; + cmCTestLog(m_CTest, HANDLER_OUTPUT, + " Each symbol represents " << tick_len << " bytes of output." << std::endl + << " '!' represents an error and '*' a warning." << std::endl + << " " << std::flush); + + // Initialize building structures + m_BuildProcessingQueue.clear(); + m_OutputLineCounter = 0; + m_ErrorsAndWarnings.clear(); + m_TotalErrors = 0; + m_TotalWarnings = 0; + m_BuildOutputLogSize = 0; + m_LastTickChar = '.'; + + // For every chunk of data + while(cmsysProcess_WaitForData(cp, &data, &length, 0)) + { + // Replace '\0' with '\n', since '\0' does not really make sense. This is + // for Visual Studio output + for(int cc =0; cc < length; ++cc) + { + if(data[cc] == 0) + { + data[cc] = '\n'; + } + } + + // Process the chunk of data + this->ProcessBuffer(data, length, tick, tick_len, ofs); + } + + this->ProcessBuffer(0, 0, tick, tick_len, ofs); + cmCTestLog(m_CTest, OUTPUT, " Size of output: " + << int(m_BuildOutputLogSize / 1024.0) << "K" << std::endl); + + // Properly handle output of the build command + cmsysProcess_WaitForExit(cp, 0); + int result = cmsysProcess_GetState(cp); + + if(result == cmsysProcess_State_Exited) + { + *retVal = cmsysProcess_GetExitValue(cp); + } + else if(result == cmsysProcess_State_Exception) + { + *retVal = cmsysProcess_GetExitException(cp); + cmCTestLog(m_CTest, WARNING, "There was an exception: " << *retVal << std::endl); + } + else if(result == cmsysProcess_State_Expired) + { + cmCTestLog(m_CTest, WARNING, "There was a timeout" << std::endl); + } + else if(result == cmsysProcess_State_Error) + { + // If there was an error running command, report that on the dashboard. + cmCTestBuildErrorWarning errorwarning; + errorwarning.m_LogLine = 1; + errorwarning.m_Text = "*** ERROR executing: "; + errorwarning.m_Text += cmsysProcess_GetErrorString(cp); + errorwarning.m_PreContext = ""; + errorwarning.m_PostContext = ""; + errorwarning.m_Error = true; + m_ErrorsAndWarnings.push_back(errorwarning); + m_TotalErrors ++; + } + + cmsysProcess_Delete(cp); + + return result; +} + +//---------------------------------------------------------------------- +void cmCTestBuildHandler::ProcessBuffer(const char* data, int length, size_t& tick, size_t tick_len, + std::ofstream& ofs) +{ +#undef cerr + const std::string::size_type tick_line_len = 50; + m_BuildProcessingQueue.insert(m_BuildProcessingQueue.end(), data, data+length); + m_BuildOutputLogSize += length; + + // until there are any lines left in the buffer + while ( 1 ) + { + // Find the end of line + t_BuildProcessingQueueType::iterator it; + for ( it = m_BuildProcessingQueue.begin(); + it != m_BuildProcessingQueue.end(); + ++ it ) + { + if ( *it == '\n' ) + { + break; + } + } + // If the end of line was found + if ( it != m_BuildProcessingQueue.end() ) + { + // Create a contiguous array for the line + m_CurrentProcessingLine.clear(); + m_CurrentProcessingLine.insert(m_CurrentProcessingLine.end(), m_BuildProcessingQueue.begin(), it); + m_CurrentProcessingLine.push_back(0); + const char* line = &*m_CurrentProcessingLine.begin(); + + // Process the line + int lineType = this->ProcessSingleLine(line); + + // Erase the line from the queue + m_BuildProcessingQueue.erase(m_BuildProcessingQueue.begin(), it+1); + + // Depending on the line type, produce error or warning, or nothing + cmCTestBuildErrorWarning errorwarning; + bool found = false; + switch ( lineType ) + { + case b_WARNING_LINE: + m_LastTickChar = '*'; + errorwarning.m_Error = false; + found = true; + m_TotalWarnings ++; + break; + case b_ERROR_LINE: + m_LastTickChar = '!'; + errorwarning.m_Error = true; + found = true; + m_TotalErrors ++; + break; + } + if ( found ) + { + // This is an error or warning, so generate report + errorwarning.m_LogLine = static_cast<int>(m_OutputLineCounter+1); + errorwarning.m_Text = line; + errorwarning.m_PreContext = ""; + errorwarning.m_PostContext = ""; + + // Copy pre-context to report + std::deque<cmStdString>::iterator it; + for ( it = m_PreContext.begin(); it != m_PreContext.end(); ++it ) + { + errorwarning.m_PreContext += *it + "\n"; + } + m_PreContext.clear(); + + // Store report + m_ErrorsAndWarnings.push_back(errorwarning); + m_LastErrorOrWarning = m_ErrorsAndWarnings.end()-1; + m_PostContextCount = 0; + } + else + { + // This is not an error or warning. + // So, figure out if this is a post-context line + if ( m_LastErrorOrWarning != m_ErrorsAndWarnings.end() && m_PostContextCount < m_MaxPostContext ) + { + m_PostContextCount ++; + m_LastErrorOrWarning->m_PostContext += line; + if ( m_PostContextCount < m_MaxPostContext ) + { + m_LastErrorOrWarning->m_PostContext += "\n"; + } + } + else + { + // Otherwise store pre-context for the next error + m_PreContext.push_back(line); + if ( m_PreContext.size() > m_MaxPreContext ) + { + m_PreContext.erase(m_PreContext.begin(), m_PreContext.end()-m_MaxPreContext); + } + } + } + m_OutputLineCounter ++; + } + else + { + break; + } + } + + // Now that the buffer is processed, display missing ticks + int tickDisplayed = false; + while ( m_BuildOutputLogSize > (tick * tick_len) ) + { + tick ++; + cmCTestLog(m_CTest, HANDLER_OUTPUT, m_LastTickChar); + tickDisplayed = true; + if ( tick % tick_line_len == 0 && tick > 0 ) + { + cmCTestLog(m_CTest, HANDLER_OUTPUT, " Size: " + << int((m_BuildOutputLogSize / 1024.0) + 1) << "K" << std::endl + << " "); + } + } + if ( tickDisplayed ) + { + m_LastTickChar = '.'; + } + + // And if this is verbose output, display the content of the chunk + cmCTestLog(m_CTest, HANDLER_VERBOSE_OUTPUT, cmCTestLogWrite(data, length)); + + // Always store the chunk to the file + ofs << cmCTestLogWrite(data, length); +} + +//---------------------------------------------------------------------- +int cmCTestBuildHandler::ProcessSingleLine(const char* data) +{ + cmCTestLog(m_CTest, DEBUG, "Line: [" << data << "]" << std::endl); + + std::vector<cmsys::RegularExpression>::iterator it; + + int warningLine = 0; + int errorLine = 0; + + // Check for regular expressions + // Errors + for ( it = m_ErrorMatchRegex.begin(); it != m_ErrorMatchRegex.end(); ++ it ) + { + if ( it->find(data) ) + { + errorLine = 1; + cmCTestLog(m_CTest, DEBUG, " Error Line: " << data << std::endl); + break; + } + } + // Warnings + for ( it = m_WarningMatchRegex.begin(); it != m_WarningMatchRegex.end(); ++ it ) + { + if ( it->find(data) ) + { + warningLine = 1; + cmCTestLog(m_CTest, DEBUG, " Warning Line: " << data << std::endl); + break; + } + } + + // Error exceptions + for ( it = m_ErrorExceptionRegex.begin(); it != m_ErrorExceptionRegex.end(); ++ it ) + { + if ( it->find(data) ) + { + errorLine = 0; + cmCTestLog(m_CTest, DEBUG, " Not an error Line: " << data << std::endl); + break; + } + } + // Warning exceptions + for ( it = m_WarningExceptionRegex.begin(); it != m_WarningExceptionRegex.end(); ++ it ) + { + if ( it->find(data) ) + { + warningLine = 0; + cmCTestLog(m_CTest, DEBUG, " Not a warning Line: " << data << std::endl); + break; + } + } + if ( errorLine ) + { + return b_ERROR_LINE; + } + if ( warningLine ) + { + return b_WARNING_LINE; + } + return b_REGULAR_LINE; +} + diff --git a/Source/CTest/cmCTestBuildHandler.h b/Source/CTest/cmCTestBuildHandler.h index 575068e..fdeac5c 100644 --- a/Source/CTest/cmCTestBuildHandler.h +++ b/Source/CTest/cmCTestBuildHandler.h @@ -44,6 +44,18 @@ public: void PopulateCustomVectors(cmMakefile *mf); private: + //! Run command specialized for make and configure. Returns process status + // and retVal is return value or exception. + int RunMakeCommand(const char* command, + int* retVal, const char* dir, int timeout, + std::ofstream& ofs); + + enum { + b_REGULAR_LINE, + b_WARNING_LINE, + b_ERROR_LINE + }; + class cmCTestCompileErrorWarningRex { public: @@ -79,6 +91,36 @@ private: std::vector<cmStdString> m_CustomWarningMatches; std::vector<cmStdString> m_CustomWarningExceptions; std::vector<cmCTestCompileErrorWarningRex> m_ErrorWarningFileLineRegex; + + std::vector<cmsys::RegularExpression> m_ErrorMatchRegex; + std::vector<cmsys::RegularExpression> m_ErrorExceptionRegex; + std::vector<cmsys::RegularExpression> m_WarningMatchRegex; + std::vector<cmsys::RegularExpression> m_WarningExceptionRegex; + + void ProcessBuffer(const char* data, int length, size_t& tick, size_t tick_len, + std::ofstream& ofs); + int ProcessSingleLine(const char* data); + + typedef std::deque<char> t_BuildProcessingQueueType; + t_BuildProcessingQueueType m_BuildProcessingQueue; + t_BuildProcessingQueueType::iterator m_BuildProcessingQueueLocation; + size_t m_BuildOutputLogSize; + std::vector<char> m_CurrentProcessingLine; + + cmStdString m_SimplifySourceDir; + cmStdString m_SimplifyBuildDir; + size_t m_OutputLineCounter; + typedef std::vector<cmCTestBuildErrorWarning> t_ErrorsAndWarningsVector; + t_ErrorsAndWarningsVector m_ErrorsAndWarnings; + t_ErrorsAndWarningsVector::iterator m_LastErrorOrWarning; + size_t m_PostContextCount; + size_t m_MaxPreContext; + size_t m_MaxPostContext; + std::deque<cmStdString> m_PreContext; + + int m_TotalErrors; + int m_TotalWarnings; + char m_LastTickChar; }; #endif |