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 // MARKER(update_precomp.py): autogen include statement, do not remove 23 #include "precompiled_basic.hxx" 24 25 #include <tools/stream.hxx> 26 #include "sbcomp.hxx" 27 #include "iosys.hxx" 28 29 // Test, ob ein I/O-Channel angegeben wurde 30 31 sal_Bool SbiParser::Channel( sal_Bool bAlways ) 32 { 33 sal_Bool bRes = sal_False; 34 Peek(); 35 if( IsHash() ) 36 { 37 SbiExpression aExpr( this ); 38 while( Peek() == COMMA || Peek() == SEMICOLON ) 39 Next(); 40 aExpr.Gen(); 41 aGen.Gen( _CHANNEL ); 42 bRes = sal_True; 43 } 44 else if( bAlways ) 45 Error( SbERR_EXPECTED, "#" ); 46 return bRes; 47 } 48 49 // Für PRINT und WRITE wird bei Objektvariablen versucht, 50 // die Default-Property anzusprechen. 51 52 // PRINT 53 54 void SbiParser::Print() 55 { 56 sal_Bool bChan = Channel(); 57 // Die Ausdrücke zum drucken: 58 while( !bAbort ) 59 { 60 if( !IsEoln( Peek() ) ) 61 { 62 SbiExpression* pExpr = new SbiExpression( this ); 63 pExpr->Gen(); 64 delete pExpr; 65 Peek(); 66 aGen.Gen( eCurTok == COMMA ? _PRINTF : _BPRINT ); 67 } 68 if( eCurTok == COMMA || eCurTok == SEMICOLON ) 69 { 70 Next(); 71 if( IsEoln( Peek() ) ) break; 72 } 73 else 74 { 75 aGen.Gen( _PRCHAR, '\n' ); 76 break; 77 } 78 } 79 if( bChan ) 80 aGen.Gen( _CHAN0 ); 81 } 82 83 // WRITE #chan, expr, ... 84 85 void SbiParser::Write() 86 { 87 sal_Bool bChan = Channel(); 88 // Die Ausdrücke zum drucken: 89 while( !bAbort ) 90 { 91 SbiExpression* pExpr = new SbiExpression( this ); 92 pExpr->Gen(); 93 delete pExpr; 94 aGen.Gen( _BWRITE ); 95 if( Peek() == COMMA ) 96 { 97 aGen.Gen( _PRCHAR, ',' ); 98 Next(); 99 if( IsEoln( Peek() ) ) break; 100 } 101 else 102 { 103 aGen.Gen( _PRCHAR, '\n' ); 104 break; 105 } 106 } 107 if( bChan ) 108 aGen.Gen( _CHAN0 ); 109 } 110 111 112 // #i92642 Handle LINE keyword outside ::Next() 113 void SbiParser::Line() 114 { 115 // #i92642: Special handling to allow name as symbol 116 if( Peek() == INPUT ) 117 { 118 Next(); 119 LineInput(); 120 } 121 else 122 { 123 aGen.Statement(); 124 125 KeywordSymbolInfo aInfo; 126 aInfo.m_aKeywordSymbol = String( RTL_CONSTASCII_USTRINGPARAM( "line" ) ); 127 aInfo.m_eSbxDataType = GetType(); 128 aInfo.m_eTok = SYMBOL; 129 130 Symbol( &aInfo ); 131 } 132 } 133 134 135 // LINE INPUT [prompt], var$ 136 137 void SbiParser::LineInput() 138 { 139 Channel( sal_True ); 140 // sal_Bool bChan = Channel( sal_True ); 141 SbiExpression* pExpr = new SbiExpression( this, SbOPERAND ); 142 /* AB 15.1.96: Keinen allgemeinen Ausdruck mehr zulassen 143 SbiExpression* pExpr = new SbiExpression( this ); 144 if( !pExpr->IsVariable() ) 145 { 146 SbiToken eTok = Peek(); 147 if( eTok == COMMA || eTok == SEMICOLON ) Next(); 148 else Error( SbERR_EXPECTED, COMMA ); 149 // mit Prompt 150 if( !bChan ) 151 { 152 pExpr->Gen(); 153 aGen.Gen( _PROMPT ); 154 } 155 else 156 Error( SbERR_VAR_EXPECTED ); 157 delete pExpr; 158 pExpr = new SbiExpression( this, SbOPERAND ); 159 } 160 */ 161 if( !pExpr->IsVariable() ) 162 Error( SbERR_VAR_EXPECTED ); 163 if( pExpr->GetType() != SbxVARIANT && pExpr->GetType() != SbxSTRING ) 164 Error( SbERR_CONVERSION ); 165 pExpr->Gen(); 166 aGen.Gen( _LINPUT ); 167 delete pExpr; 168 aGen.Gen( _CHAN0 ); // ResetChannel() nicht mehr in StepLINPUT() 169 } 170 171 // INPUT 172 173 void SbiParser::Input() 174 { 175 aGen.Gen( _RESTART ); 176 Channel( sal_True ); 177 // sal_Bool bChan = Channel( sal_True ); 178 SbiExpression* pExpr = new SbiExpression( this, SbOPERAND ); 179 /* ALT: Jetzt keinen allgemeinen Ausdruck mehr zulassen 180 SbiExpression* pExpr = new SbiExpression( this ); 181 ... 182 siehe LineInput 183 */ 184 while( !bAbort ) 185 { 186 if( !pExpr->IsVariable() ) 187 Error( SbERR_VAR_EXPECTED ); 188 pExpr->Gen(); 189 aGen.Gen( _INPUT ); 190 if( Peek() == COMMA ) 191 { 192 Next(); 193 delete pExpr; 194 pExpr = new SbiExpression( this, SbOPERAND ); 195 } 196 else break; 197 } 198 delete pExpr; 199 aGen.Gen( _CHAN0 ); // ResetChannel() nicht mehr in StepINPUT() 200 } 201 202 // OPEN stringexpr FOR mode ACCESS access mode AS Channel [Len=n] 203 204 void SbiParser::Open() 205 { 206 SbiExpression aFileName( this ); 207 SbiToken eTok; 208 TestToken( FOR ); 209 short nMode = 0; 210 short nFlags = 0; 211 switch( Next() ) 212 { 213 case INPUT: 214 nMode = STREAM_READ; nFlags |= SBSTRM_INPUT; break; 215 case OUTPUT: 216 nMode = STREAM_WRITE | STREAM_TRUNC; nFlags |= SBSTRM_OUTPUT; break; 217 case APPEND: 218 nMode = STREAM_WRITE; nFlags |= SBSTRM_APPEND; break; 219 case RANDOM: 220 nMode = STREAM_READ | STREAM_WRITE; nFlags |= SBSTRM_RANDOM; break; 221 case BINARY: 222 nMode = STREAM_READ | STREAM_WRITE; nFlags |= SBSTRM_BINARY; break; 223 default: 224 Error( SbERR_SYNTAX ); 225 } 226 if( Peek() == ACCESS ) 227 { 228 Next(); 229 eTok = Next(); 230 // #27964# Nur STREAM_READ,STREAM_WRITE-Flags in nMode beeinflussen 231 nMode &= ~(STREAM_READ | STREAM_WRITE); // löschen 232 if( eTok == READ ) 233 { 234 if( Peek() == WRITE ) 235 { 236 Next(); 237 nMode |= (STREAM_READ | STREAM_WRITE); 238 } 239 else 240 nMode |= STREAM_READ; 241 } 242 else if( eTok == WRITE ) 243 nMode |= STREAM_WRITE; 244 else 245 Error( SbERR_SYNTAX ); 246 } 247 switch( Peek() ) 248 { 249 #ifdef SHARED 250 #undef SHARED 251 #define tmpSHARED 252 #endif 253 case SHARED: 254 Next(); nMode |= STREAM_SHARE_DENYNONE; break; 255 #ifdef tmpSHARED 256 #define SHARED 257 #undef tmpSHARED 258 #endif 259 case LOCK: 260 Next(); 261 eTok = Next(); 262 if( eTok == READ ) 263 { 264 if( Peek() == WRITE ) Next(), nMode |= STREAM_SHARE_DENYALL; 265 else nMode |= STREAM_SHARE_DENYREAD; 266 } 267 else if( eTok == WRITE ) 268 nMode |= STREAM_SHARE_DENYWRITE; 269 else 270 Error( SbERR_SYNTAX ); 271 break; 272 default: break; 273 } 274 TestToken( AS ); 275 // Die Kanalnummer 276 SbiExpression* pChan = new SbiExpression( this ); 277 if( !pChan ) 278 Error( SbERR_SYNTAX ); 279 SbiExpression* pLen = NULL; 280 if( Peek() == SYMBOL ) 281 { 282 Next(); 283 String aLen( aSym ); 284 if( aLen.EqualsIgnoreCaseAscii( "LEN" ) ) 285 { 286 TestToken( EQ ); 287 pLen = new SbiExpression( this ); 288 } 289 } 290 if( !pLen ) pLen = new SbiExpression( this, 128, SbxINTEGER ); 291 // Der Stack für den OPEN-Befehl sieht wie folgt aus: 292 // Blocklänge 293 // Kanalnummer 294 // Dateiname 295 pLen->Gen(); 296 if( pChan ) 297 pChan->Gen(); 298 aFileName.Gen(); 299 aGen.Gen( _OPEN, nMode, nFlags ); 300 delete pLen; 301 delete pChan; 302 } 303 304 // NAME file AS file 305 306 void SbiParser::Name() 307 { 308 // #i92642: Special handling to allow name as symbol 309 if( Peek() == EQ ) 310 { 311 aGen.Statement(); 312 313 KeywordSymbolInfo aInfo; 314 aInfo.m_aKeywordSymbol = String( RTL_CONSTASCII_USTRINGPARAM( "name" ) ); 315 aInfo.m_eSbxDataType = GetType(); 316 aInfo.m_eTok = SYMBOL; 317 318 Symbol( &aInfo ); 319 return; 320 } 321 SbiExpression aExpr1( this ); 322 TestToken( AS ); 323 SbiExpression aExpr2( this ); 324 aExpr1.Gen(); 325 aExpr2.Gen(); 326 aGen.Gen( _RENAME ); 327 } 328 329 // CLOSE [n,...] 330 331 void SbiParser::Close() 332 { 333 Peek(); 334 if( IsEoln( eCurTok ) ) 335 aGen.Gen( _CLOSE, 0 ); 336 else 337 for( ;; ) 338 { 339 SbiExpression aExpr( this ); 340 while( Peek() == COMMA || Peek() == SEMICOLON ) 341 Next(); 342 aExpr.Gen(); 343 aGen.Gen( _CHANNEL ); 344 aGen.Gen( _CLOSE, 1 ); 345 346 if( IsEoln( Peek() ) ) 347 break; 348 } 349 } 350 351 /* vim: set noet sw=4 ts=4: */ 352