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 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_cli_ure.hxx" 30 31 #include <stdio.h> 32 #include <vector> 33 #include <memory> 34 35 #include "climaker_share.h" 36 37 #include "sal/main.h" 38 #include "osl/process.h" 39 #include "osl/file.hxx" 40 #include "osl/thread.h" 41 #include "rtl/ustrbuf.hxx" 42 #include "cppuhelper/shlib.hxx" 43 #include "cppuhelper/bootstrap.hxx" 44 #include "com/sun/star/lang/XInitialization.hpp" 45 #include "com/sun/star/lang/XSingleComponentFactory.hpp" 46 #include "com/sun/star/lang/XComponent.hpp" 47 #include "com/sun/star/container/XHierarchicalNameAccess.hpp" 48 #include "com/sun/star/container/XSet.hpp" 49 #include "com/sun/star/reflection/XTypeDescriptionEnumerationAccess.hpp" 50 #include "com/sun/star/registry/XSimpleRegistry.hpp" 51 52 using namespace ::std; 53 using namespace ::System::Reflection; 54 55 56 using namespace ::rtl; 57 using namespace ::osl; 58 using namespace ::com::sun::star; 59 using namespace ::com::sun::star::uno; 60 61 namespace climaker 62 { 63 64 //------------------------------------------------------------------------------ 65 static char const s_usingText [] = 66 "\n" 67 "using: climaker <switches> [registry-file-1 registry-file-2 ...]\n" 68 "\n" 69 "switches:\n" 70 " -O, --out <output-file> output assembly file;\n" 71 " defaults to cli_unotypes.dll if more than one\n" 72 " registry-file is given, else <registry-file>.dll\n" 73 " -T, --types types to be generated (if none is given,\n" 74 " <type1[;type2;...]> then all types of given registries are emitted\n" 75 " -X, --extra <rdb-file> additional rdb to saturate referenced types in\n" 76 " given registry file(s); these types will not be\n" 77 " emitted into the output assembly file\n" 78 " -r, --reference reference metadata from assembly file\n" 79 " <assembly-file>\n" 80 " -k, --keyfile keyfile needed for strong name\n" 81 " --assembly-version <version> sets assembly version\n" 82 " --assembly-description <text> sets assembly description text\n" 83 " --assembly-product <text> sets assembly product name\n" 84 " --assembly-company <text> sets assembly company\n" 85 " --assembly-copyright <text> sets assembly copyright\n" 86 " --assembly-trademark <text> sets assembly trademark\n" 87 " -v, --verbose verbose output to stdout\n" 88 " -h, --help this message\n" 89 "\n" 90 "example: climaker --out cli_mytypes.dll \\\n" 91 " --reference cli_uretypes.dll \\\n" 92 " --extra types.rdb \\\n" 93 " mytypes.rdb\n" 94 "\n"; 95 96 struct OptionInfo 97 { 98 char const * m_name; 99 sal_uInt32 m_name_length; 100 sal_Unicode m_short_option; 101 bool m_has_argument; 102 }; 103 104 bool g_verbose = false; 105 106 //------------------------------------------------------------------------------ 107 static const OptionInfo s_option_infos [] = { 108 { RTL_CONSTASCII_STRINGPARAM("out"), 'O', true }, 109 { RTL_CONSTASCII_STRINGPARAM("types"), 'T', true }, 110 { RTL_CONSTASCII_STRINGPARAM("extra"), 'X', true }, 111 { RTL_CONSTASCII_STRINGPARAM("reference"), 'r', true }, 112 { RTL_CONSTASCII_STRINGPARAM("keyfile"), 'k', true }, 113 { RTL_CONSTASCII_STRINGPARAM("delaySign"), 'd', true }, 114 { RTL_CONSTASCII_STRINGPARAM("assembly-version"), '\0', true }, 115 { RTL_CONSTASCII_STRINGPARAM("assembly-description"), '\0', true }, 116 { RTL_CONSTASCII_STRINGPARAM("assembly-product"), '\0', true }, 117 { RTL_CONSTASCII_STRINGPARAM("assembly-company"), '\0', true }, 118 { RTL_CONSTASCII_STRINGPARAM("assembly-copyright"), '\0', true }, 119 { RTL_CONSTASCII_STRINGPARAM("assembly-trademark"), '\0', true }, 120 { RTL_CONSTASCII_STRINGPARAM("verbose"), 'v', false }, 121 { RTL_CONSTASCII_STRINGPARAM("help"), 'h', false } 122 }; 123 124 //============================================================================== 125 static OptionInfo const * get_option_info( 126 OUString const & opt, sal_Unicode copt = '\0' ) 127 { 128 for ( sal_Int32 pos = 0; 129 pos < (sizeof (s_option_infos) / sizeof (OptionInfo)); 130 ++pos ) 131 { 132 OptionInfo const & option_info = s_option_infos[ pos ]; 133 134 if (opt.getLength() > 0) 135 { 136 if (opt.equalsAsciiL( 137 option_info.m_name, option_info.m_name_length ) && 138 (copt == '\0' || copt == option_info.m_short_option)) 139 { 140 return &option_info; 141 } 142 } 143 else 144 { 145 OSL_ASSERT( copt != '\0' ); 146 if (copt == option_info.m_short_option) 147 { 148 return &option_info; 149 } 150 } 151 } 152 OSL_ENSURE( 153 0, OUStringToOString( opt, osl_getThreadTextEncoding() ).getStr() ); 154 return 0; 155 } 156 157 //============================================================================== 158 static bool is_option( 159 OptionInfo const * option_info, sal_uInt32 * pIndex ) 160 { 161 OSL_ASSERT( option_info != 0 ); 162 if (osl_getCommandArgCount() <= *pIndex) 163 return false; 164 165 OUString arg; 166 osl_getCommandArg( *pIndex, &arg.pData ); 167 sal_Int32 len = arg.getLength(); 168 169 if (len < 2 || arg[ 0 ] != '-') 170 return false; 171 172 if (len == 2 && arg[ 1 ] == option_info->m_short_option) 173 { 174 ++(*pIndex); 175 #if OSL_DEBUG_LEVEL > 1 176 OSL_TRACE( 177 __FILE__": identified option \'%c\'", option_info->m_short_option ); 178 #endif 179 return true; 180 } 181 if (arg[ 1 ] == '-' && rtl_ustr_ascii_compare( 182 arg.pData->buffer + 2, option_info->m_name ) == 0) 183 { 184 ++(*pIndex); 185 #if OSL_DEBUG_LEVEL > 1 186 OSL_TRACE( __FILE__": identified option \'%s\'", option_info->m_name ); 187 #endif 188 return true; 189 } 190 return false; 191 } 192 193 //============================================================================== 194 static inline bool read_option( 195 bool * flag, OptionInfo const * option_info, sal_uInt32 * pIndex ) 196 { 197 bool ret = is_option( option_info, pIndex ); 198 if (ret) 199 *flag = true; 200 return ret; 201 } 202 203 //============================================================================== 204 static bool read_argument( 205 OUString * pValue, OptionInfo const * option_info, sal_uInt32 * pIndex ) 206 { 207 if (is_option( option_info, pIndex )) 208 { 209 if (*pIndex < osl_getCommandArgCount()) 210 { 211 osl_getCommandArg( *pIndex, &pValue->pData ); 212 ++(*pIndex); 213 #if OSL_DEBUG_LEVEL > 1 214 OString cstr_val( 215 OUStringToOString( *pValue, osl_getThreadTextEncoding() ) ); 216 OSL_TRACE( __FILE__": argument value: %s\n", cstr_val.getStr() ); 217 #endif 218 return true; 219 } 220 --(*pIndex); 221 } 222 return false; 223 } 224 225 //============================================================================== 226 static OUString const & path_get_working_dir() 227 { 228 static OUString s_workingDir; 229 if (! s_workingDir.getLength()) 230 osl_getProcessWorkingDir( &s_workingDir.pData ); 231 return s_workingDir; 232 } 233 234 //============================================================================== 235 static OUString path_make_absolute_file_url( OUString const & path ) 236 { 237 OUString file_url; 238 oslFileError rc = osl_getFileURLFromSystemPath( 239 path.pData, &file_url.pData ); 240 if (osl_File_E_None == rc) 241 { 242 OUString abs; 243 rc = osl_getAbsoluteFileURL( 244 path_get_working_dir().pData, file_url.pData, &abs.pData ); 245 if (osl_File_E_None == rc) 246 { 247 return abs; 248 } 249 else 250 { 251 throw RuntimeException( 252 OUSTR("cannot make absolute: ") + file_url, 253 Reference< XInterface >() ); 254 } 255 } 256 else 257 { 258 throw RuntimeException( 259 OUSTR("cannot get file url from system path: ") + path, 260 Reference< XInterface >() ); 261 } 262 } 263 264 //============================================================================== 265 Reference< registry::XSimpleRegistry > open_registries( 266 vector< OUString > const & registries, 267 Reference< XComponentContext > xContext ) 268 { 269 if (registries.empty()) 270 { 271 throw RuntimeException( 272 OUSTR("no registries given!"), 273 Reference< XInterface >() ); 274 } 275 276 Reference< registry::XSimpleRegistry > xSimReg; 277 for ( size_t nPos = registries.size(); nPos--; ) 278 { 279 Reference< registry::XSimpleRegistry > xReg( 280 xContext->getServiceManager()->createInstanceWithContext( 281 OUSTR("com.sun.star.registry.SimpleRegistry"), xContext ), 282 UNO_QUERY_THROW ); 283 xReg->open( registries[ nPos ], sal_True, sal_False ); 284 if (! xReg->isValid()) 285 { 286 throw RuntimeException( 287 OUSTR("invalid registry: ") + registries[ nPos ], 288 Reference< XInterface >() ); 289 } 290 291 if (xSimReg.is()) // nest? 292 { 293 Reference< registry::XSimpleRegistry > xNested( 294 xContext->getServiceManager()->createInstanceWithContext( 295 OUSTR("com.sun.star.registry.NestedRegistry"), xContext ), 296 UNO_QUERY_THROW ); 297 Reference< lang::XInitialization > xInit( 298 xNested, UNO_QUERY_THROW ); 299 Sequence< Any > args( 2 ); 300 args[ 0 ] <<= xReg; 301 args[ 1 ] <<= xSimReg; 302 xInit->initialize( args ); 303 xSimReg = xNested; 304 } 305 else 306 { 307 xSimReg = xReg; 308 } 309 } 310 311 return xSimReg; 312 } 313 314 } 315 316 using namespace ::climaker; 317 318 //############################################################################## 319 SAL_IMPLEMENT_MAIN() 320 { 321 sal_uInt32 nCount = osl_getCommandArgCount(); 322 if (0 == nCount) 323 { 324 printf( s_usingText ); 325 return 0; 326 } 327 328 int ret = 0; 329 Reference< XComponentContext > xContext; 330 331 try 332 { 333 OptionInfo const * info_help = 334 get_option_info( OUSTR("help") ); 335 OptionInfo const * info_verbose = 336 get_option_info( OUSTR("verbose") ); 337 OptionInfo const * info_out = 338 get_option_info( OUSTR("out") ); 339 OptionInfo const * info_types = 340 get_option_info( OUSTR("types") ); 341 OptionInfo const * info_reference = 342 get_option_info( OUSTR("reference") ); 343 OptionInfo const * info_extra = 344 get_option_info( OUSTR("extra") ); 345 OptionInfo const * info_keyfile = 346 get_option_info( OUSTR("keyfile") ); 347 OptionInfo const * info_delaySign = 348 get_option_info( OUSTR("delaySign") ); 349 OptionInfo const * info_version = 350 get_option_info( OUSTR("assembly-version") ); 351 OptionInfo const * info_product = 352 get_option_info( OUSTR("assembly-product") ); 353 OptionInfo const * info_description = 354 get_option_info( OUSTR("assembly-description") ); 355 OptionInfo const * info_company = 356 get_option_info( OUSTR("assembly-company") ); 357 OptionInfo const * info_copyright = 358 get_option_info( OUSTR("assembly-copyright") ); 359 OptionInfo const * info_trademark = 360 get_option_info( OUSTR("assembly-trademark") ); 361 362 OUString output; 363 vector< OUString > mandatory_registries; 364 vector< OUString > extra_registries; 365 vector< OUString > extra_assemblies; 366 vector< OUString > explicit_types; 367 OUString version, product, description, company, copyright, trademark, 368 keyfile, delaySign; 369 370 OUString cmd_arg; 371 for ( sal_uInt32 nPos = 0; nPos < nCount; ) 372 { 373 // options 374 if (is_option( info_help, &nPos )) 375 { 376 printf( s_usingText ); 377 return 0; 378 } 379 else if (read_argument( &cmd_arg, info_types, &nPos )) 380 { 381 sal_Int32 index = 0; 382 do 383 { 384 explicit_types.push_back( 385 cmd_arg.getToken( 0, ';', index ) ); 386 } 387 while (index >= 0); 388 } 389 else if (read_argument( &cmd_arg, info_extra, &nPos )) 390 { 391 extra_registries.push_back( 392 path_make_absolute_file_url( cmd_arg ) ); 393 } 394 else if (read_argument( &cmd_arg, info_reference, &nPos )) 395 { 396 extra_assemblies.push_back( 397 path_make_absolute_file_url( cmd_arg ) ); 398 } 399 else if (!read_option( &g_verbose, info_verbose, &nPos ) && 400 !read_argument( &output, info_out, &nPos ) && 401 !read_argument( &version, info_version, &nPos ) && 402 !read_argument( &description, info_description, &nPos ) && 403 !read_argument( &product, info_product, &nPos ) && 404 !read_argument( &company, info_company, &nPos ) && 405 !read_argument( ©right, info_copyright, &nPos ) && 406 !read_argument( &trademark, info_trademark, &nPos ) && 407 !read_argument( &keyfile, info_keyfile, &nPos ) && 408 !read_argument( &delaySign, info_delaySign, &nPos )) 409 { 410 if ( osl_getCommandArg( nPos, &cmd_arg.pData ) != 411 osl_Process_E_None ) 412 { 413 OSL_ASSERT( false ); 414 } 415 ++nPos; 416 cmd_arg = cmd_arg.trim(); 417 if (cmd_arg.getLength() > 0) 418 { 419 if (cmd_arg[ 0 ] == '-') // is option 420 { 421 OptionInfo const * option_info = 0; 422 if (cmd_arg.getLength() > 2 && 423 cmd_arg[ 1 ] == '-') 424 { 425 // long option 426 option_info = get_option_info( 427 cmd_arg.copy( 2 ), '\0' ); 428 } 429 else if (cmd_arg.getLength() == 2 && 430 cmd_arg[ 1 ] != '-') 431 { 432 // short option 433 option_info = get_option_info( 434 OUString(), cmd_arg[ 1 ] ); 435 } 436 if (option_info == 0) 437 { 438 OUStringBuffer buf; 439 buf.appendAscii( 440 RTL_CONSTASCII_STRINGPARAM("unknown option ") ); 441 buf.append( cmd_arg ); 442 buf.appendAscii( RTL_CONSTASCII_STRINGPARAM( 443 "! Use climaker --help " 444 "to print all options.") ); 445 throw RuntimeException( 446 buf.makeStringAndClear(), 447 Reference< XInterface >() ); 448 } 449 else 450 { 451 OSL_ENSURE( 0, "unhandled valid option?!" ); 452 if (option_info->m_has_argument) 453 ++nPos; 454 } 455 } 456 else 457 { 458 mandatory_registries.push_back( 459 path_make_absolute_file_url( cmd_arg ) ); 460 } 461 } 462 } 463 } 464 465 // bootstrap uno 466 xContext = ::cppu::bootstrap_InitialComponentContext( 467 Reference< registry::XSimpleRegistry >() ); 468 Reference< container::XHierarchicalNameAccess > xTDmgr( 469 xContext->getValueByName( 470 OUSTR("/singletons/com.sun.star.reflection." 471 "theTypeDescriptionManager") ), 472 UNO_QUERY_THROW ); 473 474 // get rdb tdprovider factory 475 Reference< lang::XSingleComponentFactory > xTDprov_factory( 476 ::cppu::loadSharedLibComponentFactory( 477 OUSTR("bootstrap.uno" SAL_DLLEXTENSION), OUString(), 478 OUSTR("com.sun.star.comp.stoc.RegistryTypeDescriptionProvider"), 479 Reference< lang::XMultiServiceFactory >( 480 xContext->getServiceManager(), UNO_QUERY ), 481 Reference< registry::XRegistryKey >() ), UNO_QUERY ); 482 if (! xTDprov_factory.is()) 483 { 484 throw RuntimeException( 485 OUSTR("cannot get registry typedescription provider: " 486 "bootstrap.uno" SAL_DLLEXTENSION "!"), 487 Reference< XInterface >() ); 488 } 489 490 // create registry td provider for mandatory registry files 491 Any arg( makeAny( open_registries( mandatory_registries, xContext ) ) ); 492 Reference< XInterface > xTD_provider( 493 xTDprov_factory->createInstanceWithArgumentsAndContext( 494 Sequence< Any >( &arg, 1 ), xContext ) ); 495 // insert provider to tdmgr 496 Reference< container::XSet > xSet( xTDmgr, UNO_QUERY_THROW ); 497 Any provider( makeAny( xTD_provider ) ); 498 xSet->insert( provider ); 499 OSL_ASSERT( xSet->has( provider ) ); 500 if (! extra_registries.empty()) 501 { 502 arg = makeAny( open_registries( extra_registries, xContext ) ); 503 provider = makeAny( 504 xTDprov_factory->createInstanceWithArgumentsAndContext( 505 Sequence< Any >( &arg, 1 ), xContext ) ); 506 xSet->insert( provider ); 507 OSL_ASSERT( xSet->has( provider ) ); 508 } 509 510 if (0 == output.getLength()) // no output file specified 511 { 512 // if only one rdb has been given, then take rdb name 513 if (1 == mandatory_registries.size()) 514 { 515 output = mandatory_registries[ 0 ]; 516 output = output.copy( output.lastIndexOf( '/' ) +1 ); 517 sal_Int32 dot = output.lastIndexOf( '.' ); 518 if (dot > 0) 519 output = output.copy( 0, dot ); 520 } 521 else 522 { 523 output = OUSTR("cli_unotypes"); 524 } 525 } 526 output = path_make_absolute_file_url( output ); 527 sal_Int32 slash = output.lastIndexOf( '/' ); 528 OUString sys_output_dir; 529 if (FileBase::E_None != FileBase::getSystemPathFromFileURL( 530 output.copy( 0, slash ), sys_output_dir )) 531 { 532 throw RuntimeException( 533 OUSTR("cannot get system path from file url ") + 534 output.copy( 0, slash ), 535 Reference< XInterface >() ); 536 } 537 OUString filename( output.copy( slash +1 ) ); 538 sal_Int32 dot = filename.lastIndexOf( '.' ); 539 OUString name( filename ); 540 if (dot < 0) // has no extension 541 filename += OUSTR(".dll"); 542 else 543 name = name.copy( 0, dot ); 544 ::System::String * output_dir = ustring_to_String( sys_output_dir ); 545 ::System::String * output_file = ustring_to_String( filename ); 546 547 //Get the key pair for making a strong name 548 StrongNameKeyPair* kp = NULL; 549 if (keyfile.getLength() > 0) 550 { 551 ::System::String * sKeyFile = ustring_to_String(keyfile); 552 try { 553 System::IO::FileStream* fs = new System::IO::FileStream( 554 sKeyFile, System::IO::FileMode::Open); 555 kp = new StrongNameKeyPair(fs); 556 fs->Close(); 557 } 558 catch (System::IO::FileNotFoundException * ) 559 { 560 throw Exception(OUSTR("Could not find the keyfile. Verify the --keyfile argument!"), 0); 561 } 562 } 563 else 564 { 565 if (g_verbose) 566 { 567 ::System::Console::Write( 568 S"> no key file specified. Cannot create strong name!\n"); 569 } 570 } 571 // setup assembly info: xxx todo set more? e.g. avoid strong versioning 572 AssemblyName * assembly_name = new AssemblyName(); 573 assembly_name->set_CodeBase( output_dir ); 574 assembly_name->set_Name( name ); 575 if (kp != NULL) 576 assembly_name->set_KeyPair(kp); 577 578 if (version.getLength() != 0) 579 { 580 assembly_name->set_Version( 581 new ::System::Version( ustring_to_String( version ) ) ); 582 } 583 584 // app domain 585 ::System::AppDomain * current_appdomain = 586 ::System::AppDomain::get_CurrentDomain(); 587 // target assembly 588 Emit::AssemblyBuilder * assembly_builder = 589 current_appdomain->DefineDynamicAssembly( 590 assembly_name, Emit::AssemblyBuilderAccess::Save, output_dir ); 591 if (product.getLength() != 0) 592 { 593 ::System::Type * params __gc [] = new ::System::Type * __gc [ 1 ]; 594 ::System::Object * args __gc [] = new ::System::Object * __gc [ 1 ]; 595 params[ 0 ] = __typeof (::System::String); 596 args[ 0 ] = ustring_to_String( product ); 597 assembly_builder->SetCustomAttribute( 598 new Emit::CustomAttributeBuilder( 599 __typeof (AssemblyProductAttribute)->GetConstructor( 600 params ), args ) ); 601 } 602 if (description.getLength() != 0) 603 { 604 ::System::Type * params __gc [] = new ::System::Type * __gc [ 1 ]; 605 ::System::Object * args __gc [] = new ::System::Object * __gc [ 1 ]; 606 params[ 0 ] = __typeof (::System::String); 607 args[ 0 ] = ustring_to_String( description ); 608 assembly_builder->SetCustomAttribute( 609 new Emit::CustomAttributeBuilder( 610 __typeof (AssemblyDescriptionAttribute)->GetConstructor( 611 params ), args ) ); 612 } 613 if (company.getLength() != 0) 614 { 615 ::System::Type * params __gc [] = new ::System::Type * __gc [ 1 ]; 616 ::System::Object * args __gc [] = new ::System::Object * __gc [ 1 ]; 617 params[ 0 ] = __typeof (::System::String); 618 args[ 0 ] = ustring_to_String( company ); 619 assembly_builder->SetCustomAttribute( 620 new Emit::CustomAttributeBuilder( 621 __typeof (AssemblyCompanyAttribute)->GetConstructor( 622 params ), args ) ); 623 } 624 if (copyright.getLength() != 0) 625 { 626 ::System::Type * params __gc [] = new ::System::Type * __gc [ 1 ]; 627 ::System::Object * args __gc [] = new ::System::Object * __gc [ 1 ]; 628 params[ 0 ] = __typeof (::System::String); 629 args[ 0 ] = ustring_to_String( copyright ); 630 assembly_builder->SetCustomAttribute( 631 new Emit::CustomAttributeBuilder( 632 __typeof (AssemblyCopyrightAttribute)->GetConstructor( 633 params ), args ) ); 634 } 635 if (trademark.getLength() != 0) 636 { 637 ::System::Type * params __gc [] = new ::System::Type * __gc [ 1 ]; 638 ::System::Object * args __gc [] = new ::System::Object * __gc [ 1 ]; 639 params[ 0 ] = __typeof (::System::String); 640 args[ 0 ] = ustring_to_String( trademark ); 641 assembly_builder->SetCustomAttribute( 642 new Emit::CustomAttributeBuilder( 643 __typeof (AssemblyTrademarkAttribute)->GetConstructor( 644 params ), args ) ); 645 } 646 647 // load extra assemblies 648 Assembly * assemblies __gc [] = 649 new Assembly * __gc [ extra_assemblies.size() ]; 650 for ( size_t pos = 0; pos < extra_assemblies.size(); ++pos ) 651 { 652 assemblies[ pos ] = Assembly::LoadFrom( 653 ustring_to_String( extra_assemblies[ pos ] ) ); 654 } 655 656 // type emitter 657 TypeEmitter * type_emitter = new TypeEmitter( 658 assembly_builder->DefineDynamicModule( output_file ), assemblies ); 659 // add handler resolving assembly's types 660 ::System::ResolveEventHandler * type_resolver = 661 new ::System::ResolveEventHandler( 662 type_emitter, &TypeEmitter::type_resolve ); 663 current_appdomain->add_TypeResolve( type_resolver ); 664 665 // and emit types to it 666 if (explicit_types.empty()) 667 { 668 Reference< reflection::XTypeDescriptionEnumeration > xTD_enum( 669 Reference< reflection::XTypeDescriptionEnumerationAccess >( 670 xTD_provider, UNO_QUERY_THROW ) 671 ->createTypeDescriptionEnumeration( 672 OUString() /* all IDL modules */, 673 Sequence< TypeClass >() /* all classes of types */, 674 reflection::TypeDescriptionSearchDepth_INFINITE ) ); 675 while (xTD_enum->hasMoreElements()) 676 { 677 type_emitter->get_type( xTD_enum->nextTypeDescription() ); 678 } 679 } 680 else 681 { 682 Reference< container::XHierarchicalNameAccess > xHNA( 683 xTD_provider, UNO_QUERY_THROW ); 684 for ( size_t nPos = explicit_types.size(); nPos--; ) 685 { 686 type_emitter->get_type( 687 Reference< reflection::XTypeDescription >( 688 xHNA->getByHierarchicalName( explicit_types[ nPos ] ), 689 UNO_QUERY_THROW ) ); 690 } 691 } 692 type_emitter->Dispose(); 693 694 if (g_verbose) 695 { 696 ::System::Console::Write( 697 S"> saving assembly {0}{1}{2}...", 698 output_dir, 699 new ::System::String( 700 ::System::IO::Path::DirectorySeparatorChar, 1 ), 701 output_file ); 702 } 703 assembly_builder->Save( output_file ); 704 if (g_verbose) 705 { 706 ::System::Console::WriteLine( S"ok." ); 707 } 708 current_appdomain->remove_TypeResolve( type_resolver ); 709 } 710 catch (Exception & exc) 711 { 712 OString msg( 713 OUStringToOString( exc.Message, osl_getThreadTextEncoding() ) ); 714 fprintf( 715 stderr, "\n> error: %s\n> dying abnormally...\n", msg.getStr() ); 716 ret = 1; 717 } 718 catch (::System::Exception * exc) 719 { 720 OString msg( OUStringToOString( 721 String_to_ustring( exc->ToString() ), 722 osl_getThreadTextEncoding() ) ); 723 fprintf( 724 stderr, 725 "\n> error: .NET exception occured: %s\n> dying abnormally...", 726 msg.getStr() ); 727 ret = 1; 728 } 729 730 try 731 { 732 Reference< lang::XComponent > xComp( xContext, UNO_QUERY ); 733 if (xComp.is()) 734 xComp->dispose(); 735 } 736 catch (Exception & exc) 737 { 738 OString msg( 739 OUStringToOString( exc.Message, osl_getThreadTextEncoding() ) ); 740 fprintf( 741 stderr, 742 "\n> error disposing component context: %s\n" 743 "> dying abnormally...\n", 744 msg.getStr() ); 745 ret = 1; 746 } 747 748 return ret; 749 } 750