1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
11 * OpenOffice.org is free software: you can redistribute it and/or modify
12 * it under the terms of the GNU Lesser General Public License version 3
13 * only, as published by the Free Software Foundation.
15 * OpenOffice.org is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Lesser General Public License version 3 for more details
19 * (a copy is included in the LICENSE file that accompanied this code).
21 * You should have received a copy of the GNU Lesser General Public License
22 * version 3 along with OpenOffice.org. If not, see
23 * <http://www.openoffice.org/license.html>
24 * for a copy of the LGPLv3 License.
26 ************************************************************************/
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
32 #include <stardiv/uno/repos/implementationregistration.hxx>
33 #include <stardiv/uno/script/script.hxx>
34 #include <stardiv/uno/beans/exactname.hxx>
36 #include <rtl/ustring.hxx>
37 #include <vos/dynload.hxx>
38 #include <vos/diagnose.hxx>
39 #include <usr/services.hxx>
40 #include <vcl/svapp.hxx>
41 #include <usr/ustring.hxx>
42 #include <usr/weak.hxx>
43 #include <tools/string.hxx>
44 #include <vos/conditn.hxx>
50 #define PCHAR_TO_USTRING(x) StringToOUString(String(x),CHARSET_SYSTEM)
54 class NullEngineListenerRef
: public XEngineListenerRef
56 virtual void interrupt(const InterruptEngineEvent
& Evt
) THROWS( (UsrSystemException
) ) {}
57 virtual void running(const EventObject
& Evt
) THROWS( (UsrSystemException
) ) {}
58 virtual void finished(const FinishEngineEvent
& Evt
) THROWS( (UsrSystemException
) ) {}
61 #define USTRING_TO_PCHAR(x) OUStringToString(x , CHARSET_DONTKNOW ).GetCharStr()
64 public XEngineListener
,
73 m_bIsTerminating
= FALSE
;
78 CmdDebugger( XDebuggingRef
*p
, XEngineRef
*pEngine
, XInvokationRef
*pInvokation
)
80 attach( p
, pEngine
, pInvokation
);
85 if( m_pDebuggingRef
) {
90 BOOL
queryInterface( Uik aUik
, XInterfaceRef
& rOut
);
91 void acquire() { OWeakObject::acquire(); }
92 void release() { OWeakObject::release(); }
93 void* getImplementation(Reflection
*p
) { return OWeakObject::getImplementation(p
); }
96 void attach( XDebuggingRef
*p
, XEngineRef
*pEngine
, XInvokationRef
*pInvokation
)
99 m_pEngineRef
= pEngine
;
100 m_pInvokationRef
= pInvokation
;
101 m_bIsRunning
= FALSE
;
102 m_bIsTerminating
= FALSE
;
108 virtual void disposing( const EventObject
&o
)
110 if( m_pDebuggingRef
) {
114 virtual void interrupt(const InterruptEngineEvent
& Evt
) THROWS( (UsrSystemException
) )
116 if( m_pDebuggingRef
&& ! m_bIsTerminating
) {
117 (*m_pDebuggingRef
)->stop();
118 fprintf( stderr
, "%s\n" , USTRING_TO_PCHAR(Evt
.ErrorMessage
) );
119 fprintf( stderr
, "%s.%s (%d)\n", USTRING_TO_PCHAR(Evt
.SourceCode
),
120 USTRING_TO_PCHAR(Evt
.Name
),
122 m_aDebugCondition
.set();
127 virtual void running(const EventObject
& Evt
) THROWS( (UsrSystemException
) )
129 if( m_pDebuggingRef
&& ! m_bIsTerminating
) {
130 (*m_pDebuggingRef
)->stop();
132 m_aDebugCondition
.set();
134 fprintf( stderr
, "%s\n" , "Script starts\n" );
138 virtual void finished(const FinishEngineEvent
& Evt
) THROWS( (UsrSystemException
) )
140 if( m_pDebuggingRef
&& ! m_bIsTerminating
) {
141 m_aDebugCondition
.set();
142 m_bIsRunning
= FALSE
;
143 fprintf( stderr
, "%s\n", USTRING_TO_PCHAR( Evt
.ErrorMessage
) );
147 void dumpIntrospectionToStream( const XIntrospectionAccessRef
&, FILE *f
);
148 void dumpVarToStream( const char *pcName
, const UsrAny
&any
, FILE *f
);
154 OCondition m_aDebugCondition
;
155 XDebuggingRef
*m_pDebuggingRef
;
156 XEngineRef
*m_pEngineRef
;
157 XInvokationRef
*m_pInvokationRef
;
159 int m_bIsTerminating
; // The listeners ignore everything when set
164 void CmdDebugger::cmdLine()
167 fprintf( stderr
, "entering debugger\n" );
170 m_aDebugCondition
.wait();
172 fprintf( stderr
, "(debug %d) : " , m_bIsRunning
);
174 fgets( pcLine
, 79 , stdin
);
176 if( strlen( pcLine
) ) pcLine
[strlen(pcLine
)-1] =0;
177 String
sLine( pcLine
);
179 if( ! strcmp( pcLine
, "g" ) ) {
181 m_aDebugCondition
.reset();
182 (*m_pDebuggingRef
)->doContinue();
184 else fprintf( stderr
,"no script running !\n" );
186 else if( ! strcmp( pcLine
, "s" ) ) {
188 m_aDebugCondition
.reset();
189 (*m_pDebuggingRef
)->stepOver();
191 else fprintf(stderr
, "no script running !\n" );
193 else if( ! strcmp( pcLine
, "so" ) ) {
195 m_aDebugCondition
.reset();
196 (*m_pDebuggingRef
)->stepOut();
198 else fprintf(stderr
, "no script running !\n" );
200 else if( ! strcmp( pcLine
, "si" ) ) {
202 m_aDebugCondition
.reset();
203 (*m_pDebuggingRef
)->stepIn();
205 else fprintf(stderr
, "no script running !\n" );
207 else if( ! strncmp( pcLine
, "sbp" , 3 ) ){
209 (*m_pDebuggingRef
)->setBreakPoint( UString( L
"<string>" ),
210 atoi(&pcLine
[3]) , TRUE
);
213 else if( ! strncmp( pcLine
, "rbp" , 3 ) ){
215 (*m_pDebuggingRef
)->setBreakPoint( UString( L
"<string>" ),
216 atoi(&pcLine
[3]) , FALSE
);
219 else if( ! strncmp( pcLine
, "dv " , 3 ) ) {
222 if( sLine
.GetQuotedTokenCount( String("''"),' ' ) == 3 ) {
223 nCallstack
= atoi( sLine
.GetQuotedToken( 3 , String("''"), ' ' ).GetCharStr() );
226 UString str
= (*m_pDebuggingRef
)->dumpVariable(
227 PCHAR_TO_USTRING( &pcLine
[3]),nCallstack
);
228 fprintf( stderr
, "%s\n" , USTRING_TO_PCHAR( str
) );
231 else if( ! strncmp( pcLine
, "sv " , 3 ) ) {
233 if( sLine
.GetQuotedTokenCount( String("''"),' ' ) == 3 ) {
234 nCallstack
= atoi( sLine
.GetQuotedToken( 3 , String("''"), ' ' ).GetCharStr() );
236 (*m_pDebuggingRef
)->setVariable(
237 StringToOUString( sLine
.GetQuotedToken( 1 , String("''"), ' ' ), CHARSET_SYSTEM
),
238 StringToOUString( sLine
.GetQuotedToken( 2 , String("''"), ' ' ), CHARSET_SYSTEM
),
242 else if( ! strncmp( pcLine
, "ci" ,2 ) ) {
245 ContextInformation ci
= (*m_pDebuggingRef
)->getContextInformation(atoi(&pcLine
[2]));
248 fprintf( stderr
, "File %s (%d)\n", USTRING_TO_PCHAR(ci
.Name
),
250 fprintf( stderr
, "Available variables : \n" );
251 aUString
= ci
.LocalVariableNames
.getArray();
252 iMax
= ci
.LocalVariableNames
.getLen();
254 for( i
= 0 ; i
< iMax
; i
++ ) {
255 fprintf( stderr
, " %s\n" , USTRING_TO_PCHAR( aUString
[i
]) );
259 else if ( !strcmp( pcLine
, "d" ) ) {
262 Sequence
<UString
> seq
= (*m_pDebuggingRef
)->getStackTrace();
264 aUString
= seq
.getArray();
265 int iMax
= seq
.getLen();
266 for( int i
= 0; i
< iMax
; i
++ ) {
267 fprintf( stderr
, "%s\n" , USTRING_TO_PCHAR( aUString
[i
] ) );
271 else if( !strcmp( pcLine
, "c" ) ) {
273 (*m_pEngineRef
)->cancel();
274 m_aDebugCondition
.reset();
276 else fprintf( stderr
,"no script running !\n" );
278 else if( !strcmp( pcLine
, "q" ) ) {
280 m_aDebugCondition
.reset();
281 (*m_pEngineRef
)->cancel();
284 m_bIsTerminating
= TRUE
;
285 fprintf(stderr
, "Debugger terminates\n" );
289 else if( ! strcmp( pcLine
, "id" ) ) {
291 XIntrospectionAccessRef ref
= (*m_pInvokationRef
)->getIntrospection();
293 dumpIntrospectionToStream( ref
, stderr
);
297 else if( ! strncmp( pcLine
, "idv" , 3) ) {
299 UsrAny any
= (*m_pInvokationRef
)->getValue( PCHAR_TO_USTRING( &(pcLine
[4]) ) );
300 dumpVarToStream( &(pcLine
[4]) , any
, stderr
);
302 catch(UnknownPropertyException
& e
) {
303 fprintf( stderr
, "UnknownPropertyException\n" );
305 catch(IllegalArgumentException
& e
) {
306 fprintf( stderr
, "IllegalArgumentException\n" );
309 else if( !strcmp( pcLine
, "t" ) ) {
311 else if( !strcmp( pcLine
, "h" ) ) {
312 fprintf( stderr
, "\nvalid commands :\n"
317 "Set BreakPoint : sbp Line [ModuleName]\n"
318 "Remove BreakPoint : rbp [Line] [ModuleName]\n"
319 "via XDebugging Interface :\n"
320 " dump Variable : dv varname [CallStack]\n"
321 " set Variable : sv varname value [CallStack]\n"
322 "globals via XInvokation Interface :\n"
323 " dump Global vars : id\n"
324 " dump Variable : idv varname\n"
325 " set Variable : isv varname value\n"
326 "ContextInformation : ci\n"
327 "Dump callstack : d\n"
328 "Cancel : c (stops actual script)\n"
329 "Quit : q (exits debugger)\n"
332 else if( ! strlen( pcLine
) ) {
335 fprintf( stderr
, "unknown command %s\n" , pcLine
);
340 void CmdDebugger::dumpIntrospectionToStream( const XIntrospectionAccessRef
&ref
, FILE *f
)
343 fprintf( stderr
, "Callable Attributes (Methods) :\n" );
344 Sequence
<XIdlMethodRef
> seq
= ref
->getMethods( 0 );
346 XIdlMethodRef
*aRef
= seq
.getArray();
347 for( i
= 0; i
< iMax
; i
++ ) {
348 fprintf( f
, " %s\n" , USTRING_TO_PCHAR( aRef
[i
]->getName( ) ) );
351 fprintf( stderr
, "Other attributes\n" );
352 Sequence
<Property
> seqProp
= ref
->getProperties( 0 );
353 iMax
= seqProp
.getLen();
354 Property
*aProp
= seqProp
.getArray();
355 for( i
= 0; i
< iMax
; i
++ ) {
356 fprintf( f
, " %s %s\n" , USTRING_TO_PCHAR( aProp
[i
].Type
->getName() ),
357 USTRING_TO_PCHAR( aProp
[i
].Name
) );
362 void CmdDebugger::dumpVarToStream( const char *pc
, const UsrAny
&aValue
, FILE *f
)
364 TypeClass type
= aValue
.getReflection()->getTypeClass();
366 if( TypeClass_INT
== type
) {
367 fprintf( f
, "INT32 %s : %d\n" , pc
, aValue
.getINT32() );
369 else if( TypeClass_ENUM
== type
) {
370 fprintf( f
, "ENUM %s : %d\n", pc
, aValue
.getEnumAsINT32() );
372 else if( TypeClass_STRING
== type
) {
373 fprintf( f
, "STRING %s : %s\n" , pc
, USTRING_TO_PCHAR( aValue
.getString()) );
375 else if( TypeClass_BOOLEAN
== type
) {
376 fprintf( f
, "BOOL %s : %d\n", pc
, aValue
.getBOOL() );
378 else if( TypeClass_CHAR
== type
) {
379 fprintf( f
, "char %s : %d\n", pc
, ( INT32
) aValue
.getChar() );
381 else if( TypeClass_SHORT
== type
) {
382 fprintf( f
, "INT16 %s : %d\n", pc
, (INT32
) aValue
.getINT16());
384 else if( TypeClass_LONG
== type
) {
385 fprintf( f
, "LONG %s : %d\n", pc
, (INT32
) aValue
.getINT32());
387 else if( TypeClass_UNSIGNED_SHORT
== type
) {
388 fprintf( f
, "UINT16 %s : %d\n", pc
, (INT32
) aValue
.getUINT16() );
390 else if( TypeClass_UNSIGNED_BYTE
== type
) {
391 fprintf( f
, "Byte %s : %d\n", pc
, (INT32
) aValue
.getBYTE() );
393 else if( TypeClass_UNSIGNED_INT
== type
) {
394 fprintf( f
, "UINT32 %s : %d\n", pc
, aValue
.getUINT32() );
396 else if( TypeClass_FLOAT
== type
) {
397 fprintf( f
, "float %s : %f\n" , pc
, aValue
.getFloat() );
399 else if( TypeClass_DOUBLE
== type
) {
400 fprintf( f
, "double %s : %f\n" , pc
, aValue
.getDouble() );
402 else if( TypeClass_VOID
== type
) {
403 fprintf( f
, "void %s :\n" , pc
);
405 else if( TypeClass_INTERFACE
== type
) {
406 // Check, what has been put in
407 if( aValue
.getReflection() == XPropertySet_getReflection() ) {
409 XPropertySetRef
*pRef
= ( XPropertySetRef
* ) aValue
.get();
410 XPropertySetInfoRef refInfo
= (*pRef
)->getPropertySetInfo();
411 Sequence
< Property
> seq
= refInfo
->getProperties();
412 int i
,iMax
= seq
.getLen();
415 pArray
= seq
.getArray();
416 fprintf( stderr
, "Property List :\n" );
417 for( i
= 0; i
< iMax
; i
++ ) {
418 fprintf( f
, "%s\t %s\n" , USTRING_TO_PCHAR(pArray
[i
].Type
->getName()),
419 USTRING_TO_PCHAR( pArray
[i
].Name
) );
422 else if( aValue
.getReflection() == XInvokation_getReflection() ) {
423 XInvokationRef
*pRef
= ( XInvokationRef
* ) aValue
.get();
424 XIntrospectionAccessRef refIntro
= (*pRef
)->getIntrospection();
426 dumpIntrospectionToStream( refIntro
, stderr
);
429 else if( TypeClass_SEQUENCE
== type
) {
430 fprintf( f
, "%s Sequence \n" , pc
);
433 SequenceReflection
*pSeqRefl
= ( SequenceReflection
* ) aValue
.getReflection();
435 int i
,iMax
= pSeqRefl
->getLen( aValue
);
437 for( i
= 0 ; i
< iMax
; i
++ ) {
438 dumpVarToStream( s
.GetCharStr() , pSeqRefl
->get( aValue
, i
) , stderr
);
442 fprintf( f
, "%s : unknown %d\n" , pc
, type
);
447 void CmdDebugger::detach()
449 OSL_ASSERT( m_pDebuggingRef
);
451 m_bIsRunning
= FALSE
;
454 m_pInvokationRef
= 0;
457 // Methoden von XInterface
458 BOOL
CmdDebugger::queryInterface( Uik aUik
, XInterfaceRef
& rOut
)
460 if( aUik
== XEngineListener::getSmartUik() )
461 rOut
= (XEngineListener
*)this;
463 return OWeakObject::queryInterface( aUik
, rOut
);
475 int __LOADONCALLAPI
main (int argc
, char **argv
)
477 XMultiServiceFactoryRef xSMgr
= createRegistryServiceManager();
478 registerUsrServices( xSMgr
);
479 setProcessServiceManager( xSMgr
);
481 XInterfaceRef x
= xSMgr
->createInstance( L
"stardiv.uno.repos.ImplementationRegistration" );
482 XImplementationRegistrationRef
xReg( x
, USR_QUERY
);
483 sal_Char szBuf
[1024];
485 ORealDynamicLoader::computeModuleName( "pythonengine", szBuf
, 1024 );
486 UString
aDllName( StringToOUString( szBuf
, CHARSET_SYSTEM
) );
487 xReg
->registerImplementation( L
"stardiv.loader.SharedLibrary", aDllName
, XSimpleRegistryRef() );
489 ORealDynamicLoader::computeModuleName( "aps", szBuf
, 1024 );
490 aDllName
= UString( StringToOUString( szBuf
, CHARSET_SYSTEM
) );
491 xReg
->registerImplementation( L
"stardiv.loader.SharedLibrary", aDllName
, XSimpleRegistryRef() );
493 XInterfaceRef y
= xSMgr
->createInstance( L
"stardiv.script.Python" );
494 XEngineRef
yEngine( y
, USR_QUERY
);
496 x
= xSMgr
->createInstance( L
"stardiv.script.Python" );
497 XEngineRef
xEngine( x
, USR_QUERY
);
502 Sequence
<UsrAny
> args(3);
503 UsrAny
*pArray
= args
.getArray();
504 pArray
[0].setString( L
"Arg_0" );
505 pArray
[1].setString( L
"Arg_1" );
506 pArray
[2].setString( L
"Arg_2" );
509 Script
= StringToOUString( String( argv
[2] ) , CHARSET_DONTKNOW
);
512 XInvokationRef
xInvokation( x
, USR_QUERY
);
513 XDebuggingRef
xDebug( x
, USR_QUERY
);
515 CmdDebugger
*pDbg
= new CmdDebugger( &xDebug
, &xEngine
, &xInvokation
);
517 XEngineListenerRef
xDebugRef( (XEngineListener
*) pDbg
, USR_QUERY
);
518 xEngine
->addEngineListener( xDebugRef
);
521 if( argc
>1 && ! strcmp( argv
[1] , "1" ) ) {
522 fprintf( stderr
, "one thread only\n" );
523 Script
= UString( L
"print 'Hello World'\n" );
524 xEngine
->runAsync( Script
, XInterfaceRef(), args
, XEngineListenerRef() );
526 else if( argc
>1 && ! strcmp( argv
[1] , "2" ) ) {
528 xEngine
->runAsync( UString( L
"x=1\nprint 1\n") , XInterfaceRef(), args
, XEngineListenerRef() );
529 xEngine
->runAsync( UString( L
"x=x+1\nprint 2\n") , XInterfaceRef(), args
, XEngineListenerRef() );
530 xEngine
->runAsync( UString( L
"x=x+1\nprint 3\n") , XInterfaceRef(), args
, XEngineListenerRef());
531 xEngine
->runAsync( UString( L
"x=x+1\nprint 4\n") , XInterfaceRef(), args
, XEngineListenerRef() );
536 else if( argc
>1 && ! strcmp( argv
[1] , "3" ) ) {
538 fprintf( stderr
, "1st thread in engine y, next 5 threads in engine x\n" );
539 yEngine
->runAsync( UString( L
"print 1\n") , XInterfaceRef(), args
, XEngineListenerRef() );
540 xEngine
->runAsync( UString( L
"print 2\n") , XInterfaceRef(), args
, XEngineListenerRef() );
541 xEngine
->runAsync( UString( L
"print 3\n") , XInterfaceRef(), args
, XEngineListenerRef() );
542 xEngine
->runAsync( UString( L
"print 4\n") , XInterfaceRef(), args
, XEngineListenerRef());
543 xEngine
->runAsync( UString( L
"print 5\n") , XInterfaceRef(), args
, XEngineListenerRef());
544 xEngine
->runAsync( UString( L
"print 6\n") , XInterfaceRef(), args
, XEngineListenerRef());
550 xEngine
->removeEngineListener( xDebugRef
);
552 xReg
->revokeImplementation( aDllName
, XSimpleRegistryRef() );
554 fprintf( stderr
, "main terminates\n" );