viminfo
[gnucap-felix.git] / apps / c_modify.cc
blobd66bd47e9a891448bbbd4adde651af81fe20d041
1 /*$Id: c_modify.cc,v 26.137 2010/04/10 02:37:05 al Exp $ -*- 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)
10 * any later version.
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
20 * 02110-1301, USA.
22 //testing=script,sparse 2006.07.17
23 #include "globals.h"
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 CKT_BASE::_sim->uninit();
94 while (cmd.is_alpha()) {
95 unsigned mark = cmd.cursor();
96 unsigned cmax = cmd.cursor();
97 CARD_LIST::fat_iterator ci(scope, scope->begin());
98 for (;;) {
99 cmd.reset(mark);
100 ci = findbranch(cmd, ci);
101 cmax = std::max(cmax, cmd.cursor());
102 if (ci.is_end()) {
103 break;
105 cmd.skip1b('=');
106 CARD* brh = *ci;
107 switch (command) {
108 case MODIFY:{
109 ELEMENT* e = prechecked_cast<ELEMENT*>(brh);
110 assert(e);
111 e->set_value(cmd.ctof(), 0);
112 //BUG// messy way to do this, loses other attributes
113 } break;
114 case FAULT:{
115 faultbranch(brh, sweep_fix(cmd,brh));
116 } break;
118 cmax = std::max(cmax, cmd.cursor());
119 ++ci;
121 cmd.reset(cmax);
122 if (mark == cmax) {
123 untested();
124 cmd.check(bWARNING, "what's this?");
125 cmd.skiparg();
129 /*--------------------------------------------------------------------------*/
130 class CMD_MODIFY : public CMD {
131 public:
132 void do_it(CS& cmd, CARD_LIST* Scope)
134 modify_fault(cmd, MODIFY, Scope);
136 } p1;
137 DISPATCHER<CMD>::INSTALL d1(&command_dispatcher, "modify|alter", &p1);
138 /*--------------------------------------------------------------------------*/
139 class CMD_FAULT : public CMD {
140 public:
141 void do_it(CS& cmd, CARD_LIST* Scope)
143 modify_fault(cmd, FAULT, Scope);
145 } p2;
146 DISPATCHER<CMD>::INSTALL d2(&command_dispatcher, "fault", &p2);
147 /*--------------------------------------------------------------------------*/
148 class CMD_RESTORE : public CMD {
149 public:
150 void do_it(CS&, CARD_LIST* Scope)
151 {untested();
152 command("unfault", Scope);
153 command("unmark", Scope);
155 } p3;
156 DISPATCHER<CMD>::INSTALL d3(&command_dispatcher, "restore", &p3);
157 /*--------------------------------------------------------------------------*/
158 class CMD_UNFAULT : public CMD {
159 public:
160 void do_it(CS&, CARD_LIST*)
162 while (!faultstack.empty()) {
163 faultstack.back().restore();
164 faultstack.pop_back();
166 _sim->uninit();
168 } p4;
169 DISPATCHER<CMD>::INSTALL d4(&command_dispatcher, "unfault", &p4);
170 /*--------------------------------------------------------------------------*/
172 /*--------------------------------------------------------------------------*/
173 /*--------------------------------------------------------------------------*/
174 // vim:ts=8:sw=2:noet: