diff options
Diffstat (limited to 'idl/source/cmptools')
-rw-r--r-- | idl/source/cmptools/hash.cxx | 70 | ||||
-rw-r--r-- | idl/source/cmptools/lex.cxx | 336 |
2 files changed, 406 insertions, 0 deletions
diff --git a/idl/source/cmptools/hash.cxx b/idl/source/cmptools/hash.cxx new file mode 100644 index 000000000..ef11b489e --- /dev/null +++ b/idl/source/cmptools/hash.cxx @@ -0,0 +1,70 @@ +/* -*- 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 . + */ + + +// C and C++ includes +#include <stdlib.h> + +// program-sensitive includes +#include <hash.hxx> + +#include <rtl/character.hxx> + +SvStringHashEntry * SvStringHashTable::Insert( const OString& rElement, sal_uInt32 * pInsertPos ) +{ + auto it = maString2IntMap.find(rElement); + if (it != maString2IntMap.end()) { + *pInsertPos = it->second; + return maInt2EntryMap[*pInsertPos].get(); + } + maString2IntMap[rElement] = mnNextId; + maInt2EntryMap[mnNextId] = std::make_unique<SvStringHashEntry>(rElement); + *pInsertPos = mnNextId; + mnNextId++; + return maInt2EntryMap[*pInsertPos].get(); +} + +bool SvStringHashTable::Test( const OString& rElement, sal_uInt32 * pInsertPos ) +{ + auto it = maString2IntMap.find(rElement); + if (it != maString2IntMap.end()) { + *pInsertPos = it->second; + return true; + } + return false; +} + +SvStringHashEntry * SvStringHashTable::Get( sal_uInt32 nInsertPos ) const +{ + auto it = maInt2EntryMap.find(nInsertPos); + return it->second.get(); +} + +OString SvStringHashTable::GetNearString( const OString& rName ) const +{ + for( auto const & rPair : maInt2EntryMap ) + { + SvStringHashEntry * pE = rPair.second.get(); + if( pE->GetName().equalsIgnoreAsciiCase( rName ) && pE->GetName() != rName ) + return pE->GetName(); + } + return OString(); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/idl/source/cmptools/lex.cxx b/idl/source/cmptools/lex.cxx new file mode 100644 index 000000000..eb9ad1170 --- /dev/null +++ b/idl/source/cmptools/lex.cxx @@ -0,0 +1,336 @@ +/* -*- 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 = OString("TRUE"); + aStrFalse = OString("FALSE"); + 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: */ |