xref: /aoo42x/main/basic/source/comp/io.cxx (revision cdf0e10c)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basic.hxx"
30 
31 
32 #include <tools/stream.hxx>
33 #include "sbcomp.hxx"
34 #include "iosys.hxx"
35 
36 // Test, ob ein I/O-Channel angegeben wurde
37 
38 sal_Bool SbiParser::Channel( sal_Bool bAlways )
39 {
40 	sal_Bool bRes = sal_False;
41 	Peek();
42 	if( IsHash() )
43 	{
44 		SbiExpression aExpr( this );
45 		while( Peek() == COMMA || Peek() == SEMICOLON )
46 			Next();
47 		aExpr.Gen();
48 		aGen.Gen( _CHANNEL );
49 		bRes = sal_True;
50 	}
51 	else if( bAlways )
52 		Error( SbERR_EXPECTED, "#" );
53 	return bRes;
54 }
55 
56 // Fuer PRINT und WRITE wird bei Objektvariablen versucht,
57 // die Default-Property anzusprechen.
58 
59 // PRINT
60 
61 void SbiParser::Print()
62 {
63 	sal_Bool bChan = Channel();
64 	// Die Ausdruecke zum Drucken:
65 	while( !bAbort )
66 	{
67 		if( !IsEoln( Peek() ) )
68 		{
69 			SbiExpression* pExpr = new SbiExpression( this );
70 			pExpr->Gen();
71 			delete pExpr;
72 			Peek();
73 			aGen.Gen( eCurTok == COMMA ? _PRINTF : _BPRINT );
74 		}
75 		if( eCurTok == COMMA || eCurTok == SEMICOLON )
76 		{
77 			Next();
78 			if( IsEoln( Peek() ) ) break;
79 		}
80 		else
81 		{
82 			aGen.Gen( _PRCHAR, '\n' );
83 			break;
84 		}
85 	}
86 	if( bChan )
87 		aGen.Gen( _CHAN0 );
88 }
89 
90 // WRITE #chan, expr, ...
91 
92 void SbiParser::Write()
93 {
94 	sal_Bool bChan = Channel();
95 	// Die Ausdruecke zum Drucken:
96 	while( !bAbort )
97 	{
98 		SbiExpression* pExpr = new SbiExpression( this );
99 		pExpr->Gen();
100 		delete pExpr;
101 		aGen.Gen( _BWRITE );
102 		if( Peek() == COMMA )
103 		{
104 			aGen.Gen( _PRCHAR, ',' );
105 			Next();
106 			if( IsEoln( Peek() ) ) break;
107 		}
108 		else
109 		{
110 			aGen.Gen( _PRCHAR, '\n' );
111 			break;
112 		}
113 	}
114 	if( bChan )
115 		aGen.Gen( _CHAN0 );
116 }
117 
118 
119 // #i92642 Handle LINE keyword outside ::Next()
120 void SbiParser::Line()
121 {
122 	// #i92642: Special handling to allow name as symbol
123 	if( Peek() == INPUT )
124 	{
125 		Next();
126 		LineInput();
127 	}
128 	else
129 	{
130 		aGen.Statement();
131 
132 		KeywordSymbolInfo aInfo;
133 		aInfo.m_aKeywordSymbol = String( RTL_CONSTASCII_USTRINGPARAM( "line" ) );
134 		aInfo.m_eSbxDataType = GetType();
135 		aInfo.m_eTok = SYMBOL;
136 
137 		Symbol( &aInfo );
138 	}
139 }
140 
141 
142 // LINE INPUT [prompt], var$
143 
144 void SbiParser::LineInput()
145 {
146 	Channel( sal_True );
147 	// sal_Bool bChan = Channel( sal_True );
148 	SbiExpression* pExpr = new SbiExpression( this, SbOPERAND );
149 	/* AB 15.1.96: Keinen allgemeinen Ausdruck mehr zulassen
150 	SbiExpression* pExpr = new SbiExpression( this );
151 	if( !pExpr->IsVariable() )
152 	{
153 		SbiToken eTok = Peek();
154 		if( eTok == COMMA || eTok == SEMICOLON ) Next();
155 		else Error( SbERR_EXPECTED, COMMA );
156 		// mit Prompt
157 		if( !bChan )
158 		{
159 			pExpr->Gen();
160 			aGen.Gen( _PROMPT );
161 		}
162 		else
163 			Error( SbERR_VAR_EXPECTED );
164 		delete pExpr;
165 		pExpr = new SbiExpression( this, SbOPERAND );
166 	}
167 	*/
168 	if( !pExpr->IsVariable() )
169 		Error( SbERR_VAR_EXPECTED );
170 	if( pExpr->GetType() != SbxVARIANT && pExpr->GetType() != SbxSTRING )
171 		Error( SbERR_CONVERSION );
172 	pExpr->Gen();
173 	aGen.Gen( _LINPUT );
174 	delete pExpr;
175 	aGen.Gen( _CHAN0 );		// ResetChannel() nicht mehr in StepLINPUT()
176 }
177 
178 // INPUT
179 
180 void SbiParser::Input()
181 {
182 	aGen.Gen( _RESTART );
183 	Channel( sal_True );
184 	// sal_Bool bChan = Channel( sal_True );
185 	SbiExpression* pExpr = new SbiExpression( this, SbOPERAND );
186 	/* ALT: Jetzt keinen allgemeinen Ausdruck mehr zulassen
187 	SbiExpression* pExpr = new SbiExpression( this );
188 	...
189 	siehe LineInput
190 	*/
191 	while( !bAbort )
192 	{
193 		if( !pExpr->IsVariable() )
194 			Error( SbERR_VAR_EXPECTED );
195 		pExpr->Gen();
196 		aGen.Gen( _INPUT );
197 		if( Peek() == COMMA )
198 		{
199 			Next();
200 			delete pExpr;
201 			pExpr = new SbiExpression( this, SbOPERAND );
202 		}
203 		else break;
204 	}
205 	delete pExpr;
206 	aGen.Gen( _CHAN0 );		// ResetChannel() nicht mehr in StepINPUT()
207 }
208 
209 // OPEN stringexpr FOR mode ACCCESS access mode AS Channel [Len=n]
210 
211 void SbiParser::Open()
212 {
213 	SbiExpression aFileName( this );
214 	SbiToken eTok;
215 	TestToken( FOR );
216 	short nMode = 0;
217 	short nFlags = 0;
218 	switch( Next() )
219 	{
220 		case INPUT:
221 			nMode = STREAM_READ;  nFlags |= SBSTRM_INPUT; break;
222 		case OUTPUT:
223 			nMode = STREAM_WRITE | STREAM_TRUNC; nFlags |= SBSTRM_OUTPUT; break;
224 		case APPEND:
225 			nMode = STREAM_WRITE; nFlags |= SBSTRM_APPEND; break;
226 		case RANDOM:
227 			nMode = STREAM_READ | STREAM_WRITE; nFlags |= SBSTRM_RANDOM; break;
228 		case BINARY:
229 			nMode = STREAM_READ | STREAM_WRITE; nFlags |= SBSTRM_BINARY; break;
230 		default:
231 			Error( SbERR_SYNTAX );
232 	}
233 	if( Peek() == ACCESS )
234 	{
235 		Next();
236 		eTok = Next();
237 		// #27964# Nur STREAM_READ,STREAM_WRITE-Flags in nMode beeinflussen
238 		nMode &= ~(STREAM_READ | STREAM_WRITE);		// loeschen
239 		if( eTok == READ )
240 		{
241 			if( Peek() == WRITE )
242 			{
243 				Next();
244 				nMode |= (STREAM_READ | STREAM_WRITE);
245 			}
246 			else
247 				nMode |= STREAM_READ;
248 		}
249 		else if( eTok == WRITE )
250 			nMode |= STREAM_WRITE;
251 		else
252 			Error( SbERR_SYNTAX );
253 	}
254 	switch( Peek() )
255 	{
256 #ifdef SHARED
257 #undef SHARED
258 #define tmpSHARED
259 #endif
260 		case SHARED:
261 			Next(); nMode |= STREAM_SHARE_DENYNONE; break;
262 #ifdef tmpSHARED
263 #define SHARED
264 #undef tmpSHARED
265 #endif
266 		case LOCK:
267 			Next();
268 			eTok = Next();
269 			if( eTok == READ )
270 			{
271 				if( Peek() == WRITE ) Next(), nMode |= STREAM_SHARE_DENYALL;
272 				else nMode |= STREAM_SHARE_DENYREAD;
273 			}
274 			else if( eTok == WRITE )
275 				nMode |= STREAM_SHARE_DENYWRITE;
276 			else
277 				Error( SbERR_SYNTAX );
278 			break;
279 		default: break;
280 	}
281 	TestToken( AS );
282 	// Die Kanalnummer
283 	SbiExpression* pChan = new SbiExpression( this );
284 	if( !pChan )
285 		Error( SbERR_SYNTAX );
286 	SbiExpression* pLen = NULL;
287 	if( Peek() == SYMBOL )
288 	{
289 		Next();
290 		String aLen( aSym );
291 		if( aLen.EqualsIgnoreCaseAscii( "LEN" ) )
292 		{
293 			TestToken( EQ );
294 			pLen = new SbiExpression( this );
295 		}
296 	}
297 	if( !pLen ) pLen = new SbiExpression( this, 128, SbxINTEGER );
298 	// Der Stack fuer den OPEN-Befehl sieht wie folgt aus:
299 	// Blocklaenge
300 	// Kanalnummer
301 	// Dateiname
302 	pLen->Gen();
303 	if( pChan )
304 		pChan->Gen();
305 	aFileName.Gen();
306 	aGen.Gen( _OPEN, nMode, nFlags );
307 	delete pLen;
308 	delete pChan;
309 }
310 
311 // NAME file AS file
312 
313 void SbiParser::Name()
314 {
315 	// #i92642: Special handling to allow name as symbol
316 	if( Peek() == EQ )
317 	{
318 		aGen.Statement();
319 
320 		KeywordSymbolInfo aInfo;
321 		aInfo.m_aKeywordSymbol = String( RTL_CONSTASCII_USTRINGPARAM( "name" ) );
322 		aInfo.m_eSbxDataType = GetType();
323 		aInfo.m_eTok = SYMBOL;
324 
325 		Symbol( &aInfo );
326 		return;
327 	}
328 	SbiExpression aExpr1( this );
329 	TestToken( AS );
330 	SbiExpression aExpr2( this );
331 	aExpr1.Gen();
332 	aExpr2.Gen();
333 	aGen.Gen( _RENAME );
334 }
335 
336 // CLOSE [n,...]
337 
338 void SbiParser::Close()
339 {
340 	Peek();
341 	if( IsEoln( eCurTok ) )
342 		aGen.Gen( _CLOSE, 0 );
343 	else
344 	for( ;; )
345 	{
346 		SbiExpression aExpr( this );
347 		while( Peek() == COMMA || Peek() == SEMICOLON )
348 			Next();
349 		aExpr.Gen();
350 		aGen.Gen( _CHANNEL );
351 		aGen.Gen( _CLOSE, 1 );
352 
353 		if( IsEoln( Peek() ) )
354 			break;
355 	}
356 }
357 
358 
359