xref: /trunk/main/extensions/workben/pythontest.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_extensions.hxx"
30 
31 #include <stdio.h>
32 #include <stardiv/uno/repos/implementationregistration.hxx>
33 #include <stardiv/uno/script/script.hxx>
34 #include <stardiv/uno/beans/exactname.hxx>
35 
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>
45 
46 using namespace rtl;
47 using namespace vos;
48 using namespace usr;
49 
50 #define PCHAR_TO_USTRING(x) StringToOUString(String(x),CHARSET_SYSTEM)
51 
52 
53 
54 class NullEngineListenerRef : public XEngineListenerRef
55 {
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) ) {}
59 };
60 
61 #define USTRING_TO_PCHAR(x) OUStringToString(x , CHARSET_DONTKNOW ).GetCharStr()
62 
63 class CmdDebugger :
64     public XEngineListener,
65     public OWeakObject
66 {
67 public:
68 
69     CmdDebugger()
70     {
71         m_pDebuggingRef = 0;
72         m_pEngineRef = 0;
73         m_bIsTerminating = FALSE;
74         m_bIsRunning = FALSE;
75     }
76 
77 
78     CmdDebugger( XDebuggingRef *p, XEngineRef *pEngine , XInvokationRef *pInvokation)
79     {
80         attach( p , pEngine , pInvokation );
81     }
82 
83     ~CmdDebugger()
84     {
85         if( m_pDebuggingRef ) {
86             detach();
87         }
88     }
89 
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); }
94 
95 
96     void attach( XDebuggingRef *p , XEngineRef *pEngine , XInvokationRef *pInvokation )
97     {
98         m_pDebuggingRef = p;
99         m_pEngineRef = pEngine;
100         m_pInvokationRef = pInvokation;
101         m_bIsRunning = FALSE;
102         m_bIsTerminating = FALSE;
103     }
104 
105     void detach( );
106 
107 
108     virtual void disposing( const EventObject &o )
109     {
110         if( m_pDebuggingRef ) {
111             detach();
112         }
113     }
114     virtual void interrupt(const InterruptEngineEvent& Evt) THROWS( (UsrSystemException) )
115     {
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 ),
121                                               Evt.StartLine );
122             m_aDebugCondition.set();
123             m_bIsRunning = TRUE;
124         }
125     }
126 
127     virtual void running(const EventObject& Evt) THROWS( (UsrSystemException) )
128     {
129         if( m_pDebuggingRef && ! m_bIsTerminating ) {
130             (*m_pDebuggingRef)->stop();
131 
132             m_aDebugCondition.set();
133             m_bIsRunning = TRUE;
134             fprintf( stderr, "%s\n" , "Script starts\n" );
135         }
136     }
137 
138     virtual void finished(const FinishEngineEvent& Evt) THROWS( (UsrSystemException) )
139     {
140         if( m_pDebuggingRef && ! m_bIsTerminating  ) {
141             m_aDebugCondition.set();
142             m_bIsRunning = FALSE;
143             fprintf( stderr , "%s\n", USTRING_TO_PCHAR( Evt.ErrorMessage ) );
144         }
145     }
146 
147     void dumpIntrospectionToStream( const XIntrospectionAccessRef &, FILE *f );
148     void dumpVarToStream( const char *pcName, const UsrAny &any, FILE *f );
149 
150 
151     void cmdLine();
152 protected:
153 
154     OCondition m_aDebugCondition;
155     XDebuggingRef *m_pDebuggingRef;
156     XEngineRef  *m_pEngineRef;
157     XInvokationRef *m_pInvokationRef;
158     int m_bIsRunning;
159     int m_bIsTerminating;       // The listeners ignore everything when set
160 };
161 
162 
163 
164 void CmdDebugger::cmdLine()
165 {
166         char pcLine[80];
167         fprintf( stderr, "entering debugger\n" );
168         while( TRUE ) {
169 
170             m_aDebugCondition.wait();
171 
172             fprintf( stderr , "(debug %d) : " , m_bIsRunning );
173             fflush( stderr);
174             fgets( pcLine ,  79 , stdin );
175 
176             if( strlen( pcLine) ) pcLine[strlen(pcLine)-1] =0;
177             String sLine( pcLine );
178 
179             if( ! strcmp( pcLine , "g" ) ) {
180                 if( m_bIsRunning ) {
181                     m_aDebugCondition.reset();
182                     (*m_pDebuggingRef)->doContinue();
183                 }
184                 else fprintf( stderr,"no script running !\n" );
185             }
186             else if( ! strcmp( pcLine , "s" ) ) {
187                 if( m_bIsRunning ) {
188                     m_aDebugCondition.reset();
189                     (*m_pDebuggingRef)->stepOver();
190                 }
191                 else fprintf(stderr, "no script running !\n" );
192             }
193             else if( ! strcmp( pcLine , "so" ) ) {
194                 if( m_bIsRunning ) {
195                     m_aDebugCondition.reset();
196                     (*m_pDebuggingRef)->stepOut();
197                 }
198                 else fprintf(stderr, "no script running !\n" );
199             }
200             else if( ! strcmp( pcLine , "si" ) ) {
201                 if( m_bIsRunning ) {
202                     m_aDebugCondition.reset();
203                     (*m_pDebuggingRef)->stepIn();
204                 }
205                 else fprintf(stderr, "no script running !\n" );
206             }
207             else if( ! strncmp( pcLine , "sbp" , 3 ) ){
208                 if( m_bIsRunning ) {
209                     (*m_pDebuggingRef)->setBreakPoint(  UString( L"<string>" ),
210                                                         atoi(&pcLine[3]) , TRUE );
211                 }
212             }
213             else if( ! strncmp( pcLine , "rbp" , 3 ) ){
214                 if( m_bIsRunning ) {
215                     (*m_pDebuggingRef)->setBreakPoint(  UString( L"<string>" ),
216                                                         atoi(&pcLine[3]) , FALSE );
217                 }
218             }
219             else if( ! strncmp( pcLine , "dv " , 3 ) ) {
220                 if( m_bIsRunning ) {
221                     int nCallstack = 0;
222                     if( sLine.GetQuotedTokenCount( String("''"),' ' ) == 3 ) {
223                         nCallstack = atoi( sLine.GetQuotedToken( 3 , String("''"), ' ' ).GetCharStr() );
224                     }
225 
226                     UString str = (*m_pDebuggingRef)->dumpVariable(
227                                                     PCHAR_TO_USTRING( &pcLine[3]),nCallstack);
228                     fprintf( stderr, "%s\n" , USTRING_TO_PCHAR( str ) );
229                 }
230             }
231             else if( ! strncmp( pcLine , "sv " , 3 ) ) {
232                 int nCallstack = 0;
233                 if( sLine.GetQuotedTokenCount( String("''"),' ' ) == 3 ) {
234                     nCallstack = atoi( sLine.GetQuotedToken( 3 , String("''"), ' ' ).GetCharStr() );
235                 }
236                 (*m_pDebuggingRef)->setVariable(
237                         StringToOUString( sLine.GetQuotedToken( 1 , String("''"), ' ' ), CHARSET_SYSTEM ),
238                         StringToOUString( sLine.GetQuotedToken( 2 , String("''"), ' ' ), CHARSET_SYSTEM ),
239                         nCallstack );
240 
241             }
242             else if( ! strncmp( pcLine , "ci" ,2 ) ) {
243                 if( m_bIsRunning ) {
244                     UString *aUString ;
245                     ContextInformation ci = (*m_pDebuggingRef)->getContextInformation(atoi(&pcLine[2]));
246                     int i,iMax;
247 
248                     fprintf( stderr, "File %s (%d)\n", USTRING_TO_PCHAR(ci.Name),
249                                                        ci.StartLine );
250                     fprintf( stderr, "Available variables : \n" );
251                     aUString = ci.LocalVariableNames.getArray();
252                     iMax = ci.LocalVariableNames.getLen();
253 
254                     for( i = 0 ; i < iMax ; i++ ) {
255                         fprintf( stderr, "      %s\n" , USTRING_TO_PCHAR( aUString[i]) );
256                     }
257                 }
258             }
259             else if ( !strcmp( pcLine , "d" ) ) {
260                 if( m_bIsRunning ) {
261                     UString * aUString ;
262                     Sequence<UString> seq =  (*m_pDebuggingRef)->getStackTrace();
263 
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] ) );
268                     }
269                 }
270             }
271             else if( !strcmp( pcLine , "c" ) ) {
272                 if( m_bIsRunning ) {
273                     (*m_pEngineRef)->cancel();
274                     m_aDebugCondition.reset();
275                 }
276                 else fprintf( stderr,"no script running !\n" );
277             }
278             else if( !strcmp( pcLine , "q" ) ) {
279                 if( m_bIsRunning ) {
280                     m_aDebugCondition.reset();
281                     (*m_pEngineRef)->cancel();
282                 }
283                 else {
284                     m_bIsTerminating = TRUE;
285                     fprintf(stderr,  "Debugger terminates\n" );
286                     break;
287                 }
288             }
289             else if( ! strcmp( pcLine , "id" ) ) {
290 
291                 XIntrospectionAccessRef ref = (*m_pInvokationRef)->getIntrospection();
292 
293                 dumpIntrospectionToStream( ref , stderr );
294 
295 
296             }
297             else if( ! strncmp( pcLine , "idv" , 3) ) {
298                 try {
299                     UsrAny any = (*m_pInvokationRef)->getValue( PCHAR_TO_USTRING( &(pcLine[4]) ) );
300                     dumpVarToStream( &(pcLine[4]) , any , stderr );
301                 }
302                 catch(UnknownPropertyException& e ) {
303                     fprintf( stderr, "UnknownPropertyException\n" );
304                 }
305                 catch(IllegalArgumentException& e ) {
306                     fprintf( stderr, "IllegalArgumentException\n" );
307                 }
308             }
309             else if( !strcmp( pcLine , "t" ) ) {
310             }
311             else if( !strcmp( pcLine , "h" ) ) {
312                 fprintf( stderr ,  "\nvalid commands :\n"
313                                    "Go                 : g\n"
314                                    "StepOver           : s\n"
315                                    "StepIn             : si\n"
316                                    "StepOut            : so\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"
330                                    );
331             }
332             else if( ! strlen( pcLine ) ) {
333             }
334             else {
335                 fprintf( stderr , "unknown command %s\n" , pcLine );
336             }
337         }
338 }
339 
340 void CmdDebugger::dumpIntrospectionToStream( const XIntrospectionAccessRef &ref, FILE *f )
341 {
342     int i,iMax;
343     fprintf( stderr, "Callable Attributes (Methods) :\n" );
344     Sequence<XIdlMethodRef> seq = ref->getMethods( 0 );
345     iMax = seq.getLen();
346     XIdlMethodRef *aRef = seq.getArray();
347     for( i = 0; i < iMax ; i++ ) {
348         fprintf( f, "  %s\n" , USTRING_TO_PCHAR( aRef[i]->getName( ) ) );
349     }
350 
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 ) );
358     }
359 
360 }
361 
362 void CmdDebugger::dumpVarToStream( const char *pc , const UsrAny &aValue, FILE *f )
363 {
364     TypeClass type = aValue.getReflection()->getTypeClass();
365 
366     if( TypeClass_INT == type ) {
367         fprintf( f, "INT32 %s : %d\n" , pc , aValue.getINT32() );
368     }
369     else if( TypeClass_ENUM == type ) {
370         fprintf( f, "ENUM %s : %d\n", pc ,  aValue.getEnumAsINT32() );
371     }
372     else if( TypeClass_STRING == type ) {
373         fprintf( f, "STRING %s : %s\n" , pc ,  USTRING_TO_PCHAR( aValue.getString())     );
374     }
375     else if( TypeClass_BOOLEAN == type ) {
376         fprintf( f, "BOOL %s : %d\n", pc , aValue.getBOOL() );
377     }
378     else if( TypeClass_CHAR == type  ) {
379         fprintf( f, "char %s : %d\n", pc , ( INT32) aValue.getChar() );
380     }
381     else if( TypeClass_SHORT == type ) {
382         fprintf( f, "INT16 %s : %d\n", pc , (INT32) aValue.getINT16());
383     }
384     else if( TypeClass_LONG == type ) {
385         fprintf( f, "LONG %s : %d\n", pc , (INT32) aValue.getINT32());
386     }
387     else if( TypeClass_UNSIGNED_SHORT == type ) {
388         fprintf( f, "UINT16 %s : %d\n", pc , (INT32) aValue.getUINT16() );
389     }
390     else if( TypeClass_UNSIGNED_BYTE == type ) {
391         fprintf( f, "Byte %s : %d\n", pc ,  (INT32) aValue.getBYTE() );
392     }
393     else if( TypeClass_UNSIGNED_INT == type ) {
394         fprintf( f, "UINT32 %s : %d\n", pc , aValue.getUINT32() );
395     }
396     else if( TypeClass_FLOAT == type ) {
397         fprintf( f, "float %s : %f\n" , pc , aValue.getFloat() );
398     }
399     else if( TypeClass_DOUBLE == type ) {
400         fprintf( f, "double %s : %f\n" , pc , aValue.getDouble() );
401     }
402     else if( TypeClass_VOID == type ) {
403         fprintf( f, "void %s :\n" , pc );
404     }
405     else if( TypeClass_INTERFACE == type ) {
406         // Check, what has been put in
407         if( aValue.getReflection() == XPropertySet_getReflection() ) {
408             // XPropertySet !
409             XPropertySetRef *pRef = ( XPropertySetRef * ) aValue.get();
410             XPropertySetInfoRef refInfo = (*pRef)->getPropertySetInfo();
411             Sequence< Property > seq = refInfo->getProperties();
412             int i,iMax = seq.getLen();
413 
414             Property *pArray;
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 ) );
420             }
421         }
422         else if( aValue.getReflection() == XInvokation_getReflection() ) {
423             XInvokationRef *pRef = ( XInvokationRef * ) aValue.get();
424             XIntrospectionAccessRef refIntro = (*pRef)->getIntrospection();
425 
426             dumpIntrospectionToStream( refIntro, stderr );
427         }
428     }
429     else if( TypeClass_SEQUENCE == type ) {
430         fprintf( f , "%s Sequence \n" , pc  );
431         String s( "   " );
432         s += pc;
433         SequenceReflection *pSeqRefl = ( SequenceReflection * ) aValue.getReflection();
434 
435         int i,iMax = pSeqRefl->getLen( aValue );
436 
437         for( i = 0 ; i < iMax ; i ++ ) {
438             dumpVarToStream( s.GetCharStr() , pSeqRefl->get( aValue , i ) , stderr );
439         }
440     }
441     else {
442         fprintf( f, "%s : unknown %d\n" , pc , type  );
443     }
444 
445 }
446 
447 void CmdDebugger::detach()
448 {
449     OSL_ASSERT( m_pDebuggingRef );
450 
451     m_bIsRunning = FALSE;
452     m_pDebuggingRef = 0;
453     m_pEngineRef = 0;
454     m_pInvokationRef = 0;
455 }
456 
457 // Methoden von XInterface
458 BOOL CmdDebugger::queryInterface( Uik aUik, XInterfaceRef & rOut )
459 {
460     if( aUik == XEngineListener::getSmartUik() )
461         rOut = (XEngineListener*)this;
462     else
463         return OWeakObject::queryInterface( aUik, rOut );
464     return TRUE;
465 }
466 
467 
468 
469 
470 
471 
472 /*
473  * main.
474  */
475 int __LOADONCALLAPI main (int argc, char **argv)
476 {
477     XMultiServiceFactoryRef xSMgr = createRegistryServiceManager();
478     registerUsrServices( xSMgr );
479     setProcessServiceManager( xSMgr );
480 
481     XInterfaceRef x = xSMgr->createInstance( L"stardiv.uno.repos.ImplementationRegistration" );
482     XImplementationRegistrationRef xReg( x, USR_QUERY );
483     sal_Char szBuf[1024];
484 
485     ORealDynamicLoader::computeModuleName( "pythonengine", szBuf, 1024 );
486     UString aDllName( StringToOUString( szBuf, CHARSET_SYSTEM ) );
487     xReg->registerImplementation( L"stardiv.loader.SharedLibrary", aDllName, XSimpleRegistryRef() );
488 
489     ORealDynamicLoader::computeModuleName( "aps", szBuf, 1024 );
490     aDllName = UString( StringToOUString( szBuf, CHARSET_SYSTEM ) );
491     xReg->registerImplementation( L"stardiv.loader.SharedLibrary", aDllName, XSimpleRegistryRef() );
492 
493     XInterfaceRef y = xSMgr->createInstance( L"stardiv.script.Python" );
494     XEngineRef yEngine( y, USR_QUERY );
495 
496     x = xSMgr->createInstance( L"stardiv.script.Python" );
497     XEngineRef xEngine( x, USR_QUERY );
498 
499 
500     UString Script;
501 
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" );
507 
508     if( argc > 2) {
509         Script = StringToOUString( String( argv[2] ) ,  CHARSET_DONTKNOW );
510     }
511 
512     XInvokationRef xInvokation( x , USR_QUERY );
513     XDebuggingRef xDebug( x , USR_QUERY );
514 
515     CmdDebugger *pDbg = new CmdDebugger( &xDebug , &xEngine , &xInvokation );
516 
517     XEngineListenerRef xDebugRef( (XEngineListener *) pDbg , USR_QUERY);
518     xEngine->addEngineListener( xDebugRef );
519 
520 
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() );
525     }
526     else if( argc >1 && ! strcmp( argv[1] , "2" ) )  {
527 
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() );
532 
533 
534 
535     }
536     else if( argc >1 && ! strcmp( argv[1] , "3" ) ) {
537 
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());
545 
546 
547     }
548     pDbg->cmdLine();
549 
550     xEngine->removeEngineListener( xDebugRef );
551 
552     xReg->revokeImplementation( aDllName, XSimpleRegistryRef() );
553 
554     fprintf( stderr, "main terminates\n" );
555     return 0;
556 }
557 
558