1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #include "precompiled_sal.hxx"
25 #include "sal/config.h"
26 
27 #include <cstdlib>
28 #include <iostream>
29 #include <limits>
30 #include <string>
31 
32 #include "cppunittester/protectorfactory.hxx"
33 #include "osl/module.h"
34 #include "osl/module.hxx"
35 #include "osl/thread.h"
36 #include "rtl/process.h"
37 #include "rtl/string.h"
38 #include "rtl/string.hxx"
39 #include "rtl/textcvt.h"
40 #include "rtl/ustring.hxx"
41 #include "sal/main.h"
42 #include "sal/types.h"
43 
44 #include "preextstl.h"
45 #include "cppunit/CompilerOutputter.h"
46 #include "cppunit/TestResult.h"
47 #include "cppunit/TestResultCollector.h"
48 #include "cppunit/TestRunner.h"
49 #include "cppunit/extensions/TestFactoryRegistry.h"
50 #include "cppunit/plugin/PlugInManager.h"
51 #include "cppunit/portability/Stream.h"
52 #include "cppunit/plugin/DynamicLibraryManagerException.h"
53 #include "postextstl.h"
54 
55 namespace {
56 
usageFailure()57 void usageFailure() {
58     std::cerr
59         << ("Usage: cppunittester (--protector <shared-library-path>"
60             " <function-symbol>)* <shared-library-path>")
61         << std::endl;
62     std::exit(EXIT_FAILURE);
63 }
64 
getArgument(sal_Int32 index)65 rtl::OUString getArgument(sal_Int32 index) {
66     rtl::OUString arg;
67     rtl_getAppCommandArg(index, &arg.pData);
68     return arg;
69 }
70 
convertLazy(rtl::OUString const & s16)71 std::string convertLazy(rtl::OUString const & s16) {
72     rtl::OString s8(rtl::OUStringToOString(s16, osl_getThreadTextEncoding()));
73     return std::string(
74         s8.getStr(),
75         ((static_cast< sal_uInt32 >(s8.getLength())
76           > std::numeric_limits< std::string::size_type >::max())
77          ? std::numeric_limits< std::string::size_type >::max()
78          : static_cast< std::string::size_type >(s8.getLength())));
79 }
80 
convertStrict(rtl::OUString const & s16)81 std::string convertStrict(rtl::OUString const & s16) {
82     rtl::OString s8;
83     if (!s16.convertToString(
84             &s8, osl_getThreadTextEncoding(),
85             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
86              | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
87         || (static_cast< sal_uInt32 >(s8.getLength())
88             > std::numeric_limits< std::string::size_type >::max()))
89     {
90         std::cerr
91             << "Failure converting argument from UTF-16 back to system encoding"
92             << std::endl;
93         std::exit(EXIT_FAILURE);
94     }
95     return std::string(
96         s8.getStr(), static_cast< std::string::size_type >(s8.getLength()));
97 }
98 
99 }
100 
SAL_IMPLEMENT_MAIN()101 SAL_IMPLEMENT_MAIN() {
102     CppUnit::TestResult result;
103     sal_uInt32 index = 0;
104     for (; index < rtl_getAppCommandArgCount(); index += 3) {
105         if (!getArgument(index).equalsAsciiL(
106                 RTL_CONSTASCII_STRINGPARAM("--protector")))
107         {
108             break;
109         }
110         if (rtl_getAppCommandArgCount() - index < 3) {
111             usageFailure();
112         }
113         rtl::OUString lib(getArgument(index + 1));
114         rtl::OUString sym(getArgument(index + 2));
115         oslGenericFunction fn = (new osl::Module(lib, SAL_LOADMODULE_GLOBAL))
116             ->getFunctionSymbol(sym);
117         CppUnit::Protector * p = fn == 0
118             ? 0
119             : (*reinterpret_cast< cppunittester::ProtectorFactory * >(fn))();
120         if (p == 0) {
121             std::cerr
122                 << "Failure instantiating protector \"" << convertLazy(lib)
123                 << "\", \"" << convertLazy(sym) << '"' << std::endl;
124             std::exit(EXIT_FAILURE);
125         }
126         result.pushProtector(p);
127     }
128     if (rtl_getAppCommandArgCount() - index != 1) {
129         usageFailure();
130     }
131 
132 	bool bSuccess = false;
133 	try {
134 		CppUnit::PlugInManager manager;
135 		manager.load(convertStrict(getArgument(index)));
136 		CppUnit::TestRunner runner;
137 		runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
138 		CppUnit::TestResultCollector collector;
139 		result.addListener(&collector);
140 		runner.run(result);
141 		CppUnit::CompilerOutputter(&collector, CppUnit::stdCErr()).write();
142 		bSuccess = collector.wasSuccessful();
143 	} catch( CppUnit::DynamicLibraryManagerException& e) {
144 		std::cerr << "DynamicLibraryManagerException: \"" << e.what() << "\"\n";
145 	}
146 
147     return bSuccess ? EXIT_SUCCESS : EXIT_FAILURE;
148 }
149