jdonohue 00/02/16 12:54:39
Modified: c/src/TestXSLT process.cpp
Log:
Added switch to test multithreading
Revision Changes Path
1.7 +367 -203 xml-xalan/c/src/TestXSLT/process.cpp
Index: process.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/TestXSLT/process.cpp,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- process.cpp 2000/02/10 19:28:57 1.6
+++ process.cpp 2000/02/16 20:54:39 1.7
@@ -2,7 +2,7 @@
* The Apache Software License, Version 1.1
*
*
- * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -54,6 +54,21 @@
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
+
+#if defined(WIN32)
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+# define THREADFUNCTIONRETURN DWORD WINAPI
+#else
+
+# define THREADFUNCTIONRETURN void *
+
+# if defined(__GNUC__)
+# include <pthread.h>
+# endif
+
+#endif
+
#include <cstdio>
#include <cstring>
#include <iostream>
@@ -62,6 +77,7 @@
#include <sys/stat.h>
#include <string>
+#include <strstream>
#include <dom/DOM_Node.hpp>
#include <dom/DOM_Element.hpp>
@@ -122,7 +138,7 @@
writer.println(" [-QC (Quiet Pattern Conflicts Warnings)]");
writer.println(" [-Q (Quiet Mode)]");
writer.println(" [-ESCAPE (Which characters to escape {default
is <>&\"\'\\r\\n}]");
- writer.println(" [-INDENT (Control how many spaces to indent
{default is 0})]");
+ writer.println(" [-INDENT n(Control how many spaces to indent
{default is 0})]");
writer.println(" [-TT (Trace the templates as they are being
called.)]");
writer.println(" [-TG (Trace each generation event.)]");
writer.println(" [-TS (Trace each selection event.)]");
@@ -133,16 +149,13 @@
writer.println(" [-TEXT (Use simple Text formatter.)]");
writer.println(" [-HTML (Use HTML formatter.)]");
writer.println(" [-PARAM name expression (Set a stylesheet
parameter)]");
+ writer.println(" [-MT n(Set number of threads to 'n' {default
is 1})]");
}
typedef std::map<std::string, std::string> String2StringMapType;
struct CmdLineParams
{
- std::string dumpFileName;
- DOMString specialCharacters;
- DOMString treedumpFileName;
- DOMString xslFileName;
String2StringMapType paramsMap;
bool doStackDumpOnError;
bool escapeCData;
@@ -152,17 +165,31 @@
bool shouldExpandEntityRefs;
bool stripCData;
int indentAmount;
+ int nThreads;
int outputType;
+ std::string dumpFileName;
+ std::string outFileName;
+ std::string specialCharacters;
+ std::string treedumpFileName;
+ std::string xslFileName;
std::vector <std::string> inFileNames;
- std::string outFileName;
+ CmdLineParams() :
+ paramsMap(), doStackDumpOnError(false), escapeCData(false),
+ formatOutput(false), setQuietConflictWarnings(false),
setQuietMode(false),
+ shouldExpandEntityRefs(false), stripCData(false),
indentAmount(0),
+ nThreads(1), outputType(-1), dumpFileName(),
+ specialCharacters(), treedumpFileName(),
+ outFileName(), xslFileName(), inFileNames() { }
+private:
+ CmdLineParams(const CmdLineParams& other);
};
-typedef CmdLineParams CmdLineParamsType;
-
-void getArgs(int argc, const char* argv[], CmdLineParamsType& p) throw()
+void getArgs(int argc, const char* argv[], CmdLineParams& p) throw()
{
p.outputType = -1;
+ p.nThreads = 1;
+ p.indentAmount = 0;
for (int i = 1; i < argc; i ++)
{
if (!stricmp("-ESCAPE", argv[i]))
@@ -173,13 +200,16 @@
{
if(((i+1) < argc) && (argv[i+1][0] != '-'))
p.indentAmount = atoi( argv[++i] );
- else
- p.indentAmount = 0;
}
+ else if (!stricmp("-MT", argv[i]))
+ {
+ if(((i+1) < argc) && (argv[i+1][0] != '-'))
+ p.nThreads = atoi( argv[++i] );
+ }
else if (!stricmp("-IN", argv[i]))
{
p.inFileNames.push_back(argv[++i]);
- while (! (*argv[i+1] == '-')) // Multiple entries
+ while ((i+1) < argc && ! (*argv[i+1] == '-')) //
Multiple entries
p.inFileNames.push_back(argv[++i]);
}
else if (!stricmp("-OUT", argv[i]))
@@ -260,258 +290,391 @@
}
}
-static inline bool exists(std::string &filename)
+/*
+ * Support for multiple threads
+ */
+
+THREADFUNCTIONRETURN xsltMain(void *vptr) throw(XMLException);
+
+#if defined(WIN32)
+
+void xsltMultiThreadedMain(CmdLineParams& params) throw(XMLException)
{
+ DWORD dwStackSize = 4096; // initial thread stack size
+ LPTHREAD_START_ROUTINE lpStartAddress =
(LPTHREAD_START_ROUTINE)xsltMain;
+ DWORD dwCreationFlags = 0; // creation flags
+ int nThreads = params.nThreads;
+ DWORD *ThreadIds = new DWORD[nThreads]; // array to receive thread IDs
+ HANDLE *hThreads = new HANDLE[nThreads]; // array to receive
thread handles
+ int i=0;
- struct stat statBuffer;
- return (0 == stat(filename.c_str(), &statBuffer));
+ for (i=0; i< nThreads; i++)
+ {
+ HANDLE hThread;
+
+ hThread = CreateThread(
+ 0, dwStackSize,
+ lpStartAddress, // pointer to thread
function
+ (LPVOID)¶ms, // argument for new thread
+ dwCreationFlags, // creation flags
+ &ThreadIds[i]);
+ if (! hThread)
+ {
+ LPTSTR lpBuffer; // pointer to message buffer
+
+ FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER,
+ LPCVOID (0), // pointer to message
source
+ GetLastError(),
+ DWORD (0), // language identifier for
requested message
+ (LPSTR)&lpBuffer, // pointer to
message buffer
+ DWORD (0), // maximum size of
message buffer
+ 0 // pointer to array of message
inserts
+ );
+ MessageBox(0, lpBuffer, "Error", MB_ICONSTOP);
+ }
+ else
+ hThreads[i] = hThread;
+ }
+ for (i=0; i< nThreads; i++)
+ {
+ DWORD exitCode = STILL_ACTIVE;
+ while (exitCode == STILL_ACTIVE)
+ GetExitCodeThread(hThreads[i], &exitCode);
+ std::cout << "Process " << hThreads[i] << " finished with exit
code " <<
+ exitCode << std::endl;
+ }
+ for (i=0; i< nThreads; i++)
+ CloseHandle(hThreads[i]);
+ delete []ThreadIds;
+ delete []hThreads;
}
+
+#else
-void xsltMain(int argc, const char* argv[] ) throw(XMLException)
+#if defined(__GNUC__)
+
+void xsltMultiThreadedMain(CmdLineParams& params) throw(XMLException)
{
+ int nThreads = params.nThreads;
+ pthread_t *threads = new pthread_t[nThreads]; // array to receive
thread IDs
+ for (int i=0; i< nThreads; i++)
+ {
+ pthread_t thread;
+ int retVal = pthread_create(&thread, 0,
+ (void * (*)(void *))xsltMain, (void *) ¶ms);
+ if (retVal)
+ std::cout << "Thread creation failed." << std::endl;
+ else
+ {
+ std::cout << "Created thread: " << thread << std::endl;
+ threads[i] = thread;
+ }
+ }
+ // Wait for them to finish
+ for (int i=0; i< nThreads; i++)
+ pthread_join(threads[i], 0);
+}
-/**
- * Command line interface to transform the XML according to
- * the instructions found in the XSL document.
- * -in inputXMLURL
- * -xsl XSLTransformationURL
- * -out outputFileName
- * -F (Format output pretty-printed)
- */
- XMLPlatformUtils::Initialize();
- XSLTEngineImpl::Initialize();
+#else
+
+void xsltMultiThreadedMain(CmdLineParams& params) throw(XMLException)
+{
+ std::cout << "xsltMultiThreadedMain: Not valid on this platform" <<
std::endl;
+}
+
+#endif
+
+#endif
+
+
+
+static inline bool exists(std::string &filename)
+{
+ struct stat statBuffer;
+ return (0 == stat(filename.data(), &statBuffer));
+}
+static CmdLineParams theParams;
+THREADFUNCTIONRETURN xsltMain(void *vptr) throw(XMLException)
+{
+ const CmdLineParams& params = *((CmdLineParams *)vptr);
+ const std::string outputFileNameBase = theParams.outFileName;
+
// @@ This should become a command line switch
bool shouldWriteXMLHeader = false;
-
+
// Runtime.getRuntime().traceMethodCalls(false);
// Runtime.getRuntime().traceInstructions(false);
+
+
/**
- * The default diagnostic writer...
- */
+ * The default diagnostic writer...
+ */
XercesStdTextOutputStream
theStdOut(std::cout);
XercesStdTextOutputStream
theStdErr(std::cerr);
NullTextOutputStream theNullStream;
XercesDOMPrintWriter
diagnosticsWriter(theStdErr);
- XercesDOMPrintWriter
dumpWriter(theStdErr);
-
-
- if(argc < 2)
- {
- printArgOptions(diagnosticsWriter);
- }
- else
- {
- CmdLineParamsType params;
- /*
- * Get command line arguments
- */
- getArgs(argc, argv, params);
- std::auto_ptr<TextFileOutputStream> outputFileStream;
- TextOutputStream*
outputStream = &theStdOut;
+ std::auto_ptr<TextFileOutputStream> outputFileStream;
+ TextOutputStream* outputStream =
&theStdOut;
+ DOMSupportDefault theDOMSupport;
+ XercesParserLiaison xmlParserLiaison(theDOMSupport);
- DOMStringPrintWriter pw;
+ DOMStringPrintWriter pw;
- DOMSupportDefault theDOMSupport;
- XercesParserLiaison xmlParserLiaison(theDOMSupport);
+ XPathSupportDefault theXPathSupport(theDOMSupport);
+ XSLTProcessorEnvSupportDefault theXSLProcessorSupport;
+ XObjectFactoryDefault theXObjectFactory(theXSLProcessorSupport,
theXPathSupport);
+ XPathFactoryDefault theXPathFactory;
+
+ XSLTEngineImpl processor(
+ xmlParserLiaison, theXPathSupport,
+ theXSLProcessorSupport,
+ theXObjectFactory,
+ theXPathFactory);
- XPathSupportDefault theXPathSupport(theDOMSupport);
- XSLTProcessorEnvSupportDefault theXSLProcessorSupport;
- XObjectFactoryDefault theXObjectFactory(theXSLProcessorSupport,
theXPathSupport);
- XPathFactoryDefault theXPathFactory;
+ theXSLProcessorSupport.setProcessor(&processor);
+
+ processor.setFormatter(&xmlParserLiaison);
- XSLTEngineImpl processor(
- xmlParserLiaison, theXPathSupport,
- theXSLProcessorSupport,
- theXObjectFactory,
- theXPathFactory);
- theXSLProcessorSupport.setProcessor(&processor);
- /*
- * Set specified processor flags
- */
- if (params.setQuietConflictWarnings)
- processor.setQuietConflictWarnings(true);
+ // Use separate factory instances for the stylesheet. This is really
only necessary
+ // if you want to use the stylesheet with another processor, or you
want to use
+ // it multiple times.
+ XObjectFactoryDefault
theStylesheetXObjectFactory(theXSLProcessorSupport, theXPathSupport);
+ XPathFactoryDefault theStylesheetXPathFactory;
+
+ StylesheetConstructionContextDefault
theConstructionContext(processor,
+ theXSLProcessorSupport,
+ theStylesheetXObjectFactory,
+ theStylesheetXPathFactory);
+
+ XPathExecutionContextDefault
theXPathExecutionContext(theXSLProcessorSupport,
+ theXPathSupport,
+ theXObjectFactory);
+
+ StylesheetExecutionContextDefault
theExecutionContext(theXPathExecutionContext,
+ processor);
+
+ /*
+ * Set specified processor flags
+ */
+ if (params.setQuietConflictWarnings)
+ processor.setQuietConflictWarnings(true);
- if (! params.paramsMap.empty())
- {
- String2StringMapType::iterator it =
params.paramsMap.begin();
- for ( ; it != params.paramsMap.end(); it++)
-
processor.setStylesheetParam((*it).first.c_str(),
- (*it).second.c_str());
- }
+ if (params.paramsMap.size())
+ {
+ String2StringMapType::const_iterator it =
params.paramsMap.begin();
+ for ( ; it != params.paramsMap.end(); it++)
+ processor.setStylesheetParam((*it).first.data(),
+ (*it).second.data());
+ }
- /*
- * Set specified parser flags
- */
+ /*
+ * Set specified parser flags
+ */
+ if (params.indentAmount)
xmlParserLiaison.setIndent(params.indentAmount);
- xmlParserLiaison.setSpecialCharacters(params.specialCharacters);
-
xmlParserLiaison.SetShouldExpandEntityRefs(params.shouldExpandEntityRefs);
-
+ xmlParserLiaison.setSpecialCharacters(params.specialCharacters.data());
+
xmlParserLiaison.SetShouldExpandEntityRefs(params.shouldExpandEntityRefs);
- processor.setFormatter(&xmlParserLiaison);
+ bool noOutputFileSpecified = outputFileNameBase.empty();
+ assert(! params.inFileNames.empty());
+ int nInputFiles = params.inFileNames.size();
+ int nThreads = params.nThreads;
+ int outputType = params.outputType;
+ bool stripCData = params.stripCData;
+ bool escapeCData = params.escapeCData;
+
+ // The main XSL transformation occurs here!
+ if (! params.setQuietMode)
+ processor.setDiagnosticsOutput( &diagnosticsWriter );
- // Use separate factory instances for the stylesheet. This is
really only necessary
- // if you want to use the stylesheet with another processor, or
you want to use
- // it multiple times.
- XObjectFactoryDefault
theStylesheetXObjectFactory(theXSLProcessorSupport, theXPathSupport);
- XPathFactoryDefault theStylesheetXPathFactory;
+ StylesheetRoot* stylesheet = 0;
- StylesheetConstructionContextDefault
theConstructionContext(processor,
- theXSLProcessorSupport,
- theStylesheetXObjectFactory,
- theStylesheetXPathFactory);
+ DOMString xslFileName;
+ if(0 != params.xslFileName.size())
+ {
+ xslFileName = params.xslFileName.data();
+ }
- XPathExecutionContextDefault
theXPathExecutionContext(theXSLProcessorSupport,
- theXPathSupport,
- theXObjectFactory);
+ stylesheet = processor.processStylesheet(xslFileName,
theConstructionContext);
- StylesheetExecutionContextDefault
theExecutionContext(theXPathExecutionContext,
- processor);
+ DOMString mimeEncoding("UTF-8");
+ DOMString encoding("UTF-8");
- // The main XSL transformation occurs here!
- if (! params.setQuietMode)
- processor.setDiagnosticsOutput( &diagnosticsWriter );
+ FormatterListener* formatter = 0;
- StylesheetRoot* stylesheet = 0;
+ /*
+ * Main loop to process multiple documents with a single stylesheet
+ */
+ for (int i=0; i< nInputFiles; i++)
+ {
- if(0 != params.xslFileName.length())
+ std::string theInputFileName = params.inFileNames[i];
+ std::string outputFileName;
+ XSLTInputSource theInputSource(theInputFileName.data());
+ DOM_Node sourceTree =
processor.getSourceTreeFromInput(&theInputSource);
+
+ /*
+ * If no output file specified, and multiple input files, generate an
+ * output file based on the root of each input file; otherwise construct
+ * as many unique filenames as required using the original output file
+ * name as a base.
+ */
+ if (noOutputFileSpecified)
{
- stylesheet =
processor.processStylesheet(params.xslFileName, theConstructionContext);
+ if (nInputFiles > 1)
+ {
+ outputFileName =
+ theInputFileName.substr(0,
theInputFileName.find_last_of('.'));
+ outputFileName += ".out";
+ // Strip off protocol, if its a file
protocol for local machine,
+ // otherwise we're out of luck
+ std::string LOCALFILE = "file:///";
+ if (0 == outputFileName.find(LOCALFILE))
+ outputFileName =
outputFileName.substr(LOCALFILE.size());
+ }
}
-
- /*
- * If no output file specified, and multiple input files,
generate an
- * output file based on the root of each input file; otherwise
construct
- * as many unique filenames as required using the original
output file
- * name as a base
- */
- bool noOutputFileSpecified = params.outFileName.empty();
-
- DOMString mimeEncoding("UTF-8");
- DOMString encoding("UTF-8");
-
- FormatterListener* formatter = 0;
-
- assert(! params.inFileNames.empty());
-
-
- /*
- * Main loop to process multiple documents with a single
stylesheet
- */
- int nInputFiles = params.inFileNames.size();
- for (int i=0; i< nInputFiles; i++)
+ else
{
-
- std::string theInputFileName = params.inFileNames[i];
- std::string outputFileName;
- XSLTInputSource
theInputSource(theInputFileName.c_str());
- DOM_Node sourceTree =
processor.getSourceTreeFromInput(&theInputSource);
-
- if (noOutputFileSpecified)
+ outputFileName = outputFileNameBase;
+ if (nInputFiles > 1)
{
- if (nInputFiles > 1)
+ int ix = 0;
+ while (exists(outputFileName)) // Make
sure it's unique
{
- outputFileName =
- theInputFileName.substr(0,
theInputFileName.find_last_of('.'));
- outputFileName += ".out";
- // Strip off protocol, if its a
file protocol for local machine,
- // otherwise we're out of luck
- std::string LOCALFILE = "file:///";
- if (0 == outputFileName.find(LOCALFILE))
- outputFileName =
outputFileName.substr(LOCALFILE.size());
+ char buffer[16];
+ sprintf(buffer, "%d", ix++);
+ outputFileName = outputFileNameBase;
+ outputFileName += buffer;
}
- }
- else
- {
- outputFileName = params.outFileName;
- if (exists(outputFileName)) // Make
sure it's unique
- outputFileName += '0'+i;
-
}
- if (! outputFileName.empty())
- {
- outputFileStream =
- std::auto_ptr<TextFileOutputStream>(new
TextFileOutputStream(
-
outputFileName.c_str()));
- outputStream = outputFileStream.get();
- }
- XercesDOMPrintWriter resultWriter(*outputStream);
-
- assert(0 != stylesheet);
- if(Formatter::OUTPUT_METH_XML == params.outputType)
- {
- FormatterToXML* fToXML = new
FormatterToXML(resultWriter,
+ }
+ /*
+ * If multithreaded option specified, append the thread id
+ * to the output file name
+ */
+ if (nThreads > 1)
+ {
+ long pid =
+#if defined(WIN32)
+ GetCurrentThreadId();
+#else
+#if defined(__GNUC__)
+ pthread_self();
+#else
+ 0;
+#endif
+#endif
+ char buffer[16];
+ sprintf(buffer, ".%d", pid);
+ outputFileName += buffer;
+ }
+ if (! outputFileName.empty())
+ {
+ outputFileStream =
+ std::auto_ptr<TextFileOutputStream>(new
TextFileOutputStream(
+ outputFileName.data()));
+ outputStream = outputFileStream.get();
+ }
+ XercesDOMPrintWriter resultWriter(*outputStream);
+
+
+ assert(0 != stylesheet);
+
+ if(Formatter::OUTPUT_METH_XML == outputType)
+ {
+ FormatterToXML* fToXML = new
FormatterToXML(resultWriter,
+ stylesheet->m_version,
+ stylesheet->getOutputIndent(),
+ xmlParserLiaison.getIndent(),
+ mimeEncoding,
+ stylesheet->m_mediatype,
+ stylesheet->getOutputDoctypeSystem(),
+ stylesheet->getOutputDoctypePublic(),
+ true, // xmlDecl
+ stylesheet->m_standalone,
+ &(stylesheet->getCdataSectionElems()));
+ fToXML->m_shouldWriteXMLHeader = shouldWriteXMLHeader;
+ fToXML->m_attrSpecialChars =
xmlParserLiaison.getSpecialCharacters();
+ fToXML->m_stripCData = stripCData;
+ fToXML->m_escapeCData = escapeCData;
+ formatter = fToXML;
+ }
+ else if(Formatter::OUTPUT_METH_TEXT == outputType)
+ {
+ FormatterToText* fToText = new
FormatterToText(resultWriter);
+ formatter = fToText;
+ }
+ else if(Formatter::OUTPUT_METH_HTML == outputType)
+ {
+ FormatterToHTML* fToHTML
+ = new FormatterToHTML(resultWriter,
stylesheet->m_version,
stylesheet->getOutputIndent(),
- xmlParserLiaison.getIndent(),
- mimeEncoding,
+ xmlParserLiaison.getIndent(),
mimeEncoding,
stylesheet->m_mediatype,
stylesheet->getOutputDoctypeSystem(),
stylesheet->getOutputDoctypePublic(),
- true, // xmlDecl
+ false, // xmlDecl
stylesheet->m_standalone,
&(stylesheet->getCdataSectionElems()));
- fToXML->m_shouldWriteXMLHeader =
shouldWriteXMLHeader;
- fToXML->m_attrSpecialChars =
xmlParserLiaison.getSpecialCharacters();
- fToXML->m_stripCData = params.stripCData;
- fToXML->m_escapeCData = params.escapeCData;
- formatter = fToXML;
- }
- else if(Formatter::OUTPUT_METH_TEXT ==
params.outputType)
- {
- FormatterToText* fToText = new
FormatterToText(resultWriter);
- formatter = fToText;
- }
- else if(Formatter::OUTPUT_METH_HTML ==
params.outputType)
- {
- FormatterToHTML* fToHTML
- = new FormatterToHTML(resultWriter,
- stylesheet->m_version,
-
stylesheet->getOutputIndent(),
-
xmlParserLiaison.getIndent(), mimeEncoding,
- stylesheet->m_mediatype,
-
stylesheet->getOutputDoctypeSystem(),
-
stylesheet->getOutputDoctypePublic(),
- false, // xmlDecl
-
stylesheet->m_standalone,
-
&(stylesheet->getCdataSectionElems()));
-
- fToHTML->m_attrSpecialChars =
xmlParserLiaison.getSpecialCharacters();
- fToHTML->m_stripCData = params.stripCData;
- formatter = fToHTML;
- }
- XSLTResultTarget* rTreeTarget = 0;
- if(0 == formatter)
- {
- rTreeTarget = new
XSLTResultTarget(&resultWriter);
- }
- else
- {
- rTreeTarget = new XSLTResultTarget();
- rTreeTarget->setFormatterListener(formatter);
-
xmlParserLiaison.setFormatterListener(formatter);
- }
- stylesheet->process(sourceTree, *rTreeTarget,
theExecutionContext);
- delete rTreeTarget;
+ fToHTML->m_attrSpecialChars =
xmlParserLiaison.getSpecialCharacters();
+ fToHTML->m_stripCData = stripCData;
+ formatter = fToHTML;
}
+ XSLTResultTarget* rTreeTarget = 0;
+ if(0 == formatter)
+ {
+ rTreeTarget = new XSLTResultTarget(&resultWriter);
+ }
+ else
+ {
+ rTreeTarget = new XSLTResultTarget();
+ rTreeTarget->setFormatterListener(formatter);
+ xmlParserLiaison.setFormatterListener(formatter);
+ }
+ stylesheet->process(sourceTree, *rTreeTarget,
theExecutionContext);
delete formatter;
+ delete rTreeTarget;
}
-}
+ return 0;
+}
int main(int argc, const char* argv[]) throw()
{
+ /**
+ * Command line interface to transform the XML according to
+ * the instructions found in the XSL document.
+ * -in inputXMLURL
+ * -xsl XSLTransformationURL
+ * -out outputFileName
+ * -F (Format output pretty-printed)
+ */
+
+ XMLPlatformUtils::Initialize();
+ XSLTEngineImpl::Initialize();
+
+ /*
+ * Get command line arguments
+ */
+ getArgs(argc, argv, theParams);
+
try
{
- xsltMain(argc, argv);
+ if (theParams.nThreads > 1)
+ xsltMultiThreadedMain(theParams);
+ else
+ xsltMain(&theParams);
}
catch (XSLException& e)
@@ -564,3 +727,4 @@
return 0;
}
+