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