mirror of
https://github.com/pocoproject/poco.git
synced 2025-10-27 19:10:20 +01:00
new trunk (base for 1.5)
windows build only
This commit is contained in:
268
CppParser/src/NameSpace.cpp
Normal file
268
CppParser/src/NameSpace.cpp
Normal file
@@ -0,0 +1,268 @@
|
||||
//
|
||||
// Namespace.cpp
|
||||
//
|
||||
// $Id: //poco/1.3/CppParser/src/NameSpace.cpp#3 $
|
||||
//
|
||||
// Library: CppParser
|
||||
// Package: SymbolTable
|
||||
// Module: Namespace
|
||||
//
|
||||
// Copyright (c) 2006, Applied Informatics Software Engineering GmbH.
|
||||
// and Contributors.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person or organization
|
||||
// obtaining a copy of the software and accompanying documentation covered by
|
||||
// this license (the "Software") to use, reproduce, display, distribute,
|
||||
// execute, and transmit the Software, and to prepare derivative works of the
|
||||
// Software, and to permit third-parties to whom the Software is furnished to
|
||||
// do so, all subject to the following:
|
||||
//
|
||||
// The copyright notices in the Software and this entire statement, including
|
||||
// the above license grant, this restriction and the following disclaimer,
|
||||
// must be included in all copies of the Software, in whole or in part, and
|
||||
// all derivative works of the Software, unless such copies or derivative
|
||||
// works are solely in the form of machine-executable object code generated by
|
||||
// a source language processor.
|
||||
//
|
||||
// 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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
||||
// SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
||||
// FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
||||
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
|
||||
#include "Poco/CppParser/NameSpace.h"
|
||||
#include "Poco/Exception.h"
|
||||
#include <sstream>
|
||||
#include <cstddef>
|
||||
|
||||
|
||||
using Poco::ExistsException;
|
||||
using Poco::NotFoundException;
|
||||
|
||||
|
||||
namespace Poco {
|
||||
namespace CppParser {
|
||||
|
||||
|
||||
NameSpace::NameSpace()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NameSpace::NameSpace(const std::string& name, NameSpace* pNameSpace):
|
||||
Symbol(name, pNameSpace)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
NameSpace::~NameSpace()
|
||||
{
|
||||
for (SymbolTable::iterator it = _symbols.begin(); it != _symbols.end(); ++it)
|
||||
{
|
||||
delete it->second;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::addSymbol(Symbol* pSymbol)
|
||||
{
|
||||
poco_check_ptr (pSymbol);
|
||||
|
||||
_symbols.insert(SymbolTable::value_type(pSymbol->name(), pSymbol));
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::importSymbol(const std::string& fullName)
|
||||
{
|
||||
std::string localName;
|
||||
std::string::size_type pos = fullName.find_last_of(':');
|
||||
if (pos != std::string::npos && pos < fullName.size() - 1)
|
||||
{
|
||||
localName.assign(fullName, pos + 1, fullName.size() - pos - 1);
|
||||
_importedSymbols[localName] = fullName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::importNameSpace(const std::string& nameSpace)
|
||||
{
|
||||
_importedNameSpaces.push_back(nameSpace);
|
||||
}
|
||||
|
||||
|
||||
NameSpace::Iterator NameSpace::begin() const
|
||||
{
|
||||
return _symbols.begin();
|
||||
}
|
||||
|
||||
|
||||
NameSpace::Iterator NameSpace::end() const
|
||||
{
|
||||
return _symbols.end();
|
||||
}
|
||||
|
||||
|
||||
Symbol* NameSpace::lookup(const std::string& name) const
|
||||
{
|
||||
std::set<const NameSpace*> alreadyVisited;
|
||||
return lookup(name, alreadyVisited);
|
||||
}
|
||||
|
||||
|
||||
Symbol* NameSpace::lookup(const std::string& name, std::set<const NameSpace*>& alreadyVisited) const
|
||||
{
|
||||
Symbol* pSymbol = 0;
|
||||
|
||||
if (name.empty())
|
||||
return pSymbol;
|
||||
|
||||
if (alreadyVisited.find(this) != alreadyVisited.end())
|
||||
return pSymbol;
|
||||
std::string head;
|
||||
std::string tail;
|
||||
splitName(name, head, tail);
|
||||
|
||||
alreadyVisited.insert(this);
|
||||
bool currentNSInserted = true;
|
||||
|
||||
|
||||
if (head.empty())
|
||||
{
|
||||
alreadyVisited.insert(this);
|
||||
return root()->lookup(tail, alreadyVisited);
|
||||
}
|
||||
SymbolTable::const_iterator it = _symbols.find(head);
|
||||
if (it != _symbols.end())
|
||||
{
|
||||
pSymbol = it->second;
|
||||
if (!tail.empty())
|
||||
{
|
||||
alreadyVisited.insert(this);
|
||||
NameSpace* pNS = dynamic_cast<NameSpace*>(pSymbol);
|
||||
if (pNS)
|
||||
pSymbol = static_cast<NameSpace*>(pSymbol)->lookup(tail, alreadyVisited);
|
||||
else
|
||||
pSymbol = 0;
|
||||
}
|
||||
}
|
||||
else if (tail.empty())
|
||||
{
|
||||
AliasMap::const_iterator itAlias = _importedSymbols.find(head);
|
||||
if (itAlias != _importedSymbols.end())
|
||||
pSymbol = lookup(itAlias->second, alreadyVisited);
|
||||
else
|
||||
{
|
||||
for (NameSpaceVec::const_iterator it = _importedNameSpaces.begin(); !pSymbol && it != _importedNameSpaces.end(); ++it)
|
||||
{
|
||||
Symbol* pNS = lookup(*it, alreadyVisited);
|
||||
if (pNS && pNS->kind() == Symbol::SYM_NAMESPACE)
|
||||
{
|
||||
pSymbol = static_cast<NameSpace*>(pNS)->lookup(name, alreadyVisited);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
NameSpace* pNS = nameSpace();
|
||||
if (!pSymbol && pNS && (alreadyVisited.find(pNS) == alreadyVisited.end()))
|
||||
{
|
||||
// if we have to go up, never push the NS!
|
||||
if (currentNSInserted)
|
||||
alreadyVisited.erase(this);
|
||||
pSymbol = nameSpace()->lookup(name, alreadyVisited);
|
||||
}
|
||||
return pSymbol;
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::nameSpaces(SymbolTable& table) const
|
||||
{
|
||||
extract(Symbol::SYM_NAMESPACE, table);
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::typeDefs(SymbolTable& table) const
|
||||
{
|
||||
extract(Symbol::SYM_TYPEDEF, table);
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::enums(SymbolTable& table) const
|
||||
{
|
||||
extract(Symbol::SYM_ENUM, table);
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::classes(SymbolTable& table) const
|
||||
{
|
||||
extract(Symbol::SYM_STRUCT, table);
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::functions(SymbolTable& table) const
|
||||
{
|
||||
extract(Symbol::SYM_FUNCTION, table);
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::variables(SymbolTable& table) const
|
||||
{
|
||||
extract(Symbol::SYM_VARIABLE, table);
|
||||
}
|
||||
|
||||
|
||||
Symbol::Kind NameSpace::kind() const
|
||||
{
|
||||
return Symbol::SYM_NAMESPACE;
|
||||
}
|
||||
|
||||
|
||||
std::string NameSpace::toString() const
|
||||
{
|
||||
std::ostringstream ostr;
|
||||
ostr << "namespace " << name() << "\n{\n";
|
||||
for (Iterator it = begin(); it != end(); ++it)
|
||||
{
|
||||
ostr << it->second->fullName() << "\n";
|
||||
ostr << it->second->toString() << "\n";
|
||||
}
|
||||
ostr << "}\n";
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::splitName(const std::string& name, std::string& head, std::string& tail)
|
||||
{
|
||||
std::string::size_type pos = name.find(':');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
head.assign(name, 0, pos);
|
||||
pos += 2;
|
||||
poco_assert (pos < name.length());
|
||||
tail.assign(name, pos, name.length() - pos);
|
||||
}
|
||||
else head = name;
|
||||
}
|
||||
|
||||
|
||||
NameSpace* NameSpace::root()
|
||||
{
|
||||
static NameSpace root;
|
||||
return &root;
|
||||
}
|
||||
|
||||
|
||||
void NameSpace::extract(Symbol::Kind kind, SymbolTable& table) const
|
||||
{
|
||||
for (SymbolTable::const_iterator it = _symbols.begin(); it != _symbols.end(); ++it)
|
||||
{
|
||||
if (it->second->kind() == kind)
|
||||
table.insert(*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} } // namespace Poco::CppParser
|
||||
Reference in New Issue
Block a user