LibreOffice Module basic (master) 1
io.cxx
Go to the documentation of this file.
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 <basic/sberrors.hxx>
21#include <parser.hxx>
22#include <iosys.hxx>
23#include <memory>
24
25// test if there's an I/O channel
26
27bool SbiParser::Channel( bool bAlways )
28{
29 bool bRes = false;
30 Peek();
31 if( IsHash() )
32 {
33 SbiExpression aExpr( this );
34 while( Peek() == COMMA || Peek() == SEMICOLON )
35 Next();
36 aExpr.Gen();
38 bRes = true;
39 }
40 else if( bAlways )
42 return bRes;
43}
44
45// it's tried that at object variables the Default-
46// Property is addressed for PRINT and WRITE
47
49{
50 bool bChan = Channel();
51
52 while( !bAbort )
53 {
54 if( !IsEoln( Peek() ) )
55 {
56 auto pExpr = std::make_unique<SbiExpression>(this);
57 pExpr->Gen();
58 pExpr.reset();
59 Peek();
61 }
62 if( eCurTok == COMMA || eCurTok == SEMICOLON )
63 {
64 Next();
65 if( IsEoln( Peek() ) ) break;
66 }
67 else
68 {
70 break;
71 }
72 }
73 if( bChan )
75}
76
77// WRITE #chan, expr, ...
78
80{
81 bool bChan = Channel();
82
83 while( !bAbort )
84 {
85 auto pExpr = std::make_unique<SbiExpression>(this);
86 pExpr->Gen();
87 pExpr.reset();
89 if( Peek() == COMMA )
90 {
92 Next();
93 if( IsEoln( Peek() ) ) break;
94 }
95 else
96 {
98 break;
99 }
100 }
101 if( bChan )
103}
104
105
106// #i92642 Handle LINE keyword outside ::Next()
108{
109 // #i92642: Special handling to allow name as symbol
110 if( Peek() == INPUT )
111 {
112 Next();
113 LineInput();
114 }
115 else
116 {
117 aGen.Statement();
118
119 KeywordSymbolInfo aInfo;
120 aInfo.m_aKeywordSymbol = "line";
121 aInfo.m_eSbxDataType = GetType();
122
123 Symbol( &aInfo );
124 }
125}
126
127
128// LINE INPUT [prompt], var$
129
131{
132 Channel( true );
133 auto pExpr = std::make_unique<SbiExpression>( this, SbOPERAND );
134 if( !pExpr->IsVariable() )
136 if( pExpr->GetType() != SbxVARIANT && pExpr->GetType() != SbxSTRING )
138 pExpr->Gen();
140 pExpr.reset();
141 aGen.Gen( SbiOpcode::CHAN0_ ); // ResetChannel() not in StepLINPUT() anymore
142}
143
144// INPUT
145
147{
149 Channel( true );
150 auto pExpr = std::make_unique<SbiExpression>( this, SbOPERAND );
151 while( !bAbort )
152 {
153 if( !pExpr->IsVariable() )
155 pExpr->Gen();
157 if( Peek() == COMMA )
158 {
159 Next();
160 pExpr.reset(new SbiExpression( this, SbOPERAND ));
161 }
162 else break;
163 }
164 pExpr.reset();
166}
167
168// OPEN stringexpr FOR mode ACCESS access mode AS Channel [Len=n]
169
171{
172 bInStatement = true;
173 SbiExpression aFileName( this );
174 SbiToken eTok;
175 TestToken( FOR );
176 StreamMode nMode = StreamMode::NONE;
178 switch( Next() )
179 {
180 case INPUT:
181 nMode = StreamMode::READ; nFlags |= SbiStreamFlags::Input; break;
182 case OUTPUT:
183 nMode = StreamMode::WRITE | StreamMode::TRUNC; nFlags |= SbiStreamFlags::Output; break;
184 case APPEND:
185 nMode = StreamMode::WRITE; nFlags |= SbiStreamFlags::Append; break;
186 case RANDOM:
187 nMode = StreamMode::READ | StreamMode::WRITE; nFlags |= SbiStreamFlags::Random; break;
188 case BINARY:
189 nMode = StreamMode::READ | StreamMode::WRITE; nFlags |= SbiStreamFlags::Binary; break;
190 default:
192 }
193 if( Peek() == ACCESS )
194 {
195 Next();
196 eTok = Next();
197 // influence only READ,WRITE-Flags in nMode
198 nMode &= ~StreamMode(StreamMode::READ | StreamMode::WRITE); // delete
199 if( eTok == READ )
200 {
201 if( Peek() == WRITE )
202 {
203 Next();
204 nMode |= StreamMode::READ | StreamMode::WRITE;
205 }
206 else
207 nMode |= StreamMode::READ;
208 }
209 else if( eTok == WRITE )
210 nMode |= StreamMode::WRITE;
211 else
213 }
214 switch( Peek() )
215 {
216 case SHARED:
217 Next(); nMode |= StreamMode::SHARE_DENYNONE; break;
218 case LOCK:
219 Next();
220 eTok = Next();
221 if( eTok == READ )
222 {
223 if( Peek() == WRITE )
224 {
225 Next();
226 nMode |= StreamMode::SHARE_DENYALL;
227 }
228 else nMode |= StreamMode::SHARE_DENYREAD;
229 }
230 else if( eTok == WRITE )
231 nMode |= StreamMode::SHARE_DENYWRITE;
232 else
234 break;
235 default: break;
236 }
237 TestToken( AS );
238 // channel number
239 auto pChan = std::make_unique<SbiExpression>( this );
240 std::unique_ptr<SbiExpression> pLen;
241 if( Peek() == SYMBOL )
242 {
243 Next();
244 if( aSym.equalsIgnoreAsciiCase("LEN") )
245 {
246 TestToken( EQ );
247 pLen.reset(new SbiExpression( this ));
248 }
249 }
250 if( !pLen ) pLen.reset(new SbiExpression( this, 128, SbxINTEGER ));
251 // the stack for the OPEN command looks as follows:
252 // block length
253 // channel number
254 // file name
255 pLen->Gen();
256 pChan->Gen();
257 aFileName.Gen();
258 aGen.Gen( SbiOpcode::OPEN_, static_cast<sal_uInt32>(nMode), static_cast<sal_uInt32>(nFlags) );
259 bInStatement = false;
260}
261
262// NAME file AS file
263
265{
266 // #i92642: Special handling to allow name as symbol
267 if( Peek() == EQ )
268 {
269 aGen.Statement();
270
271 KeywordSymbolInfo aInfo;
272 aInfo.m_aKeywordSymbol = "name";
273 aInfo.m_eSbxDataType = GetType();
274
275 Symbol( &aInfo );
276 return;
277 }
278 SbiExpression aExpr1( this );
279 TestToken( AS );
280 SbiExpression aExpr2( this );
281 aExpr1.Gen();
282 aExpr2.Gen();
284}
285
286// CLOSE [n,...]
287
289{
290 Peek();
291 if( IsEoln( eCurTok ) )
293 else
294 for( ;; )
295 {
296 SbiExpression aExpr( this );
297 while( Peek() == COMMA || Peek() == SEMICOLON )
298 Next();
299 aExpr.Gen();
302
303 if( IsEoln( Peek() ) )
304 break;
305 }
306}
307
308
309/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
sal_uInt32 Gen(SbiOpcode)
Definition: codegen.cxx:88
void Statement()
Definition: codegen.cxx:56
void Gen(RecursiveMode eRecMode=UNDEFINED)
Definition: exprgen.cxx:260
void Close()
Definition: io.cxx:288
friend class SbiExpression
Definition: parser.hxx:33
void Input()
Definition: io.cxx:146
bool TestToken(SbiToken)
Definition: parser.cxx:261
bool Channel(bool bAlways=false)
Definition: io.cxx:27
void LineInput()
Definition: io.cxx:130
void Symbol(const KeywordSymbolInfo *pKeywordSymbolInfo)
Definition: parser.cxx:491
void Open()
Definition: io.cxx:170
void Name()
Definition: io.cxx:264
void Write()
Definition: io.cxx:79
void Print()
Definition: io.cxx:48
SbiCodeGen aGen
Definition: parser.hxx:68
void Line()
Definition: io.cxx:107
bool IsHash() const
Definition: scanner.hxx:74
bool bInStatement
Definition: scanner.hxx:68
bool bAbort
Definition: scanner.hxx:59
SbxDataType GetType() const
Definition: scanner.hxx:92
OUString aSym
Definition: scanner.hxx:45
SbiToken Next()
Definition: token.cxx:309
static bool IsEoln(SbiToken t)
Definition: token.hxx:127
void Error(ErrCode c)
Definition: token.hxx:123
SbiToken Peek()
Definition: token.cxx:248
SbiToken eCurTok
Definition: token.hxx:103
@ SbOPERAND
Definition: expr.hxx:57
SbiStreamFlags
Definition: iosys.hxx:36
READ
#define ERRCODE_BASIC_EXPECTED
Definition: sberrors.hxx:125
#define ERRCODE_BASIC_VAR_EXPECTED
Definition: sberrors.hxx:127
#define ERRCODE_BASIC_SYNTAX
Definition: sberrors.hxx:25
#define ERRCODE_BASIC_CONVERSION
Definition: sberrors.hxx:30
@ SbxVARIANT
Definition: sbxdef.hxx:51
@ SbxSTRING
Definition: sbxdef.hxx:46
@ SbxINTEGER
Definition: sbxdef.hxx:40
StreamMode
OUString m_aKeywordSymbol
Definition: expr.hxx:49
SbxDataType m_eSbxDataType
Definition: expr.hxx:50
SbiToken
Definition: token.hxx:30
@ AS
Definition: token.hxx:38
@ OUTPUT
Definition: token.hxx:79
@ ACCESS
Definition: token.hxx:79
@ LOCK
Definition: token.hxx:80
@ SEMICOLON
Definition: token.hxx:34
@ WRITE
Definition: token.hxx:64
@ SHARED
Definition: token.hxx:61
@ EQ
Definition: token.hxx:73
@ RANDOM
Definition: token.hxx:79
@ FOR
Definition: token.hxx:53
@ INPUT
Definition: token.hxx:55
@ SYMBOL
Definition: token.hxx:78
@ BINARY
Definition: token.hxx:79
@ APPEND
Definition: token.hxx:79
@ COMMA
Definition: token.hxx:33