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