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 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 65 rtl::OUString getArgument(sal_Int32 index) { 66 rtl::OUString arg; 67 rtl_getAppCommandArg(index, &arg.pData); 68 return arg; 69 } 70 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 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 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