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 #include <iostream> 28 29 #include "sal/main.h" 30 #include "rtl/process.h" 31 #include "rtl/ustrbuf.hxx" 32 #include "unodevtools/typemanager.hxx" 33 #include "unodevtools/options.hxx" 34 #include "skeletonjava.hxx" 35 #include "skeletoncpp.hxx" 36 37 #include "com/sun/star/uno/Reference.hxx" 38 39 using namespace ::rtl; 40 using namespace ::skeletonmaker; 41 using namespace ::unodevtools; 42 using namespace ::com::sun::star::uno; 43 44 namespace { 45 46 static const char usageText[] = 47 "\n sub-commands:\n" 48 " dump dump declarations on stdout (e.g. constructors, methods, type\n" 49 " mapping for properties) or complete method bodies with\n" 50 " method forwarding.\n" 51 " component generates language specific code skeleton files using the\n" 52 " implementation name as the file and class name\n" 53 " calc-add-in generates a language specific code skeleton for a calc add-in\n" 54 " using the implementation name as the file and class name. A \n" 55 " service type is necessary, referencing an interface which defines\n" 56 " the new add-in functions.\n" 57 " add-on generates a language specific code skeleton for an add-on compnent\n" 58 " using the implementation name as the file and class name. The protocol\n" 59 " name(s) and the corresponding command(s) have to be specified with the\n" 60 " '-p' option.\n" 61 "\n options:\n" 62 " -env:INIFILENAME=<url> url specifies a URL to an UNO ini|rc file of an\n" 63 " existing UNO environment (URE, office installation).\n" 64 " -env:UNO_TYPES=<url> url specifies a binary type library file. It can be\n" 65 " a space separated list of urls.\n" 66 " -a, --all list all interface methods, not only the direct\n" 67 " ones\n" 68 " --(java4|java5|cpp) select the target language\n" 69 " --java4 generate output for Java 1.4 or earlier\n" 70 " --java5 generate output for Java 1.5 or later (is \n" 71 " currently the default)\n" 72 " --cpp generate output for C++\n" 73 " -sn, --shortnames using namespace abbreviation 'css:': for\n" 74 " '::com::sun::star::', only valid for sub-command\n" 75 " 'dump' and target language 'cpp'. It is default for the\n" 76 " sub-command 'component'.\n" 77 " --propertysetmixin the generated skeleton implements the cppu::PropertySetMixin\n" 78 " helper if a referenced new style service specifies an\n" 79 " interface which provides attributes (directly or inherited).\n" 80 " -lh --licenseheader generates a default OpenOffice.org LGPL license\n" 81 " header at the beginning of a component source file.\n" 82 " This option is taken into account in 'component' mode\n" 83 " only and if -o is unequal 'stdout'.\n" 84 " -bc specifies that the generated calc add-in is backward\n" 85 " --backward-compatible compatible to older office versions and implement the\n" 86 " former required add-in interfaces where the implementation\n" 87 " is mapped on the new add-in configuration. In this case\n" 88 " the config schema needs to be bundled with the extension\n" 89 " add-in as well. Default is a minimal add-in component\n" 90 " skeleton based on the configuration coming with the\n" 91 " office since OO.org 2.0.4.\n" 92 " -o <path> path specifies an existing directory where the\n" 93 " output files are generated to, only valid for\n" 94 " sub-command 'component'. If path=stdout the generated\n" 95 " code is generated on standard out instead of a file.\n" 96 " -l <file> specifies a binary type library (can be used more\n" 97 " than once). The type library is integrated as an\n" 98 " additional type provider in the bootstrapped type\n" 99 " system.\n" 100 " -n <name> specifies an implementation name for the component\n" 101 " (used as classname, filename and package|namespace\n" 102 " name). In 'dump' mode it is used as classname (e.g.\n" 103 " \"MyBase::\", C++ only) to generate method bodies not\n" 104 " inline.\n" 105 " -d <name> specifies a base classname or a delegator.\n" 106 " In 'dump' mode it is used as a delegator to forward\n" 107 " methods. It can be used as '<name>::' for base\n" 108 " forwarding, or '<name>->|.' for composition.\n" 109 " Using \"_\" means that a default bodies with default\n" 110 " return values are dumped.\n" 111 " -t <name> specifies an UNOIDL type name, e.g.\n" 112 " com.sun.star.text.XText (can be used more than once)\n" 113 " -p <protocol:cmd(s)> specifies an add-on protocol name and the corresponding\n" 114 " command names, where the commands are a ',' separated list\n" 115 " of unique commands. This option is only valid for add-ons.\n" 116 " -V, --version print version number and exit\n" 117 " -h, --help print this help and exit\n\n"; 118 119 void printUsageAndExit(const char* programname, const char* version) 120 { 121 std::cerr 122 << "\n using: " << programname 123 << " (-env:INIFILENAME=<url> | -env:UNO_TYPES=<url>)\n" 124 << " dump [<options>] -t <type> ...\n" 125 << " " << programname 126 << " (-env:INIFILENAME=<url> | -env:UNO_TYPES=<url>)\n" 127 << " component [<options>] -n <name> -t <type> ...\n" 128 << " " << programname 129 << " (-env:INIFILENAME=<url> | -env:UNO_TYPES=<url>)\n" 130 << " calc-add-in [<options>] -n <name> -t <add-in_service>\n" 131 << " " << programname 132 << " (-env:INIFILENAME=<url> | -env:UNO_TYPES=<url>)\n" 133 << " add-on [<options>] -n <name> -p <protocol_name:command,...>\n" 134 << " " << programname << " -V, --version\n" 135 << " " << programname << " -h, --help\n" 136 << usageText 137 << programname << " Version " << version << "\n\n"; 138 } 139 140 } 141 142 SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, /*argv*/) 143 { 144 const char* version = "0.4"; 145 const char* programname = "uno-skeletonmaker"; 146 147 if ( argc <= 1 ) { 148 printUsageAndExit(programname, version); 149 exit(EXIT_FAILURE); 150 } 151 152 ProgramOptions options; 153 std::vector< OUString > registries; 154 std::vector< OString > types; 155 OString delegate; 156 157 try { 158 159 sal_Int32 nPos = 0; 160 sal_Int32 nCount = (sal_Int32)rtl_getAppCommandArgCount(); 161 OUString arg, sOption; 162 sal_Bool bOption=sal_False; 163 164 // check command 165 rtl_getAppCommandArg(nPos++, &arg.pData); 166 if ( arg.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("dump"))) ) { 167 options.dump = true; 168 } else if ( arg.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("component"))) ) { 169 options.dump = false; 170 options.shortnames = true; 171 } else if ( arg.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("calc-add-in"))) ) { 172 options.dump = false; 173 options.shortnames = true; 174 options.componenttype = 2; 175 } else if ( arg.equals(OUString(RTL_CONSTASCII_USTRINGPARAM("add-on"))) ) { 176 options.dump = false; 177 options.shortnames = true; 178 options.componenttype = 3; 179 } else if ( readOption( &bOption, "h", &nPos, arg) || 180 readOption( &bOption, "help", &nPos, arg) ) { 181 printUsageAndExit(programname, version); 182 exit(EXIT_SUCCESS); 183 } else if ( readOption( &bOption, "V", &nPos, arg) || 184 readOption( &bOption, "version", &nPos, arg) ) { 185 std::cerr << "\n Sun Microsystems (R) " << programname 186 << " Version " << version << "\n\n"; 187 exit(EXIT_SUCCESS); 188 } else { 189 std::cerr 190 << "ERROR: unexpected command \"" 191 << OUStringToOString(arg, RTL_TEXTENCODING_UTF8).getStr() 192 << "\"!\n"; 193 printUsageAndExit(programname, version); 194 exit(EXIT_FAILURE); 195 } 196 197 // read up to arguments 198 while ( nPos < nCount ) 199 { 200 rtl_getAppCommandArg(nPos, &arg.pData); 201 202 if ( readOption( &bOption, "a", &nPos, arg) || 203 readOption( &bOption, "all", &nPos, arg) ) { 204 options.all = true; 205 continue; 206 } 207 if ( readOption( &bOption, "java4", &nPos, arg) ) { 208 options.java5 = false; 209 options.language = 1; 210 continue; 211 } 212 if ( readOption( &bOption, "java5", &nPos, arg) ) { 213 options.java5 = true; 214 options.language = 1; 215 continue; 216 } 217 if ( readOption( &bOption, "cpp", &nPos, arg) ) { 218 options.java5 = false; 219 options.language = 2; 220 continue; 221 } 222 if ( readOption( &bOption, "sn", &nPos, arg) || 223 readOption( &bOption, "shortnames", &nPos, arg) ) { 224 options.shortnames = true; 225 continue; 226 } 227 if ( readOption( &bOption, "lh", &nPos, arg) || 228 readOption( &bOption, "licenseheader", &nPos, arg) ) { 229 options.license = true; 230 continue; 231 } 232 if ( readOption( &bOption, "bc", &nPos, arg) || 233 readOption( &bOption, "backward-compatible", &nPos, arg) ) { 234 options.backwardcompatible = true; 235 continue; 236 } 237 if ( readOption( &bOption, "propertysetmixin", &nPos, arg) ) { 238 options.supportpropertysetmixin = true; 239 continue; 240 } 241 if ( readOption( &sOption, "d", &nPos, arg) ) { 242 delegate = OUStringToOString(sOption, RTL_TEXTENCODING_UTF8); 243 continue; 244 } 245 if ( readOption( &sOption, "n", &nPos, arg) ) { 246 options.implname = OUStringToOString(sOption, RTL_TEXTENCODING_UTF8); 247 continue; 248 } 249 if ( readOption( &sOption, "o", &nPos, arg) ) { 250 options.outputpath = OUStringToOString(sOption, RTL_TEXTENCODING_UTF8); 251 continue; 252 } 253 if ( readOption( &sOption, "l", &nPos, arg) ) { 254 registries.push_back(sOption); 255 continue; 256 } 257 if ( readOption( &sOption, "t", &nPos, arg) ) { 258 types.push_back(OUStringToOString(sOption, RTL_TEXTENCODING_UTF8)); 259 continue; 260 } 261 if ( readOption( &sOption, "p", &nPos, arg) ) { 262 OString sTmp(OUStringToOString(sOption, RTL_TEXTENCODING_UTF8)); 263 sal_Int32 nIndex= sTmp.indexOf(':'); 264 OString sPrt = sTmp.copy(0, nIndex+1); 265 OString sCmds = sTmp.copy(nIndex+1); 266 267 nIndex = 0; 268 std::vector< OString > vCmds; 269 do { 270 OString sCmd = sCmds.getToken( 0, ',', nIndex ); 271 vCmds.push_back(sCmd); 272 } while ( nIndex >= 0 ); 273 274 options.protocolCmdMap.insert(ProtocolCmdMap::value_type(sPrt, vCmds)); 275 continue; 276 } 277 278 279 // else illegal argument 280 OUStringBuffer buf( 64 ); 281 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("unexpected parameter \"")); 282 buf.append(arg); 283 buf.appendAscii(RTL_CONSTASCII_STRINGPARAM("\"!")); 284 throw RuntimeException(buf.makeStringAndClear(), 285 Reference< XInterface >()); 286 } 287 288 if ( types.empty() && options.componenttype != 3) { 289 std::cerr 290 << ("\nError: no type is specified, use the -T option at least once\n"); 291 printUsageAndExit(programname, version); 292 exit(EXIT_FAILURE); 293 } 294 295 UnoTypeManager manager; 296 if ( !manager.init(registries) ) { 297 std::cerr 298 << ("\nError: Using the binary type libraries failed, check the -L" 299 " options\n"); 300 exit(EXIT_FAILURE); 301 } 302 303 if ( options.dump ) { 304 std::vector< OString >::const_iterator iter = types.begin(); 305 while (iter != types.end()) { 306 std::cout << "\n/***************************************************" 307 "*****************************/\n"; 308 switch (options.language ) 309 { 310 case 1: //Java 311 java::generateDocumentation(std::cout, options, manager, 312 *iter, delegate); 313 break; 314 case 2: //C++ 315 cpp::generateDocumentation(std::cout, options, manager, 316 *iter, delegate); 317 break; 318 default: 319 OSL_ASSERT(false); 320 break; 321 } 322 ++iter; 323 } 324 } else { 325 switch ( options.language ) 326 { 327 case 1: //Java 328 java::generateSkeleton(options, manager, types, delegate); 329 break; 330 case 2: //C++ 331 cpp::generateSkeleton(options, manager, types, delegate); 332 break; 333 default: 334 OSL_ASSERT(false); 335 break; 336 } 337 } 338 339 } catch (CannotDumpException & e) { 340 std::cout.flush(); 341 std::cerr << "\nError: " << e.m_message << std::endl; 342 } catch(Exception& e) { 343 std::cout.flush(); 344 std::cerr 345 << "\nError: " 346 << OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr() 347 << std::endl; 348 } 349 350 return 0; 351 } 352