1 /*************************************************************************
2 *
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
6 *
7 * OpenOffice.org - a multi-platform office productivity suite
8 *
9 * This file is part of OpenOffice.org.
10 *
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
14 *
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
20 *
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org.  If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
25 *
26 ************************************************************************/
27 
28 #include "precompiled_sal.hxx"
29 #include "sal/config.h"
30 
31 #include <cstdlib>
32 #include <iostream>
33 #include <limits>
34 #include <string>
35 
36 #include "cppunittester/protectorfactory.hxx"
37 #include "osl/module.h"
38 #include "osl/module.hxx"
39 #include "osl/thread.h"
40 #include "rtl/process.h"
41 #include "rtl/string.h"
42 #include "rtl/string.hxx"
43 #include "rtl/textcvt.h"
44 #include "rtl/ustring.hxx"
45 #include "sal/main.h"
46 #include "sal/types.h"
47 
48 #include "preextstl.h"
49 #include "cppunit/CompilerOutputter.h"
50 #include "cppunit/TestResult.h"
51 #include "cppunit/TestResultCollector.h"
52 #include "cppunit/TestRunner.h"
53 #include "cppunit/extensions/TestFactoryRegistry.h"
54 #include "cppunit/plugin/PlugInManager.h"
55 #include "cppunit/portability/Stream.h"
56 #include "cppunit/plugin/DynamicLibraryManagerException.h"
57 #include "postextstl.h"
58 
59 namespace {
60 
61 void usageFailure() {
62     std::cerr
63         << ("Usage: cppunittester (--protector <shared-library-path>"
64             " <function-symbol>)* <shared-library-path>")
65         << std::endl;
66     std::exit(EXIT_FAILURE);
67 }
68 
69 rtl::OUString getArgument(sal_Int32 index) {
70     rtl::OUString arg;
71     rtl_getAppCommandArg(index, &arg.pData);
72     return arg;
73 }
74 
75 std::string convertLazy(rtl::OUString const & s16) {
76     rtl::OString s8(rtl::OUStringToOString(s16, osl_getThreadTextEncoding()));
77     return std::string(
78         s8.getStr(),
79         ((static_cast< sal_uInt32 >(s8.getLength())
80           > std::numeric_limits< std::string::size_type >::max())
81          ? std::numeric_limits< std::string::size_type >::max()
82          : static_cast< std::string::size_type >(s8.getLength())));
83 }
84 
85 std::string convertStrict(rtl::OUString const & s16) {
86     rtl::OString s8;
87     if (!s16.convertToString(
88             &s8, osl_getThreadTextEncoding(),
89             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
90              | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
91         || (static_cast< sal_uInt32 >(s8.getLength())
92             > std::numeric_limits< std::string::size_type >::max()))
93     {
94         std::cerr
95             << "Failure converting argument from UTF-16 back to system encoding"
96             << std::endl;
97         std::exit(EXIT_FAILURE);
98     }
99     return std::string(
100         s8.getStr(), static_cast< std::string::size_type >(s8.getLength()));
101 }
102 
103 }
104 
105 SAL_IMPLEMENT_MAIN() {
106     CppUnit::TestResult result;
107     sal_uInt32 index = 0;
108     for (; index < rtl_getAppCommandArgCount(); index += 3) {
109         if (!getArgument(index).equalsAsciiL(
110                 RTL_CONSTASCII_STRINGPARAM("--protector")))
111         {
112             break;
113         }
114         if (rtl_getAppCommandArgCount() - index < 3) {
115             usageFailure();
116         }
117         rtl::OUString lib(getArgument(index + 1));
118         rtl::OUString sym(getArgument(index + 2));
119         oslGenericFunction fn = (new osl::Module(lib, SAL_LOADMODULE_GLOBAL))
120             ->getFunctionSymbol(sym);
121         CppUnit::Protector * p = fn == 0
122             ? 0
123             : (*reinterpret_cast< cppunittester::ProtectorFactory * >(fn))();
124         if (p == 0) {
125             std::cerr
126                 << "Failure instantiating protector \"" << convertLazy(lib)
127                 << "\", \"" << convertLazy(sym) << '"' << std::endl;
128             std::exit(EXIT_FAILURE);
129         }
130         result.pushProtector(p);
131     }
132     if (rtl_getAppCommandArgCount() - index != 1) {
133         usageFailure();
134     }
135 
136 	bool bSuccess = false;
137 	try {
138 		CppUnit::PlugInManager manager;
139 		manager.load(convertStrict(getArgument(index)));
140 		CppUnit::TestRunner runner;
141 		runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
142 		CppUnit::TestResultCollector collector;
143 		result.addListener(&collector);
144 		runner.run(result);
145 		CppUnit::CompilerOutputter(&collector, CppUnit::stdCErr()).write();
146 		bSuccess = collector.wasSuccessful();
147 	} catch( CppUnit::DynamicLibraryManagerException& e) {
148 		std::cerr << "DynamicLibraryManagerException: \"" << e.what() << "\"\n";
149 	}
150 
151     return bSuccess ? EXIT_SUCCESS : EXIT_FAILURE;
152 }
153