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