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