/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include <memory>
#include <hash.hxx>
#include <lex.hxx>
#include <globals.hxx>
#include <rtl/strbuf.hxx>
#include<rtl/character.hxx>
OString SvToken::GetTokenAsString() const
{
OString aStr;
switch( nType )
{
case SVTOKENTYPE::Empty:
break;
case SVTOKENTYPE::Comment:
aStr = aString;
break;
case SVTOKENTYPE::Integer:
aStr = OString::number(nLong);
break;
case SVTOKENTYPE::String:
aStr = aString;
break;
case SVTOKENTYPE::Bool:
aStr = bBool ? "TRUE" : "FALSE";
break;
case SVTOKENTYPE::Identifier:
aStr = aString;
break;
case SVTOKENTYPE::Char:
aStr = OString(cChar);
break;
case SVTOKENTYPE::EndOfFile:
case SVTOKENTYPE::HashId:
break;
}
return aStr;
}
SvToken & SvToken::operator = ( const SvToken & rObj )
{
if( this != &rObj )
{
nLine = rObj.nLine;
nColumn = rObj.nColumn;
nType = rObj.nType;
aString = rObj.aString;
nLong = rObj.nLong;
}
return *this;
}
void SvTokenStream::InitCtor()
{
aStrTrue = "TRUE"_ostr;
aStrFalse = "FALSE"_ostr;
nLine = nColumn = 0;
nBufPos = 0;
nMaxPos = 0;
c = GetNextChar();
FillTokenList();
}
SvTokenStream::SvTokenStream( const OUString & rFileName )
: pInStream( new SvFileStream( rFileName, StreamMode::STD_READ ) )
, aFileName( rFileName )
{
InitCtor();
}
SvTokenStream::~SvTokenStream()
{
}
void SvTokenStream::FillTokenList()
{
SvToken * pToken = new SvToken();
aTokList.push_back(std::unique_ptr<SvToken>(pToken));
do
{
if( !MakeToken( *pToken ) )
{
if (!aTokList.empty())
{
*pToken = SvToken();
std::vector<std::unique_ptr<SvToken> >::const_iterator it = aTokList.begin();
pToken->SetLine((*it)->GetLine());
pToken->SetColumn((*it)->GetColumn());
}
break;
}
else if( pToken->IsComment() )
*pToken = SvToken();
else if( pToken->IsEof() )
break;
else
{
pToken = new SvToken();
aTokList.push_back(std::unique_ptr<SvToken>(pToken));
}
}
while( !pToken->IsEof() );
pCurToken = aTokList.begin();
}
char SvTokenStream::GetNextChar()
{
char nChar;
while (aBufStr.getLength() <= nBufPos)
{
if (pInStream->ReadLine(aBufStr))
{
nLine++;
nColumn = 0;
nBufPos = 0;
}
else
{
aBufStr.clear();
nColumn = 0;
nBufPos = 0;
return '\0';
}
}
nChar = aBufStr[nBufPos++];
nColumn += nChar == '\t' ? nTabSize : 1;
return nChar;
}
sal_uInt64 SvTokenStream::GetNumber()
{
sal_uInt64 l = 0;
short nLog = 10;
if( '0' == c )
{
c = GetFastNextChar();
if( 'x' == c )
{
nLog = 16;
c = GetFastNextChar();
}
}
if( nLog == 16 )
{
while( rtl::isAsciiHexDigit( static_cast<unsigned char>(c) ) )
{
if( rtl::isAsciiDigit( static_cast<unsigned char>(c) ) )
l = l * nLog + (c - '0');
else
l = l * nLog
+ (rtl::toAsciiUpperCase( static_cast<unsigned char>(c) )
- 'A' + 10 );
c = GetFastNextChar();
}
}
else
{
while( rtl::isAsciiDigit( static_cast<unsigned char>(c) ) || 'x' == c )
{
l = l * nLog + (c - '0');
c = GetFastNextChar();
}
}
return l;
}
bool SvTokenStream::MakeToken( SvToken & rToken )
{
do
{
if( 0 == c )
c = GetNextChar();
// skip whitespace
while( rtl::isAsciiWhiteSpace( static_cast<unsigned char>(c) )
|| 26 == c )
{
c = GetFastNextChar();
nColumn += c == '\t' ? nTabSize : 1;
}
}
while( 0 == c && !IsEof() && ( ERRCODE_NONE == pInStream->GetError() ) );
sal_uInt64 nLastLine = nLine;
sal_uInt64 nLastColumn = nColumn;
// comment
if( '/' == c )
{
// time optimization, no comments
char c1 = c;
c = GetFastNextChar();
if( '/' == c )
{
while( '\0' != c )
{
c = GetFastNextChar();
}
c = GetNextChar();
rToken.nType = SVTOKENTYPE::Comment;
}
else if( '*' == c )
{
c = GetFastNextChar();
do
{
while( '*' != c )
{
if( '\0' == c )
{
c = GetNextChar();
if( IsEof() )
return false;
}
else
c = GetFastNextChar();
}
c = GetFastNextChar();
}
while( '/' != c && !IsEof() && ( ERRCODE_NONE == pInStream->GetError() ) );
if( IsEof() || ( ERRCODE_NONE != pInStream->GetError() ) )
return false;
c = GetNextChar();
rToken.nType = SVTOKENTYPE::Comment;
CalcColumn();
}
else
{
rToken.nType = SVTOKENTYPE::Char;
rToken.cChar = c1;
}
}
else if( c == '"' )
{
OStringBuffer aStr(128);
bool bDone = false;
while( !bDone && !IsEof() && c )
{
c = GetFastNextChar();
if( '\0' == c )
{
// read strings beyond end of line
aStr.append('\n');
c = GetNextChar();
if( IsEof() )
return false;
}
if( c == '"' )
{
c = GetFastNextChar();
bDone = true;
}
else
aStr.append(c);
}
if( IsEof() || ( ERRCODE_NONE != pInStream->GetError() ) )
return false;
rToken.nType = SVTOKENTYPE::String;
rToken.aString = aStr.makeStringAndClear();
}
else if( rtl::isAsciiDigit( static_cast<unsigned char>(c) ) )
{
rToken.nType = SVTOKENTYPE::Integer;
rToken.nLong = GetNumber();
}
else if( rtl::isAsciiAlpha (static_cast<unsigned char>(c)) || (c == '_') )
{
OStringBuffer aBuf(64);
while( rtl::isAsciiAlphanumeric( static_cast<unsigned char>(c) )
|| c == '_' || c == ':')
{
aBuf.append(c);
c = GetFastNextChar();
}
OString aStr = aBuf.makeStringAndClear();
if( aStr.equalsIgnoreAsciiCase( aStrTrue ) )
{
rToken.nType = SVTOKENTYPE::Bool;
rToken.bBool = true;
}
else if( aStr.equalsIgnoreAsciiCase( aStrFalse ) )
{
rToken.nType = SVTOKENTYPE::Bool;
rToken.bBool = false;
}
else
{
sal_uInt32 nHashId;
if( GetIdlApp().pHashTable->Test( aStr, &nHashId ) )
rToken.SetHash( GetIdlApp().pHashTable->Get( nHashId ) );
else
{
rToken.nType = SVTOKENTYPE::Identifier;
rToken.aString = aStr;
}
}
}
else if( IsEof() )
{
rToken.nType = SVTOKENTYPE::EndOfFile;
}
else
{
rToken.nType = SVTOKENTYPE::Char;
rToken.cChar = c;
c = GetFastNextChar();
}
rToken.SetLine( nLastLine );
rToken.SetColumn( nLastColumn );
return pInStream->GetError() == ERRCODE_NONE;
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
↑ V530 The return value of function 'append' is required to be utilized.
↑ V530 The return value of function 'append' is required to be utilized.
↑ V530 The return value of function 'append' is required to be utilized.
↑ V1037 Two or more case-branches perform the same actions. Check lines: 35, 41, 47