Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*
3 : : * This file is part of the LibreOffice project.
4 : : *
5 : : * This Source Code Form is subject to the terms of the Mozilla Public
6 : : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : : *
9 : : * This file incorporates work covered by the following license notice:
10 : : *
11 : : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : : * contributor license agreements. See the NOTICE file distributed
13 : : * with this work for additional information regarding copyright
14 : : * ownership. The ASF licenses this file to you under the Apache
15 : : * License, Version 2.0 (the "License"); you may not use this file
16 : : * except in compliance with the License. You may obtain a copy of
17 : : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : : */
19 : :
20 : : #include "sbcomp.hxx"
21 : : #include "iosys.hxx"
22 : :
23 : : // test if there's an I/O channel
24 : :
25 : 30 : bool SbiParser::Channel( bool bAlways )
26 : : {
27 : 30 : bool bRes = false;
28 : 30 : Peek();
29 [ + - ]: 30 : if( IsHash() )
30 : : {
31 [ + - ]: 30 : SbiExpression aExpr( this );
32 [ + - ][ + + ]: 58 : while( Peek() == COMMA || Peek() == SEMICOLON )
[ + - ][ - + ]
[ + + ]
33 [ + - ]: 28 : Next();
34 [ + - ]: 30 : aExpr.Gen();
35 [ + - ]: 30 : aGen.Gen( _CHANNEL );
36 [ + - ]: 30 : bRes = true;
37 : : }
38 [ # # ]: 0 : else if( bAlways )
39 : 0 : Error( SbERR_EXPECTED, "#" );
40 : 30 : return bRes;
41 : : }
42 : :
43 : : // it's tried that at object variables the Default-
44 : : // Property is addressed for PRINT and WRITE
45 : :
46 : 30 : void SbiParser::Print()
47 : : {
48 : 30 : bool bChan = Channel();
49 : :
50 [ + - ]: 30 : while( !bAbort )
51 : : {
52 [ + + ]: 30 : if( !IsEoln( Peek() ) )
53 : : {
54 [ + - ]: 28 : SbiExpression* pExpr = new SbiExpression( this );
55 : 28 : pExpr->Gen();
56 [ + - ]: 28 : delete pExpr;
57 : 28 : Peek();
58 [ - + ]: 28 : aGen.Gen( eCurTok == COMMA ? _PRINTF : _BPRINT );
59 : : }
60 [ + - ][ - + ]: 30 : if( eCurTok == COMMA || eCurTok == SEMICOLON )
61 : : {
62 : 0 : Next();
63 [ # # ]: 0 : if( IsEoln( Peek() ) ) break;
64 : : }
65 : : else
66 : : {
67 : 30 : aGen.Gen( _PRCHAR, '\n' );
68 : 30 : break;
69 : : }
70 : : }
71 [ + - ]: 30 : if( bChan )
72 : 30 : aGen.Gen( _CHAN0 );
73 : 30 : }
74 : :
75 : : // WRITE #chan, expr, ...
76 : :
77 : 0 : void SbiParser::Write()
78 : : {
79 : 0 : bool bChan = Channel();
80 : :
81 [ # # ]: 0 : while( !bAbort )
82 : : {
83 [ # # ]: 0 : SbiExpression* pExpr = new SbiExpression( this );
84 : 0 : pExpr->Gen();
85 [ # # ]: 0 : delete pExpr;
86 : 0 : aGen.Gen( _BWRITE );
87 [ # # ]: 0 : if( Peek() == COMMA )
88 : : {
89 : 0 : aGen.Gen( _PRCHAR, ',' );
90 : 0 : Next();
91 [ # # ]: 0 : if( IsEoln( Peek() ) ) break;
92 : : }
93 : : else
94 : : {
95 : 0 : aGen.Gen( _PRCHAR, '\n' );
96 : 0 : break;
97 : : }
98 : : }
99 [ # # ]: 0 : if( bChan )
100 : 0 : aGen.Gen( _CHAN0 );
101 : 0 : }
102 : :
103 : :
104 : : // #i92642 Handle LINE keyword outside ::Next()
105 : 0 : void SbiParser::Line()
106 : : {
107 : : // #i92642: Special handling to allow name as symbol
108 [ # # ]: 0 : if( Peek() == INPUT )
109 : : {
110 : 0 : Next();
111 : 0 : LineInput();
112 : : }
113 : : else
114 : : {
115 [ # # ]: 0 : aGen.Statement();
116 : :
117 : 0 : KeywordSymbolInfo aInfo;
118 [ # # ]: 0 : aInfo.m_aKeywordSymbol = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "line" ) );
119 : 0 : aInfo.m_eSbxDataType = GetType();
120 : 0 : aInfo.m_eTok = SYMBOL;
121 : :
122 [ # # ]: 0 : Symbol( &aInfo );
123 : : }
124 : 0 : }
125 : :
126 : :
127 : : // LINE INPUT [prompt], var$
128 : :
129 : 0 : void SbiParser::LineInput()
130 : : {
131 : 0 : Channel( true );
132 [ # # ]: 0 : SbiExpression* pExpr = new SbiExpression( this, SbOPERAND );
133 [ # # ]: 0 : if( !pExpr->IsVariable() )
134 : 0 : Error( SbERR_VAR_EXPECTED );
135 [ # # ][ # # ]: 0 : if( pExpr->GetType() != SbxVARIANT && pExpr->GetType() != SbxSTRING )
[ # # ]
136 : 0 : Error( SbERR_CONVERSION );
137 : 0 : pExpr->Gen();
138 : 0 : aGen.Gen( _LINPUT );
139 [ # # ]: 0 : delete pExpr;
140 : 0 : aGen.Gen( _CHAN0 ); // ResetChannel() not in StepLINPUT() anymore
141 : 0 : }
142 : :
143 : : // INPUT
144 : :
145 : 0 : void SbiParser::Input()
146 : : {
147 : 0 : aGen.Gen( _RESTART );
148 : 0 : Channel( true );
149 [ # # ]: 0 : SbiExpression* pExpr = new SbiExpression( this, SbOPERAND );
150 [ # # ]: 0 : while( !bAbort )
151 : : {
152 [ # # ]: 0 : if( !pExpr->IsVariable() )
153 : 0 : Error( SbERR_VAR_EXPECTED );
154 : 0 : pExpr->Gen();
155 : 0 : aGen.Gen( _INPUT );
156 [ # # ]: 0 : if( Peek() == COMMA )
157 : : {
158 : 0 : Next();
159 [ # # ]: 0 : delete pExpr;
160 [ # # ]: 0 : pExpr = new SbiExpression( this, SbOPERAND );
161 : : }
162 : 0 : else break;
163 : : }
164 [ # # ]: 0 : delete pExpr;
165 : 0 : aGen.Gen( _CHAN0 );
166 : 0 : }
167 : :
168 : : // OPEN stringexpr FOR mode ACCCESS access mode AS Channel [Len=n]
169 : :
170 : 2 : void SbiParser::Open()
171 : : {
172 : 2 : bInStatement = true;
173 [ + - ]: 2 : SbiExpression aFileName( this );
174 : : SbiToken eTok;
175 [ + - ]: 2 : TestToken( FOR );
176 : 2 : short nMode = 0;
177 : 2 : short nFlags = 0;
178 [ + - ][ - + : 2 : switch( Next() )
- - - - ]
179 : : {
180 : : case INPUT:
181 : 0 : nMode = STREAM_READ; nFlags |= SBSTRM_INPUT; break;
182 : : case OUTPUT:
183 : 2 : nMode = STREAM_WRITE | STREAM_TRUNC; nFlags |= SBSTRM_OUTPUT; break;
184 : : case APPEND:
185 : 0 : nMode = STREAM_WRITE; nFlags |= SBSTRM_APPEND; break;
186 : : case RANDOM:
187 : 0 : nMode = STREAM_READ | STREAM_WRITE; nFlags |= SBSTRM_RANDOM; break;
188 : : case BINARY:
189 : 0 : nMode = STREAM_READ | STREAM_WRITE; nFlags |= SBSTRM_BINARY; break;
190 : : default:
191 [ # # ]: 0 : Error( SbERR_SYNTAX );
192 : : }
193 [ + - ][ - + ]: 2 : if( Peek() == ACCESS )
194 : : {
195 [ # # ]: 0 : Next();
196 [ # # ]: 0 : eTok = Next();
197 : : // influence only STREAM_READ,STREAM_WRITE-Flags in nMode
198 : 0 : nMode &= ~(STREAM_READ | STREAM_WRITE); // delete
199 [ # # ]: 0 : if( eTok == READ )
200 : : {
201 [ # # ][ # # ]: 0 : if( Peek() == WRITE )
202 : : {
203 [ # # ]: 0 : Next();
204 : 0 : nMode |= (STREAM_READ | STREAM_WRITE);
205 : : }
206 : : else
207 : 0 : nMode |= STREAM_READ;
208 : : }
209 [ # # ]: 0 : else if( eTok == WRITE )
210 : 0 : nMode |= STREAM_WRITE;
211 : : else
212 [ # # ]: 0 : Error( SbERR_SYNTAX );
213 : : }
214 [ + - ]: 2 : switch( Peek() )
[ - - + ]
215 : : {
216 : : #ifdef SHARED
217 : : #undef SHARED
218 : : #define tmpSHARED
219 : : #endif
220 : : case SHARED:
221 [ # # ]: 0 : Next(); nMode |= STREAM_SHARE_DENYNONE; break;
222 : : #ifdef tmpSHARED
223 : : #define SHARED
224 : : #undef tmpSHARED
225 : : #endif
226 : : case LOCK:
227 [ # # ]: 0 : Next();
228 [ # # ]: 0 : eTok = Next();
229 [ # # ]: 0 : if( eTok == READ )
230 : : {
231 [ # # ][ # # ]: 0 : if( Peek() == WRITE ) Next(), nMode |= STREAM_SHARE_DENYALL;
[ # # ]
232 : 0 : else nMode |= STREAM_SHARE_DENYREAD;
233 : : }
234 [ # # ]: 0 : else if( eTok == WRITE )
235 : 0 : nMode |= STREAM_SHARE_DENYWRITE;
236 : : else
237 [ # # ]: 0 : Error( SbERR_SYNTAX );
238 : 0 : break;
239 : 2 : default: break;
240 : : }
241 [ + - ]: 2 : TestToken( AS );
242 : : // channel number
243 [ + - ][ + - ]: 2 : SbiExpression* pChan = new SbiExpression( this );
244 [ - + ]: 2 : if( !pChan )
245 [ # # ]: 0 : Error( SbERR_SYNTAX );
246 : 2 : SbiExpression* pLen = NULL;
247 [ + - ][ - + ]: 2 : if( Peek() == SYMBOL )
248 : : {
249 [ # # ]: 0 : Next();
250 [ # # ]: 0 : if( aSym.equalsIgnoreAsciiCaseAsciiL(RTL_CONSTASCII_STRINGPARAM("LEN")) )
251 : : {
252 [ # # ]: 0 : TestToken( EQ );
253 [ # # ][ # # ]: 0 : pLen = new SbiExpression( this );
254 : : }
255 : : }
256 [ + - ][ + - ]: 2 : if( !pLen ) pLen = new SbiExpression( this, 128, SbxINTEGER );
[ + - ]
257 : : // the stack for the OPEN command looks as follows:
258 : : // block length
259 : : // channel number
260 : : // file name
261 [ + - ]: 2 : pLen->Gen();
262 [ + - ]: 2 : if( pChan )
263 [ + - ]: 2 : pChan->Gen();
264 [ + - ]: 2 : aFileName.Gen();
265 [ + - ]: 2 : aGen.Gen( _OPEN, nMode, nFlags );
266 [ + - ][ + - ]: 2 : delete pLen;
267 [ + - ][ + - ]: 2 : delete pChan;
268 [ + - ]: 2 : bInStatement = false;
269 : 2 : }
270 : :
271 : : // NAME file AS file
272 : :
273 : 0 : void SbiParser::Name()
274 : : {
275 : : // #i92642: Special handling to allow name as symbol
276 [ # # ][ # # ]: 0 : if( Peek() == EQ )
277 : : {
278 [ # # ]: 0 : aGen.Statement();
279 : :
280 : 0 : KeywordSymbolInfo aInfo;
281 [ # # ]: 0 : aInfo.m_aKeywordSymbol = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "name" ) );
282 : 0 : aInfo.m_eSbxDataType = GetType();
283 : 0 : aInfo.m_eTok = SYMBOL;
284 : :
285 [ # # ]: 0 : Symbol( &aInfo );
286 : 0 : return;
287 : : }
288 [ # # ]: 0 : SbiExpression aExpr1( this );
289 [ # # ]: 0 : TestToken( AS );
290 [ # # ]: 0 : SbiExpression aExpr2( this );
291 [ # # ]: 0 : aExpr1.Gen();
292 [ # # ]: 0 : aExpr2.Gen();
293 [ # # ][ # # ]: 0 : aGen.Gen( _RENAME );
[ # # ]
294 : : }
295 : :
296 : : // CLOSE [n,...]
297 : :
298 : 32 : void SbiParser::Close()
299 : : {
300 : 32 : Peek();
301 [ - + ]: 32 : if( IsEoln( eCurTok ) )
302 : 0 : aGen.Gen( _CLOSE, 0 );
303 : : else
304 : 32 : for( ;; )
305 : : {
306 [ + - ]: 32 : SbiExpression aExpr( this );
307 [ + - ][ + - ]: 32 : while( Peek() == COMMA || Peek() == SEMICOLON )
[ + - ][ - + ]
[ - + ]
308 [ # # ]: 0 : Next();
309 [ + - ]: 32 : aExpr.Gen();
310 [ + - ]: 32 : aGen.Gen( _CHANNEL );
311 [ + - ]: 32 : aGen.Gen( _CLOSE, 1 );
312 : :
313 [ + - ][ + - ]: 32 : if( IsEoln( Peek() ) )
314 : : break;
315 [ + - ][ - + ]: 32 : }
316 : 32 : }
317 : :
318 : :
319 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|