1 /*$Id: e_base.cc,v 26.137 2010/04/10 02:37:33 al Exp $ -*- C++ -*-
2  * Copyright (C) 2001 Albert Davis
3  * Author: Albert Davis <aldavis@gnu.org>
4  *
5  * This file is part of "Gnucap", the Gnu Circuit Analysis Package
6  *
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)
10  * any later version.
11  *
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.
16  *
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
20  * 02110-1301, USA.
21  *------------------------------------------------------------------
22  * Base class for "cards" in the circuit description file
23  */
24 //testing=script 2006.07.12
25 #include "u_sim_data.h"
26 #include "m_wave.h"
27 #include "u_prblst.h"
28 #include "u_xprobe.h"
29 #include "e_base.h"
30 /*--------------------------------------------------------------------------*/
fix_case(char c)31 static char fix_case(char c)
32 {
33   return ((OPT::case_insensitive) ? (static_cast<char>(tolower(c))) : (c));
34 }
35 /*--------------------------------------------------------------------------*/
tr_probe_num(const std::string &) const36 double CKT_BASE::tr_probe_num(const std::string&)const {return NOT_VALID;}
ac_probe_ext(const std::string &) const37 XPROBE CKT_BASE::ac_probe_ext(const std::string&)const {return XPROBE(NOT_VALID, mtNONE);}
38 /*--------------------------------------------------------------------------*/
39 SIM_DATA* CKT_BASE::_sim = NULL;
40 PROBE_LISTS* CKT_BASE::_probe_lists = NULL;
41 /*--------------------------------------------------------------------------*/
~CKT_BASE()42 CKT_BASE::~CKT_BASE()
43 {
44   trace1("~CKT_BASE", _probes);
45   if (_probes == 0) {
46   }else if (!_probe_lists) {untested();
47   }else if (!_sim) {untested();
48   }else{
49     _probe_lists->purge(this);
50   }
51   trace1("", _probes);
52   assert(_probes==0);
53 }
54 /*--------------------------------------------------------------------------*/
long_label() const55 const std::string CKT_BASE::long_label()const
56 {
57   //incomplete();
58   std::string buffer(short_label());
59   //for (const CKT_BASE* brh = owner(); exists(brh); brh = brh->owner()) {
60   //  buffer += '.' + brh->short_label();
61   //}
62   return buffer;
63 }
64 /*--------------------------------------------------------------------------*/
probe_num(const std::string & what) const65 double CKT_BASE::probe_num(const std::string& what)const
66 {
67   double x;
68   if (_sim->analysis_is_ac()) {
69     x = ac_probe_num(what);
70   }else{
71     x = tr_probe_num(what);
72   }
73   return (std::abs(x)>=1) ? x : floor(x/OPT::floor + .5) * OPT::floor;
74 }
75 /*--------------------------------------------------------------------------*/
ac_probe_num(const std::string & what) const76 double CKT_BASE::ac_probe_num(const std::string& what)const
77 {
78   size_t length = what.length();
79   mod_t modifier = mtNONE;
80   bool want_db = false;
81   char parameter[BUFLEN+1];
82   strcpy(parameter, what.c_str());
83 
84   if (length > 2  &&  Umatch(&parameter[length-2], "db ")) {
85     want_db = true;
86     length -= 2;
87   }
88   if (length > 1) { // selects modifier based on last letter of parameter
89     switch (fix_case(parameter[length-1])) {
90       case 'm': modifier = mtMAG;   length--;	break;
91       case 'p': modifier = mtPHASE; length--;	break;
92       case 'r': modifier = mtREAL;  length--;	break;
93       case 'i': modifier = mtIMAG;  length--;	break;
94       default:  modifier = mtNONE;		break;
95     }
96   }
97   parameter[length] = '\0'; // chop
98 
99   // "p" is "what" with the modifier chopped off.
100   // Try that first.
101   XPROBE xp = ac_probe_ext(parameter);
102 
103   // If we don't find it, try again with the full string.
104   if (!xp.exists()) {
105     xp = ac_probe_ext(what);
106     if (!xp.exists()) {
107       // Still didn't find anything.  Print "??".
108     }else{
109       untested();
110       // The second attempt worked.
111     }
112   }
113   return xp(modifier, want_db);
114 }
115 /*--------------------------------------------------------------------------*/
probe(const CKT_BASE * This,const std::string & what)116 /*static*/ double CKT_BASE::probe(const CKT_BASE *This, const std::string& what)
117 {
118   if (exists(This)) {
119     return This->probe_num(what);
120   }else{				/* return 0 if doesn't exist */
121     return 0.0;				/* happens when optimized models */
122   }					/* don't have all parts */
123 }
124 /*--------------------------------------------------------------------------*/
find_wave(const std::string & probe_name)125 /*static*/ WAVE* CKT_BASE::find_wave(const std::string& probe_name)
126 {
127   int ii = 0;
128   for (PROBELIST::const_iterator
129        p  = _probe_lists->store[_sim->_mode].begin();
130        p != _probe_lists->store[_sim->_mode].end();
131        ++p) {
132     if (wmatch(p->label(), probe_name)) {
133       return &(_sim->_waves[ii]);
134     }else{
135     }
136     ++ii;
137   }
138   return NULL;
139 }
140 /*--------------------------------------------------------------------------*/
141 /*--------------------------------------------------------------------------*/
142