1 /*$Id: u_nodemap.cc,v 1.1 2009-10-23 12:01:45 felix Exp $ -*- C++ -*-
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)
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
22 *------------------------------------------------------------------
23 * node name to number mapping -- for named nodes
25 //testing=script,complete 2006.07.14
28 #include "u_nodemap.h"
29 /*--------------------------------------------------------------------------*/
30 NODE
ground_node("0",0);
31 /*--------------------------------------------------------------------------*/
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
)
46 for (iterator i
= _node_map
.begin(); i
!= _node_map
.end(); ++i
) {
48 CKT_NODE
* s
=dynamic_cast<CKT_NODE
*>(i
->second
);
50 if (i
->first
!= "0" && s
) {
53 i
->second
= (NODE_BASE
*) new CKT_NODE(s
);
59 /*--------------------------------------------------------------------------*/
62 trace0("NODE_MAP::~NODE_MAP");
63 for (iterator i
= _node_map
.begin(); i
!= _node_map
.end(); ++i
) {
64 if (i
->first
!= "0") {
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 {
77 for (NODE_MAP::const_iterator ni
= _node_map
.begin(); ni
!= _node_map
.end(); ++ni
) {
78 NODE_BASE
* n
= (*ni
).second
;
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
);
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()) {
99 }else if (OPT::case_insensitive
) {
100 notstd::to_lower(&s
);
101 i
= _node_map
.find(s
);
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(".");
116 trace1("new_node", s_in
);
117 // allow leading dot only (stupid)
118 if(dotplace
== std::string::npos
|| s_in
.c_str()[0]=='.'){
120 error(bWARNING
,"something wrong with dotplace" + s_in
+ "\n");
123 if (OPT::case_insensitive
) {
124 notstd::to_lower(&s
);
127 NODE_BASE
* node
= _node_map
[s
];
128 CKT_NODE
* cnode
=dynamic_cast<CKT_NODE
*>(node
);
131 incomplete(); // type/name collision
135 // increments how_many() when lookup fails (new s)
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
141 _node_map
[s
] = dynamic_cast<NODE_BASE
*>(node
);
143 trace2("NODE_MAP::new_node ", s
, node
->user_number());
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
);
158 NODE_BASE
* node
= _node_map
[s
];
159 ADP_NODE
* anode
= dynamic_cast<ADP_NODE
*>(node
);
162 error(bDANGER
, "node exists and is not an adp node: %s\n", node
->long_label().c_str());
166 // increments how_many() when lookup fails (new s)
169 anode
= new ADP_NODE( s
, p
);
171 node
= prechecked_cast
<NODE_BASE
*>(anode
);
173 trace2("NODE_MAP::new_adp_node", anode
->long_label(),
175 // ^^^^ is really the map number of the new node
179 trace2("NODE_MAP::new_adp_node already there.", hp(anode
), anode
->short_label());
181 assert(_node_map
[s
]);
185 /*--------------------------------------------------------------------------*/
186 // vim:ts=8:sw=2:noet: