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? 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 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 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 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 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 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 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 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 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 498 void SbiDisas::ImmOp( String& rText ) 499 { 500 rText += String::CreateFromInt32(nOp1); 501 } 502 503 // OnGoto Operand 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 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 520 void SbiDisas::ReturnOp( String& rText ) 521 { 522 if( nOp1 ) 523 LblOp( rText ); 524 } 525 526 // 0, 1 or Label 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 538 void SbiDisas::PromptOp( String& rText ) 539 { 540 if( nOp1 ) 541 rText.AppendAscii( "\"? \"" ); 542 } 543 544 // 0 or 1 545 void SbiDisas::CloseOp( String& rText ) 546 { 547 rText.AppendAscii( nOp1 ? "Channel" : "All" ); 548 } 549 550 // Print character 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 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 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 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 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 645 void SbiDisas::CaseOp( String& rText ) 646 { 647 LblOp( rText ); 648 rText += ','; 649 rText.AppendAscii( pOp1[ nOp2 - SbxEQ + _EQ ] ); 650 } 651 652 // Row, column 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 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