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