From fb49a723c0b8906bd4840b52d711bc337c0bc4e3 Mon Sep 17 00:00:00 2001 From: "axel%pike.org" Date: Thu, 16 Jan 2003 15:02:13 +0000 Subject: [PATCH] not part of build, a C interface to the XALAN testcases. produces rdf output to load into buster. test app only git-svn-id: svn://10.0.0.236/trunk@136416 18797224-902f-48f8-a5cc-f745e15eee43 --- .../transformiix/source/main/testXalan.cpp | 412 ++++++++++++++++++ 1 file changed, 412 insertions(+) create mode 100644 mozilla/extensions/transformiix/source/main/testXalan.cpp diff --git a/mozilla/extensions/transformiix/source/main/testXalan.cpp b/mozilla/extensions/transformiix/source/main/testXalan.cpp new file mode 100644 index 00000000000..b31cf9e5c14 --- /dev/null +++ b/mozilla/extensions/transformiix/source/main/testXalan.cpp @@ -0,0 +1,412 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (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.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is TransforMiiX XSLT Processor. + * + * The Initial Developer of the Original Code is + * Axel Hecht. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Axel Hecht + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "txStandaloneXSLTProcessor.h" +#include "nsXPCOM.h" +#include +#include "nsDoubleHashtable.h" +#include "nsIComponentManager.h" +#include "nsILocalFile.h" +#include "nsISimpleEnumerator.h" +#include "nsString.h" +#include "nsVoidArray.h" +#include "prenv.h" +#include "nsDirectoryServiceUtils.h" +#include "nsDirectoryServiceDefs.h" + +#ifdef NS_TRACE_MALLOC +#include "nsTraceMalloc.h" +#endif + +/** + * Prints the command line help screen to the console + */ +void printHelp() +{ + cerr << "testXalan [-o output-file] [category]*" << endl << endl; + cerr << "Options:"; + cerr << endl << endl; + cerr << "\t-o specify output file (default: write to stdout)"; + cerr << endl << endl; + cerr << "\t Specify XALAN_DIR in your environement." << endl; + cerr << endl; +} + +/** + * Helper class to report success and failure to RDF + */ +class txRDFOut +{ +public: + explicit txRDFOut(ostream* aOut) + : mOut(aOut), mSuccess(0), mFail(0), mParent(nsnull) + { + } + explicit txRDFOut(const nsACString& aName, txRDFOut* aParent) + : mName(aName), mOut(aParent->mOut), mSuccess(0), mFail(0), + mParent(aParent) + { + } + ~txRDFOut() + { + *mOut << " \n" << + " " << + mSuccess << + "\n" << + " " << + mFail << + "\n" << + " " << endl; + } + + void feed(const nsACString& aTest, PRBool aSuccess) + { + *mOut << " \n"; + } + + void succeeded() + { + if (mParent) + mParent->succeeded(); + ++mSuccess; + } + void failed() + { + if (mParent) + mParent->failed(); + ++mFail; + } +private: + nsCAutoString mName; + ostream* mOut; + PRUint32 mSuccess, mFail; + txRDFOut* mParent; +}; + +static void +readToString(istream& aIstream, nsACString& aString) +{ + static char buffer[1024]; + int read = 0; + do { + aIstream.read(buffer, 1024); + read = aIstream.gcount(); + aString.Append(Substring(buffer, buffer + read)); + } while (!aIstream.eof()); +} + +/** + * Get the XALAN_DIR environment variable and return a nsIFile for + * the conf and the conf-gold subdirectory. Create a TEMP file, too. + * Return an error if either does not exist. + */ +static nsresult +setupXalan(const char* aPath, nsIFile** aConf, nsIFile** aConfGold, + nsIFile** aTemp) +{ + nsresult rv; + nsCOMPtr conf(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, + &rv)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr tmpFile; + rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(tmpFile)); + NS_ENSURE_SUCCESS(rv, rv); + tmpFile->Append(NS_LITERAL_STRING("xalan.out")); + rv = tmpFile->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 0600); + rv = conf->InitWithNativePath(nsDependentCString(aPath)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr gold; + rv = conf->Clone(getter_AddRefs(gold)); + NS_ENSURE_SUCCESS(rv, rv); + rv = conf->Append(NS_LITERAL_STRING("conf")); + NS_ENSURE_SUCCESS(rv, rv); + PRBool isDir; + rv = conf->IsDirectory(&isDir); + if (NS_FAILED(rv) || !isDir) { + return NS_ERROR_FILE_NOT_DIRECTORY; + } + rv = gold->Append(NS_LITERAL_STRING("conf-gold")); + NS_ENSURE_SUCCESS(rv, rv); + rv = gold->IsDirectory(&isDir); + if (NS_FAILED(rv) || !isDir || !conf || !gold) { + return NS_ERROR_FILE_NOT_DIRECTORY; + } + // got conf and conf-gold subdirectories + *aConf = conf; + NS_ADDREF(*aConf); + *aConfGold = gold; + NS_ADDREF(*aConfGold); + *aTemp = tmpFile; + NS_ADDREF(*aTemp); + return NS_OK; +} + +/** + * Run a category of Xalan tests + */ +void runCategory(nsIFile* aConfCat, nsIFile* aGoldCat, nsIFile* aRefTmp, + txRDFOut* aOut) +{ + nsresult rv; + //clone the nsIFiles, so that we can return easily + nsCOMPtr conf, gold; + aConfCat->Clone(getter_AddRefs(conf)); + aGoldCat->Clone(getter_AddRefs(gold)); + nsCAutoString catName, refTmp; + conf->GetNativeLeafName(catName); + aRefTmp->GetNativePath(refTmp); + txRDFOut results(catName, aOut); + nsCOMPtr tests; + rv = conf->GetDirectoryEntries(getter_AddRefs(tests)); + if (NS_FAILED(rv)) + return; + PRBool hasMore, isFile; + nsCAutoString leaf; + NS_NAMED_LITERAL_CSTRING(xsl, ".xsl"); + while (NS_SUCCEEDED(tests->HasMoreElements(&hasMore)) && hasMore) { + nsCOMPtr test; + tests->GetNext(getter_AddRefs(test)); + test->GetNativeLeafName(leaf); + if (xsl.Equals(Substring(leaf, leaf.Length()-4, 4))) { + // we have a stylesheet, let's look for source and reference + nsAFlatCString::char_iterator start, ext; + leaf.BeginWriting(start); + leaf.EndWriting(ext); + ext -= 2; + // overwrite extension with .xml + *ext = 'm'; // this one was easy + nsCOMPtr source; + conf->Clone(getter_AddRefs(source)); + rv = source->AppendNative(leaf); + if (NS_SUCCEEDED(rv) && NS_SUCCEEDED(source->IsFile(&isFile)) && + isFile) { + nsCOMPtr reference; + gold->Clone(getter_AddRefs(reference)); + // overwrite extension with .out + --ext; + nsCharTraits::copy(ext, "out", 3); + rv = reference->AppendNative(leaf); + if (NS_SUCCEEDED(rv) && + NS_SUCCEEDED(reference->IsFile(&isFile)) && + isFile) { + nsCAutoString src, style, refPath; + test->GetNativePath(style); + source->GetNativePath(src); + reference->GetNativePath(refPath); + SimpleErrorObserver obs; + txStandaloneXSLTProcessor proc; + fstream result(refTmp.get(), + ios::in | ios::out | ios::trunc); + rv = proc.transform(src, style, result, obs); + PRBool success = PR_FALSE; + if (NS_SUCCEEDED(rv)) { + result.flush(); + PRInt64 resultSize, refSize; + aRefTmp->GetFileSize(&resultSize); + reference->GetFileSize(&refSize); + result.seekg(0); + int read, toread = (int)resultSize; + nsCString resContent, refContent; + resContent.SetCapacity(toread); + readToString(result, resContent); + result.close(); + ifstream refStream(refPath.get()); + toread = (int)refSize; + refContent.SetCapacity(toread); + readToString(refStream, refContent); + refStream.close(); + success = resContent.Equals(refContent); + } + ext--; + results.feed(Substring(start, ext), success); + } + } + } + } +} +/** + * The Xalan testcases app + */ +int main(int argc, char** argv) +{ +#ifdef NS_TRACE_MALLOC + NS_TraceMallocStartupArgs(argc, argv); +#endif + char* xalan = PR_GetEnv("XALAN_DIR"); + if (!xalan) { + printHelp(); + return 1; + } + nsresult rv; + rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr conf, gold, resFile; + rv = setupXalan(xalan, getter_AddRefs(conf), getter_AddRefs(gold), + getter_AddRefs(resFile)); + if (NS_FAILED(rv)) { + NS_ShutdownXPCOM(nsnull); + printHelp(); + return -1; + } + + //-- handle output stream + ostream* resultOutput = &cout; + ofstream resultFileStream; + + int argn = 1; + // skip -- gnu style options + while (argn < argc) { + nsDependentCString opt(argv[argn]); + if (!Substring(opt, 0, 2).Equals(NS_LITERAL_CSTRING("--"))) { + break; + } + ++argn; + } + if (argn < argc) { + nsDependentCString opt(argv[argn]); + if (Substring(opt, 0, 2).Equals(NS_LITERAL_CSTRING("-o"))) { + if (opt.Length() > 2) { + const nsAFlatCString& fname = + PromiseFlatCString(Substring(opt, 2, opt.Length()-2)); + resultFileStream.open(fname.get(), ios::out); + } + else { + ++argn; + if (argn < argc) { + resultFileStream.open(argv[argn], ios::out); + } + } + if (!resultFileStream) { + cerr << "error opening output file" << endl; + PRBool exists; + if (NS_SUCCEEDED(resFile->Exists(&exists)) && exists) + resFile->Remove(PR_FALSE); + NS_ShutdownXPCOM(nsnull); + return -1; + } + ++argn; + resultOutput = &resultFileStream; + } + } + + if (!txXSLTProcessor::txInit()) { + PRBool exists; + if (NS_SUCCEEDED(resFile->Exists(&exists)) && exists) + resFile->Remove(PR_FALSE); + NS_ShutdownXPCOM(nsnull); + return 1; + } + + *resultOutput << "\n" << + "" << endl; + + txRDFOut* rdfOut = new txRDFOut(resultOutput); + nsCOMPtr tempFile; + if (argn < argc) { + // categories are specified + while (argn < argc) { + nsDependentCString cat(argv[argn++]); + rv = conf->AppendNative(cat); + if (NS_SUCCEEDED(rv)) { + rv = gold->AppendNative(cat); + if (NS_SUCCEEDED(rv)) { + runCategory(conf, gold, resFile, rdfOut); + rv = gold->GetParent(getter_AddRefs(tempFile)); + NS_ASSERTION(NS_SUCCEEDED(rv), "can't go back?"); + gold = tempFile; + } + rv = conf->GetParent(getter_AddRefs(tempFile)); + NS_ASSERTION(NS_SUCCEEDED(rv), "can't go back?"); + conf = tempFile; + } + } + } + else { + // no category specified, do everything + nsCOMPtr cats; + rv = conf->GetDirectoryEntries(getter_AddRefs(cats)); + PRBool hasMore, isDir; + nsCAutoString leaf; + while (NS_SUCCEEDED(cats->HasMoreElements(&hasMore)) && hasMore) { + nsCOMPtr cat; + cats->GetNext(getter_AddRefs(cat)); + rv = cat->IsDirectory(&isDir); + if (NS_SUCCEEDED(rv) && isDir) { + rv = cat->GetNativeLeafName(leaf); + if (NS_SUCCEEDED(rv) && + !leaf.Equals(NS_LITERAL_CSTRING("CVS"))) { + rv = gold->AppendNative(leaf); + if (NS_SUCCEEDED(rv)) { + runCategory(cat, gold, resFile, rdfOut); + rv = gold->GetParent(getter_AddRefs(tempFile)); + gold = tempFile; + } + } + } + } + } + delete rdfOut; + rdfOut = nsnull; + *resultOutput << "" << endl; + PRBool exists; + if (NS_SUCCEEDED(resFile->Exists(&exists)) && exists) + resFile->Remove(PR_FALSE); + resultFileStream.close(); + txXSLTProcessor::txShutdown(); + rv = NS_ShutdownXPCOM(nsnull); +#ifdef NS_TRACE_MALLOC + NS_TraceMallocShutdown(); +#endif + NS_ENSURE_SUCCESS(rv, rv); + return 0; +}