1 /*$Id: c_modify.cc,v 1.3 2010-07-27 07:45:31 felix Exp $ -*- C++ -*-
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)
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
23 //testing=script,sparse 2006.07.17
28 extern const int swp_type
[];
29 extern const int swp_count
[], swp_steps
[];
30 extern const int swp_nest
;
31 /*--------------------------------------------------------------------------*/
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()) {
44 error(bWARNING
, brh
->long_label() + ": not a device, can't fault:\n");
45 }else if (brh
->subckt()) {
47 error(bWARNING
, brh
->long_label() + " has subckt, can't fault:\n");
49 faultstack
.push_back(CARDSTASH(brh
));
50 ELEMENT
* e
= prechecked_cast
<ELEMENT
*>(brh
);
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();
65 if (swp_steps
[swp_nest
] != 0 && cmd
.is_float()) {
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') {
74 throw Exception("log sweep can't pass zero");
78 value
= start
* pow( (last
/start
), offset
);
82 value
= start
+ (last
-start
) * offset
;
84 IO::mstdout
.setfloatwidth(7)
85 << swp_count
[swp_nest
]+1 << "> sweep " << brh
->long_label()
86 << " =" << value
<< '\n';
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());
101 ci
= findbranch(cmd
, ci
);
102 cmax
= std::max(cmax
, cmd
.cursor());
110 ELEMENT
* e
= prechecked_cast
<ELEMENT
*>(brh
);
112 e
->set_value(cmd
.ctof(), 0);
113 //BUG// messy way to do this, loses other attributes
116 faultbranch(brh
, sweep_fix(cmd
,brh
));
119 cmax
= std::max(cmax
, cmd
.cursor());
125 cmd
.check(bWARNING
, "what's this?");
130 /*--------------------------------------------------------------------------*/
131 class CMD_MODIFY
: public CMD
{
133 void do_it(CS
& cmd
, CARD_LIST
* Scope
)
135 modify_fault(cmd
, MODIFY
, Scope
);
138 DISPATCHER
<CMD
>::INSTALL
d1(&command_dispatcher
, "modify|alter", &p1
);
139 /*--------------------------------------------------------------------------*/
140 class CMD_FAULT
: public CMD
{
142 void do_it(CS
& cmd
, CARD_LIST
* Scope
)
144 modify_fault(cmd
, FAULT
, Scope
);
147 DISPATCHER
<CMD
>::INSTALL
d2(&command_dispatcher
, "fault", &p2
);
148 /*--------------------------------------------------------------------------*/
149 class CMD_RESTORE
: public CMD
{
151 void do_it(CS
&, CARD_LIST
* Scope
)
153 command("unfault", Scope
);
154 command("unmark", Scope
);
157 DISPATCHER
<CMD
>::INSTALL
d3(&command_dispatcher
, "restore", &p3
);
158 /*--------------------------------------------------------------------------*/
159 class CMD_UNFAULT
: public CMD
{
161 void do_it(CS
&, CARD_LIST
*)
163 while (!faultstack
.empty()) {
164 faultstack
.back().restore();
165 faultstack
.pop_back();
167 trace0("CMD_UNFAULT");
171 DISPATCHER
<CMD
>::INSTALL
d4(&command_dispatcher
, "unfault", &p4
);
172 /*--------------------------------------------------------------------------*/
174 /*--------------------------------------------------------------------------*/
175 /*--------------------------------------------------------------------------*/
176 // vim:ts=8:sw=2:noet: