blob: 6bed727af2f347dfb64aba385860bb334af44d3e [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
// Base header file. Must be first.
#include <xalanc/Include/PlatformDefinitions.hpp>
#if defined(XALAN_CLASSIC_IOSTREAMS)
#include <iostream.h>
#else
#include <iostream>
#endif
#include <cstdio>
XALAN_USING_STD(cerr)
XALAN_USING_STD(cout)
XALAN_USING_STD(endl)
#include <xercesc/util/PlatformUtils.hpp>
#include <xercesc/parsers/XercesDOMParser.hpp>
#include <xalanc/XercesParserLiaison/XercesParserLiaison.hpp>
#include <xalanc/XercesParserLiaison/XercesDOMSupport.hpp>
#include <xalanc/XalanTransformer/XalanTransformer.hpp>
#include <xalanc/XalanTransformer/XercesDOMWrapperParsedSource.hpp>
// HARNESS HEADERS...
#include "xalanc/Harness/XalanXMLFileReporter.hpp"
#include "xalanc/Harness/XalanFileUtility.hpp"
//#define XALAN_VQ_SPECIAL_TRACE
#if defined(XALAN_VQ_SPECIAL_TRACE)
#include "C:/Program Files/Rational/Quantify/pure.h"
#endif
// Just hoist everything...
XALAN_CPP_NAMESPACE_USE
// This is here for memory leak testing.
#if !defined(NDEBUG) && defined(_MSC_VER)
#include <crtdbg.h>
#endif
void
setHelp(XalanFileUtility& h)
{
h.args.getHelpStream() << endl
<< "conf dir [-sub -out -gold -source (XST | XPL | DOM)]"
<< endl
<< endl
<< "dir (base directory for testcases)"
<< endl
<< "-sub dir (specific directory)"
<< endl
<< "-out dir (base directory for output)"
<< endl
<< "-gold dir (base directory for gold files)"
<< endl
<< "-src type (parsed source; XalanSourceTree(d), XercesParserLiasion, XercesDOM)"
<< endl;
}
static const char* const excludeStylesheets[] =
{
// "output22.xsl", // Excluded because it outputs EBCDIC
0
};
inline bool
checkForExclusion(const XalanDOMString& currentFile)
{
for (size_t i = 0; excludeStylesheets[i] != 0; ++i)
{
if (equals(currentFile, excludeStylesheets[i]))
{
return true;
}
}
return false;
}
int
parseWithTransformer(
int sourceType,
XalanTransformer& xalan,
const XSLTInputSource& xmlInput,
const XalanCompiledStylesheet* styleSheet,
const XSLTResultTarget& output,
XalanXMLFileReporter& logFile,
XalanFileUtility& h)
{
const XalanParsedSource* parsedSource = 0;
int theResult = 0;
// Parse the XML source accordingly.
//
if (sourceType != 0 )
{
theResult = xalan.parseSource(xmlInput, parsedSource, true);
h.data.xmlFormat = XalanDOMString("XercesParserLiasion");
}
else
{
theResult = xalan.parseSource(xmlInput, parsedSource, false);
h.data.xmlFormat = XalanDOMString("XalanSourceTree");
}
// If the source was parsed correctly then perform the transform else report the failure.
//
if (parsedSource == 0)
{
// Report the failure and be sure to increment fail count.
//
cout << "ParseWTransformer - Failed to parse source document for " << h.data.testOrFile << endl;
++h.data.fail;
logFile.logErrorResult(h.data.testOrFile, XalanDOMString("Failed to parse source document. ") + xalan.getLastError());
}
else
{
theResult = xalan.transform(*parsedSource, styleSheet, output);
xalan.destroyParsedSource(parsedSource);
}
return theResult;
}
int
parseWithXerces(
XalanTransformer& xalan,
const XSLTInputSource& xmlInput,
const XalanCompiledStylesheet* styleSheet,
const XSLTResultTarget& output,
XalanXMLFileReporter& logFile,
XalanFileUtility& h)
{
XALAN_USING_XERCES(XercesDOMParser)
XALAN_USING_XERCES(DOMDocument)
h.data.xmlFormat = XalanDOMString("Xerces_DOM");
XercesDOMParser theParser;
theParser.setDoValidation(true);
theParser.setDoNamespaces(true);
theParser.parse(xmlInput);
DOMDocument* const theDOM = theParser.getDocument();
theDOM->normalize();
XercesDOMSupport theDOMSupport;
XercesParserLiaison theParserLiaison;
int theResult = 0;
try
{
const XercesDOMWrapperParsedSource parsedSource(
theDOM,
theParserLiaison,
theDOMSupport,
XalanDOMString(xmlInput.getSystemId()));
theResult = xalan.transform(parsedSource, styleSheet, output);
}
catch(...)
{
// Report the failure and be sure to increment fail count.
//
cout << "parseWXerces - Failed to parse source document for " << h.data.testOrFile << endl;
++h.data.fail;
logFile.logErrorResult(h.data.testOrFile, XalanDOMString("Failed to parse source document. ") + xalan.getLastError());
}
return theResult;
}
int
runTests(
int argc,
char* argv[])
{
int theResult = 0;
try
{
XalanFileUtility h;
// Set the program help string, then get the command line parameters.
//
setHelp(h);
if (h.getParams(argc, argv, "CONF-RESULTS") == true)
{
XalanTransformer xalan;
// Get drive designation for final analysis and generate Unique name for results log.
//
const XalanDOMString drive(h.getDrive()); // This is used to get stylesheet for final analysis
const XalanDOMString resultFilePrefix("conf"); // This & UniqRunid used for log file name.
const XalanDOMString UniqRunid = h.generateUniqRunid();
const XalanDOMString resultsFile(drive + h.args.output + resultFilePrefix + UniqRunid + XalanFileUtility::s_xmlSuffix);
// Open results log, and do some initialization of result data.
//
XalanXMLFileReporter logFile(resultsFile);
logFile.logTestFileInit("Conformance Testing:");
h.data.xmlFormat = XalanDOMString("NotSet");
// Get the list of Directories that are below conf and iterate through them
//
// Flag indicates directory found. Used in conjunction with -sub cmd-line arg.
bool foundDir = false;
typedef XalanFileUtility::FileNameVectorType FileNameVectorType;
const FileNameVectorType dirs = h.getDirectoryNames(h.args.base);
int theResult = 0;
for(FileNameVectorType::size_type j = 0;
j < dirs.size() && theResult == 0;
++j)
{
// Skip all but the specified directory if the -sub cmd-line option was used.
//
const XalanDOMString& currentDir = dirs[j];
if (length(h.args.sub) == 0 || equals(currentDir, h.args.sub) == true)
{
// Check that output directory is there.
//
const XalanDOMString theOutputDir = h.args.output + currentDir;
h.checkAndCreateDir(theOutputDir);
// Indicate that directory was processed and get test files from the directory
//
foundDir = true;
const FileNameVectorType files = h.getTestFileNames(h.args.base, currentDir, true);
// Log directory in results log and process it's files.
//
logFile.logTestCaseInit(currentDir);
for(FileNameVectorType::size_type i = 0; i < files.size(); i++)
{
XalanXMLFileReporter::Hashtable attrs;
const XalanDOMString& currentFile = files[i];
if (checkForExclusion(currentFile))
continue;
h.data.testOrFile = currentFile;
const XalanDOMString theXSLFile = h.args.base + currentDir + XalanFileUtility::s_pathSep + currentFile;
// Check and see if the .xml file exists. If not skip this .xsl file and continue.
bool fileStatus = true;
const XalanDOMString theXMLFile = h.generateFileName(theXSLFile, "xml", &fileStatus);
if (!fileStatus)
continue;
h.data.xmlFileURL = theXMLFile;
h.data.xslFileURL = theXSLFile;
XalanDOMString theGoldFile = h.args.gold + currentDir + XalanFileUtility::s_pathSep + currentFile;
theGoldFile = h.generateFileName(theGoldFile, "out");
const XalanDOMString outbase = h.args.output + currentDir + XalanFileUtility::s_pathSep + currentFile;
const XalanDOMString theOutputFile = h.generateFileName(outbase, "out");
const XSLTInputSource xslInputSource(theXSLFile);
const XSLTInputSource xmlInputSource(theXMLFile);
const XSLTResultTarget resultFile(theOutputFile);
// Parsing(compile) the XSL stylesheet and report the results..
//
const XalanCompiledStylesheet* compiledSS = 0;
xalan.compileStylesheet(xslInputSource, compiledSS);
if (compiledSS == 0 )
{
// Report the failure and be sure to increment fail count.
//
cout << "Failed to parse stylesheet for " << currentFile << endl;
h.data.fail += 1;
logFile.logErrorResult(currentFile, XalanDOMString("Failed to parse stylesheet. ") + xalan.getLastError());
continue;
}
// Parse the Source XML based on input parameters, and then perform transform.
//
switch (h.args.source)
{
case 0:
case 1:
theResult = parseWithTransformer(h.args.source, xalan, xmlInputSource, compiledSS, resultFile, logFile, h);
break;
case 2:
theResult = parseWithXerces(xalan, xmlInputSource, compiledSS, resultFile, logFile, h);
break;
}
// Check and report results... Then delete compiled stylesheet.
//
h.checkResults(theOutputFile, theGoldFile, logFile);
xalan.destroyStylesheet(compiledSS);
}
logFile.logTestCaseClose("Done", "Pass");
}
}
// Check to see if -sub cmd-line directory was processed correctly.
//
if (!foundDir)
{
cout << "Specified test directory: \"" << c_str(TranscodeToLocalCodePage(h.args.sub)) << "\" not found" << endl;
}
else if (theResult != 0)
{
cout << "An unexpected tranformer error occurred. The error code is "
<< theResult
<< "\n"
<< "The error message is \""
<< xalan.getLastError()
<< endl;
}
h.reportPassFail(logFile, UniqRunid);
logFile.logTestFileClose("Conformance ", "Done");
logFile.close();
h.analyzeResults(xalan, resultsFile);
}
}
catch(...)
{
cerr << "Initialization of testing harness failed!" << endl << endl;
}
return theResult;
}
int
main(
int argc,
char* argv[])
{
#if !defined(NDEBUG) && defined(_MSC_VER)
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
#endif
#if defined(XALAN_VQ_SPECIAL_TRACE)
QuantifyStopRecordingData();
QuantifyClearData();
#endif
int theResult = 0;
try
{
XALAN_USING_XERCES(XMLPlatformUtils)
// Call the static initializers for xerces and xalan, and create a transformer
//
XMLPlatformUtils::Initialize();
XalanTransformer::initialize();
theResult = runTests(argc, argv);
XalanTransformer::terminate();
XMLPlatformUtils::Terminate();
XalanTransformer::ICUCleanUp();
}
catch(...)
{
cerr << "Initialization failed!" << endl << endl;
theResult = -1;
}
return theResult;
}