Even more cleanups, fix time on certain platforms such as windows, cygwin, and linux. Hopefully we can add entries for other platforms until try_compile works. Also escape certain characters for xml.

This commit is contained in:
Andy Cedilnik 2002-10-14 15:11:21 -04:00
parent 066cea228b
commit f4859295eb
2 changed files with 111 additions and 30 deletions

View File

@ -21,6 +21,54 @@
#include <stdio.h>
#include <time.h>
/* Implement floattime() for various platforms */
// Taken from Python 2.1.3
#if defined( _WIN32 ) && !defined( __CYGWIN__ )
# define HAVE_FTIME
# defint FTIME _ftime_
#elif defined( __CYGWIN__ ) || defined( __linux__ )
# include <sys/time.h>
# define HAVE_GETTIMEOFDAY
#endif
static double
floattime(void)
{
/* There are three ways to get the time:
(1) gettimeofday() -- resolution in microseconds
(2) ftime() -- resolution in milliseconds
(3) time() -- resolution in seconds
In all cases the return value is a float in seconds.
Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
fail, so we fall back on ftime() or time().
Note: clock resolution does not imply clock accuracy! */
#ifdef HAVE_GETTIMEOFDAY
{
struct timeval t;
#ifdef GETTIMEOFDAY_NO_TZ
if (gettimeofday(&t) == 0)
return (double)t.tv_sec + t.tv_usec*0.000001;
#else /* !GETTIMEOFDAY_NO_TZ */
if (gettimeofday(&t, (struct timezone *)NULL) == 0)
return (double)t.tv_sec + t.tv_usec*0.000001;
#endif /* !GETTIMEOFDAY_NO_TZ */
}
#endif /* !HAVE_GETTIMEOFDAY */
{
#if defined(HAVE_FTIME)
struct timeb t;
FTIME(&t);
return (double)t.time + (double)t.millitm * (double)0.001;
#else /* !HAVE_FTIME */
time_t secs;
time(&secs);
return (double)secs;
#endif /* !HAVE_FTIME */
}
}
static std::string CleanString(std::string str)
{
std::string::size_type spos = str.find_first_not_of(" \n\t");
@ -31,7 +79,7 @@ static std::string CleanString(std::string str)
}
if ( epos != str.npos )
{
epos ++;
epos = epos - spos + 1;
}
return str.substr(spos, epos);
}
@ -105,6 +153,30 @@ static const char* cmCTestWarningExceptions[] = {
0
};
std::string ctest::MakeXMLSafe(const std::string& str)
{
std::string::size_type pos = 0;
cmOStringStream ost;
for ( pos = 0; pos < str.size(); pos ++ )
{
char ch = str[pos];
if ( ch > 126 )
{
ost << "&" << hex << ch;
}
else
{
switch ( ch )
{
case '&': ost << "&amp;"; break;
case '<': ost << "&lt;"; break;
case '>': ost << "&gt;"; break;
default: ost << ch;
}
}
}
return ost.str();
}
bool TryExecutable(const char *dir, const char *file,
std::string *fullPath, const char *subdir)
@ -646,7 +718,8 @@ void ctest::GenerateDartBuildOutput(std::ostream& os,
<< m_DartConfiguration["Site"] << "\">\n"
<< "<Build>\n"
<< "\t<StartDateTime>" << m_StartBuild << "</StartDateTime>\n"
<< "<BuildCommand>" << m_DartConfiguration["MakeCommand"]
<< "<BuildCommand>"
<< this->MakeXMLSafe(m_DartConfiguration["MakeCommand"])
<< "</BuildCommand>" << std::endl;
std::vector<cmCTestBuildErrorWarning>::iterator it;
@ -655,7 +728,8 @@ void ctest::GenerateDartBuildOutput(std::ostream& os,
cmCTestBuildErrorWarning *cm = &(*it);
os << "\t<" << (cm->m_Error ? "Error" : "Warning") << ">\n"
<< "\t\t<BuildLogLine>" << cm->m_LogLine << "</BuildLogLine>\n"
<< "\t\t<Text>" << cm->m_Text << "\n</Text>" << std::endl;
<< "\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>"
@ -671,8 +745,10 @@ void ctest::GenerateDartBuildOutput(std::ostream& os,
os << "\t\t<SourceLineNumber>" << cm->m_LineNumber
<< "</SourceLineNumber>" << std::endl;
}
os << "\t\t<PreContext>" << cm->m_PreContext << "</PreContext>\n"
<< "\t\t<PostContext>" << cm->m_PostContext << "</PostContext>\n"
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;
@ -789,15 +865,14 @@ void ctest::ProcessDirectory(std::vector<std::string> &passed,
std::string output;
int retVal;
clock_t clock_start, clock_finish;
double clocks_per_sec = (double)CLOCKS_PER_SEC;
clock_start = clock();
double clock_start, clock_finish;
clock_start = floattime();
bool res = cmSystemTools::RunCommand(testCommand.c_str(), output,
retVal, 0, false);
clock_finish = clock();
clock_finish = floattime();
cres.m_ExecutionTime = (double)(clock_finish - clock_start) / clocks_per_sec;
cres.m_ExecutionTime = (double)(clock_finish - clock_start);
cres.m_FullCommandLine = testCommand;
if (!res || retVal != 0)
@ -923,47 +998,52 @@ void ctest::GenerateDartOutput(std::ostream& os)
<< "\" BuildStamp=\"" << m_CurrentTag << "-Experimental\" Name=\""
<< m_DartConfiguration["Site"] << "\">\n"
<< "<Testing>\n"
<< " <StartDateTime>" << m_StartTest << "</StartDateTime>\n"
<< " <TestList>\n";
<< "\t<StartDateTime>" << m_StartTest << "</StartDateTime>\n"
<< "\t<TestList>\n";
tm_TestResultsVector::size_type cc;
for ( cc = 0; cc < m_TestResults.size(); cc ++ )
{
cmCTestTestResult *result = &m_TestResults[cc];
os << " <Test>" << result->m_Path << "/" << result->m_Name
os << "\t\t<Test>" << this->MakeXMLSafe(result->m_Path)
<< "/" << this->MakeXMLSafe(result->m_Name)
<< "</Test>" << std::endl;
}
os << " </TestList>\n";
os << "\t</TestList>\n";
for ( cc = 0; cc < m_TestResults.size(); cc ++ )
{
cmCTestTestResult *result = &m_TestResults[cc];
os << " <Test Status=\"" << (result->m_ReturnValue?"failed":"passed")
os << "\t<Test Status=\"" << (result->m_ReturnValue?"failed":"passed")
<< "\">\n"
<< " <Name>" << result->m_Name << "</Name>\n"
<< " <Path>" << result->m_Path << "</Path>\n"
<< " <FullName>" << result->m_Path << "/" << result->m_Name << "</FullName>\n"
<< " <FullCommandLine>" << result->m_FullCommandLine << "</FullCommandLine>\n"
<< " <Results>" << std::endl;
<< "\t\t<Name>" << this->MakeXMLSafe(result->m_Name) << "</Name>\n"
<< "\t\t<Path>" << this->MakeXMLSafe(result->m_Path) << "</Path>\n"
<< "\t\t<FullName>" << this->MakeXMLSafe(result->m_Path)
<< "/" << this->MakeXMLSafe(result->m_Name) << "</FullName>\n"
<< "\t\t<FullCommandLine>"
<< this->MakeXMLSafe(result->m_FullCommandLine)
<< "</FullCommandLine>\n"
<< "\t\t<Results>" << std::endl;
if ( result->m_ReturnValue )
{
os << " <NamedMeasurement type=\"text/string\" name=\"Exit Code\"><Value>"
os << "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Code\"><Value>"
<< "CHILDSTATUS" << "</Value></NamedMeasurement>\n"
<< " <NamedMeasurement type=\"text/string\" name=\"Exit Value\"><Value>"
<< "\t\t\t<NamedMeasurement type=\"text/string\" name=\"Exit Value\"><Value>"
<< result->m_ReturnValue << "</Value></NamedMeasurement>" << std::endl;
}
os << " <NamedMeasurement type=\"numeric/double\" "
os << "\t\t\t<NamedMeasurement type=\"numeric/double\" "
<< "name=\"Execution Time\"><Value>"
<< result->m_ExecutionTime << "</Value></NamedMeasurement>\n"
<< " <NamedMeasurement type=\"text/string\" "
<< "\t\t\t<NamedMeasurement type=\"text/string\" "
<< "name=\"Completion Status\"><Value>"
<< result->m_CompletionStatus << "</Value></NamedMeasurement>\n"
<< " <Measurement>\n"
<< " <Value>" << result->m_Output << "</Value>\n"
<< " </Measurement>\n"
<< " </Results>\n"
<< " </Test>" << std::endl;
<< "\t\t\t<Measurement>\n"
<< "\t\t\t\t<Value>" << this->MakeXMLSafe(result->m_Output)
<< "</Value>\n"
<< "\t\t\t</Measurement>\n"
<< "\t\t</Results>\n"
<< "\t</Test>" << std::endl;
}
os << "<EndDateTime>" << m_EndTest << "</EndDateTime>\n"
os << "\t<EndDateTime>" << m_EndTest << "</EndDateTime>\n"
<< "</Testing>\n"
<< "</Site>" << std::endl;
}

View File

@ -151,5 +151,6 @@ private:
bool OpenFile(const std::string& path,
const std::string& name, std::ofstream& stream);
std::string MakeXMLSafe(const std::string&);
};