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