xref: /AOO41X/main/basic/source/classes/disas.cxx (revision e1f63238eb022c8a12b30d46a012444ff20e0951)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_basic.hxx"
26 
27 #include <stdio.h>
28 #include <string.h>
29 #include <tools/stream.hxx>
30 #include <basic/sbx.hxx>
31 #include "sb.hxx"
32 #include "iosys.hxx"
33 #include "disas.hxx"
34 #include "sbtrace.hxx"
35 
36 
37 static const char* pOp1[] = {
38     "NOP",
39 
40     // Operators
41     // the following operators have the same order as in
42     // enum SbxVarOp
43     "EXP", "MUL", "DIV", "MOD", "PLUS", "MINUS", "NEG",
44     "EQ", "NE", "LT", "GT", "LE", "GE",
45     "IDIV", "AND", "OR", "XOR", "EQV", "IMP", "NOT",
46     "CAT",
47     // End enum SbxVarOp
48     "LIKE", "IS",
49     // Load/Store
50     "ARGC",             // Create new Argv
51     "ARGV",             // TOS ==> current Argv
52     "INPUT",            // Input ==> TOS
53     "LINPUT",           // Line Input ==> TOS
54     "GET",              // get TOS
55     "SET",              // Save Object TOS ==> TOS-1
56     "PUT",              // TOS ==> TOS-1
57     "CONST",            // TOS ==> TOS-1, then ReadOnly
58     "DIM",              // DIM
59     "REDIM",            // REDIM
60     "REDIMP",           // REDIM PRESERVE
61     "ERASE",            // delete TOS
62     // Branch
63     "STOP",             // End of program
64     "INITFOR",          // FOR-Variable init
65     "NEXT",             // FOR-Variable increment
66     "CASE",             // Begin CASE
67     "ENDCASE",          // End CASE
68     "STDERR",           // Default error handling
69     "NOERROR",          // No error handling
70     "LEAVE",            // leave UP
71     // I/O
72     "CHANNEL",          // TOS = Channelnumber
73     "PRINT",            // print TOS
74     "PRINTF",           // print TOS in field
75     "WRITE",            // write TOS
76     "RENAME",           // Rename Tos+1 to Tos
77     "PROMPT",           // TOS = Prompt for Input
78     "RESTART",          // Define restart point
79     "STDIO",            // Switch to I/O channel 0
80     // Misc
81     "EMPTY",            // Empty statement to stack
82     "ERROR",            // TOS = error code
83     "LSET",             // Save object TOS ==> TOS-1
84     "RSET",             // Save object TOS ==> TOS-1 (TODO: Same as above?)
85     "REDIMP_ERASE",
86     "INITFOREACH",
87     "VBASET",
88     "ERASE_CLEAR",
89     "ARRAYACCESS",
90     "BYVAL"
91 };
92 
93 static const char* pOp2[] = {
94     "NUMBER",            // Load a numeric constant (+ID)
95     "STRING",            // Load a string constant (+ID)
96     "CONSTANT",          // Immediate Load (+value)
97     "ARGN",              // Save named args in argv (+StringID)
98     "PAD",               // Pad String to defined length (+length)
99     // Branches
100     "JUMP",              // Jump to target (+Target)
101     "JUMP.T",            // evaluate TOS, conditional jump (+Target)
102     "JUMP.F",            // evaluate TOS, conditional jump (+Target)
103     "ONJUMP",            // evaluate TOS, jump into JUMP-table (+MaxVal)
104     "GOSUB",             // UP-Call (+Target)
105     "RETURN",            // UP-Return (+0 or Target)
106     "TESTFOR",           // Test FOR-Variable, increment (+Endlabel)
107     "CASETO",            // Tos+1 <= Case <= Tos, 2xremove (+Target)
108     "ERRHDL",            // Error-Handler (+Offset)
109     "RESUME",            // Resume after errors (+0 or 1 or Label)
110     // I/O
111     "CLOSE",             // (+channel/0)
112     "PRCHAR",            // (+char)
113     // Objects
114     "SETCLASS",          // Test Set + Classname (+StringId)
115     "TESTCLASS",         // Check TOS class (+StringId)
116     "LIB",               // Set Libname for Declare-Procs (+StringId)
117     // New since Beta 3 (TODO: Which Beta3?)
118     "BASED",             // TOS is incremted about BASE, push BASE before
119     "ARGTYP",            // Convert last parameter in argv (+Type)
120     "VBASETCLASS",
121 };
122 
123 static const char* pOp3[] = {
124     // All opcodes with two operands
125     "RTL",              // Load from RTL (+StringID+Typ)
126     "FIND",             // Load (+StringID+Typ)
127     "ELEM",             // Load element (+StringID+Typ)
128     "PARAM",            // Parameter (+Offset+Typ)
129 
130     // Branching
131     "CALL",             // Call DECLARE method (+StringID+Typ)
132     "CALL.C",           // Call Cdecl-DECLARE method (+StringID+Typ)
133     "CASEIS",           // Case-Test (+Test-Opcode+False-Target)
134     "STMNT",            // Start of a statement (+Line+Col)
135 
136     // I/O
137     "OPEN",             // (+SvStreamFlags+Flags)
138 
139     // Objects and variables
140     "LOCAL",            // Local variables (+StringID+Typ)
141     "PUBLIC",           // Modul global var (+StringID+Typ)
142     "GLOBAL",           // Global var (+StringID+Typ)
143     "CREATE",           // Create object (+StringId+StringId)
144     "STATIC",           // Create static object (+StringId+StringId)
145     "TCREATE",          // Create User defined Object (+StringId+StringId)
146     "DCREATE",          // Create User defined Object-Array kreieren (+StringId+StringId)
147     "GLOBAL_P",         // Define persistent global var (existing after basic restart)
148                         // P=PERSIST (+StringID+Typ)
149     "FIND_G",           // Searches for global var with special handling due to _GLOBAL_P
150     "DCREATE_REDIMP",   // Change dimensions of a user defined Object-Array (+StringId+StringId)
151     "FIND_CM",          // Search inside a class module (CM) to enable global search in time
152     "PUBLIC_P",         // Module global Variable (persisted between calls)(+StringID+Typ)
153     "FIND_STATIC",      // local static var lookup (+StringID+Typ)
154 };
155 
156 static const char** pOps[3] = { pOp1, pOp2, pOp3 };
157 
158 typedef void( SbiDisas::*Func )( String& );  // Processing routines
159 
160 static const Func pOperand2[] = {
161     &SbiDisas::StrOp,   // Load a numeric constant (+ID)
162     &SbiDisas::StrOp,   // Load a string constant (+ID)
163     &SbiDisas::ImmOp,   // Immediate Load (+Wert)
164     &SbiDisas::StrOp,   // Save a named argument (+ID)
165     &SbiDisas::ImmOp,   // Strip String to fixed size (+length)
166 
167     // Branches
168     &SbiDisas::LblOp,   // Jump (+Target)
169     &SbiDisas::LblOp,   // eval TOS, conditional jump (+Target)
170     &SbiDisas::LblOp,   // eval TOS, conditional jump (+Target)
171     &SbiDisas::OnOp,    // eval TOS, jump in JUMP table (+MaxVal)
172     &SbiDisas::LblOp,   // UP call (+Target)
173     &SbiDisas::ReturnOp,    // UP Return (+0 or Target)
174     &SbiDisas::LblOp,   // test FOR-Variable, increment (+Endlabel)
175     &SbiDisas::LblOp,   // Tos+1 <= Case <= Tos), 2xremove (+Target)
176     &SbiDisas::LblOp,   // Error handler (+Offset)
177     &SbiDisas::ResumeOp,    // Resume after errors (+0 or 1 or Label)
178 
179     // I/O
180     &SbiDisas::CloseOp, // (+channel/0)
181     &SbiDisas::CharOp,  // (+char)
182 
183     // Objects
184     &SbiDisas::StrOp,   // Test classname (+StringId)
185     &SbiDisas::StrOp,   // TESTCLASS, Check TOS class (+StringId)
186     &SbiDisas::StrOp,   // Set libname for declare procs (+StringId)
187     &SbiDisas::ImmOp,   // TOS is incremented about BASE erhoeht, BASE pushed before
188     &SbiDisas::TypeOp,  // Convert last parameter to/in(?) argv (+Typ)
189     &SbiDisas::StrOp,   // VBASETCLASS (+StringId)
190 };
191 
192 static const Func pOperand3[] = {
193     // All opcodes with two operands
194     &SbiDisas::VarOp,   // Load from RTL (+StringID+Typ)
195     &SbiDisas::VarOp,   // Load (+StringID+Typ)
196     &SbiDisas::VarOp,   // Load Element (+StringID+Typ)
197     &SbiDisas::OffOp,   // Parameter (+Offset+Typ)
198 
199     // Branch
200     &SbiDisas::VarOp,   // Call DECLARE-Method (+StringID+Typ)
201     &SbiDisas::VarOp,   // Call CDecl-DECLARE-Methode (+StringID+Typ)
202     &SbiDisas::CaseOp,  // Case-Test (+Test-Opcode+False-Target)
203     &SbiDisas::StmntOp, // Statement (+Row+Column)
204 
205     // I/O
206     &SbiDisas::StrmOp,  // (+SvStreamFlags+Flags)
207 
208     // Objects
209     &SbiDisas::VarDefOp,   // Define local var (+StringID+Typ)
210     &SbiDisas::VarDefOp,   // Define Module global var (+StringID+Typ)
211     &SbiDisas::VarDefOp,   // Define global var (+StringID+Typ)
212     &SbiDisas::Str2Op,     // Create object (+StringId+StringId)
213     &SbiDisas::VarDefOp,   // Define static object (+StringID+Typ)
214     &SbiDisas::Str2Op,     // Create User defined Object (+StringId+StringId)
215     &SbiDisas::Str2Op,     // Create User defined Object-Array (+StringId+StringId)
216     &SbiDisas::VarDefOp,   // Define persistent global var P=PERSIST (+StringID+Typ)
217     &SbiDisas::VarOp,    // Searches for global var with special handling due to  _GLOBAL_P
218     &SbiDisas::Str2Op,     // Redimensionate User defined Object-Array (+StringId+StringId)
219     &SbiDisas::VarOp,    // FIND_CM
220     &SbiDisas::VarDefOp, // PUBLIC_P
221     &SbiDisas::VarOp,    // FIND_STATIC
222 };
223 
224 // TODO: Why as method? Isn't a simple define sufficient?
_crlf()225 static const char* _crlf()
226 {
227 #if defined (UNX) || defined( PM2 )
228     return "\n";
229 #else
230     return "\r\n";
231 #endif
232 }
233 
234 // This method exists because we want to load the file as own segment
Disassemble(String & rText)235 sal_Bool SbModule::Disassemble( String& rText )
236 {
237     rText.Erase();
238     if( pImage )
239     {
240         SbiDisas aDisas( this, pImage );
241         aDisas.Disas( rText );
242     }
243     return sal_Bool( rText.Len() != 0 );
244 }
245 
SbiDisas(SbModule * p,const SbiImage * q)246 SbiDisas::SbiDisas( SbModule* p, const SbiImage* q ) : rImg( *q ), pMod( p )
247 {
248     memset( cLabels, 0, 8192 );
249     nLine = 0;
250     nOff = 0;
251     nPC = 0;
252     nOp1 = nOp2 = nParts = 0;
253     eOp = _NOP;
254     // Set Label-Bits
255     nOff = 0;
256     while( Fetch() )
257     {
258         switch( eOp )
259         {
260             case _RESUME: if( nOp1 <= 1 ) break;
261             case _RETURN: if( !nOp1 ) break;
262             case _JUMP:
263             case _JUMPT:
264             case _JUMPF:
265             case _GOSUB:
266             case _TESTFOR:
267             case _CASEIS:
268             case _CASETO:
269             case _ERRHDL:
270                 cLabels[ (nOp1 & 0xffff) >> 3 ] |= ( 1 << ( nOp1 & 7 ) );
271                 break;
272             default: break;
273         }
274     }
275     nOff = 0;
276     // Add the publics
277     for( sal_uInt16 i = 0; i < pMod->GetMethods()->Count(); i++ )
278     {
279         SbMethod* pMeth = PTR_CAST(SbMethod,pMod->GetMethods()->Get( i ));
280         if( pMeth )
281         {
282             sal_uInt16 nPos = (sal_uInt16) (pMeth->GetId());
283             cLabels[ nPos >> 3 ] |= ( 1 << ( nPos & 7 ) );
284         }
285     }
286 }
287 
288 // Read current opcode
Fetch()289 sal_Bool SbiDisas::Fetch()
290 {
291     nPC = nOff;
292     if( nOff >= rImg.GetCodeSize() )
293         return sal_False;
294     const unsigned char* p = (const unsigned char*)( rImg.GetCode() + nOff );
295     eOp = (SbiOpcode) ( *p++ & 0xFF );
296     if( eOp <= SbOP0_END )
297     {
298         nOp1 = nOp2 = 0;
299         nParts = 1;
300         nOff++;
301         return sal_True;
302     }
303     else if( eOp <= SbOP1_END )
304     {
305         nOff += 5;
306         if( nOff > rImg.GetCodeSize() )
307             return sal_False;
308         nOp1 = *p++; nOp1 |= *p++ << 8; nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
309         nParts = 2;
310         return sal_True;
311     }
312     else if( eOp <= SbOP2_END )
313     {
314         nOff += 9;
315         if( nOff > rImg.GetCodeSize() )
316             return sal_False;
317         nOp1 = *p++; nOp1 |= *p++ << 8; nOp1 |= *p++ << 16; nOp1 |= *p++ << 24;
318         nOp2 = *p++; nOp2 |= *p++ << 8; nOp2 |= *p++ << 16; nOp2 |= *p++ << 24;
319         nParts = 3;
320         return sal_True;
321     }
322     else
323         return sal_False;
324 }
325 
Disas(SvStream & r)326 void SbiDisas::Disas( SvStream& r )
327 {
328     String aText;
329     nOff = 0;
330     while( DisasLine( aText ) )
331     {
332         ByteString aByteText( aText, gsl_getSystemTextEncoding() );
333         r.WriteLine( aByteText );
334     }
335 }
336 
Disas(String & r)337 void SbiDisas::Disas( String& r )
338 {
339     r.Erase();
340     String aText;
341     nOff = 0;
342     while( DisasLine( aText ) )
343     {
344         r += aText;
345         r.AppendAscii( _crlf() );
346     }
347     aText.ConvertLineEnd();
348 }
349 
DisasLine(String & rText)350 sal_Bool SbiDisas::DisasLine( String& rText )
351 {
352     char cBuf[ 100 ];
353     const char* pMask[] = {
354         "%08" SAL_PRIXUINT32 "                            ",
355         "%08" SAL_PRIXUINT32 " %02X                   ",
356         "%08" SAL_PRIXUINT32 " %02X %08X          ",
357         "%08" SAL_PRIXUINT32 " %02X %08X %08X " };
358     rText.Erase();
359     if( !Fetch() )
360         return sal_False;
361 
362 #ifdef DBG_TRACE_BASIC
363     String aTraceStr_STMNT;
364 #endif
365 
366     // New line?
367     if( eOp == _STMNT && nOp1 != nLine )
368     {
369         // Find line
370         String aSource = rImg.aOUSource;
371         nLine = nOp1;
372         sal_uInt16 n = 0;
373         sal_uInt16 l = (sal_uInt16)nLine;
374         while( --l ) {
375             n = aSource.SearchAscii( "\n", n );
376             if( n == STRING_NOTFOUND ) break;
377             else n++;
378         }
379         // Show position
380         if( n != STRING_NOTFOUND )
381         {
382             sal_uInt16 n2 = aSource.SearchAscii( "\n", n );
383             if( n2 == STRING_NOTFOUND ) n2 = aSource.Len() - n;
384             String s( aSource.Copy( n, n2 - n + 1 ) );
385             sal_Bool bDone;
386             do {
387                 bDone = sal_True;
388                 n = s.Search( '\r' );
389                 if( n != STRING_NOTFOUND ) bDone = sal_False, s.Erase( n, 1 );
390                 n = s.Search( '\n' );
391                 if( n != STRING_NOTFOUND ) bDone = sal_False, s.Erase( n, 1 );
392             } while( !bDone );
393 //          snprintf( cBuf, sizeof(cBuf), pMask[ 0 ], nPC );
394 //          rText += cBuf;
395             rText.AppendAscii( "; " );
396             rText += s;
397             rText.AppendAscii( _crlf() );
398 
399 #ifdef DBG_TRACE_BASIC
400             aTraceStr_STMNT = s;
401 #endif
402         }
403     }
404 
405     // Label?
406     const char* p = "";
407     if( cLabels[ nPC >> 3 ] & ( 1 << ( nPC & 7 ) ) )
408     {
409         // Public?
410         ByteString aByteMethName;
411         for( sal_uInt16 i = 0; i < pMod->GetMethods()->Count(); i++ )
412         {
413             SbMethod* pMeth = PTR_CAST(SbMethod,pMod->GetMethods()->Get( i ));
414             if( pMeth )
415             {
416                 aByteMethName = ByteString( pMeth->GetName(), gsl_getSystemTextEncoding() );
417                 if( pMeth->GetId() == nPC )
418                 {
419                     p = aByteMethName.GetBuffer();
420                     break;
421                 }
422                 if( pMeth->GetId() >= nPC )
423                     break;
424             }
425         }
426         snprintf( cBuf, sizeof(cBuf), pMask[ 0 ], nPC );
427         rText.AppendAscii( cBuf );
428         if( p && *p )
429         {
430             rText.AppendAscii( p );
431         }
432         else
433         {
434             // fix warning (now error) for "Lbl%04lX" format
435             snprintf( cBuf, sizeof(cBuf), "Lbl%08" SAL_PRIXUINT32, nPC );
436             rText.AppendAscii( cBuf );
437         }
438         rText += ':';
439         rText.AppendAscii( _crlf() );
440     }
441     snprintf( cBuf, sizeof(cBuf), pMask[ nParts ], nPC, (sal_uInt16) eOp, nOp1, nOp2 );
442 
443     String aPCodeStr;
444     aPCodeStr.AppendAscii( cBuf );
445     int n = eOp;
446     if( eOp >= SbOP2_START )
447         n -= SbOP2_START;
448     else if( eOp >= SbOP1_START )
449         n -= SbOP1_START;
450     aPCodeStr += '\t';
451     aPCodeStr.AppendAscii( pOps[ nParts-1 ][ n ] );
452     aPCodeStr += '\t';
453     switch( nParts )
454     {
455         case 2: (this->*( pOperand2[ n ] ) )( aPCodeStr ); break;
456         case 3: (this->*( pOperand3[ n ] ) )( aPCodeStr ); break;
457     }
458 
459     rText += aPCodeStr;
460 
461 #ifdef DBG_TRACE_BASIC
462     dbg_RegisterTraceTextForPC( pMod, nPC, aTraceStr_STMNT, aPCodeStr );
463 #endif
464 
465     return sal_True;
466 }
467 
468 // Read from StringPool
StrOp(String & rText)469 void SbiDisas::StrOp( String& rText )
470 {
471     String aStr = rImg.GetString( (sal_uInt16)nOp1 );
472     ByteString aByteString( aStr, RTL_TEXTENCODING_ASCII_US );
473     const char* p = aByteString.GetBuffer();
474     if( p )
475     {
476         rText += '"';
477         rText.AppendAscii( p );
478         rText += '"';
479     }
480     else
481     {
482         rText.AppendAscii( "?String? " );
483         rText += (sal_uInt16)nOp1;
484     }
485 }
486 
Str2Op(String & rText)487 void SbiDisas::Str2Op( String& rText )
488 {
489     StrOp( rText );
490     rText += ',';
491     String s;
492     nOp1 = nOp2;
493     StrOp( s );
494     rText += s;
495 }
496 
497 // Immediate Operand
ImmOp(String & rText)498 void SbiDisas::ImmOp( String& rText )
499 {
500     rText += String::CreateFromInt32(nOp1);
501 }
502 
503 // OnGoto Operand
OnOp(String & rText)504 void SbiDisas::OnOp( String& rText )
505 {
506     rText += String::CreateFromInt32(nOp1 & 0x7FFF);
507     if( nOp1 & 0x800 )
508         rText.AppendAscii( "\t; Gosub" );
509 }
510 
511 // Label
LblOp(String & rText)512 void SbiDisas::LblOp( String& rText )
513 {
514     char cBuf[ 10 ];
515     snprintf( cBuf, sizeof(cBuf), "Lbl%04" SAL_PRIXUINT32, nOp1 );
516     rText.AppendAscii( cBuf );
517 }
518 
519 // 0 or Label
ReturnOp(String & rText)520 void SbiDisas::ReturnOp( String& rText )
521 {
522     if( nOp1 )
523         LblOp( rText );
524 }
525 
526 // 0, 1 or Label
ResumeOp(String & rText)527 void SbiDisas::ResumeOp( String& rText )
528 {
529     switch( nOp1 )
530     {
531         case 1: rText.AppendAscii( "NEXT" ); break;
532         case 2: LblOp( rText );
533     }
534 }
535 
536 // print Prompt
537 // sal_False/TRUE
PromptOp(String & rText)538 void SbiDisas::PromptOp( String& rText )
539 {
540     if( nOp1 )
541         rText.AppendAscii( "\"? \"" );
542 }
543 
544 // 0 or 1
CloseOp(String & rText)545 void SbiDisas::CloseOp( String& rText )
546 {
547     rText.AppendAscii( nOp1 ? "Channel" : "All" );
548 }
549 
550 // Print character
CharOp(String & rText)551 void SbiDisas::CharOp( String& rText )
552 {
553     const char* p = NULL;
554     switch( nOp1 )
555     {
556         case  7: p = "'\\a'"; break;
557         case  9: p = "'\\t'"; break;
558         case 10: p = "'\\n'"; break;
559         case 12: p = "'\\f'"; break;
560         case 13: p = "'\\r'"; break;
561     }
562     if( p ) rText.AppendAscii( p );
563     else if( nOp1 >= ' ' )
564         rText += '\'',
565         rText += (char) nOp1,
566         rText += '\'';
567     else
568         rText.AppendAscii( "char " ),
569         rText += (sal_uInt16)nOp1;
570 }
571 
572 // Print var: String-ID and type
VarOp(String & rText)573 void SbiDisas::VarOp( String& rText )
574 {
575     rText += rImg.GetString( (sal_uInt16)(nOp1 & 0x7FFF) );
576     rText.AppendAscii( "\t; " );
577     // The type
578     sal_uInt32 n = nOp1;
579     nOp1 = nOp2;
580     TypeOp( rText );
581     if( n & 0x8000 )
582         rText.AppendAscii( ", Args" );
583 }
584 
585 // Define variable: String-ID and type
VarDefOp(String & rText)586 void SbiDisas::VarDefOp( String& rText )
587 {
588     rText += rImg.GetString( (sal_uInt16)(nOp1 & 0x7FFF) );
589     rText.AppendAscii( "\t; " );
590     // The Typ
591     nOp1 = nOp2;
592     TypeOp( rText );
593 }
594 
595 // Print variable: Offset and Typ
OffOp(String & rText)596 void SbiDisas::OffOp( String& rText )
597 {
598     rText += String::CreateFromInt32( nOp1 & 0x7FFF );
599     rText.AppendAscii( "\t; " );
600     // The type
601     sal_uInt32 n = nOp1;
602     nOp1 = nOp2;
603     TypeOp( rText );
604     if( n & 0x8000 )
605         rText.AppendAscii( ", Args" );
606 }
607 
608 // Data type
609 #ifdef HP9000 // TODO: remove this!
610 static char* SbiDisas_TypeOp_pTypes[13] = {
611     "Empty","Null","Integer","Long","Single","Double",
612     "Currency","Date","String","Object","Error","Boolean",
613     "Variant" };
614 #define pTypes SbiDisas_TypeOp_pTypes
615 #endif
TypeOp(String & rText)616 void SbiDisas::TypeOp( String& rText )
617 {
618     // AB 19.1.96: Typ kann Flag f�r BYVAL enthalten (StepARGTYP)
619     if( nOp1 & 0x8000 )
620     {
621         nOp1 &= 0x7FFF;     // Flag wegfiltern
622         rText.AppendAscii( "BYVAL " );
623     }
624     if( nOp1 < 13 )
625     {
626 #ifndef HP9000
627         static char pTypes[][13] = {
628             "Empty","Null","Integer","Long","Single","Double",
629             "Currency","Date","String","Object","Error","Boolean",
630             "Variant" };
631 #endif
632         rText.AppendAscii( pTypes[ nOp1 ] );
633     }
634     else
635     {
636         rText.AppendAscii( "type " );
637         rText += (sal_uInt16)nOp1;
638     }
639 }
640 #ifdef HP9000
641 #undef pTypes
642 #endif
643 
644 // sal_True-Label, condition Opcode
CaseOp(String & rText)645 void SbiDisas::CaseOp( String& rText )
646 {
647     LblOp( rText );
648     rText += ',';
649     rText.AppendAscii( pOp1[ nOp2 - SbxEQ + _EQ ] );
650 }
651 
652 // Row, column
StmntOp(String & rText)653 void SbiDisas::StmntOp( String& rText )
654 {
655     rText += String::CreateFromInt32( nOp1 );
656     rText += ',';
657     sal_uInt32 nCol = nOp2 & 0xFF;
658     sal_uInt32 nFor = nOp2 / 0x100;
659     rText += String::CreateFromInt32( nCol );
660     rText.AppendAscii( " (For-Level: " );
661     rText += String::CreateFromInt32( nFor );
662     rText += ')';
663 }
664 
665 // open mode, flags
StrmOp(String & rText)666 void SbiDisas::StrmOp( String& rText )
667 {
668     char cBuf[ 10 ];
669     snprintf( cBuf, sizeof(cBuf), "%04" SAL_PRIXUINT32, nOp1 );
670     rText.AppendAscii( cBuf );
671     if( nOp2 & SBSTRM_INPUT )
672         rText.AppendAscii( ", Input" );
673     if( nOp2 & SBSTRM_OUTPUT )
674         rText.AppendAscii( ", Output" );
675     if( nOp2 & SBSTRM_APPEND )
676         rText.AppendAscii( ", Append" );
677     if( nOp2 & SBSTRM_RANDOM )
678         rText.AppendAscii( ", Random" );
679     if( nOp2 & SBSTRM_BINARY )
680         rText.AppendAscii( ", Binary" );
681 }
682 
683 
684