diff options
author | Roberto Raggi <qtc-committer@nokia.com> | 2008-12-22 14:10:47 +0100 |
---|---|---|
committer | Roberto Raggi <qtc-committer@nokia.com> | 2008-12-22 14:10:47 +0100 |
commit | 0422bcbbd599cafe87735087804a434b78e353ff (patch) | |
tree | 51056c498b7909be18eb64058876c23226d3cfb3 /src/libs/cplusplus/PreprocessorEnvironment.cpp | |
parent | e325aa38d91c9d11b9645004e786924c49e2b325 (diff) | |
download | qt-creator-0422bcbbd599cafe87735087804a434b78e353ff.tar.gz |
Some more clean up in the preprocessor.
Diffstat (limited to 'src/libs/cplusplus/PreprocessorEnvironment.cpp')
-rw-r--r-- | src/libs/cplusplus/PreprocessorEnvironment.cpp | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/src/libs/cplusplus/PreprocessorEnvironment.cpp b/src/libs/cplusplus/PreprocessorEnvironment.cpp new file mode 100644 index 0000000000..693fe6160e --- /dev/null +++ b/src/libs/cplusplus/PreprocessorEnvironment.cpp @@ -0,0 +1,235 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception +** version 1.3, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ +/* + Copyright 2005 Roberto Raggi <roberto@kdevelop.org> + + Permission to use, copy, modify, distribute, and sell this software and its + documentation for any purpose is hereby granted without fee, provided that + the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation. + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + KDEVELOP TEAM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#include "PreprocessorEnvironment.h" +#include "Macro.h" +#include <cstring> + +using namespace CPlusPlus; + +Environment::Environment() + : currentLine(0), + hideNext(false), + _macros(0), + _allocated_macros(0), + _macro_count(-1), + _hash(0), + _hash_count(401) +{ +} + +Environment::~Environment() +{ + if (_macros) { + qDeleteAll(firstMacro(), lastMacro()); + free(_macros); + } + + if (_hash) + free(_hash); +} + +unsigned Environment::macroCount() const +{ + return _macro_count + 1; +} + +Macro *Environment::macroAt(unsigned index) const +{ + return _macros[index]; +} + +Macro *Environment::bind(const Macro &__macro) +{ + Q_ASSERT(! __macro.name().isEmpty()); + + Macro *m = new Macro (__macro); + m->_hashcode = hashCode(m->name()); + + if (++_macro_count == _allocated_macros) { + if (! _allocated_macros) + _allocated_macros = 401; + else + _allocated_macros <<= 1; + + _macros = (Macro **) realloc(_macros, sizeof(Macro *) * _allocated_macros); + } + + _macros[_macro_count] = m; + + if (! _hash || _macro_count > (_hash_count >> 1)) { + rehash(); + } else { + const unsigned h = m->_hashcode % _hash_count; + m->_next = _hash[h]; + _hash[h] = m; + } + + return m; +} + +Macro *Environment::remove(const QByteArray &name) +{ + Macro macro; + macro.setName(name); + macro.setHidden(true); + macro.setFileName(currentFile); + macro.setLine(currentLine); + return bind(macro); +} + +bool Environment::isBuiltinMacro(const QByteArray &s) const +{ + if (s.length() != 8) + return false; + + if (s[0] == '_') { + if (s[1] == '_') { + if (s[2] == 'D') { + if (s[3] == 'A') { + if (s[4] == 'T') { + if (s[5] == 'E') { + if (s[6] == '_') { + if (s[7] == '_') { + return true; + } + } + } + } + } + } + else if (s[2] == 'F') { + if (s[3] == 'I') { + if (s[4] == 'L') { + if (s[5] == 'E') { + if (s[6] == '_') { + if (s[7] == '_') { + return true; + } + } + } + } + } + } + else if (s[2] == 'L') { + if (s[3] == 'I') { + if (s[4] == 'N') { + if (s[5] == 'E') { + if (s[6] == '_') { + if (s[7] == '_') { + return true; + } + } + } + } + } + } + else if (s[2] == 'T') { + if (s[3] == 'I') { + if (s[4] == 'M') { + if (s[5] == 'E') { + if (s[6] == '_') { + if (s[7] == '_') { + return true; + } + } + } + } + } + } + } + } + return false; +} + +Macro *Environment::resolve(const QByteArray &name) const +{ + if (! _macros) + return 0; + + Macro *it = _hash[hashCode(name) % _hash_count]; + for (; it; it = it->_next) { + if (it->name() != name) + continue; + else if (it->isHidden()) + return 0; + else break; + } + return it; +} + +unsigned Environment::hashCode(const QByteArray &s) +{ + unsigned hash_value = 0; + + for (int i = 0; i < s.size (); ++i) + hash_value = (hash_value << 5) - hash_value + s.at (i); + + return hash_value; +} + +void Environment::rehash() +{ + if (_hash) { + free(_hash); + _hash_count <<= 1; + } + + _hash = (Macro **) calloc(_hash_count, sizeof(Macro *)); + + for (Macro **it = firstMacro(); it != lastMacro(); ++it) { + Macro *m= *it; + const unsigned h = m->_hashcode % _hash_count; + m->_next = _hash[h]; + _hash[h] = m; + } +} |