1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "ExternalViewLogger.hxx"
22 #include <boost/assert.hpp>
26 #define SNPRINTF(buffer, size, format, args) _snprintf(buffer, size, format, args)
28 #define SNPRINTF(buffer, size, format, args) snprintf(buffer, size, format, args)
36 NodeDescription::NodeDescription(const string
& parent
, const string
& refersTo
, const string
& value
, bool inUse
) :
37 mParentNodeId(parent
),
38 mRefersToNodeId(refersTo
),
43 ExternalViewLoggerImpl::ExternalViewLoggerImpl(const string
& fileName
) :
45 mFile(fileName
.c_str())
48 throw "Cannot open file";
51 string
ExternalViewLoggerImpl::getNewStyleName()
55 SNPRINTF(buff
, sizeof(buff
), "Style_%d", i
++);
59 void ExternalViewLoggerImpl::beginTree()
61 mParentNodeStack
.push("");
64 void ExternalViewLoggerImpl::dumpNodeContainer(const std::string
& fileName
)
66 std::ofstream
file(fileName
.c_str());
67 NodeContainer_t::iterator iter
= mNodeContainer
.begin();
68 NodeContainer_t::iterator iter_end
= mNodeContainer
.end();
69 for (; iter
!= iter_end
; ++iter
)
71 file
<< iter
->first
<< string(" ") << iter
->second
->mParentNodeId
<< string(" ") << iter
->second
->mRefersToNodeId
<< string(" ") << iter
->second
->mNodeValue
<< endl
;
75 void ExternalViewLoggerImpl::endTree()
77 mFile
<< "digraph {" << endl
;
78 mFile
<< "Root [shape=box, color=grey];" << endl
;
80 while (!mParentNodeStack
.empty())
81 mParentNodeStack
.pop();
83 mParentNodeStack
.push("Root");
85 NodeContainer_t::iterator iter
= mNodeContainer
.begin();
86 NodeContainer_t::iterator iter_end
= mNodeContainer
.end();
87 for (; iter
!= iter_end
; ++iter
)
89 if (isUnreferencedLeaf(iter
->first
))
91 string newStyleName
= getNewStyleName();
92 mFile
<< newStyleName
<< " [shape=box];" << endl
;
93 mFile
<< mParentNodeStack
.top() << " -> " << newStyleName
<< endl
;
94 mParentNodeStack
.push(newStyleName
);
95 dumpTree(iter
->first
);
96 mParentNodeStack
.pop();
100 mFile
<< "}" << endl
;
103 void ExternalViewLoggerImpl::beginNode(const std::string
& nodeId
, const std::string
& value
, const std::string
& refersToNodeId
, bool inUse
)
105 mNodeContainer
.insert(
106 NodeContainer_t::value_type(nodeId
,
107 NodeDescription::Pointer_t(new NodeDescription(mParentNodeStack
.top(), refersToNodeId
, value
, inUse
))));
108 mParentNodeStack
.push(nodeId
);
111 void ExternalViewLoggerImpl::endNode(const std::string
& nodeId
)
113 mParentNodeStack
.pop();
116 bool ExternalViewLoggerImpl::isLeaf(const std::string
& nodeId
)
120 NodeContainer_t::const_iterator iter
= mNodeContainer
.begin();
121 NodeContainer_t::const_iterator iter_end
= mNodeContainer
.end();
122 for (; iter
!= iter_end
; ++iter
)
124 if (iter
->second
->mParentNodeId
== nodeId
)
133 bool ExternalViewLoggerImpl::isUnreferencedLeaf(const string
& nodeId
)
135 return isLeaf(nodeId
) && !isReferenced(nodeId
);
138 bool ExternalViewLoggerImpl::isReferenced(const string
& nodeId
)
140 bool isReferenced
= false;
142 NodeContainer_t::const_iterator iter
= mNodeContainer
.begin();
143 NodeContainer_t::const_iterator iter_end
= mNodeContainer
.end();
144 for (; iter
!= iter_end
; ++iter
)
146 if (iter
->second
->mRefersToNodeId
== nodeId
)
155 bool ExternalViewLoggerImpl::isReferingToOtherNode(const string
& nodeId
)
157 NodeContainer_t::const_iterator iter
= mNodeContainer
.find(nodeId
);
158 BOOST_ASSERT(iter
!= mNodeContainer
.end());
159 return !iter
->second
->mRefersToNodeId
.empty();
162 bool ExternalViewLoggerImpl::hasParent(const string
& nodeId
)
164 NodeContainer_t::const_iterator iter
= mNodeContainer
.find(nodeId
);
165 BOOST_ASSERT(iter
!= mNodeContainer
.end());
166 return iter
->second
->mParentNodeId
!= "Root" && iter
->second
->mParentNodeId
!= "";
169 string
ExternalViewLoggerImpl::getValue(const string
& nodeId
)
171 return mNodeContainer
.find(nodeId
)->second
->mNodeValue
;
174 void ExternalViewLoggerImpl::dumpTree(const string
& nodeId
)
176 if (nodeId
!= "Root")
178 mFile
<< nodeId
<< " [label=\"(" << getValue(nodeId
) << ")\",shape=box];" << endl
;
179 mFile
<< mParentNodeStack
.top() << " -> " << nodeId
<< ";" << endl
;
180 if (isReferingToOtherNode(nodeId
))
182 mParentNodeStack
.push(nodeId
);
183 dumpTree(mNodeContainer
.find(nodeId
)->second
->mRefersToNodeId
);
184 mParentNodeStack
.pop();
188 if (hasParent(nodeId
))
189 dumpTree(mNodeContainer
.find(nodeId
)->second
->mParentNodeId
);
194 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */