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