Version 6.4.0.3, tag libreoffice-6.4.0.3
[LibreOffice.git] / basic / source / comp / io.cxx
blob45581c70e9f226fda45246235af449a906d809d6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <basic/sberrors.hxx>
21 #include <parser.hxx>
22 #include <iosys.hxx>
23 #include <memory>
25 // test if there's an I/O channel
27 bool SbiParser::Channel( bool bAlways )
29 bool bRes = false;
30 Peek();
31 if( IsHash() )
33 SbiExpression aExpr( this );
34 while( Peek() == COMMA || Peek() == SEMICOLON )
35 Next();
36 aExpr.Gen();
37 aGen.Gen( SbiOpcode::CHANNEL_ );
38 bRes = true;
40 else if( bAlways )
41 Error( ERRCODE_BASIC_EXPECTED, "#" );
42 return bRes;
45 // it's tried that at object variables the Default-
46 // Property is addressed for PRINT and WRITE
48 void SbiParser::Print()
50 bool bChan = Channel();
52 while( !bAbort )
54 if( !IsEoln( Peek() ) )
56 std::unique_ptr<SbiExpression> pExpr(new SbiExpression( this ));
57 pExpr->Gen();
58 pExpr.reset();
59 Peek();
60 aGen.Gen( eCurTok == COMMA ? SbiOpcode::PRINTF_ : SbiOpcode::BPRINT_ );
62 if( eCurTok == COMMA || eCurTok == SEMICOLON )
64 Next();
65 if( IsEoln( Peek() ) ) break;
67 else
69 aGen.Gen( SbiOpcode::PRCHAR_, '\n' );
70 break;
73 if( bChan )
74 aGen.Gen( SbiOpcode::CHAN0_ );
77 // WRITE #chan, expr, ...
79 void SbiParser::Write()
81 bool bChan = Channel();
83 while( !bAbort )
85 std::unique_ptr<SbiExpression> pExpr(new SbiExpression( this ));
86 pExpr->Gen();
87 pExpr.reset();
88 aGen.Gen( SbiOpcode::BWRITE_ );
89 if( Peek() == COMMA )
91 aGen.Gen( SbiOpcode::PRCHAR_, ',' );
92 Next();
93 if( IsEoln( Peek() ) ) break;
95 else
97 aGen.Gen( SbiOpcode::PRCHAR_, '\n' );
98 break;
101 if( bChan )
102 aGen.Gen( SbiOpcode::CHAN0_ );
106 // #i92642 Handle LINE keyword outside ::Next()
107 void SbiParser::Line()
109 // #i92642: Special handling to allow name as symbol
110 if( Peek() == INPUT )
112 Next();
113 LineInput();
115 else
117 aGen.Statement();
119 KeywordSymbolInfo aInfo;
120 aInfo.m_aKeywordSymbol = "line";
121 aInfo.m_eSbxDataType = GetType();
123 Symbol( &aInfo );
128 // LINE INPUT [prompt], var$
130 void SbiParser::LineInput()
132 Channel( true );
133 std::unique_ptr<SbiExpression> pExpr(new SbiExpression( this, SbOPERAND ));
134 if( !pExpr->IsVariable() )
135 Error( ERRCODE_BASIC_VAR_EXPECTED );
136 if( pExpr->GetType() != SbxVARIANT && pExpr->GetType() != SbxSTRING )
137 Error( ERRCODE_BASIC_CONVERSION );
138 pExpr->Gen();
139 aGen.Gen( SbiOpcode::LINPUT_ );
140 pExpr.reset();
141 aGen.Gen( SbiOpcode::CHAN0_ ); // ResetChannel() not in StepLINPUT() anymore
144 // INPUT
146 void SbiParser::Input()
148 aGen.Gen( SbiOpcode::RESTART_ );
149 Channel( true );
150 std::unique_ptr<SbiExpression> pExpr(new SbiExpression( this, SbOPERAND ));
151 while( !bAbort )
153 if( !pExpr->IsVariable() )
154 Error( ERRCODE_BASIC_VAR_EXPECTED );
155 pExpr->Gen();
156 aGen.Gen( SbiOpcode::INPUT_ );
157 if( Peek() == COMMA )
159 Next();
160 pExpr.reset(new SbiExpression( this, SbOPERAND ));
162 else break;
164 pExpr.reset();
165 aGen.Gen( SbiOpcode::CHAN0_ );
168 // OPEN stringexpr FOR mode ACCESS access mode AS Channel [Len=n]
170 void SbiParser::Open()
172 bInStatement = true;
173 SbiExpression aFileName( this );
174 SbiToken eTok;
175 TestToken( FOR );
176 StreamMode nMode = StreamMode::NONE;
177 SbiStreamFlags nFlags = SbiStreamFlags::NONE;
178 switch( Next() )
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:
191 Error( ERRCODE_BASIC_SYNTAX );
193 if( Peek() == ACCESS )
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 )
201 if( Peek() == WRITE )
203 Next();
204 nMode |= StreamMode::READ | StreamMode::WRITE;
206 else
207 nMode |= StreamMode::READ;
209 else if( eTok == WRITE )
210 nMode |= StreamMode::WRITE;
211 else
212 Error( ERRCODE_BASIC_SYNTAX );
214 switch( Peek() )
216 case SHARED:
217 Next(); nMode |= StreamMode::SHARE_DENYNONE; break;
218 case LOCK:
219 Next();
220 eTok = Next();
221 if( eTok == READ )
223 if( Peek() == WRITE )
225 Next();
226 nMode |= StreamMode::SHARE_DENYALL;
228 else nMode |= StreamMode::SHARE_DENYREAD;
230 else if( eTok == WRITE )
231 nMode |= StreamMode::SHARE_DENYWRITE;
232 else
233 Error( ERRCODE_BASIC_SYNTAX );
234 break;
235 default: break;
237 TestToken( AS );
238 // channel number
239 std::unique_ptr<SbiExpression> pChan(new SbiExpression( this ));
240 std::unique_ptr<SbiExpression> pLen;
241 if( Peek() == SYMBOL )
243 Next();
244 if( aSym.equalsIgnoreAsciiCase("LEN") )
246 TestToken( EQ );
247 pLen.reset(new SbiExpression( this ));
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;
262 // NAME file AS file
264 void SbiParser::Name()
266 // #i92642: Special handling to allow name as symbol
267 if( Peek() == EQ )
269 aGen.Statement();
271 KeywordSymbolInfo aInfo;
272 aInfo.m_aKeywordSymbol = "name";
273 aInfo.m_eSbxDataType = GetType();
275 Symbol( &aInfo );
276 return;
278 SbiExpression aExpr1( this );
279 TestToken( AS );
280 SbiExpression aExpr2( this );
281 aExpr1.Gen();
282 aExpr2.Gen();
283 aGen.Gen( SbiOpcode::RENAME_ );
286 // CLOSE [n,...]
288 void SbiParser::Close()
290 Peek();
291 if( IsEoln( eCurTok ) )
292 aGen.Gen( SbiOpcode::CLOSE_, 0 );
293 else
294 for( ;; )
296 SbiExpression aExpr( this );
297 while( Peek() == COMMA || Peek() == SEMICOLON )
298 Next();
299 aExpr.Gen();
300 aGen.Gen( SbiOpcode::CHANNEL_ );
301 aGen.Gen( SbiOpcode::CLOSE_, 1 );
303 if( IsEoln( Peek() ) )
304 break;
309 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */