xref: /AOO41X/main/basic/source/comp/io.cxx (revision e1f63238eb022c8a12b30d46a012444ff20e0951)
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