testing
[gnucap-felix.git] / src / c_modify.cc
blob922b8bc72da91a12c3f54210dda726d1fe6c8971
1 /*$Id: c_modify.cc,v 1.3 2010-07-27 07:45:31 felix Exp $ -*- C++ -*-
2 * vim:ts=8:sw=2:et:
3 * Copyright (C) 2001 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.
23 //testing=script,sparse 2006.07.17
24 #include "e_elemnt.h"
25 #include "u_cardst.h"
26 #include "c_comand.h"
28 extern const int swp_type[];
29 extern const int swp_count[], swp_steps[];
30 extern const int swp_nest;
31 /*--------------------------------------------------------------------------*/
32 namespace {
33 /*--------------------------------------------------------------------------*/
34 enum WHATTODO {FAULT, MODIFY};
35 std::list<CARDSTASH> faultstack;
36 /*--------------------------------------------------------------------------*/
37 /* faultbranch: "fault" a single branch. (temporarily change a value)
38 * save the existing info in "faultlist", then patch
40 void faultbranch(CARD* brh, double value)
42 if (!brh->is_device()) {
43 untested();
44 error(bWARNING, brh->long_label() + ": not a device, can't fault:\n");
45 }else if (brh->subckt()) {
46 untested();
47 error(bWARNING, brh->long_label() + " has subckt, can't fault:\n");
48 }else{
49 faultstack.push_back(CARDSTASH(brh));
50 ELEMENT* e = prechecked_cast<ELEMENT*>(brh);
51 assert(e);
52 e->set_value(value, 0);
53 //BUG// messy way to do this, loses other attributes
56 /*--------------------------------------------------------------------------*/
57 /* sweep_fix: fix the value for sweep command.
58 * (find value by interpolation)
59 * if not sweeping, return "start" (the first arg).
61 double sweep_fix(CS& cmd, const CARD *brh)
63 double start = cmd.ctof();
64 double value = start;
65 if (swp_steps[swp_nest] != 0 && cmd.is_float()) {
66 untested();
67 double last = cmd.ctof();
68 double offset = static_cast<double>(swp_count[swp_nest])
69 / static_cast<double>(swp_steps[swp_nest]);
70 if (swp_type[swp_nest]=='L') {
71 untested();
72 if (start == 0.) {
73 untested();
74 throw Exception("log sweep can't pass zero");
75 value = 0;
76 }else{
77 untested();
78 value = start * pow( (last/start), offset );
80 }else{
81 untested();
82 value = start + (last-start) * offset;
84 IO::mstdout.setfloatwidth(7)
85 << swp_count[swp_nest]+1 << "> sweep " << brh->long_label()
86 << " =" << value << '\n';
88 return value;
90 /*--------------------------------------------------------------------------*/
91 void modify_fault(CS& cmd, WHATTODO command, CARD_LIST* scope)
93 trace0("modify_fault");
94 CKT_BASE::_sim->uninit();
95 while (cmd.is_alpha()) {
96 unsigned mark = cmd.cursor();
97 unsigned cmax = cmd.cursor();
98 CARD_LIST::fat_iterator ci(scope, scope->begin());
99 for (;;) {
100 cmd.reset(mark);
101 ci = findbranch(cmd, ci);
102 cmax = std::max(cmax, cmd.cursor());
103 if (ci.is_end()) {
104 break;
106 cmd.skip1b('=');
107 CARD* brh = *ci;
108 switch (command) {
109 case MODIFY:{
110 ELEMENT* e = prechecked_cast<ELEMENT*>(brh);
111 assert(e);
112 e->set_value(cmd.ctof(), 0);
113 //BUG// messy way to do this, loses other attributes
114 } break;
115 case FAULT:{
116 faultbranch(brh, sweep_fix(cmd,brh));
117 } break;
119 cmax = std::max(cmax, cmd.cursor());
120 ++ci;
122 cmd.reset(cmax);
123 if (mark == cmax) {
124 untested();
125 cmd.check(bWARNING, "what's this?");
126 cmd.skiparg();
130 /*--------------------------------------------------------------------------*/
131 class CMD_MODIFY : public CMD {
132 public:
133 void do_it(CS& cmd, CARD_LIST* Scope)
135 modify_fault(cmd, MODIFY, Scope);
137 } p1;
138 DISPATCHER<CMD>::INSTALL d1(&command_dispatcher, "modify|alter", &p1);
139 /*--------------------------------------------------------------------------*/
140 class CMD_FAULT : public CMD {
141 public:
142 void do_it(CS& cmd, CARD_LIST* Scope)
144 modify_fault(cmd, FAULT, Scope);
146 } p2;
147 DISPATCHER<CMD>::INSTALL d2(&command_dispatcher, "fault", &p2);
148 /*--------------------------------------------------------------------------*/
149 class CMD_RESTORE : public CMD {
150 public:
151 void do_it(CS&, CARD_LIST* Scope)
152 {untested();
153 command("unfault", Scope);
154 command("unmark", Scope);
156 } p3;
157 DISPATCHER<CMD>::INSTALL d3(&command_dispatcher, "restore", &p3);
158 /*--------------------------------------------------------------------------*/
159 class CMD_UNFAULT : public CMD {
160 public:
161 void do_it(CS&, CARD_LIST*)
163 while (!faultstack.empty()) {
164 faultstack.back().restore();
165 faultstack.pop_back();
167 trace0("CMD_UNFAULT");
168 _sim->uninit();
170 } p4;
171 DISPATCHER<CMD>::INSTALL d4(&command_dispatcher, "unfault", &p4);
172 /*--------------------------------------------------------------------------*/
174 /*--------------------------------------------------------------------------*/
175 /*--------------------------------------------------------------------------*/
176 // vim:ts=8:sw=2:noet: