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