/************************************************************** * * 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 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ #include "ExternalViewLogger.hxx" #include #include #include #ifdef WNT #define SNPRINTF(buffer, size, format, args) _snprintf(buffer, size, format, args) #else #define SNPRINTF(buffer, size, format, args) snprintf(buffer, size, format, args) #endif using namespace std; namespace util { NodeDescription::NodeDescription(const string& parent, const string& refersTo, const string& value, bool inUse) : mParentNodeId(parent), mRefersToNodeId(refersTo), mNodeValue(value), mInUse(inUse) {} ExternalViewLoggerImpl::ExternalViewLoggerImpl(const string& fileName) : mFileName(fileName), mFile(fileName.c_str()) { if (!mFile) throw "Cannot open file"; } string ExternalViewLoggerImpl::getNewStyleName() { static int i = 0; char buff[20]; SNPRINTF(buff, sizeof(buff), "Style_%d", i++); return string(buff); } void ExternalViewLoggerImpl::beginTree() { mParentNodeStack.push(""); } void ExternalViewLoggerImpl::dumpNodeContainer(const std::string& fileName) { std::ofstream file(fileName.c_str()); NodeContainer_t::iterator iter = mNodeContainer.begin(); NodeContainer_t::iterator iter_end = mNodeContainer.end(); for (; iter != iter_end; ++iter) { file << iter->first << string(" ") << iter->second->mParentNodeId << string(" ") << iter->second->mRefersToNodeId << string(" ") << iter->second->mNodeValue << endl; } } void ExternalViewLoggerImpl::endTree() { //dumpNodeContainer(mFileName + string(".dmp")); mFile << "digraph {" << endl; mFile << "Root [shape=box, color=grey];" << endl; while (!mParentNodeStack.empty()) mParentNodeStack.pop(); mParentNodeStack.push("Root"); NodeContainer_t::iterator iter = mNodeContainer.begin(); NodeContainer_t::iterator iter_end = mNodeContainer.end(); for (; iter != iter_end; ++iter) { if (isUnreferencedLeaf(iter->first)) { string newStyleName = getNewStyleName(); mFile << newStyleName << " [shape=box];" << endl; mFile << mParentNodeStack.top() << " -> " << newStyleName << endl; mParentNodeStack.push(newStyleName); dumpTree(iter->first); mParentNodeStack.pop(); } } mFile << "}" << endl; } void ExternalViewLoggerImpl::beginNode(const std::string& nodeId, const std::string& value, const std::string& refersToNodeId, bool inUse) { mNodeContainer.insert( NodeContainer_t::value_type(nodeId, NodeDescription::Pointer_t(new NodeDescription(mParentNodeStack.top(), refersToNodeId, value, inUse)))); mParentNodeStack.push(nodeId); } void ExternalViewLoggerImpl::endNode(const std::string& nodeId) { mParentNodeStack.pop(); } bool ExternalViewLoggerImpl::isLeaf(const std::string& nodeId) { bool isLeaf = true; NodeContainer_t::const_iterator iter = mNodeContainer.begin(); NodeContainer_t::const_iterator iter_end = mNodeContainer.end(); for (; iter != iter_end; ++iter) { if (iter->second->mParentNodeId == nodeId) { isLeaf = false; break; } } return isLeaf; } bool ExternalViewLoggerImpl::isUnreferencedLeaf(const string& nodeId) { return isLeaf(nodeId) && !isReferenced(nodeId); } bool ExternalViewLoggerImpl::isReferenced(const string& nodeId) { bool isReferenced = false; NodeContainer_t::const_iterator iter = mNodeContainer.begin(); NodeContainer_t::const_iterator iter_end = mNodeContainer.end(); for (; iter != iter_end; ++iter) { if (iter->second->mRefersToNodeId == nodeId) { isReferenced = true; break; } } return isReferenced; } bool ExternalViewLoggerImpl::isReferingToOtherNode(const string& nodeId) { NodeContainer_t::const_iterator iter = mNodeContainer.find(nodeId); BOOST_ASSERT(iter != mNodeContainer.end()); return !iter->second->mRefersToNodeId.empty(); } bool ExternalViewLoggerImpl::hasParent(const string& nodeId) { NodeContainer_t::const_iterator iter = mNodeContainer.find(nodeId); BOOST_ASSERT(iter != mNodeContainer.end()); return iter->second->mParentNodeId != "Root" && iter->second->mParentNodeId != ""; } string ExternalViewLoggerImpl::getValue(const string& nodeId) { return mNodeContainer.find(nodeId)->second->mNodeValue; } void ExternalViewLoggerImpl::dumpTree(const string& nodeId) { if (nodeId != "Root") { mFile << nodeId << " [label=\"(" << getValue(nodeId) << ")\",shape=box];" << endl; mFile << mParentNodeStack.top() << " -> " << nodeId << ";" << endl; if (isReferingToOtherNode(nodeId)) { mParentNodeStack.push(nodeId); dumpTree(mNodeContainer.find(nodeId)->second->mRefersToNodeId); mParentNodeStack.pop(); } } if (hasParent(nodeId)) dumpTree(mNodeContainer.find(nodeId)->second->mParentNodeId); } } // namespace util