Avoid potential negative array index access to cached text.
[LibreOffice.git] / idl / source / cmptools / lex.cxx
blobe8fd0280d3935d6ccc300f1cc4f936719bec516b
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <memory>
21 #include <hash.hxx>
22 #include <lex.hxx>
23 #include <globals.hxx>
24 #include <rtl/strbuf.hxx>
25 #include<rtl/character.hxx>
27 OString SvToken::GetTokenAsString() const
29 OString aStr;
30 switch( nType )
32 case SVTOKENTYPE::Empty:
33 break;
34 case SVTOKENTYPE::Comment:
35 aStr = aString;
36 break;
37 case SVTOKENTYPE::Integer:
38 aStr = OString::number(nLong);
39 break;
40 case SVTOKENTYPE::String:
41 aStr = aString;
42 break;
43 case SVTOKENTYPE::Bool:
44 aStr = bBool ? "TRUE" : "FALSE";
45 break;
46 case SVTOKENTYPE::Identifier:
47 aStr = aString;
48 break;
49 case SVTOKENTYPE::Char:
50 aStr = OString(cChar);
51 break;
52 case SVTOKENTYPE::EndOfFile:
53 case SVTOKENTYPE::HashId:
54 break;
57 return aStr;
60 SvToken & SvToken::operator = ( const SvToken & rObj )
62 if( this != &rObj )
64 nLine = rObj.nLine;
65 nColumn = rObj.nColumn;
66 nType = rObj.nType;
67 aString = rObj.aString;
68 nLong = rObj.nLong;
70 return *this;
73 void SvTokenStream::InitCtor()
75 aStrTrue = "TRUE"_ostr;
76 aStrFalse = "FALSE"_ostr;
77 nLine = nColumn = 0;
78 nBufPos = 0;
79 nMaxPos = 0;
80 c = GetNextChar();
81 FillTokenList();
84 SvTokenStream::SvTokenStream( const OUString & rFileName )
85 : pInStream( new SvFileStream( rFileName, StreamMode::STD_READ ) )
86 , aFileName( rFileName )
88 InitCtor();
91 SvTokenStream::~SvTokenStream()
95 void SvTokenStream::FillTokenList()
97 SvToken * pToken = new SvToken();
98 aTokList.push_back(std::unique_ptr<SvToken>(pToken));
101 if( !MakeToken( *pToken ) )
103 if (!aTokList.empty())
105 *pToken = SvToken();
106 std::vector<std::unique_ptr<SvToken> >::const_iterator it = aTokList.begin();
108 pToken->SetLine((*it)->GetLine());
109 pToken->SetColumn((*it)->GetColumn());
111 break;
113 else if( pToken->IsComment() )
114 *pToken = SvToken();
115 else if( pToken->IsEof() )
116 break;
117 else
119 pToken = new SvToken();
120 aTokList.push_back(std::unique_ptr<SvToken>(pToken));
123 while( !pToken->IsEof() );
124 pCurToken = aTokList.begin();
127 char SvTokenStream::GetNextChar()
129 char nChar;
130 while (aBufStr.getLength() <= nBufPos)
132 if (pInStream->ReadLine(aBufStr))
134 nLine++;
135 nColumn = 0;
136 nBufPos = 0;
138 else
140 aBufStr.clear();
141 nColumn = 0;
142 nBufPos = 0;
143 return '\0';
146 nChar = aBufStr[nBufPos++];
147 nColumn += nChar == '\t' ? nTabSize : 1;
148 return nChar;
151 sal_uInt64 SvTokenStream::GetNumber()
153 sal_uInt64 l = 0;
154 short nLog = 10;
156 if( '0' == c )
158 c = GetFastNextChar();
159 if( 'x' == c )
161 nLog = 16;
162 c = GetFastNextChar();
166 if( nLog == 16 )
168 while( rtl::isAsciiHexDigit( static_cast<unsigned char>(c) ) )
170 if( rtl::isAsciiDigit( static_cast<unsigned char>(c) ) )
171 l = l * nLog + (c - '0');
172 else
173 l = l * nLog
174 + (rtl::toAsciiUpperCase( static_cast<unsigned char>(c) )
175 - 'A' + 10 );
176 c = GetFastNextChar();
179 else
181 while( rtl::isAsciiDigit( static_cast<unsigned char>(c) ) || 'x' == c )
183 l = l * nLog + (c - '0');
184 c = GetFastNextChar();
188 return l;
191 bool SvTokenStream::MakeToken( SvToken & rToken )
195 if( 0 == c )
196 c = GetNextChar();
197 // skip whitespace
198 while( rtl::isAsciiWhiteSpace( static_cast<unsigned char>(c) )
199 || 26 == c )
201 c = GetFastNextChar();
202 nColumn += c == '\t' ? nTabSize : 1;
205 while( 0 == c && !IsEof() && ( ERRCODE_NONE == pInStream->GetError() ) );
207 sal_uInt64 nLastLine = nLine;
208 sal_uInt64 nLastColumn = nColumn;
209 // comment
210 if( '/' == c )
212 // time optimization, no comments
213 char c1 = c;
214 c = GetFastNextChar();
215 if( '/' == c )
217 while( '\0' != c )
219 c = GetFastNextChar();
221 c = GetNextChar();
222 rToken.nType = SVTOKENTYPE::Comment;
224 else if( '*' == c )
226 c = GetFastNextChar();
229 while( '*' != c )
231 if( '\0' == c )
233 c = GetNextChar();
234 if( IsEof() )
235 return false;
237 else
238 c = GetFastNextChar();
240 c = GetFastNextChar();
242 while( '/' != c && !IsEof() && ( ERRCODE_NONE == pInStream->GetError() ) );
243 if( IsEof() || ( ERRCODE_NONE != pInStream->GetError() ) )
244 return false;
245 c = GetNextChar();
246 rToken.nType = SVTOKENTYPE::Comment;
247 CalcColumn();
249 else
251 rToken.nType = SVTOKENTYPE::Char;
252 rToken.cChar = c1;
255 else if( c == '"' )
257 OStringBuffer aStr(128);
258 bool bDone = false;
259 while( !bDone && !IsEof() && c )
261 c = GetFastNextChar();
262 if( '\0' == c )
264 // read strings beyond end of line
265 aStr.append('\n');
266 c = GetNextChar();
267 if( IsEof() )
268 return false;
270 if( c == '"' )
272 c = GetFastNextChar();
273 bDone = true;
275 else
276 aStr.append(c);
278 if( IsEof() || ( ERRCODE_NONE != pInStream->GetError() ) )
279 return false;
280 rToken.nType = SVTOKENTYPE::String;
281 rToken.aString = aStr.makeStringAndClear();
283 else if( rtl::isAsciiDigit( static_cast<unsigned char>(c) ) )
285 rToken.nType = SVTOKENTYPE::Integer;
286 rToken.nLong = GetNumber();
289 else if( rtl::isAsciiAlpha (static_cast<unsigned char>(c)) || (c == '_') )
291 OStringBuffer aBuf(64);
292 while( rtl::isAsciiAlphanumeric( static_cast<unsigned char>(c) )
293 || c == '_' || c == ':')
295 aBuf.append(c);
296 c = GetFastNextChar();
298 OString aStr = aBuf.makeStringAndClear();
299 if( aStr.equalsIgnoreAsciiCase( aStrTrue ) )
301 rToken.nType = SVTOKENTYPE::Bool;
302 rToken.bBool = true;
304 else if( aStr.equalsIgnoreAsciiCase( aStrFalse ) )
306 rToken.nType = SVTOKENTYPE::Bool;
307 rToken.bBool = false;
309 else
311 sal_uInt32 nHashId;
312 if( GetIdlApp().pHashTable->Test( aStr, &nHashId ) )
313 rToken.SetHash( GetIdlApp().pHashTable->Get( nHashId ) );
314 else
316 rToken.nType = SVTOKENTYPE::Identifier;
317 rToken.aString = aStr;
321 else if( IsEof() )
323 rToken.nType = SVTOKENTYPE::EndOfFile;
325 else
327 rToken.nType = SVTOKENTYPE::Char;
328 rToken.cChar = c;
329 c = GetFastNextChar();
331 rToken.SetLine( nLastLine );
332 rToken.SetColumn( nLastColumn );
333 return pInStream->GetError() == ERRCODE_NONE;
336 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */