1 /**********
2 Copyright 1990 Regents of the University of California. All rights reserved.
3 Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
4 **********/
5
6 /*
7 * Circuit simulation commands.
8 */
9
10 #include "ngspice/ngspice.h"
11 #include "ngspice/cpdefs.h"
12 #include "ngspice/ftedefs.h"
13 #include "ngspice/ftedev.h"
14 #include "ngspice/ftedebug.h"
15 #include "ngspice/dvec.h"
16 #include "ngspice/trandefs.h"
17
18 #include "circuits.h"
19 #include "runcoms2.h"
20 #include "runcoms.h"
21 #include "variable.h"
22 #include "breakp2.h"
23 #include "plotting/graf.h"
24 #include "spiceif.h"
25 #include "outitf.h"
26 #include "numparam/numpaif.h"
27
28 #include "ngspice/inpdefs.h"
29
30 #if defined(XSPICE) && (defined(SIMULATOR) || defined(SHARED_MODULE))
31 #include "ngspice/evtproto.h"
32 #endif
33
34 extern void line_free_x(struct card *deck, bool recurse);
35 extern INPmodel *modtab;
36
37 #ifdef SHARED_MODULE
38 extern void exec_controls(wordlist *newcontrols);
39 #endif
40
41 #define line_free(line, flag) \
42 do { \
43 line_free_x(line, flag); \
44 line = NULL; \
45 } while(0)
46
47
48 /* Continue a simulation. If there is non in progress, this is the
49 * equivalent of "run".
50 */
51
52 /* This is a hack to tell iplot routine to redraw the grid and initialize
53 the display device
54 */
55
56 bool resumption = FALSE;
57
58
59 void
com_resume(wordlist * wl)60 com_resume(wordlist *wl)
61 {
62 struct dbcomm *db;
63 int err;
64
65 /*rawfile output saj*/
66 bool dofile = FALSE;
67 char buf[BSIZE_SP];
68 bool ascii = AsciiRawFile;
69 /*end saj*/
70
71 NG_IGNORE(wl);
72
73 /*saj fix segment*/
74 if (!ft_curckt) {
75 fprintf(cp_err, "Error: there aren't any circuits loaded.\n");
76 return;
77 } else if (ft_curckt->ci_ckt == NULL) { /* Set noparse? */
78 fprintf(cp_err, "Error: circuit not parsed.\n");
79 return;
80 }
81 /*saj*/
82
83 if (ft_curckt->ci_inprogress == FALSE) {
84 fprintf(cp_err, "Note: run starting\n");
85 com_run(NULL);
86 return;
87 }
88 ft_curckt->ci_inprogress = TRUE;
89 ft_setflag = TRUE;
90
91 reset_trace();
92 for (db = dbs, resumption = FALSE; db; db = db->db_next)
93 if (db->db_type == DB_IPLOT || db->db_type == DB_IPLOTALL)
94 resumption = TRUE;
95
96 /*rawfile output saj*/
97 if (last_used_rawfile)
98 dofile = TRUE;
99
100 if (cp_getvar("filetype", CP_STRING, buf, sizeof(buf))) {
101 if (eq(buf, "binary"))
102 ascii = FALSE;
103 else if (eq(buf, "ascii"))
104 ascii = TRUE;
105 else
106 fprintf(cp_err,
107 "Warning: strange file type \"%s\" (using \"ascii\")\n", buf);
108 }
109
110 if (dofile) {
111 if (!last_used_rawfile)
112 rawfileFp = stdout;
113 #if defined(__MINGW32__) || defined(_MSC_VER)
114 /* ask if binary or ASCII, open file with w or wb hvogt 15.3.2000 */
115 else if (ascii) {
116 if ((rawfileFp = fopen(last_used_rawfile, "a")) == NULL) {
117 perror(last_used_rawfile);
118 ft_setflag = FALSE;
119 return;
120 }
121 } else if (!ascii) {
122 if ((rawfileFp = fopen(last_used_rawfile, "ab")) == NULL) {
123 perror(last_used_rawfile);
124 ft_setflag = FALSE;
125 return;
126 }
127 }
128 /*---------------------------------------------------------------------------*/
129 #else
130 else if (!(rawfileFp = fopen(last_used_rawfile, "a"))) {
131 perror(last_used_rawfile);
132 ft_setflag = FALSE;
133 return;
134 }
135 #endif
136 rawfileBinary = !ascii;
137 } else {
138 rawfileFp = NULL;
139 } /* if dofile */
140
141 /*end saj*/
142
143 err = if_run(ft_curckt->ci_ckt, "resume", NULL,
144 ft_curckt->ci_symtab);
145
146 /*close rawfile saj*/
147 if (rawfileFp) {
148 if (ftell(rawfileFp) == 0) {
149 (void) fclose(rawfileFp);
150 (void) unlink(last_used_rawfile);
151 } else {
152 (void) fclose(rawfileFp);
153 }
154 }
155 /*end saj*/
156
157 if (err == 1) {
158 /* The circuit was interrupted somewhere. */
159
160 fprintf(cp_err, "simulation interrupted\n");
161 } else if (err == 2) {
162 fprintf(cp_err, "simulation aborted\n");
163 ft_curckt->ci_inprogress = FALSE;
164 } else {
165 ft_curckt->ci_inprogress = FALSE;
166 }
167 }
168
169
170 /* Throw out the circuit struct and recreate it from the deck. */
171 void
com_rset(wordlist * wl)172 com_rset(wordlist *wl)
173 {
174 NG_IGNORE(wl);
175
176 if (ft_curckt == NULL) {
177 fprintf(cp_err, "Error: there is no circuit loaded.\n");
178 return;
179 }
180 com_remcirc(NULL);
181 inp_source_recent();
182 }
183
184
185 /* Clears ckt and removes current circuit from database */
186 void
com_remcirc(wordlist * wl)187 com_remcirc(wordlist *wl)
188 {
189 struct variable *v, *next;
190 struct card *dd; /*in: the spice deck */
191 struct circ *p, *prev = NULL;
192
193 NG_IGNORE(wl);
194
195 if (ft_curckt == NULL) {
196 fprintf(cp_err, "Error: there is no circuit loaded.\n");
197 return;
198 }
199
200 /* delete numparam data structure dicoS */
201 nupa_del_dicoS();
202 /* delete entry in dicoslist */
203 nupa_rem_dicoslist(ft_curckt->ci_dicos);
204
205 dbfree(ft_curckt->ci_dbs);
206 ft_curckt->ci_dbs = NULL;
207 dbs = NULL;
208
209 /* The next lines stem from com_rset */
210 INPkillMods();
211
212 #if defined(XSPICE) && (defined(SIMULATOR) || defined(SHARED_MODULE))
213 /* remove event queues, if XSPICE and not nutmeg */
214 if (ft_curckt->ci_ckt)
215 EVTunsetup(ft_curckt->ci_ckt);
216 #endif
217
218 if_cktfree(ft_curckt->ci_ckt, ft_curckt->ci_symtab);
219 for (v = ft_curckt->ci_vars; v; v = next) {
220 next = v->va_next;
221 tfree(v->va_name);
222 if (v->va_type == CP_STRING)
223 tfree(v->va_string);
224 tfree(v);
225 }
226 ft_curckt->ci_vars = NULL;
227 /* delete the deck, parameter list, and options list in ft_curckt */
228 dd = ft_curckt->ci_deck;
229 line_free(dd, TRUE);
230 dd = ft_curckt->ci_param;
231 line_free(dd, TRUE);
232 dd = ft_curckt->ci_options;
233 line_free(dd, TRUE);
234 dd = ft_curckt->ci_meas;
235 line_free(dd, TRUE);
236
237 wl_free(ft_curckt->ci_commands);
238
239 tfree(ft_curckt->FTEstats);
240
241 ft_sim->deleteTask (ft_curckt->ci_ckt, ft_curckt->ci_defTask);
242 if (ft_curckt->ci_specTask)
243 ft_sim->deleteTask (ft_curckt->ci_ckt, ft_curckt->ci_specTask);
244
245 if (ft_curckt->ci_name)
246 tfree(ft_curckt->ci_name);
247 if (ft_curckt->ci_filename)
248 tfree(ft_curckt->ci_filename);
249 rem_tlist(ft_curckt->devtlist);
250 rem_tlist(ft_curckt->modtlist);
251
252 inp_mc_free();
253
254 /* delete the actual circuit entry from ft_circuits */
255 for (p = ft_circuits; p; p = p->ci_next) {
256 if (ft_curckt == p) {
257 if (prev == NULL) {
258 ft_circuits = p->ci_next;
259 tfree(p);
260 p = NULL;
261 break;
262 } else {
263 prev->ci_next = p->ci_next;
264 tfree(p);
265 p = NULL;
266 break;
267 }
268 }
269 prev = p;
270 }
271
272 /* make first entry in ft_circuits the actual circuit (or NULL) */
273 ft_curckt = ft_circuits;
274 if (ft_curckt) {
275 modtab = ft_curckt->ci_modtab;
276 dbs = ft_curckt->ci_dbs;
277 nupa_set_dicoslist(ft_curckt->ci_dicos);
278 }
279 }
280