xref: /trunk/main/basic/source/comp/io.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_basic.hxx"
30 
31 
32 #include <tools/stream.hxx>
33 #include "sbcomp.hxx"
34 #include "iosys.hxx"
35 
36 // Test, ob ein I/O-Channel angegeben wurde
37 
38 sal_Bool SbiParser::Channel( sal_Bool bAlways )
39 {
40     sal_Bool bRes = sal_False;
41     Peek();
42     if( IsHash() )
43     {
44         SbiExpression aExpr( this );
45         while( Peek() == COMMA || Peek() == SEMICOLON )
46             Next();
47         aExpr.Gen();
48         aGen.Gen( _CHANNEL );
49         bRes = sal_True;
50     }
51     else if( bAlways )
52         Error( SbERR_EXPECTED, "#" );
53     return bRes;
54 }
55 
56 // Fuer PRINT und WRITE wird bei Objektvariablen versucht,
57 // die Default-Property anzusprechen.
58 
59 // PRINT
60 
61 void SbiParser::Print()
62 {
63     sal_Bool bChan = Channel();
64     // Die Ausdruecke zum Drucken:
65     while( !bAbort )
66     {
67         if( !IsEoln( Peek() ) )
68         {
69             SbiExpression* pExpr = new SbiExpression( this );
70             pExpr->Gen();
71             delete pExpr;
72             Peek();
73             aGen.Gen( eCurTok == COMMA ? _PRINTF : _BPRINT );
74         }
75         if( eCurTok == COMMA || eCurTok == SEMICOLON )
76         {
77             Next();
78             if( IsEoln( Peek() ) ) break;
79         }
80         else
81         {
82             aGen.Gen( _PRCHAR, '\n' );
83             break;
84         }
85     }
86     if( bChan )
87         aGen.Gen( _CHAN0 );
88 }
89 
90 // WRITE #chan, expr, ...
91 
92 void SbiParser::Write()
93 {
94     sal_Bool bChan = Channel();
95     // Die Ausdruecke zum Drucken:
96     while( !bAbort )
97     {
98         SbiExpression* pExpr = new SbiExpression( this );
99         pExpr->Gen();
100         delete pExpr;
101         aGen.Gen( _BWRITE );
102         if( Peek() == COMMA )
103         {
104             aGen.Gen( _PRCHAR, ',' );
105             Next();
106             if( IsEoln( Peek() ) ) break;
107         }
108         else
109         {
110             aGen.Gen( _PRCHAR, '\n' );
111             break;
112         }
113     }
114     if( bChan )
115         aGen.Gen( _CHAN0 );
116 }
117 
118 
119 // #i92642 Handle LINE keyword outside ::Next()
120 void SbiParser::Line()
121 {
122     // #i92642: Special handling to allow name as symbol
123     if( Peek() == INPUT )
124     {
125         Next();
126         LineInput();
127     }
128     else
129     {
130         aGen.Statement();
131 
132         KeywordSymbolInfo aInfo;
133         aInfo.m_aKeywordSymbol = String( RTL_CONSTASCII_USTRINGPARAM( "line" ) );
134         aInfo.m_eSbxDataType = GetType();
135         aInfo.m_eTok = SYMBOL;
136 
137         Symbol( &aInfo );
138     }
139 }
140 
141 
142 // LINE INPUT [prompt], var$
143 
144 void SbiParser::LineInput()
145 {
146     Channel( sal_True );
147     // sal_Bool bChan = Channel( sal_True );
148     SbiExpression* pExpr = new SbiExpression( this, SbOPERAND );
149     /* AB 15.1.96: Keinen allgemeinen Ausdruck mehr zulassen
150     SbiExpression* pExpr = new SbiExpression( this );
151     if( !pExpr->IsVariable() )
152     {
153         SbiToken eTok = Peek();
154         if( eTok == COMMA || eTok == SEMICOLON ) Next();
155         else Error( SbERR_EXPECTED, COMMA );
156         // mit Prompt
157         if( !bChan )
158         {
159             pExpr->Gen();
160             aGen.Gen( _PROMPT );
161         }
162         else
163             Error( SbERR_VAR_EXPECTED );
164         delete pExpr;
165         pExpr = new SbiExpression( this, SbOPERAND );
166     }
167     */
168     if( !pExpr->IsVariable() )
169         Error( SbERR_VAR_EXPECTED );
170     if( pExpr->GetType() != SbxVARIANT && pExpr->GetType() != SbxSTRING )
171         Error( SbERR_CONVERSION );
172     pExpr->Gen();
173     aGen.Gen( _LINPUT );
174     delete pExpr;
175     aGen.Gen( _CHAN0 );     // ResetChannel() nicht mehr in StepLINPUT()
176 }
177 
178 // INPUT
179 
180 void SbiParser::Input()
181 {
182     aGen.Gen( _RESTART );
183     Channel( sal_True );
184     // sal_Bool bChan = Channel( sal_True );
185     SbiExpression* pExpr = new SbiExpression( this, SbOPERAND );
186     /* ALT: Jetzt keinen allgemeinen Ausdruck mehr zulassen
187     SbiExpression* pExpr = new SbiExpression( this );
188     ...
189     siehe LineInput
190     */
191     while( !bAbort )
192     {
193         if( !pExpr->IsVariable() )
194             Error( SbERR_VAR_EXPECTED );
195         pExpr->Gen();
196         aGen.Gen( _INPUT );
197         if( Peek() == COMMA )
198         {
199             Next();
200             delete pExpr;
201             pExpr = new SbiExpression( this, SbOPERAND );
202         }
203         else break;
204     }
205     delete pExpr;
206     aGen.Gen( _CHAN0 );     // ResetChannel() nicht mehr in StepINPUT()
207 }
208 
209 // OPEN stringexpr FOR mode ACCCESS access mode AS Channel [Len=n]
210 
211 void SbiParser::Open()
212 {
213     SbiExpression aFileName( this );
214     SbiToken eTok;
215     TestToken( FOR );
216     short nMode = 0;
217     short nFlags = 0;
218     switch( Next() )
219     {
220         case INPUT:
221             nMode = STREAM_READ;  nFlags |= SBSTRM_INPUT; break;
222         case OUTPUT:
223             nMode = STREAM_WRITE | STREAM_TRUNC; nFlags |= SBSTRM_OUTPUT; break;
224         case APPEND:
225             nMode = STREAM_WRITE; nFlags |= SBSTRM_APPEND; break;
226         case RANDOM:
227             nMode = STREAM_READ | STREAM_WRITE; nFlags |= SBSTRM_RANDOM; break;
228         case BINARY:
229             nMode = STREAM_READ | STREAM_WRITE; nFlags |= SBSTRM_BINARY; break;
230         default:
231             Error( SbERR_SYNTAX );
232     }
233     if( Peek() == ACCESS )
234     {
235         Next();
236         eTok = Next();
237         // #27964# Nur STREAM_READ,STREAM_WRITE-Flags in nMode beeinflussen
238         nMode &= ~(STREAM_READ | STREAM_WRITE);     // loeschen
239         if( eTok == READ )
240         {
241             if( Peek() == WRITE )
242             {
243                 Next();
244                 nMode |= (STREAM_READ | STREAM_WRITE);
245             }
246             else
247                 nMode |= STREAM_READ;
248         }
249         else if( eTok == WRITE )
250             nMode |= STREAM_WRITE;
251         else
252             Error( SbERR_SYNTAX );
253     }
254     switch( Peek() )
255     {
256 #ifdef SHARED
257 #undef SHARED
258 #define tmpSHARED
259 #endif
260         case SHARED:
261             Next(); nMode |= STREAM_SHARE_DENYNONE; break;
262 #ifdef tmpSHARED
263 #define SHARED
264 #undef tmpSHARED
265 #endif
266         case LOCK:
267             Next();
268             eTok = Next();
269             if( eTok == READ )
270             {
271                 if( Peek() == WRITE ) Next(), nMode |= STREAM_SHARE_DENYALL;
272                 else nMode |= STREAM_SHARE_DENYREAD;
273             }
274             else if( eTok == WRITE )
275                 nMode |= STREAM_SHARE_DENYWRITE;
276             else
277                 Error( SbERR_SYNTAX );
278             break;
279         default: break;
280     }
281     TestToken( AS );
282     // Die Kanalnummer
283     SbiExpression* pChan = new SbiExpression( this );
284     if( !pChan )
285         Error( SbERR_SYNTAX );
286     SbiExpression* pLen = NULL;
287     if( Peek() == SYMBOL )
288     {
289         Next();
290         String aLen( aSym );
291         if( aLen.EqualsIgnoreCaseAscii( "LEN" ) )
292         {
293             TestToken( EQ );
294             pLen = new SbiExpression( this );
295         }
296     }
297     if( !pLen ) pLen = new SbiExpression( this, 128, SbxINTEGER );
298     // Der Stack fuer den OPEN-Befehl sieht wie folgt aus:
299     // Blocklaenge
300     // Kanalnummer
301     // Dateiname
302     pLen->Gen();
303     if( pChan )
304         pChan->Gen();
305     aFileName.Gen();
306     aGen.Gen( _OPEN, nMode, nFlags );
307     delete pLen;
308     delete pChan;
309 }
310 
311 // NAME file AS file
312 
313 void SbiParser::Name()
314 {
315     // #i92642: Special handling to allow name as symbol
316     if( Peek() == EQ )
317     {
318         aGen.Statement();
319 
320         KeywordSymbolInfo aInfo;
321         aInfo.m_aKeywordSymbol = String( RTL_CONSTASCII_USTRINGPARAM( "name" ) );
322         aInfo.m_eSbxDataType = GetType();
323         aInfo.m_eTok = SYMBOL;
324 
325         Symbol( &aInfo );
326         return;
327     }
328     SbiExpression aExpr1( this );
329     TestToken( AS );
330     SbiExpression aExpr2( this );
331     aExpr1.Gen();
332     aExpr2.Gen();
333     aGen.Gen( _RENAME );
334 }
335 
336 // CLOSE [n,...]
337 
338 void SbiParser::Close()
339 {
340     Peek();
341     if( IsEoln( eCurTok ) )
342         aGen.Gen( _CLOSE, 0 );
343     else
344     for( ;; )
345     {
346         SbiExpression aExpr( this );
347         while( Peek() == COMMA || Peek() == SEMICOLON )
348             Next();
349         aExpr.Gen();
350         aGen.Gen( _CHANNEL );
351         aGen.Gen( _CLOSE, 1 );
352 
353         if( IsEoln( Peek() ) )
354             break;
355     }
356 }
357 
358 
359