1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: pythontest.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
35 #include <stardiv/uno/repos/implementationregistration.hxx>
36 #include <stardiv/uno/script/script.hxx>
37 #include <stardiv/uno/beans/exactname.hxx>
39 #include <rtl/ustring.hxx>
40 #include <vos/dynload.hxx>
41 #include <vos/diagnose.hxx>
42 #include <usr/services.hxx>
43 #include <vcl/svapp.hxx>
44 #include <usr/ustring.hxx>
45 #include <usr/weak.hxx>
46 #include <tools/string.hxx>
47 #include <vos/conditn.hxx>
48 #if OSL_DEBUG_LEVEL == 0
57 #define PCHAR_TO_USTRING(x) StringToOUString(String(x),CHARSET_SYSTEM)
61 class NullEngineListenerRef
: public XEngineListenerRef
63 virtual void interrupt(const InterruptEngineEvent
& Evt
) THROWS( (UsrSystemException
) ) {}
64 virtual void running(const EventObject
& Evt
) THROWS( (UsrSystemException
) ) {}
65 virtual void finished(const FinishEngineEvent
& Evt
) THROWS( (UsrSystemException
) ) {}
68 #define USTRING_TO_PCHAR(x) OUStringToString(x , CHARSET_DONTKNOW ).GetCharStr()
71 public XEngineListener
,
80 m_bIsTerminating
= FALSE
;
85 CmdDebugger( XDebuggingRef
*p
, XEngineRef
*pEngine
, XInvokationRef
*pInvokation
)
87 attach( p
, pEngine
, pInvokation
);
92 if( m_pDebuggingRef
) {
97 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
98 void acquire() { OWeakObject::acquire(); }
99 void release() { OWeakObject::release(); }
100 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
103 void attach( XDebuggingRef
*p
, XEngineRef
*pEngine
, XInvokationRef
*pInvokation
)
106 m_pEngineRef
= pEngine
;
107 m_pInvokationRef
= pInvokation
;
108 m_bIsRunning
= FALSE
;
109 m_bIsTerminating
= FALSE
;
115 virtual void disposing( const EventObject
&o
)
117 if( m_pDebuggingRef
) {
121 virtual void interrupt(const InterruptEngineEvent
& Evt
) THROWS( (UsrSystemException
) )
123 if( m_pDebuggingRef
&& ! m_bIsTerminating
) {
124 (*m_pDebuggingRef
)->stop();
125 fprintf( stderr
, "%s\n" , USTRING_TO_PCHAR(Evt
.ErrorMessage
) );
126 fprintf( stderr
, "%s.%s (%d)\n", USTRING_TO_PCHAR(Evt
.SourceCode
),
127 USTRING_TO_PCHAR(Evt
.Name
),
129 m_aDebugCondition
.set();
134 virtual void running(const EventObject
& Evt
) THROWS( (UsrSystemException
) )
136 if( m_pDebuggingRef
&& ! m_bIsTerminating
) {
137 (*m_pDebuggingRef
)->stop();
139 m_aDebugCondition
.set();
141 fprintf( stderr
, "%s\n" , "Script starts\n" );
145 virtual void finished(const FinishEngineEvent
& Evt
) THROWS( (UsrSystemException
) )
147 if( m_pDebuggingRef
&& ! m_bIsTerminating
) {
148 m_aDebugCondition
.set();
149 m_bIsRunning
= FALSE
;
150 fprintf( stderr
, "%s\n", USTRING_TO_PCHAR( Evt
.ErrorMessage
) );
154 void dumpIntrospectionToStream( const XIntrospectionAccessRef
&, FILE *f
);
155 void dumpVarToStream( const char *pcName
, const UsrAny
&any
, FILE *f
);
161 OCondition m_aDebugCondition
;
162 XDebuggingRef
*m_pDebuggingRef
;
163 XEngineRef
*m_pEngineRef
;
164 XInvokationRef
*m_pInvokationRef
;
166 int m_bIsTerminating
; // The listeners ignore everything when set
171 void CmdDebugger::cmdLine()
174 fprintf( stderr
, "entering debugger\n" );
177 m_aDebugCondition
.wait();
179 fprintf( stderr
, "(debug %d) : " , m_bIsRunning
);
181 fgets( pcLine
, 79 , stdin
);
183 if( strlen( pcLine
) ) pcLine
[strlen(pcLine
)-1] =0;
184 String
sLine( pcLine
);
186 if( ! strcmp( pcLine
, "g" ) ) {
188 m_aDebugCondition
.reset();
189 (*m_pDebuggingRef
)->doContinue();
191 else fprintf( stderr
,"no script running !\n" );
193 else if( ! strcmp( pcLine
, "s" ) ) {
195 m_aDebugCondition
.reset();
196 (*m_pDebuggingRef
)->stepOver();
198 else fprintf(stderr
, "no script running !\n" );
200 else if( ! strcmp( pcLine
, "so" ) ) {
202 m_aDebugCondition
.reset();
203 (*m_pDebuggingRef
)->stepOut();
205 else fprintf(stderr
, "no script running !\n" );
207 else if( ! strcmp( pcLine
, "si" ) ) {
209 m_aDebugCondition
.reset();
210 (*m_pDebuggingRef
)->stepIn();
212 else fprintf(stderr
, "no script running !\n" );
214 else if( ! strncmp( pcLine
, "sbp" , 3 ) ){
216 (*m_pDebuggingRef
)->setBreakPoint( UString( L
"<string>" ),
217 atoi(&pcLine
[3]) , TRUE
);
220 else if( ! strncmp( pcLine
, "rbp" , 3 ) ){
222 (*m_pDebuggingRef
)->setBreakPoint( UString( L
"<string>" ),
223 atoi(&pcLine
[3]) , FALSE
);
226 else if( ! strncmp( pcLine
, "dv " , 3 ) ) {
229 if( sLine
.GetQuotedTokenCount( String("''"),' ' ) == 3 ) {
230 nCallstack
= atoi( sLine
.GetQuotedToken( 3 , String("''"), ' ' ).GetCharStr() );
233 UString str
= (*m_pDebuggingRef
)->dumpVariable(
234 PCHAR_TO_USTRING( &pcLine
[3]),nCallstack
);
235 fprintf( stderr
, "%s\n" , USTRING_TO_PCHAR( str
) );
238 else if( ! strncmp( pcLine
, "sv " , 3 ) ) {
240 if( sLine
.GetQuotedTokenCount( String("''"),' ' ) == 3 ) {
241 nCallstack
= atoi( sLine
.GetQuotedToken( 3 , String("''"), ' ' ).GetCharStr() );
243 (*m_pDebuggingRef
)->setVariable(
244 StringToOUString( sLine
.GetQuotedToken( 1 , String("''"), ' ' ), CHARSET_SYSTEM
),
245 StringToOUString( sLine
.GetQuotedToken( 2 , String("''"), ' ' ), CHARSET_SYSTEM
),
249 else if( ! strncmp( pcLine
, "ci" ,2 ) ) {
252 ContextInformation ci
= (*m_pDebuggingRef
)->getContextInformation(atoi(&pcLine
[2]));
255 fprintf( stderr
, "File %s (%d)\n", USTRING_TO_PCHAR(ci
.Name
),
257 fprintf( stderr
, "Available variables : \n" );
258 aUString
= ci
.LocalVariableNames
.getArray();
259 iMax
= ci
.LocalVariableNames
.getLen();
261 for( i
= 0 ; i
< iMax
; i
++ ) {
262 fprintf( stderr
, " %s\n" , USTRING_TO_PCHAR( aUString
[i
]) );
266 else if ( !strcmp( pcLine
, "d" ) ) {
269 Sequence
<UString
> seq
= (*m_pDebuggingRef
)->getStackTrace();
271 aUString
= seq
.getArray();
272 int iMax
= seq
.getLen();
273 for( int i
= 0; i
< iMax
; i
++ ) {
274 fprintf( stderr
, "%s\n" , USTRING_TO_PCHAR( aUString
[i
] ) );
278 else if( !strcmp( pcLine
, "c" ) ) {
280 (*m_pEngineRef
)->cancel();
281 m_aDebugCondition
.reset();
283 else fprintf( stderr
,"no script running !\n" );
285 else if( !strcmp( pcLine
, "q" ) ) {
287 m_aDebugCondition
.reset();
288 (*m_pEngineRef
)->cancel();
291 m_bIsTerminating
= TRUE
;
292 fprintf(stderr
, "Debugger terminates\n" );
296 else if( ! strcmp( pcLine
, "id" ) ) {
298 XIntrospectionAccessRef ref
= (*m_pInvokationRef
)->getIntrospection();
300 dumpIntrospectionToStream( ref
, stderr
);
304 else if( ! strncmp( pcLine
, "idv" , 3) ) {
306 UsrAny any
= (*m_pInvokationRef
)->getValue( PCHAR_TO_USTRING( &(pcLine
[4]) ) );
307 dumpVarToStream( &(pcLine
[4]) , any
, stderr
);
309 catch(UnknownPropertyException
& e
) {
310 fprintf( stderr
, "UnknownPropertyException\n" );
312 catch(IllegalArgumentException
& e
) {
313 fprintf( stderr
, "IllegalArgumentException\n" );
316 else if( !strcmp( pcLine
, "t" ) ) {
318 else if( !strcmp( pcLine
, "h" ) ) {
319 fprintf( stderr
, "\nvalid commands :\n"
324 "Set BreakPoint : sbp Line [ModuleName]\n"
325 "Remove BreakPoint : rbp [Line] [ModuleName]\n"
326 "via XDebugging Interface :\n"
327 " dump Variable : dv varname [CallStack]\n"
328 " set Variable : sv varname value [CallStack]\n"
329 "globals via XInvokation Interface :\n"
330 " dump Global vars : id\n"
331 " dump Variable : idv varname\n"
332 " set Variable : isv varname value\n"
333 "ContextInformation : ci\n"
334 "Dump callstack : d\n"
335 "Cancel : c (stops actual script)\n"
336 "Quit : q (exits debugger)\n"
339 else if( ! strlen( pcLine
) ) {
342 fprintf( stderr
, "unknown command %s\n" , pcLine
);
347 void CmdDebugger::dumpIntrospectionToStream( const XIntrospectionAccessRef
&ref
, FILE *f
)
350 fprintf( stderr
, "Callable Attributes (Methods) :\n" );
351 Sequence
<XIdlMethodRef
> seq
= ref
->getMethods( 0 );
353 XIdlMethodRef
*aRef
= seq
.getArray();
354 for( i
= 0; i
< iMax
; i
++ ) {
355 fprintf( f
, " %s\n" , USTRING_TO_PCHAR( aRef
[i
]->getName( ) ) );
358 fprintf( stderr
, "Other attributes\n" );
359 Sequence
<Property
> seqProp
= ref
->getProperties( 0 );
360 iMax
= seqProp
.getLen();
361 Property
*aProp
= seqProp
.getArray();
362 for( i
= 0; i
< iMax
; i
++ ) {
363 fprintf( f
, " %s %s\n" , USTRING_TO_PCHAR( aProp
[i
].Type
->getName() ),
364 USTRING_TO_PCHAR( aProp
[i
].Name
) );
369 void CmdDebugger::dumpVarToStream( const char *pc
, const UsrAny
&aValue
, FILE *f
)
371 TypeClass type
= aValue
.getReflection()->getTypeClass();
373 if( TypeClass_INT
== type
) {
374 fprintf( f
, "INT32 %s : %d\n" , pc
, aValue
.getINT32() );
376 else if( TypeClass_ENUM
== type
) {
377 fprintf( f
, "ENUM %s : %d\n", pc
, aValue
.getEnumAsINT32() );
379 else if( TypeClass_STRING
== type
) {
380 fprintf( f
, "STRING %s : %s\n" , pc
, USTRING_TO_PCHAR( aValue
.getString()) );
382 else if( TypeClass_BOOLEAN
== type
) {
383 fprintf( f
, "BOOL %s : %d\n", pc
, aValue
.getBOOL() );
385 else if( TypeClass_CHAR
== type
) {
386 fprintf( f
, "char %s : %d\n", pc
, ( INT32
) aValue
.getChar() );
388 else if( TypeClass_SHORT
== type
) {
389 fprintf( f
, "INT16 %s : %d\n", pc
, (INT32
) aValue
.getINT16());
391 else if( TypeClass_LONG
== type
) {
392 fprintf( f
, "LONG %s : %d\n", pc
, (INT32
) aValue
.getINT32());
394 else if( TypeClass_UNSIGNED_SHORT
== type
) {
395 fprintf( f
, "UINT16 %s : %d\n", pc
, (INT32
) aValue
.getUINT16() );
397 else if( TypeClass_UNSIGNED_BYTE
== type
) {
398 fprintf( f
, "Byte %s : %d\n", pc
, (INT32
) aValue
.getBYTE() );
400 else if( TypeClass_UNSIGNED_INT
== type
) {
401 fprintf( f
, "UINT32 %s : %d\n", pc
, aValue
.getUINT32() );
403 else if( TypeClass_FLOAT
== type
) {
404 fprintf( f
, "float %s : %f\n" , pc
, aValue
.getFloat() );
406 else if( TypeClass_DOUBLE
== type
) {
407 fprintf( f
, "double %s : %f\n" , pc
, aValue
.getDouble() );
409 else if( TypeClass_VOID
== type
) {
410 fprintf( f
, "void %s :\n" , pc
);
412 else if( TypeClass_INTERFACE
== type
) {
413 // Check, what has been put in
414 if( aValue
.getReflection() == XPropertySet_getReflection() ) {
416 XPropertySetRef
*pRef
= ( XPropertySetRef
* ) aValue
.get();
417 XPropertySetInfoRef refInfo
= (*pRef
)->getPropertySetInfo();
418 Sequence
< Property
> seq
= refInfo
->getProperties();
419 int i
,iMax
= seq
.getLen();
422 pArray
= seq
.getArray();
423 fprintf( stderr
, "Property List :\n" );
424 for( i
= 0; i
< iMax
; i
++ ) {
425 fprintf( f
, "%s\t %s\n" , USTRING_TO_PCHAR(pArray
[i
].Type
->getName()),
426 USTRING_TO_PCHAR( pArray
[i
].Name
) );
429 else if( aValue
.getReflection() == XInvokation_getReflection() ) {
430 XInvokationRef
*pRef
= ( XInvokationRef
* ) aValue
.get();
431 XIntrospectionAccessRef refIntro
= (*pRef
)->getIntrospection();
433 dumpIntrospectionToStream( refIntro
, stderr
);
436 else if( TypeClass_SEQUENCE
== type
) {
437 fprintf( f
, "%s Sequence \n" , pc
);
440 SequenceReflection
*pSeqRefl
= ( SequenceReflection
* ) aValue
.getReflection();
442 int i
,iMax
= pSeqRefl
->getLen( aValue
);
444 for( i
= 0 ; i
< iMax
; i
++ ) {
445 dumpVarToStream( s
.GetCharStr() , pSeqRefl
->get( aValue
, i
) , stderr
);
449 fprintf( f
, "%s : unknown %d\n" , pc
, type
);
454 void CmdDebugger::detach()
456 assert( m_pDebuggingRef
);
458 m_bIsRunning
= FALSE
;
461 m_pInvokationRef
= 0;
464 // Methoden von XInterface
465 BOOL
CmdDebugger::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
467 if( aUik
== XEngineListener::getSmartUik() )
468 rOut
= (XEngineListener
*)this;
470 return OWeakObject::queryInterface( aUik
, rOut
);
482 int __LOADONCALLAPI
main (int argc
, char **argv
)
484 XMultiServiceFactoryRef xSMgr
= createRegistryServiceManager();
485 registerUsrServices( xSMgr
);
486 setProcessServiceManager( xSMgr
);
488 XInterfaceRef x
= xSMgr
->createInstance( L
"stardiv.uno.repos.ImplementationRegistration" );
489 XImplementationRegistrationRef
xReg( x
, USR_QUERY
);
490 sal_Char szBuf
[1024];
492 ORealDynamicLoader::computeModuleName( "pythonengine", szBuf
, 1024 );
493 UString
aDllName( StringToOUString( szBuf
, CHARSET_SYSTEM
) );
494 xReg
->registerImplementation( L
"stardiv.loader.SharedLibrary", aDllName
, XSimpleRegistryRef() );
496 ORealDynamicLoader::computeModuleName( "aps", szBuf
, 1024 );
497 aDllName
= UString( StringToOUString( szBuf
, CHARSET_SYSTEM
) );
498 xReg
->registerImplementation( L
"stardiv.loader.SharedLibrary", aDllName
, XSimpleRegistryRef() );
500 XInterfaceRef y
= xSMgr
->createInstance( L
"stardiv.script.Python" );
501 XEngineRef
yEngine( y
, USR_QUERY
);
503 x
= xSMgr
->createInstance( L
"stardiv.script.Python" );
504 XEngineRef
xEngine( x
, USR_QUERY
);
509 Sequence
<UsrAny
> args(3);
510 UsrAny
*pArray
= args
.getArray();
511 pArray
[0].setString( L
"Arg_0" );
512 pArray
[1].setString( L
"Arg_1" );
513 pArray
[2].setString( L
"Arg_2" );
516 Script
= StringToOUString( String( argv
[2] ) , CHARSET_DONTKNOW
);
519 XInvokationRef
xInvokation( x
, USR_QUERY
);
520 XDebuggingRef
xDebug( x
, USR_QUERY
);
522 CmdDebugger
*pDbg
= new CmdDebugger( &xDebug
, &xEngine
, &xInvokation
);
524 XEngineListenerRef
xDebugRef( (XEngineListener
*) pDbg
, USR_QUERY
);
525 xEngine
->addEngineListener( xDebugRef
);
528 if( argc
>1 && ! strcmp( argv
[1] , "1" ) ) {
529 fprintf( stderr
, "one thread only\n" );
530 Script
= UString( L
"print 'Hello World'\n" );
531 xEngine
->runAsync( Script
, XInterfaceRef(), args
, XEngineListenerRef() );
533 else if( argc
>1 && ! strcmp( argv
[1] , "2" ) ) {
535 xEngine
->runAsync( UString( L
"x=1\nprint 1\n") , XInterfaceRef(), args
, XEngineListenerRef() );
536 xEngine
->runAsync( UString( L
"x=x+1\nprint 2\n") , XInterfaceRef(), args
, XEngineListenerRef() );
537 xEngine
->runAsync( UString( L
"x=x+1\nprint 3\n") , XInterfaceRef(), args
, XEngineListenerRef());
538 xEngine
->runAsync( UString( L
"x=x+1\nprint 4\n") , XInterfaceRef(), args
, XEngineListenerRef() );
543 else if( argc
>1 && ! strcmp( argv
[1] , "3" ) ) {
545 fprintf( stderr
, "1st thread in engine y, next 5 threads in engine x\n" );
546 yEngine
->runAsync( UString( L
"print 1\n") , XInterfaceRef(), args
, XEngineListenerRef() );
547 xEngine
->runAsync( UString( L
"print 2\n") , XInterfaceRef(), args
, XEngineListenerRef() );
548 xEngine
->runAsync( UString( L
"print 3\n") , XInterfaceRef(), args
, XEngineListenerRef() );
549 xEngine
->runAsync( UString( L
"print 4\n") , XInterfaceRef(), args
, XEngineListenerRef());
550 xEngine
->runAsync( UString( L
"print 5\n") , XInterfaceRef(), args
, XEngineListenerRef());
551 xEngine
->runAsync( UString( L
"print 6\n") , XInterfaceRef(), args
, XEngineListenerRef());
557 xEngine
->removeEngineListener( xDebugRef
);
559 xReg
->revokeImplementation( aDllName
, XSimpleRegistryRef() );
561 fprintf( stderr
, "main terminates\n" );