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 0 : bool SbiParser::Channel( bool bAlways )
26 : {
27 0 : bool bRes = false;
28 0 : Peek();
29 0 : if( IsHash() )
30 : {
31 0 : SbiExpression aExpr( this );
32 0 : while( Peek() == COMMA || Peek() == SEMICOLON )
33 0 : Next();
34 0 : aExpr.Gen();
35 0 : aGen.Gen( _CHANNEL );
36 0 : bRes = true;
37 : }
38 0 : else if( bAlways )
39 0 : Error( SbERR_EXPECTED, "#" );
40 0 : return bRes;
41 : }
42 :
43 : // it's tried that at object variables the Default-
44 : // Property is addressed for PRINT and WRITE
45 :
46 0 : void SbiParser::Print()
47 : {
48 0 : bool bChan = Channel();
49 :
50 0 : while( !bAbort )
51 : {
52 0 : if( !IsEoln( Peek() ) )
53 : {
54 0 : SbiExpression* pExpr = new SbiExpression( this );
55 0 : pExpr->Gen();
56 0 : delete pExpr;
57 0 : Peek();
58 0 : aGen.Gen( eCurTok == COMMA ? _PRINTF : _BPRINT );
59 : }
60 0 : if( eCurTok == COMMA || eCurTok == SEMICOLON )
61 : {
62 0 : Next();
63 0 : if( IsEoln( Peek() ) ) break;
64 : }
65 : else
66 : {
67 0 : aGen.Gen( _PRCHAR, '\n' );
68 0 : break;
69 : }
70 : }
71 0 : if( bChan )
72 0 : aGen.Gen( _CHAN0 );
73 0 : }
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 0 : void SbiParser::Open()
171 : {
172 0 : bInStatement = true;
173 0 : SbiExpression aFileName( this );
174 : SbiToken eTok;
175 0 : TestToken( FOR );
176 0 : short nMode = 0;
177 0 : short nFlags = 0;
178 0 : switch( Next() )
179 : {
180 : case INPUT:
181 0 : nMode = STREAM_READ; nFlags |= SBSTRM_INPUT; break;
182 : case OUTPUT:
183 0 : 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 0 : 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 0 : 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 0 : default: break;
240 : }
241 0 : TestToken( AS );
242 : // channel number
243 0 : SbiExpression* pChan = new SbiExpression( this );
244 0 : if( !pChan )
245 0 : Error( SbERR_SYNTAX );
246 0 : SbiExpression* pLen = NULL;
247 0 : 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 0 : 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 0 : pLen->Gen();
262 0 : if( pChan )
263 0 : pChan->Gen();
264 0 : aFileName.Gen();
265 0 : aGen.Gen( _OPEN, nMode, nFlags );
266 0 : delete pLen;
267 0 : delete pChan;
268 0 : bInStatement = false;
269 0 : }
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 0 : void SbiParser::Close()
299 : {
300 0 : Peek();
301 0 : if( IsEoln( eCurTok ) )
302 0 : aGen.Gen( _CLOSE, 0 );
303 : else
304 0 : for( ;; )
305 : {
306 0 : SbiExpression aExpr( this );
307 0 : while( Peek() == COMMA || Peek() == SEMICOLON )
308 0 : Next();
309 0 : aExpr.Gen();
310 0 : aGen.Gen( _CHANNEL );
311 0 : aGen.Gen( _CLOSE, 1 );
312 :
313 0 : if( IsEoln( Peek() ) )
314 : break;
315 0 : }
316 0 : }
317 :
318 :
319 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|