bump to -rc12
[gnucap-felix.git] / lib / u_nodemap.cc
blobb33b58f76fd527236755ea0aec522aad2f3c22d3
1 /*$Id: u_nodemap.cc,v 1.1 2009-10-23 12:01:45 felix Exp $ -*- C++ -*-
2 * vim:ts=8:sw=2:et:
3 * Copyright (C) 2002 Albert Davis
4 * Author: Albert Davis <aldavis@gnu.org>
6 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3, or (at your option)
11 * any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 * 02110-1301, USA.
22 *------------------------------------------------------------------
23 * node name to number mapping -- for named nodes
25 //testing=script,complete 2006.07.14
26 #include "e_node.h"
27 #include "e_adp.h"
28 #include "u_nodemap.h"
29 /*--------------------------------------------------------------------------*/
30 NODE ground_node("0",0);
31 /*--------------------------------------------------------------------------*/
32 NODE_MAP::NODE_MAP()
33 : _node_map(), ckt(0), adp(0)
35 _node_map["0"] = &ground_node;
37 /*--------------------------------------------------------------------------*/
38 /* copy constructor: deep copy
39 * The std::map copy constructor does a shallow copy,
40 * then replace second with a deep copy.
42 NODE_MAP::NODE_MAP(const NODE_MAP& p)
43 : _node_map(p._node_map)
45 unreachable();
46 for (iterator i = _node_map.begin(); i != _node_map.end(); ++i) {
47 untested();
48 CKT_NODE* s=dynamic_cast<CKT_NODE*>(i->second);
50 if (i->first != "0" && s) {
51 untested();
52 assert(i->second);
53 i->second = (NODE_BASE*) new CKT_NODE(s);
54 }else{
55 untested();
59 /*--------------------------------------------------------------------------*/
60 NODE_MAP::~NODE_MAP()
62 trace0("NODE_MAP::~NODE_MAP");
63 for (iterator i = _node_map.begin(); i != _node_map.end(); ++i) {
64 if (i->first != "0") {
65 assert(i->second);
66 delete i->second;
70 /*--------------------------------------------------------------------------*/
71 //#ifdef DO_TRACE FIXME!
72 // slow/stupid, but used for sckt node naming.
73 // need map<unsigned, NODE_BASE*>;
74 NODE_BASE* NODE_MAP::operator[](unsigned x)const {
75 USE(x);
77 for (NODE_MAP::const_iterator ni = _node_map.begin(); ni != _node_map.end(); ++ni) {
78 NODE_BASE* n = (*ni).second;
79 USE(n);
80 string label = (*ni).first;
81 trace2("NODE_MAP::operator[]", x, label);
83 CKT_NODE* c = dynamic_cast<CKT_NODE*>(n);
84 if(c && c->user_number() == x){ return c; };
86 error(bDANGER, "cannot find %d\n", x);
87 assert(false);
88 return 0;
90 /*--------------------------------------------------------------------------*/
91 /* return a pointer to a node given a string
92 * returns NULL pointer if no match
94 NODE_BASE* NODE_MAP::operator[](std::string s)
96 const_iterator i = _node_map.find(s);
97 if (i != _node_map.end()) {
98 return i->second;
99 }else if (OPT::case_insensitive) {
100 notstd::to_lower(&s);
101 i = _node_map.find(s);
102 }else{
103 return NULL;
105 return (i != _node_map.end()) ? i->second : NULL;
107 /*--------------------------------------------------------------------------*/
108 /* return a pointer to a node given a string
109 * creates a new one if it isn't already there.
111 CKT_NODE* NODE_MAP::new_node(std::string s_in, const CARD_LIST* scope)
113 std::string::size_type dotplace = s_in.find_last_of(".");
114 string s = s_in;
116 trace1("new_node", s_in);
117 // allow leading dot only (stupid)
118 if(dotplace == std::string::npos || s_in.c_str()[0]=='.'){
119 }else{
120 error(bWARNING,"something wrong with dotplace" + s_in + "\n");
123 if (OPT::case_insensitive) {
124 notstd::to_lower(&s);
125 }else{
127 NODE_BASE* node = _node_map[s];
128 CKT_NODE* cnode=dynamic_cast<CKT_NODE*>(node);
130 if(node && !cnode){
131 incomplete(); // type/name collision
132 assert(false);
135 // increments how_many() when lookup fails (new s)
136 if (!node) {
137 node = new CKT_NODE(s, how_many(), scope);
138 //trace2("NODE_MAP::new_node", s, node->user_number());
139 // ^^^^ is really the map number of the new node
140 ckt++;
141 _node_map[s] = dynamic_cast<NODE_BASE*>(node);
143 trace2("NODE_MAP::new_node ", s, node->user_number());
144 assert(node);
145 return dynamic_cast<CKT_NODE*>(node);
147 /*--------------------------------------------------------------------------*/
148 ADP_NODE* NODE_MAP::new_adp_node(std::string s, const CARD_LIST* p)
150 std::string::size_type dotplace = s.find_last_of(".");
151 assert(dotplace == std::string::npos); USE(dotplace);
153 trace1("NODE_MAP::new_node ", s);
154 if (OPT::case_insensitive) {
155 notstd::to_lower(&s);
156 }else{
158 NODE_BASE* node = _node_map[s];
159 ADP_NODE* anode = dynamic_cast<ADP_NODE*>(node);
161 if (node && !anode){
162 error(bDANGER, "node exists and is not an adp node: %s\n", node->long_label().c_str());
163 assert(0);
166 // increments how_many() when lookup fails (new s)
167 if (!node) {
168 assert(!anode);
169 anode = new ADP_NODE( s, p);
170 assert(anode);
171 node = prechecked_cast<NODE_BASE*>(anode);
172 assert(node);
173 trace2("NODE_MAP::new_adp_node", anode->long_label(),
174 anode->m_());
175 // ^^^^ is really the map number of the new node
176 adp++;
177 _node_map[s] = node;
178 }else{ untested();
179 trace2("NODE_MAP::new_adp_node already there.", hp(anode), anode->short_label());
181 assert(_node_map[s]);
182 assert(anode);
183 return anode;
185 /*--------------------------------------------------------------------------*/
186 // vim:ts=8:sw=2:noet: