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 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 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 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() 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 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 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 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 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 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