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