1 /*$Id: e_base.cc 2015/02/05 al $ -*- C++ -*-
2 * Copyright (C) 2001 Albert Davis
3 * Author: Albert Davis <aldavis@gnu.org>
5 * This file is part of "Gnucap", the Gnu Circuit Analysis Package
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3, or (at your option)
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21 *------------------------------------------------------------------
22 * Base class for "cards" in the circuit description file
24 //testing=script 2014.07.04
26 #include "u_sim_data.h"
33 /*--------------------------------------------------------------------------*/
34 static char fix_case(char c
)
36 return ((OPT::case_insensitive
) ? (static_cast<char>(tolower(c
))) : (c
));
38 /*--------------------------------------------------------------------------*/
39 double CKT_BASE::tr_probe_num(const std::string
&)const {return NOT_VALID
;}
40 double CKT_BASE::tt_probe_num(const std::string
&)const {return NOT_VALID
;}
41 XPROBE
CKT_BASE::ac_probe_ext(const std::string
&)const {return XPROBE(NOT_VALID
, mtNONE
);}
42 XPROBE
CKT_BASE::sens_probe_ext(const std::string
&)const {
43 trace1("CKT_BASE::sens_probe_ext", typeid(*this).name());
44 return XPROBE(NOT_VALID
, mtNONE
);
46 /*--------------------------------------------------------------------------*/
47 SIM_DATA
* CKT_BASE::_sim
= NULL
;
48 PROBE_LISTS
* CKT_BASE::_probe_lists
= NULL
;
49 /*--------------------------------------------------------------------------*/
50 double CKT_BASE::tt_behaviour
= 0;
51 double CKT_BASE::tr_behaviour_del
= 0;
52 double CKT_BASE::tr_behaviour_rel
= 0;
53 double CKT_BASE::tt_behaviour_del
= 0;
54 double CKT_BASE::tt_behaviour_rel
= 0;
55 /*--------------------------------------------------------------------------*/
58 trace1("~CKT_BASE", _probes
);
60 }else if (!_probe_lists
) {untested();
61 }else if (!_sim
) {untested();
63 _probe_lists
->purge(this);
66 /*--------------------------------------------------------------------------*/
67 const std::string
CKT_BASE::long_label()const
69 trace0("CKT_BASE::long_label");
71 std::string
buffer(short_label());
72 //for (const CKT_BASE* brh = owner(); exists(brh); brh = brh->owner()) {untested();
73 // buffer += '.' + brh->short_label();
77 /*--------------------------------------------------------------------------*/
78 bool CKT_BASE::help(CS
& Cmd
, OMSTREAM
& Out
)const
80 if (help_text() != "") {
81 unsigned here
= Cmd
.cursor();
84 CS
ht(CS::_STRING
, help_text());
86 Out
<< ht
.get_to("@@");
87 }else if (ht
.scan("@@" + keyword
+ ' ')) {
88 Out
<< ht
.get_to("@@");
89 }else if (keyword
== "?") {
90 while (ht
.scan("@@")) {
91 Out
<< " " << ht
.get_to("\n") << '\n';
94 Cmd
.warn(bWARNING
, here
, "no help on subtopic " + Cmd
.substr(here
));
101 /*--------------------------------------------------------------------------*/
102 double CKT_BASE::probe_num(const std::string
& what
)const
104 trace2("CKT_BASE::probe_num", what
, long_label());
106 if (_sim
->analysis_is_tt()){
107 x
= tt_probe_num(what
) ;
108 }else if (_sim
->analysis_is_ac()) {
109 x
= ac_probe_num(what
);
110 }else if (_sim
->analysis_is_sens()) {
111 x
= ac_probe_num(what
);
113 x
= tr_probe_num(what
);
116 return x
; // (std::abs(x)>=1) ? x : floor(x/OPT::floor + .5) * OPT::floor;
118 /*--------------------------------------------------------------------------*/
119 double CKT_BASE::ac_probe_num(const std::string
& what
)const
121 trace1("CKT_BASE::ac_probe_num", what
);
122 size_t length
= what
.length();
123 mod_t modifier
= mtNONE
;
124 bool want_db
= false;
125 char parameter
[BUFLEN
+1];
126 strcpy(parameter
, what
.c_str());
128 if (length
> 2 && Umatch(¶meter
[length
-2], "db ")) {
132 if (length
> 1) { // selects modifier based on last letter of parameter
133 switch (fix_case(parameter
[length
-1])) {
134 case 'm': modifier
= mtMAG
; length
--; break;
135 case 'p': modifier
= mtPHASE
; length
--; break;
136 case 'r': modifier
= mtREAL
; length
--; break;
137 case 'i': modifier
= mtIMAG
; length
--; break;
138 default: modifier
= mtNONE
; break;
141 parameter
[length
] = '\0'; // chop
143 // "p" is "what" with the modifier chopped off.
146 if (_sim
->analysis_is_ac()) {
147 xp
= XPROBE(ac_probe_ext(parameter
));
149 xp
= XPROBE(sens_probe_ext(parameter
));
152 // If we don't find it, try again with the full string.
154 xp
= ac_probe_ext(what
);
156 // Still didn't find anything. Print "??".
158 // The second attempt worked.
161 return xp(modifier
, want_db
);
163 /*--------------------------------------------------------------------------*/
164 /*static*/ double CKT_BASE::probe(const CKT_BASE
*This
, const std::string
& what
)
167 return This
->probe_num(what
);
168 }else{ /* return 0 if doesn't exist */
169 return 0.0; /* happens when optimized models */
170 } /* don't have all parts */
172 /*--------------------------------------------------------------------------*/
173 /*static*/ WAVE_LIST
& CKT_BASE::create_waves(const std::string
& coll_name
)
176 _sim
->_label
= coll_name
;
177 return _sim
->_waves
[coll_name
];
179 /*--------------------------------------------------------------------------*/
180 /*static*/ WAVE_LIST
* CKT_BASE::find_waves(const std::string
& coll_name
)
182 std::map
<std::string
,WAVE_LIST
>::iterator i
;
183 string n
= coll_name
;
184 if (0 && OPT::case_insensitive
) { untested();
185 notstd::to_upper(&n
);
188 i
= _sim
->_waves
.find(n
);
189 if(i
!=_sim
->_waves
.end()){
195 /*--------------------------------------------------------------------------*/
196 /*static*/ WAVE
& CKT_BASE::create_wave(const std::string
& wave_name
, std::string coll_name
)
199 if(coll_name
==""){untested();
200 coll_name
= _sim
->_label
;
203 std::string n
= wave_name
;
204 if (OPT::case_insensitive
) {
205 notstd::to_upper(&n
);
208 return _sim
->_waves
[coll_name
][n
];
210 /*--------------------------------------------------------------------------*/
211 /*static*/ WAVE
* CKT_BASE::find_wave(const std::string
& probe_name
)
213 trace2("find_wave", probe_name
, _sim
->_label
);
214 std::map
<std::string
,WAVE
>* w
= &_sim
->_waves
[_sim
->_label
];
215 std::map
<std::string
,WAVE
>::iterator i
;
216 string n
= probe_name
;
217 if (OPT::case_insensitive
) {
218 notstd::to_upper(&n
);
222 if(i
!=_sim
->_waves
[_sim
->_label
].end()){
228 CS
cmd(CS::_STRING
, probe_name
);
229 prefix
= cmd
.ctos(":");
231 if(_sim
->_waves
.find(prefix
) == _sim
->_waves
.end()) {
237 suffix
= cmd
.ctos("");
238 if (OPT::case_insensitive
) {
239 notstd::to_upper(&suffix
);
242 trace0(("\"" + prefix
+ "\":\"" + suffix
+ "\"").c_str());
243 i
= _sim
->_waves
[prefix
].find(suffix
);
244 if(i
!=_sim
->_waves
[prefix
].end()){
250 /*--------------------------------------------------------------------------*/
251 bool CKT_BASE::operator!=(const std::string
& n
)const {return strcasecmp(_label
.c_str(),n
.c_str())!=0;}
252 /*--------------------------------------------------------------------------*/
253 /*--------------------------------------------------------------------------*/
254 // vim:ts=8:sw=2:noet: