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 "postextstl.h"
57 
58 namespace {
59 
60 void usageFailure() {
61     std::cerr
62         << ("Usage: cppunittester (--protector <shared-library-path>"
63             " <function-symbol>)* <shared-library-path>")
64         << std::endl;
65     std::exit(EXIT_FAILURE);
66 }
67 
68 rtl::OUString getArgument(sal_Int32 index) {
69     rtl::OUString arg;
70     rtl_getAppCommandArg(index, &arg.pData);
71     return arg;
72 }
73 
74 std::string convertLazy(rtl::OUString const & s16) {
75     rtl::OString s8(rtl::OUStringToOString(s16, osl_getThreadTextEncoding()));
76     return std::string(
77         s8.getStr(),
78         ((static_cast< sal_uInt32 >(s8.getLength())
79           > std::numeric_limits< std::string::size_type >::max())
80          ? std::numeric_limits< std::string::size_type >::max()
81          : static_cast< std::string::size_type >(s8.getLength())));
82 }
83 
84 std::string convertStrict(rtl::OUString const & s16) {
85     rtl::OString s8;
86     if (!s16.convertToString(
87             &s8, osl_getThreadTextEncoding(),
88             (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR
89              | RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
90         || (static_cast< sal_uInt32 >(s8.getLength())
91             > std::numeric_limits< std::string::size_type >::max()))
92     {
93         std::cerr
94             << "Failure converting argument from UTF-16 back to system encoding"
95             << std::endl;
96         std::exit(EXIT_FAILURE);
97     }
98     return std::string(
99         s8.getStr(), static_cast< std::string::size_type >(s8.getLength()));
100 }
101 
102 }
103 
104 SAL_IMPLEMENT_MAIN() {
105     CppUnit::TestResult result;
106     sal_uInt32 index = 0;
107     for (; index < rtl_getAppCommandArgCount(); index += 3) {
108         if (!getArgument(index).equalsAsciiL(
109                 RTL_CONSTASCII_STRINGPARAM("--protector")))
110         {
111             break;
112         }
113         if (rtl_getAppCommandArgCount() - index < 3) {
114             usageFailure();
115         }
116         rtl::OUString lib(getArgument(index + 1));
117         rtl::OUString sym(getArgument(index + 2));
118         oslGenericFunction fn = (new osl::Module(lib, SAL_LOADMODULE_GLOBAL))
119             ->getFunctionSymbol(sym);
120         CppUnit::Protector * p = fn == 0
121             ? 0
122             : (*reinterpret_cast< cppunittester::ProtectorFactory * >(fn))();
123         if (p == 0) {
124             std::cerr
125                 << "Failure instantiating protector \"" << convertLazy(lib)
126                 << "\", \"" << convertLazy(sym) << '"' << std::endl;
127             std::exit(EXIT_FAILURE);
128         }
129         result.pushProtector(p);
130     }
131     if (rtl_getAppCommandArgCount() - index != 1) {
132         usageFailure();
133     }
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     return collector.wasSuccessful() ? EXIT_SUCCESS : EXIT_FAILURE;
143 }
144