LCOV - code coverage report
Current view: top level - pyuno/source/module - pyuno_runtime.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 466 0.0 %
Date: 2014-04-14 Functions: 0 24 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; eval:(c-set-style "bsd"); tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <config_features.h>
      21             : #include <config_folders.h>
      22             : 
      23             : #include "pyuno_impl.hxx"
      24             : 
      25             : #include <osl/thread.h>
      26             : #include <osl/module.h>
      27             : #include <osl/process.h>
      28             : #include <rtl/strbuf.hxx>
      29             : #include <rtl/ustrbuf.hxx>
      30             : #include <rtl/bootstrap.hxx>
      31             : #include <locale.h>
      32             : 
      33             : #include <typelib/typedescription.hxx>
      34             : 
      35             : #include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
      36             : #include <com/sun/star/beans/XMaterialHolder.hpp>
      37             : #include <com/sun/star/beans/theIntrospection.hpp>
      38             : #include <com/sun/star/script/Converter.hpp>
      39             : #include <com/sun/star/script/InvocationAdapterFactory.hpp>
      40             : #include <com/sun/star/reflection/theCoreReflection.hpp>
      41             : 
      42             : 
      43             : using com::sun::star::uno::Reference;
      44             : using com::sun::star::uno::XInterface;
      45             : using com::sun::star::uno::Any;
      46             : using com::sun::star::uno::TypeDescription;
      47             : using com::sun::star::uno::Sequence;
      48             : using com::sun::star::uno::Type;
      49             : using com::sun::star::uno::UNO_QUERY;
      50             : using com::sun::star::uno::Exception;
      51             : using com::sun::star::uno::RuntimeException;
      52             : using com::sun::star::uno::XComponentContext;
      53             : using com::sun::star::lang::WrappedTargetRuntimeException;
      54             : using com::sun::star::lang::XSingleServiceFactory;
      55             : using com::sun::star::lang::XUnoTunnel;
      56             : using com::sun::star::reflection::theCoreReflection;
      57             : using com::sun::star::reflection::XIdlReflection;
      58             : using com::sun::star::reflection::InvocationTargetException;
      59             : using com::sun::star::script::Converter;
      60             : using com::sun::star::script::XTypeConverter;
      61             : using com::sun::star::script::XInvocationAdapterFactory2;
      62             : using com::sun::star::script::XInvocation;
      63             : using com::sun::star::beans::XMaterialHolder;
      64             : using com::sun::star::beans::XIntrospection;
      65             : using com::sun::star::beans::theIntrospection;
      66             : 
      67             : #include <vector>
      68             : 
      69             : namespace pyuno
      70             : {
      71             : 
      72             : static PyTypeObject RuntimeImpl_Type =
      73             : {
      74             :     PyVarObject_HEAD_INIT (&PyType_Type, 0)
      75             :     "pyuno_runtime",
      76             :     sizeof (RuntimeImpl),
      77             :     0,
      78             :     (destructor) RuntimeImpl::del,
      79             :     (printfunc) 0,
      80             :     (getattrfunc) 0,
      81             :     (setattrfunc) 0,
      82             :     0,
      83             :     (reprfunc) 0,
      84             :     0,
      85             :     0,
      86             :     0,
      87             :     (hashfunc) 0,
      88             :     (ternaryfunc) 0,
      89             :     (reprfunc) 0,
      90             :     (getattrofunc)0,
      91             :     (setattrofunc)0,
      92             :     NULL,
      93             :     0,
      94             :     NULL,
      95             :     (traverseproc)0,
      96             :     (inquiry)0,
      97             :     (richcmpfunc)0,
      98             :     0,
      99             :     (getiterfunc)0,
     100             :     (iternextfunc)0,
     101             :     NULL,
     102             :     NULL,
     103             :     NULL,
     104             :     NULL,
     105             :     NULL,
     106             :     (descrgetfunc)0,
     107             :     (descrsetfunc)0,
     108             :     0,
     109             :     (initproc)0,
     110             :     (allocfunc)0,
     111             :     (newfunc)0,
     112             :     (freefunc)0,
     113             :     (inquiry)0,
     114             :     NULL,
     115             :     NULL,
     116             :     NULL,
     117             :     NULL,
     118             :     NULL,
     119             :     (destructor)0
     120             : #if PY_VERSION_HEX >= 0x02060000
     121             :     , 0
     122             : #endif
     123             : };
     124             : 
     125             : /*----------------------------------------------------------------------
     126             :   Runtime implementation
     127             :  -----------------------------------------------------------------------*/
     128           0 : static void getRuntimeImpl( PyRef & globalDict, PyRef &runtimeImpl )
     129             :     throw ( com::sun::star::uno::RuntimeException )
     130             : {
     131           0 :     PyThreadState * state = PyThreadState_Get();
     132           0 :     if( ! state )
     133             :     {
     134             :         throw RuntimeException( OUString( "python global interpreter must be held (thread must be attached)" ),
     135           0 :                                 Reference< XInterface > () );
     136             :     }
     137             : 
     138           0 :     PyObject* pModule = PyImport_AddModule("__main__");
     139             : 
     140           0 :     if (!pModule)
     141             :     {
     142           0 :         throw RuntimeException("can't import __main__ module", Reference< XInterface > ());
     143             :     }
     144             : 
     145           0 :     globalDict = PyRef( PyModule_GetDict(pModule));
     146             : 
     147           0 :     if( ! globalDict.is() ) // FATAL !
     148             :     {
     149           0 :         throw RuntimeException("can't find __main__ module", Reference< XInterface > ());
     150             :     }
     151           0 :     runtimeImpl = PyDict_GetItemString( globalDict.get() , "pyuno_runtime" );
     152           0 : }
     153             : 
     154           0 : static PyRef importUnoModule( ) throw ( RuntimeException )
     155             : {
     156             :     // import the uno module
     157           0 :     PyRef module( PyImport_ImportModule( "uno" ), SAL_NO_ACQUIRE );
     158           0 :     if( PyErr_Occurred() )
     159             :     {
     160           0 :         PyRef excType, excValue, excTraceback;
     161           0 :         PyErr_Fetch( (PyObject **)&excType, (PyObject**)&excValue,(PyObject**)&excTraceback);
     162             :         // As of Python 2.7 this gives a rather non-useful "<traceback object at 0xADDRESS>",
     163             :         // but it is the best we can do in the absence of uno._uno_extract_printable_stacktrace
     164             :         // Who knows, a future Python might print something better.
     165           0 :         PyRef str( PyObject_Str( excTraceback.get() ), SAL_NO_ACQUIRE );
     166             : 
     167           0 :         OUStringBuffer buf;
     168           0 :         buf.appendAscii( "python object raised an unknown exception (" );
     169           0 :         PyRef valueRep( PyObject_Repr( excValue.get() ), SAL_NO_ACQUIRE );
     170           0 :         buf.appendAscii( PyStr_AsString( valueRep.get())).appendAscii( ", traceback follows\n" );
     171           0 :         buf.appendAscii( PyStr_AsString( str.get() ) );
     172           0 :         buf.appendAscii( ")" );
     173           0 :         throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
     174             :     }
     175           0 :     PyRef dict( PyModule_GetDict( module.get() ) );
     176           0 :     return dict;
     177             : }
     178             : 
     179           0 : static void readLoggingConfig( sal_Int32 *pLevel, FILE **ppFile )
     180             : {
     181           0 :     *pLevel = LogLevel::NONE;
     182           0 :     *ppFile = 0;
     183           0 :     OUString fileName;
     184             :     osl_getModuleURLFromFunctionAddress(
     185             :         reinterpret_cast< oslGenericFunction >(readLoggingConfig),
     186           0 :         (rtl_uString **) &fileName );
     187           0 :     fileName = fileName.copy( fileName.lastIndexOf( '/' )+1 );
     188             : #if HAVE_FEATURE_MACOSX_MACLIKE_APP_STRUCTURE
     189             :     fileName += "../" LIBO_ETC_FOLDER "/";
     190             : #endif
     191           0 :     fileName += SAL_CONFIGFILE("pyuno" );
     192           0 :     rtl::Bootstrap bootstrapHandle( fileName );
     193             : 
     194           0 :     OUString str;
     195           0 :     if( bootstrapHandle.getFrom( "PYUNO_LOGLEVEL", str ) )
     196             :     {
     197           0 :         if ( str == "NONE" )
     198           0 :             *pLevel = LogLevel::NONE;
     199           0 :         else if ( str == "CALL" )
     200           0 :             *pLevel = LogLevel::CALL;
     201           0 :         else if ( str == "ARGS" )
     202           0 :             *pLevel = LogLevel::ARGS;
     203             :         else
     204             :         {
     205             :             fprintf( stderr, "unknown loglevel %s\n",
     206           0 :                      OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
     207             :         }
     208             :     }
     209           0 :     if( *pLevel > LogLevel::NONE )
     210             :     {
     211           0 :         *ppFile = stdout;
     212           0 :         if( bootstrapHandle.getFrom( "PYUNO_LOGTARGET", str ) )
     213             :         {
     214           0 :             if ( str == "stdout" )
     215           0 :                 *ppFile = stdout;
     216           0 :             else if ( str == "stderr" )
     217           0 :                 *ppFile = stderr;
     218             :             else
     219             :             {
     220             :                 oslProcessInfo data;
     221           0 :                 data.Size = sizeof( data );
     222             :                 osl_getProcessInfo(
     223           0 :                     0 , osl_Process_IDENTIFIER , &data );
     224           0 :                 osl_getSystemPathFromFileURL( str.pData, &str.pData);
     225           0 :                 OString o = OUStringToOString( str, osl_getThreadTextEncoding() );
     226           0 :                 o += ".";
     227           0 :                 o += OString::number( data.Ident );
     228             : 
     229           0 :                 *ppFile = fopen( o.getStr() , "w" );
     230           0 :                 if ( *ppFile )
     231             :                 {
     232             :                     // do not buffer (useful if e.g. analyzing a crash)
     233           0 :                     setvbuf( *ppFile, 0, _IONBF, 0 );
     234             :                 }
     235             :                 else
     236             :                 {
     237             :                     fprintf( stderr, "couldn't create file %s\n",
     238           0 :                              OUStringToOString( str, RTL_TEXTENCODING_UTF8 ).getStr() );
     239             : 
     240           0 :                 }
     241             :             }
     242             :         }
     243           0 :     }
     244           0 : }
     245             : 
     246             : /*-------------------------------------------------------------------
     247             :  RuntimeImpl implementations
     248             :  *-------------------------------------------------------------------*/
     249           0 : PyRef stRuntimeImpl::create( const Reference< XComponentContext > &ctx )
     250             :     throw( com::sun::star::uno::RuntimeException )
     251             : {
     252           0 :     RuntimeImpl *me = PyObject_New (RuntimeImpl, &RuntimeImpl_Type);
     253           0 :     if( ! me )
     254             :         throw RuntimeException(
     255             :             OUString(  "cannot instantiate pyuno::RuntimeImpl"  ),
     256           0 :             Reference< XInterface > () );
     257           0 :     me->cargo = 0;
     258             :     // must use a different struct here, as the PyObject_New
     259             :     // makes C++ unusable
     260           0 :     RuntimeCargo *c = new RuntimeCargo();
     261           0 :     readLoggingConfig( &(c->logLevel) , &(c->logFile) );
     262           0 :     log( c, LogLevel::CALL, "Instantiating pyuno bridge" );
     263             : 
     264           0 :     c->valid = true;
     265           0 :     c->xContext = ctx;
     266           0 :     c->xInvocation = Reference< XSingleServiceFactory > (
     267           0 :         ctx->getServiceManager()->createInstanceWithContext(
     268             :             OUString(  "com.sun.star.script.Invocation"  ),
     269           0 :             ctx ),
     270           0 :         UNO_QUERY );
     271           0 :     if( ! c->xInvocation.is() )
     272             :         throw RuntimeException(
     273             :             OUString(  "pyuno: couldn't instantiate invocation service"  ),
     274           0 :             Reference< XInterface > () );
     275             : 
     276           0 :     c->xTypeConverter = Converter::create(ctx);
     277           0 :     if( ! c->xTypeConverter.is() )
     278             :         throw RuntimeException(
     279             :             OUString(  "pyuno: couldn't instantiate typeconverter service" ),
     280           0 :             Reference< XInterface > () );
     281             : 
     282           0 :     c->xCoreReflection = theCoreReflection::get(ctx);
     283             : 
     284           0 :     c->xAdapterFactory = css::script::InvocationAdapterFactory::create(ctx);
     285             : 
     286           0 :     c->xIntrospection = theIntrospection::get(ctx);
     287             : 
     288           0 :     Any a = ctx->getValueByName("/singletons/com.sun.star.reflection.theTypeDescriptionManager");
     289           0 :     a >>= c->xTdMgr;
     290           0 :     if( ! c->xTdMgr.is() )
     291             :         throw RuntimeException(
     292             :             OUString(  "pyuno: couldn't retrieve typedescriptionmanager" ),
     293           0 :             Reference< XInterface > () );
     294             : 
     295           0 :     me->cargo =c;
     296           0 :     return PyRef( reinterpret_cast< PyObject * > ( me ), SAL_NO_ACQUIRE );
     297             : }
     298             : 
     299           0 : void  stRuntimeImpl::del(PyObject* self)
     300             : {
     301           0 :     RuntimeImpl *me = reinterpret_cast< RuntimeImpl * > ( self );
     302           0 :     if( me->cargo->logFile )
     303           0 :         fclose( me->cargo->logFile );
     304           0 :     delete me->cargo;
     305           0 :     PyObject_Del (self);
     306           0 : }
     307             : 
     308             : 
     309           0 : void Runtime::initialize( const Reference< XComponentContext > & ctx )
     310             :     throw ( RuntimeException )
     311             : {
     312           0 :     PyRef globalDict, runtime;
     313           0 :     getRuntimeImpl( globalDict , runtime );
     314           0 :     RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
     315             : 
     316           0 :     if( runtime.is() && impl->cargo->valid )
     317             :     {
     318             :         throw RuntimeException("pyuno runtime has already been initialized before",
     319           0 :                                 Reference< XInterface > () );
     320             :     }
     321           0 :     PyRef keep( RuntimeImpl::create( ctx ) );
     322           0 :     PyDict_SetItemString( globalDict.get(), "pyuno_runtime" , keep.get() );
     323           0 :     Py_XINCREF( keep.get() );
     324           0 : }
     325             : 
     326             : 
     327           0 : bool Runtime::isInitialized() throw ( RuntimeException )
     328             : {
     329           0 :     PyRef globalDict, runtime;
     330           0 :     getRuntimeImpl( globalDict , runtime );
     331           0 :     RuntimeImpl *impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
     332           0 :     return runtime.is() && impl->cargo->valid;
     333             : }
     334             : 
     335           0 : Runtime::Runtime() throw(  RuntimeException )
     336           0 :     : impl( 0 )
     337             : {
     338           0 :     PyRef globalDict, runtime;
     339           0 :     getRuntimeImpl( globalDict , runtime );
     340           0 :     if( ! runtime.is() )
     341             :     {
     342             :         throw RuntimeException(
     343             :             OUString( "pyuno runtime is not initialized, "
     344             :                                                   "(the pyuno.bootstrap needs to be called before using any uno classes)"),
     345           0 :             Reference< XInterface > () );
     346             :     }
     347           0 :     impl = reinterpret_cast< RuntimeImpl * > (runtime.get());
     348           0 :     Py_XINCREF( runtime.get() );
     349           0 : }
     350             : 
     351           0 : Runtime::Runtime( const Runtime & r )
     352             : {
     353           0 :     impl = r.impl;
     354           0 :     Py_XINCREF( reinterpret_cast< PyObject * >(impl) );
     355           0 : }
     356             : 
     357           0 : Runtime::~Runtime()
     358             : {
     359           0 :     Py_XDECREF( reinterpret_cast< PyObject * >(impl) );
     360           0 : }
     361             : 
     362           0 : Runtime & Runtime::operator = ( const Runtime & r )
     363             : {
     364           0 :     PyRef temp( reinterpret_cast< PyObject * >(r.impl) );
     365           0 :     Py_XINCREF( temp.get() );
     366           0 :     Py_XDECREF( reinterpret_cast< PyObject * >(impl) );
     367           0 :     impl = r.impl;
     368           0 :     return *this;
     369             : }
     370             : 
     371           0 : PyRef Runtime::any2PyObject (const Any &a ) const
     372             :     throw ( com::sun::star::script::CannotConvertException,
     373             :             com::sun::star::lang::IllegalArgumentException,
     374             :             RuntimeException)
     375             : {
     376           0 :     if( ! impl->cargo->valid )
     377             :     {
     378             :         throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject",
     379           0 :                                 Reference< XInterface > () );
     380             :     }
     381             : 
     382           0 :     switch (a.getValueTypeClass ())
     383             :     {
     384             :     case typelib_TypeClass_VOID:
     385             :     {
     386           0 :         Py_INCREF (Py_None);
     387           0 :         return PyRef(Py_None);
     388             :     }
     389             :     case typelib_TypeClass_CHAR:
     390             :     {
     391           0 :         sal_Unicode c = *(sal_Unicode*)a.getValue();
     392           0 :         return PyRef( PyUNO_char_new( c , *this ), SAL_NO_ACQUIRE );
     393             :     }
     394             :     case typelib_TypeClass_BOOLEAN:
     395             :     {
     396           0 :         sal_Bool b = sal_Bool();
     397           0 :         if ((a >>= b) && b)
     398           0 :             return Py_True;
     399             :         else
     400           0 :             return Py_False;
     401             :     }
     402             :     case typelib_TypeClass_BYTE:
     403             :     case typelib_TypeClass_SHORT:
     404             :     case typelib_TypeClass_UNSIGNED_SHORT:
     405             :     case typelib_TypeClass_LONG:
     406             :     {
     407           0 :         sal_Int32 l = 0;
     408           0 :         a >>= l;
     409           0 :         return PyRef( PyLong_FromLong (l), SAL_NO_ACQUIRE );
     410             :     }
     411             :     case typelib_TypeClass_UNSIGNED_LONG:
     412             :     {
     413           0 :         sal_uInt32 l = 0;
     414           0 :         a >>= l;
     415           0 :         return PyRef( PyLong_FromUnsignedLong (l), SAL_NO_ACQUIRE );
     416             :     }
     417             :     case typelib_TypeClass_HYPER:
     418             :     {
     419           0 :         sal_Int64 l = 0;
     420           0 :         a >>= l;
     421           0 :         return PyRef( PyLong_FromLongLong (l), SAL_NO_ACQUIRE);
     422             :     }
     423             :     case typelib_TypeClass_UNSIGNED_HYPER:
     424             :     {
     425           0 :         sal_uInt64 l = 0;
     426           0 :         a >>= l;
     427           0 :         return PyRef( PyLong_FromUnsignedLongLong (l), SAL_NO_ACQUIRE);
     428             :     }
     429             :     case typelib_TypeClass_FLOAT:
     430             :     {
     431           0 :         float f = 0.0;
     432           0 :         a >>= f;
     433           0 :         return PyRef(PyFloat_FromDouble (f), SAL_NO_ACQUIRE);
     434             :     }
     435             :     case typelib_TypeClass_DOUBLE:
     436             :     {
     437           0 :         double d = 0.0;
     438           0 :         a >>= d;
     439           0 :         return PyRef( PyFloat_FromDouble (d), SAL_NO_ACQUIRE);
     440             :     }
     441             :     case typelib_TypeClass_STRING:
     442             :     {
     443           0 :         OUString tmp_ostr;
     444           0 :         a >>= tmp_ostr;
     445           0 :         return ustring2PyUnicode( tmp_ostr );
     446             :     }
     447             :     case typelib_TypeClass_TYPE:
     448             :     {
     449           0 :         Type t;
     450           0 :         a >>= t;
     451           0 :         OString o = OUStringToOString( t.getTypeName(), RTL_TEXTENCODING_ASCII_US );
     452             :         return PyRef(
     453             :             PyUNO_Type_new (
     454             :                 o.getStr(),  (com::sun::star::uno::TypeClass)t.getTypeClass(), *this),
     455           0 :             SAL_NO_ACQUIRE);
     456             :     }
     457             :     case typelib_TypeClass_ANY:
     458             :     {
     459             :         //I don't think this can happen.
     460           0 :         Py_INCREF (Py_None);
     461           0 :         return Py_None;
     462             :     }
     463             :     case typelib_TypeClass_ENUM:
     464             :     {
     465           0 :         sal_Int32 l = *(sal_Int32 *) a.getValue();
     466           0 :         TypeDescription desc( a.getValueType() );
     467           0 :         if( desc.is() )
     468             :         {
     469           0 :             desc.makeComplete();
     470             :             typelib_EnumTypeDescription *pEnumDesc =
     471           0 :                 (typelib_EnumTypeDescription *) desc.get();
     472           0 :             for( int i = 0 ; i < pEnumDesc->nEnumValues ; i ++ )
     473             :             {
     474           0 :                 if( pEnumDesc->pEnumValues[i] == l )
     475             :                 {
     476           0 :                     OString v = OUStringToOString( pEnumDesc->ppEnumNames[i], RTL_TEXTENCODING_ASCII_US);
     477           0 :                     OString e = OUStringToOString( pEnumDesc->aBase.pTypeName, RTL_TEXTENCODING_ASCII_US);
     478           0 :                     return PyRef( PyUNO_Enum_new(e.getStr(),v.getStr(), *this ), SAL_NO_ACQUIRE );
     479             :                 }
     480             :             }
     481             :         }
     482           0 :         OUStringBuffer buf;
     483           0 :         buf.appendAscii( "Any carries enum " );
     484           0 :         buf.append( a.getValueType().getTypeName());
     485           0 :         buf.appendAscii( " with invalid value " ).append( l );
     486           0 :         throw RuntimeException( buf.makeStringAndClear() , Reference< XInterface > ()  );
     487             :     }
     488             :     case typelib_TypeClass_EXCEPTION:
     489             :     case typelib_TypeClass_STRUCT:
     490             :     {
     491           0 :         PyRef excClass = getClass( a.getValueType().getTypeName(), *this );
     492           0 :         PyRef value = PyRef( PyUNO_new_UNCHECKED (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE);
     493           0 :         PyRef argsTuple( PyTuple_New( 1 ) , SAL_NO_ACQUIRE );
     494           0 :         PyTuple_SetItem( argsTuple.get() , 0 , value.getAcquired() );
     495           0 :         PyRef ret( PyObject_CallObject( excClass.get() , argsTuple.get() ), SAL_NO_ACQUIRE );
     496           0 :         if( ! ret.is() )
     497             :         {
     498           0 :             OUStringBuffer buf;
     499           0 :             buf.appendAscii( "Couldn't instantiate python representation of structered UNO type " );
     500           0 :             buf.append( a.getValueType().getTypeName() );
     501           0 :             throw RuntimeException( buf.makeStringAndClear(), Reference< XInterface > () );
     502             :         }
     503             : 
     504           0 :         if( com::sun::star::uno::TypeClass_EXCEPTION == a.getValueTypeClass() )
     505             :         {
     506             :             // add the message in a standard python way !
     507           0 :             PyRef args( PyTuple_New( 1 ), SAL_NO_ACQUIRE );
     508             : 
     509             :             // assuming that the Message is always the first member, wuuuu
     510           0 :             void *pData = (void*)a.getValue();
     511           0 :             OUString message = *(OUString * )pData;
     512           0 :             PyRef pymsg = ustring2PyString( message );
     513           0 :             PyTuple_SetItem( args.get(), 0 , pymsg.getAcquired() );
     514             :             // the exception base functions want to have an "args" tuple,
     515             :             // which contains the message
     516           0 :             PyObject_SetAttrString( ret.get(), "args", args.get() );
     517             :         }
     518           0 :         return ret;
     519             :     }
     520             :     case typelib_TypeClass_SEQUENCE:
     521             :     {
     522           0 :         Sequence<Any> s;
     523             : 
     524           0 :         Sequence< sal_Int8 > byteSequence;
     525           0 :         if( a >>= byteSequence )
     526             :         {
     527             :             // byte sequence is treated in a special way because of peformance reasons
     528             :             // @since 0.9.2
     529           0 :             return PyRef( PyUNO_ByteSequence_new( byteSequence, *this ), SAL_NO_ACQUIRE );
     530             :         }
     531             :         else
     532             :         {
     533           0 :             Reference< XTypeConverter > tc = getImpl()->cargo->xTypeConverter;
     534           0 :             Reference< XSingleServiceFactory > ssf = getImpl()->cargo->xInvocation;
     535           0 :             tc->convertTo (a, ::getCppuType (&s)) >>= s;
     536           0 :             PyRef tuple( PyTuple_New (s.getLength()), SAL_NO_ACQUIRE);
     537           0 :             int i=0;
     538             :             try
     539             :             {
     540           0 :                 for ( i = 0; i < s.getLength (); i++)
     541             :                 {
     542           0 :                     PyRef element;
     543           0 :                     element = any2PyObject (tc->convertTo (s[i], s[i].getValueType() ));
     544             :                     OSL_ASSERT( element.is() );
     545           0 :                     PyTuple_SetItem( tuple.get(), i, element.getAcquired() );
     546           0 :                 }
     547             :             }
     548           0 :             catch( com::sun::star::uno::Exception & )
     549             :             {
     550           0 :                 for( ; i < s.getLength() ; i ++ )
     551             :                 {
     552           0 :                     Py_INCREF( Py_None );
     553           0 :                     PyTuple_SetItem( tuple.get(), i,  Py_None );
     554             :                 }
     555           0 :                 throw;
     556             :             }
     557           0 :             return tuple;
     558           0 :         }
     559             :     }
     560             :     case typelib_TypeClass_INTERFACE:
     561             :     {
     562           0 :         Reference< XUnoTunnel > tunnel;
     563           0 :         a >>= tunnel;
     564           0 :         if( tunnel.is() )
     565             :         {
     566           0 :             sal_Int64 that = tunnel->getSomething( ::pyuno::Adapter::getUnoTunnelImplementationId() );
     567           0 :             if( that )
     568           0 :                 return ((Adapter*)sal::static_int_cast< sal_IntPtr >(that))->getWrappedObject();
     569             :         }
     570             :         //This is just like the struct case:
     571           0 :         return PyRef( PyUNO_new (a, getImpl()->cargo->xInvocation), SAL_NO_ACQUIRE );
     572             :     }
     573             :     default:
     574             :     {
     575           0 :         OUStringBuffer buf;
     576           0 :         buf.appendAscii( "Unknown UNO type class " );
     577           0 :         buf.append( (sal_Int32 ) a.getValueTypeClass() );
     578           0 :         throw RuntimeException(buf.makeStringAndClear( ), Reference< XInterface > () );
     579             :     }
     580             :     }
     581             : }
     582             : 
     583           0 : static Sequence< Type > invokeGetTypes( const Runtime & r , PyObject * o )
     584             : {
     585           0 :     Sequence< Type > ret;
     586             : 
     587           0 :     PyRef method( PyObject_GetAttrString( o , "getTypes" ), SAL_NO_ACQUIRE );
     588           0 :     raiseInvocationTargetExceptionWhenNeeded( r );
     589           0 :     if( method.is() && PyCallable_Check( method.get() ) )
     590             :     {
     591           0 :         PyRef types( PyObject_CallObject( method.get(), 0 ) , SAL_NO_ACQUIRE );
     592           0 :         raiseInvocationTargetExceptionWhenNeeded( r );
     593           0 :         if( types.is() && PyTuple_Check( types.get() ) )
     594             :         {
     595           0 :             int size = PyTuple_Size( types.get() );
     596             : 
     597             :             // add the XUnoTunnel interface  for uno object identity concept (hack)
     598           0 :             ret.realloc( size + 1 );
     599           0 :             for( int i = 0 ; i < size ; i ++ )
     600             :             {
     601           0 :                 Any a = r.pyObject2Any(PyTuple_GetItem(types.get(),i));
     602           0 :                 a >>= ret[i];
     603           0 :             }
     604           0 :             ret[size] = getCppuType( (Reference< com::sun::star::lang::XUnoTunnel> *) 0 );
     605           0 :         }
     606             :     }
     607           0 :     return ret;
     608             : }
     609             : 
     610             : static OUString
     611           0 : lcl_ExceptionMessage(PyObject *const o, OUString const*const pWrapped)
     612             : {
     613           0 :     OUStringBuffer buf;
     614           0 :     buf.appendAscii("Couldn't convert ");
     615           0 :     PyRef reprString( PyObject_Str(o), SAL_NO_ACQUIRE );
     616           0 :     buf.appendAscii( PyStr_AsString(reprString.get()) );
     617           0 :     buf.appendAscii(" to a UNO type");
     618           0 :     if (pWrapped)
     619             :     {
     620           0 :         buf.appendAscii("; caught exception: ");
     621           0 :         buf.append(*pWrapped);
     622             :     }
     623           0 :     return buf.makeStringAndClear();
     624             : }
     625             : 
     626           0 : Any Runtime::pyObject2Any ( const PyRef & source, enum ConversionMode mode ) const
     627             :     throw ( com::sun::star::uno::RuntimeException )
     628             : {
     629           0 :     if( ! impl->cargo->valid )
     630             :     {
     631             :         throw RuntimeException("pyuno runtime must be initialized before calling any2PyObject",
     632           0 :                                 Reference< XInterface > () );
     633             :     }
     634             : 
     635           0 :     Any a;
     636           0 :     PyObject *o = source.get();
     637           0 :     if( Py_None == o )
     638             :     {
     639             : 
     640             :     }
     641             :     // In Python 3, there is no PyInt type.
     642             : #if PY_MAJOR_VERSION < 3
     643             :     else if (PyInt_Check (o))
     644             :     {
     645             :         if( o == Py_True )
     646             :         {
     647             :             sal_Bool b = sal_True;
     648             :             a = Any( &b, getBooleanCppuType() );
     649             :         }
     650             :         else if ( o == Py_False )
     651             :         {
     652             :             sal_Bool b = sal_False;
     653             :             a = Any( &b, getBooleanCppuType() );
     654             :         }
     655             :         else
     656             :         {
     657             :             sal_Int32 l = (sal_Int32) PyLong_AsLong( o );
     658             :             if( l < 128 && l >= -128 )
     659             :             {
     660             :                 sal_Int8 b = (sal_Int8 ) l;
     661             :                 a <<= b;
     662             :             }
     663             :             else if( l <= 0x7fff && l >= -0x8000 )
     664             :             {
     665             :                 sal_Int16 s = (sal_Int16) l;
     666             :                 a <<= s;
     667             :             }
     668             :             else
     669             :             {
     670             :                 a <<= l;
     671             :             }
     672             :         }
     673             :     }
     674             : #endif /* PY_MAJOR_VERSION < 3 */
     675           0 :     else if (PyLong_Check (o))
     676             :     {
     677             : #if PY_MAJOR_VERSION >= 3
     678             :         // Convert the Python 3 booleans that are actually of type PyLong.
     679           0 :         if(o == Py_True)
     680             :         {
     681           0 :             sal_Bool b = sal_True;
     682           0 :             a = Any(&b, getBooleanCppuType());
     683             :         }
     684           0 :         else if(o == Py_False)
     685             :         {
     686           0 :             sal_Bool b = sal_False;
     687           0 :             a = Any(&b, getBooleanCppuType());
     688             :         }
     689             :         else
     690             :         {
     691             : #endif /* PY_MAJOR_VERSION >= 3 */
     692           0 :         sal_Int64 l = (sal_Int64)PyLong_AsLong (o);
     693           0 :         if( l < 128 && l >= -128 )
     694             :         {
     695           0 :             sal_Int8 b = (sal_Int8 ) l;
     696           0 :             a <<= b;
     697             :         }
     698           0 :         else if( l <= 0x7fff && l >= -0x8000 )
     699             :         {
     700           0 :             sal_Int16 s = (sal_Int16) l;
     701           0 :             a <<= s;
     702             :         }
     703           0 :         else if( l <= SAL_CONST_INT64(0x7fffffff) &&
     704           0 :                  l >= -SAL_CONST_INT64(0x80000000) )
     705             :         {
     706           0 :             sal_Int32 l32 = (sal_Int32) l;
     707           0 :             a <<= l32;
     708             :         }
     709             :         else
     710             :         {
     711           0 :             a <<= l;
     712             :         }
     713             : #if PY_MAJOR_VERSION >= 3
     714             :         }
     715             : #endif
     716             :     }
     717           0 :     else if (PyFloat_Check (o))
     718             :     {
     719           0 :         double d = PyFloat_AsDouble (o);
     720           0 :         a <<= d;
     721             :     }
     722           0 :     else if (PyStrBytes_Check(o) || PyUnicode_Check(o))
     723             :     {
     724           0 :         a <<= pyString2ustring(o);
     725             :     }
     726           0 :     else if (PyTuple_Check (o))
     727             :     {
     728           0 :         Sequence<Any> s (PyTuple_Size (o));
     729           0 :         for (int i = 0; i < PyTuple_Size (o); i++)
     730             :         {
     731           0 :             s[i] = pyObject2Any (PyTuple_GetItem (o, i), mode );
     732             :         }
     733           0 :         a <<= s;
     734             :     }
     735             :     else
     736             :     {
     737           0 :         Runtime runtime;
     738             :         // should be removed, in case ByteSequence gets derived from String
     739           0 :         if( PyObject_IsInstance( o, getByteSequenceClass( runtime ).get() ) )
     740             :         {
     741           0 :             PyRef str(PyObject_GetAttrString( o , "value" ),SAL_NO_ACQUIRE);
     742           0 :             Sequence< sal_Int8 > seq;
     743           0 :             if( PyStrBytes_Check( str.get() ) )
     744             :             {
     745           0 :                 seq = Sequence<sal_Int8 > (
     746           0 :                     (sal_Int8*) PyStrBytes_AsString(str.get()), PyStrBytes_Size(str.get()));
     747             :             }
     748           0 :             a <<= seq;
     749             :         }
     750             :         else
     751           0 :         if( PyObject_IsInstance( o, getTypeClass( runtime ).get() ) )
     752             :         {
     753           0 :             Type t = PyType2Type( o );
     754           0 :             a <<= t;
     755             :         }
     756           0 :         else if( PyObject_IsInstance( o, getEnumClass( runtime ).get() ) )
     757             :         {
     758           0 :             a = PyEnum2Enum( o );
     759             :         }
     760           0 :         else if( isInstanceOfStructOrException( o ) )
     761             :         {
     762           0 :             PyRef struc(PyObject_GetAttrString( o , "value" ),SAL_NO_ACQUIRE);
     763           0 :             PyUNO * obj = (PyUNO*)struc.get();
     764           0 :             Reference< XMaterialHolder > holder( obj->members->xInvocation, UNO_QUERY );
     765           0 :             if( holder.is( ) )
     766           0 :                 a = holder->getMaterial();
     767             :             else
     768             :             {
     769             :                 throw RuntimeException(
     770             :                     "struct or exception wrapper does not support XMaterialHolder",
     771           0 :                     Reference< XInterface > () );
     772           0 :             }
     773             :         }
     774           0 :         else if( PyObject_IsInstance( o, getPyUnoClass().get() ) )
     775             :         {
     776             :             PyUNO* o_pi;
     777           0 :             o_pi = (PyUNO*) o;
     778           0 :             if (o_pi->members->wrappedObject.getValueTypeClass () ==
     779           0 :                 com::sun::star::uno::TypeClass_STRUCT ||
     780           0 :                 o_pi->members->wrappedObject.getValueTypeClass () ==
     781             :                 com::sun::star::uno::TypeClass_EXCEPTION)
     782             :             {
     783           0 :                 Reference<XMaterialHolder> my_mh (o_pi->members->xInvocation, UNO_QUERY);
     784             : 
     785           0 :                 if (!my_mh.is ())
     786             :                 {
     787             :                     throw RuntimeException(
     788             :                         "struct wrapper does not support XMaterialHolder",
     789           0 :                         Reference< XInterface > () );
     790             :                 }
     791             :                 else
     792           0 :                     a = my_mh->getMaterial ();
     793             :             }
     794             :             else
     795             :             {
     796           0 :                 a = o_pi->members->wrappedObject;
     797             :             }
     798             :         }
     799           0 :         else if( PyObject_IsInstance( o, getCharClass( runtime ).get() ) )
     800             :         {
     801           0 :             sal_Unicode c = PyChar2Unicode( o );
     802           0 :             a.setValue( &c, getCharCppuType( ));
     803             :         }
     804           0 :         else if( PyObject_IsInstance( o, getAnyClass( runtime ).get() ) )
     805             :         {
     806           0 :             if( ACCEPT_UNO_ANY == mode )
     807             :             {
     808           0 :                 a = pyObject2Any( PyRef( PyObject_GetAttrString( o , "value" ), SAL_NO_ACQUIRE) );
     809           0 :                 Type t;
     810           0 :                 pyObject2Any( PyRef( PyObject_GetAttrString( o, "type" ), SAL_NO_ACQUIRE ) ) >>= t;
     811             : 
     812             :                 try
     813             :                 {
     814           0 :                     a = getImpl()->cargo->xTypeConverter->convertTo( a, t );
     815             :                 }
     816           0 :                 catch( const com::sun::star::uno::Exception & e )
     817             :                 {
     818             :                     throw WrappedTargetRuntimeException(
     819           0 :                             e.Message, e.Context, makeAny(e));
     820           0 :                 }
     821             :             }
     822             :             else
     823             :             {
     824             :                 throw RuntimeException(
     825             :                     OUString( "uno.Any instance not accepted during method call, "
     826             :                                   "use uno.invoke instead"  ),
     827           0 :                     Reference< XInterface > () );
     828             :             }
     829             :         }
     830             :         else
     831             :         {
     832           0 :             Reference< XInterface > mappedObject;
     833           0 :             Reference< XInvocation > adapterObject;
     834             : 
     835             :             // instance already mapped out to the world ?
     836           0 :             PyRef2Adapter::iterator ii = impl->cargo->mappedObjects.find( PyRef( o ) );
     837           0 :             if( ii != impl->cargo->mappedObjects.end() )
     838             :             {
     839           0 :                 adapterObject = ii->second;
     840             :             }
     841             : 
     842           0 :             if( adapterObject.is() )
     843             :             {
     844             :                 // object got already bridged !
     845           0 :                 Reference< com::sun::star::lang::XUnoTunnel > tunnel( adapterObject, UNO_QUERY );
     846             : 
     847             :                 Adapter *pAdapter = ( Adapter * )
     848             :                     sal::static_int_cast< sal_IntPtr >(
     849           0 :                         tunnel->getSomething(
     850           0 :                             ::pyuno::Adapter::getUnoTunnelImplementationId() ) );
     851             : 
     852           0 :                 mappedObject = impl->cargo->xAdapterFactory->createAdapter(
     853           0 :                     adapterObject, pAdapter->getWrappedTypes() );
     854             :             }
     855             :             else
     856             :             {
     857             :                 try {
     858           0 :                     Sequence<Type> interfaces = invokeGetTypes(*this, o);
     859           0 :                     if (interfaces.getLength())
     860             :                     {
     861           0 :                         Adapter *pAdapter = new Adapter( o, interfaces );
     862           0 :                         mappedObject =
     863           0 :                             getImpl()->cargo->xAdapterFactory->createAdapter(
     864           0 :                                 pAdapter, interfaces );
     865             : 
     866             :                         // keep a list of exported objects to ensure object identity !
     867           0 :                         impl->cargo->mappedObjects[ PyRef(o) ] =
     868           0 :                             com::sun::star::uno::WeakReference< XInvocation > ( pAdapter );
     869           0 :                     }
     870           0 :                 } catch (InvocationTargetException const& e) {
     871           0 :                     OUString const msg(lcl_ExceptionMessage(o, &e.Message));
     872             :                     throw WrappedTargetRuntimeException( // re-wrap that
     873           0 :                             msg, e.Context, e.TargetException);
     874             :                 }
     875             :             }
     876           0 :             if( mappedObject.is() )
     877             :             {
     878           0 :                 a = com::sun::star::uno::makeAny( mappedObject );
     879             :             }
     880             :             else
     881             :             {
     882           0 :                 OUString const msg(lcl_ExceptionMessage(o, 0));
     883           0 :                 throw RuntimeException(msg, Reference<XInterface>());
     884           0 :             }
     885           0 :         }
     886             :     }
     887           0 :     return a;
     888             : }
     889             : 
     890           0 : Any Runtime::extractUnoException( const PyRef & excType, const PyRef &excValue, const PyRef &excTraceback) const
     891             : {
     892           0 :     OUString str;
     893           0 :     Any ret;
     894           0 :     if( excTraceback.is() )
     895             :     {
     896           0 :         Exception e;
     897           0 :         PyRef unoModule;
     898           0 :         if ( impl )
     899             :         {
     900             :             try
     901             :             {
     902           0 :                 unoModule = impl->cargo->getUnoModule();
     903             :             }
     904           0 :             catch (const Exception &ei)
     905             :             {
     906           0 :                 e=ei;
     907             :             }
     908             :         }
     909           0 :         if( unoModule.is() )
     910             :         {
     911             :             PyRef extractTraceback(
     912           0 :                 PyDict_GetItemString(unoModule.get(),"_uno_extract_printable_stacktrace" ) );
     913             : 
     914           0 :             if( PyCallable_Check(extractTraceback.get()) )
     915             :             {
     916           0 :                 PyRef args( PyTuple_New( 1), SAL_NO_ACQUIRE );
     917           0 :                 PyTuple_SetItem( args.get(), 0, excTraceback.getAcquired() );
     918           0 :                 PyRef pyStr( PyObject_CallObject( extractTraceback.get(),args.get() ), SAL_NO_ACQUIRE);
     919           0 :                 str = OUString::createFromAscii( PyStr_AsString(pyStr.get()) );
     920             :             }
     921             :             else
     922             :             {
     923           0 :                 str = "Couldn't find uno._uno_extract_printable_stacktrace";
     924           0 :             }
     925             :         }
     926             :         else
     927             :         {
     928           0 :             str = "Could not load uno.py, no stacktrace available";
     929           0 :             if ( !e.Message.isEmpty() )
     930             :             {
     931           0 :                 str += OUString (" (Error loading uno.py: ");
     932           0 :                 str += e.Message;
     933           0 :                 str += OUString (")");
     934             :             }
     935           0 :         }
     936             : 
     937             :     }
     938             :     else
     939             :     {
     940             :         // it may occur, that no traceback is given (e.g. only native code below)
     941           0 :         str = "no traceback available";
     942             :     }
     943             : 
     944           0 :     if( isInstanceOfStructOrException( excValue.get() ) )
     945             :     {
     946           0 :         ret = pyObject2Any( excValue );
     947             :     }
     948             :     else
     949             :     {
     950           0 :         OUStringBuffer buf;
     951           0 :         PyRef typeName( PyObject_Str( excType.get() ), SAL_NO_ACQUIRE );
     952           0 :         if( typeName.is() )
     953             :         {
     954           0 :             buf.appendAscii( PyStr_AsString( typeName.get() ) );
     955             :         }
     956             :         else
     957             :         {
     958           0 :             buf.appendAscii( "no typename available" );
     959             :         }
     960           0 :         buf.appendAscii( ": " );
     961           0 :         PyRef valueRep( PyObject_Str( excValue.get() ), SAL_NO_ACQUIRE );
     962           0 :         if( valueRep.is() )
     963             :         {
     964           0 :             buf.appendAscii( PyStr_AsString( valueRep.get()));
     965             :         }
     966             :         else
     967             :         {
     968           0 :             buf.appendAscii( "Couldn't convert exception value to a string" );
     969             :         }
     970           0 :         buf.appendAscii( ", traceback follows\n" );
     971           0 :         if( !str.isEmpty() )
     972             :         {
     973           0 :             buf.append( str );
     974           0 :             buf.appendAscii( "\n" );
     975             :         }
     976             :         else
     977             :         {
     978           0 :             buf.appendAscii( ", no traceback available\n" );
     979             :         }
     980           0 :         RuntimeException e;
     981           0 :         e.Message = buf.makeStringAndClear();
     982             : #if OSL_DEBUG_LEVEL > 0
     983             :         fprintf( stderr, "Python exception: %s\n",
     984             :                  OUStringToOString(e.Message, RTL_TEXTENCODING_UTF8).getStr() );
     985             : #endif
     986           0 :         ret = com::sun::star::uno::makeAny( e );
     987             :     }
     988           0 :     return ret;
     989             : }
     990             : 
     991             : 
     992             : static const char * g_NUMERICID = "pyuno.lcNumeric";
     993           0 : static ::std::vector< OString > g_localeList;
     994             : 
     995           0 : static const char *ensureUnlimitedLifetime( const char *str )
     996             : {
     997           0 :     int size = g_localeList.size();
     998             :     int i;
     999           0 :     for( i = 0 ; i < size ; i ++ )
    1000             :     {
    1001           0 :         if( 0 == strcmp( g_localeList[i].getStr(), str ) )
    1002           0 :             break;
    1003             :     }
    1004           0 :     if( i == size )
    1005             :     {
    1006           0 :         g_localeList.push_back( str );
    1007             :     }
    1008           0 :     return g_localeList[i].getStr();
    1009             : }
    1010             : 
    1011             : 
    1012           0 : PyThreadAttach::PyThreadAttach( PyInterpreterState *interp)
    1013             :     throw ( com::sun::star::uno::RuntimeException )
    1014             : {
    1015           0 :     tstate = PyThreadState_New( interp );
    1016           0 :     if( !tstate  )
    1017             :         throw RuntimeException(
    1018             :             OUString( "Couldn't create a pythreadstate"  ),
    1019           0 :             Reference< XInterface > () );
    1020           0 :     PyEval_AcquireThread( tstate);
    1021             :     // set LC_NUMERIC to "C"
    1022             :     const char * oldLocale =
    1023           0 :         ensureUnlimitedLifetime( setlocale( LC_NUMERIC, 0 )  );
    1024           0 :     setlocale( LC_NUMERIC, "C" );
    1025             :     PyRef locale( // python requires C locale
    1026           0 :         PyLong_FromVoidPtr( (void*)oldLocale ), SAL_NO_ACQUIRE);
    1027             :     PyDict_SetItemString(
    1028           0 :         PyThreadState_GetDict(), g_NUMERICID, locale.get() );
    1029           0 : }
    1030             : 
    1031           0 : PyThreadAttach::~PyThreadAttach()
    1032             : {
    1033             :     PyObject *value =
    1034           0 :         PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
    1035           0 :     if( value )
    1036           0 :         setlocale( LC_NUMERIC, (const char * ) PyLong_AsVoidPtr( value ) );
    1037           0 :     PyThreadState_Clear( tstate );
    1038           0 :     PyEval_ReleaseThread( tstate );
    1039           0 :     PyThreadState_Delete( tstate );
    1040             : 
    1041           0 : }
    1042             : 
    1043           0 : PyThreadDetach::PyThreadDetach() throw ( com::sun::star::uno::RuntimeException )
    1044             : {
    1045           0 :     tstate = PyThreadState_Get();
    1046             :     PyObject *value =
    1047           0 :         PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
    1048           0 :     if( value )
    1049           0 :         setlocale( LC_NUMERIC, (const char * ) PyLong_AsVoidPtr( value ) );
    1050           0 :     PyEval_ReleaseThread( tstate );
    1051           0 : }
    1052             : 
    1053             :     /** Acquires the global interpreter lock again
    1054             : 
    1055             :     */
    1056           0 : PyThreadDetach::~PyThreadDetach()
    1057             : {
    1058           0 :     PyEval_AcquireThread( tstate );
    1059             : //     PyObject *value =
    1060             : //         PyDict_GetItemString( PyThreadState_GetDict( ), g_NUMERICID );
    1061             : 
    1062             :     // python requires C LC_NUMERIC locale,
    1063             :     // always set even when it is already "C"
    1064           0 :     setlocale( LC_NUMERIC, "C" );
    1065           0 : }
    1066             : 
    1067             : 
    1068           0 : PyRef RuntimeCargo::getUnoModule()
    1069             : {
    1070           0 :     if( ! dictUnoModule.is() )
    1071             :     {
    1072           0 :         dictUnoModule = importUnoModule();
    1073             :     }
    1074           0 :     return dictUnoModule;
    1075             : }
    1076           0 : }
    1077             : 
    1078             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10