1 /***************************************************************************
2 JSPICE3 adaptation of Spice3e2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California.  All rights reserved.
4 Authors: 1985 Wayne A. Christopher
5          1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 /*
9  * For dealing with nutmeg input decks and command scripts
10  */
11 
12 #include "spice.h"
13 #include "ftedefs.h"
14 #include "fteinp.h"
15 
16 void
nutcom_edit(wl)17 nutcom_edit(wl)
18 
19 wordlist *wl;
20 {
21     int inter;
22 
23     inter = cp_interactive;
24     cp_interactive = false;
25 
26     if (SCEDactive()) {
27         ShowPrompt("Exit sced to edit.");
28         return;
29     }
30     for ( ; wl; wl = wl->wl_next) {
31 
32         /* ignore -r, -n */
33         if (eq(wl->wl_word,"-n"))
34             continue;
35 
36         if (eq(wl->wl_word,"-r"))
37             continue;
38 
39         (void)inp_edit(wl->wl_word);
40     }
41     cp_interactive = inter;
42     return;
43 }
44 
45 
46 bool
inp_edit(filename)47 inp_edit(filename)
48 
49 char *filename;
50 {
51     char buf[BSIZE_SP], buf2[BSIZE_SP], *editor;
52     extern char *kw_editor;
53 
54     if (cp_getvar(kw_editor, VT_STRING, buf2)) {
55         editor = buf2;
56     }
57     else {
58         if (!(editor = getenv("EDITOR"))) {
59             if (Def_Editor && *Def_Editor)
60             editor = Def_Editor;
61         else
62             editor = "/usr/ucb/vi";
63         }
64     }
65     (void) sprintf(buf, "%s %s", editor, filename);
66     /* Note: probably don't want this if editor creates its
67      * own window.
68      */
69     return (DevXterm(buf));
70 }
71 
72 
73 /* nutmeg SCED interface */
74 #ifdef notdef
75 void
nutcom_sced(wl)76 nutcom_sced(wl)
77 
78 wordlist *wl;
79 {
80     FILE *fp,*errfp,*outfp,*errtmp,*outtmp;
81     char *errmsg = "Error: no symbolic representation found.\n";
82     char *filename,*errfile,*outfile;
83     int inter;
84 
85     inter = cp_interactive;
86     cp_interactive = false;
87 top:
88     if (wl) {
89 
90         /* ignore -r, -n */
91         if (eq(wl->wl_word,"-n")) {
92             wl = wl->wl_next;
93             goto top;
94         }
95         if (eq(wl->wl_word,"-r")) {
96             wl = wl->wl_next;
97             goto top;
98         }
99         filename = wl->wl_word;
100     }
101     else {
102         filename = "noname";
103     }
104     errfile = smktemp("er");
105     outfile = smktemp("ot");
106 
107     errfp = fopen(errfile,"w+");
108     outfp = fopen(outfile,"w");
109     if (errfp == NULL || outfp == NULL) {
110         fprintf(cp_err,"Error: redirection failed.\n");
111         return;
112     }
113     errtmp = cp_err;
114     outtmp = cp_out;
115     cp_err = cp_curerr = errfp;
116     cp_out = cp_curout = outfp;
117     (void)sced(filename);
118     cp_curout = outtmp;
119     cp_curerr = errtmp;
120     cp_ioreset();
121     unlink(errfile);
122     unlink(outfile);
123     tfree(errfile);
124     tfree(outfile);
125 
126     cp_interactive = inter;
127 }
128 #endif
129 
130 
131 /* The routine to source a spice input deck. We read the deck in, take out
132  * the front-end commands, and create a CKT structure. Also we filter out
133  * the following cards: .save, .width, .four, .print, and .plot, to perform
134  * after the run is over.
135  */
136 
137 void
inp_nutsource(fp,comfile,filename)138 inp_nutsource(fp, comfile, filename)
139 
140 FILE *fp;
141 bool comfile;
142 char *filename;
143 {
144     struct line *deck, *dd;
145     bool commands = comfile;
146     FILE *lastin, *lastout, *lasterr;
147 
148     inp_readall(fp, &deck, NULL);
149 
150     if (!deck)
151         return;
152 
153     if (!deck->li_next)
154         fprintf(cp_err, "Warning: no cards in deck...\n");
155 
156     /* Now save the IO context and start a new control set...  After
157      * we are done with the source we'll put the old file descriptors
158      * back.  I guess we could use a FILE stack, but since this routine
159      * is recursive anyway...
160      */
161     lastin = cp_curin;
162     lastout = cp_curout;
163     lasterr = cp_curerr;
164     cp_curin = cp_in;
165     cp_curout = cp_out;
166     cp_curerr = cp_err;
167     cp_pushcontrol();
168 
169     for (dd = deck->li_next; dd; dd = dd->li_next) {
170         if ((dd->li_line[0] == '*') && (dd->li_line[1] != '#')) {
171             continue;
172         }
173         if (!*dd->li_line ||
174             (commands && (*dd->li_line == '#' ||
175             *dd->li_line == '*'))) {
176             /* So blank lines in com files don't get
177              * considered as circuits.
178              * Also kill comments in commands.
179              */
180             continue;
181         }
182         if (ciprefix(".control", dd->li_line)) {
183             if (!comfile) {
184                 if (commands)
185                     fprintf(cp_err,
186                     "Warning: redundant .control card\n");
187                 else
188                     commands = true;
189             }
190             continue;
191         }
192         if (ciprefix(".endc", dd->li_line)) {
193             if (!comfile) {
194                 if (commands)
195                     commands = false;
196                 else
197                     fprintf(cp_err,
198                     "Warning: misplaced .endc card\n");
199             }
200             continue;
201         }
202         if (commands || prefix("*#", dd->li_line)) {
203             if (prefix("*#", dd->li_line))
204                 (void) cp_evloop(dd->li_line + 2);
205             else
206                 (void) cp_evloop(dd->li_line);
207         }
208     }
209     inp_deckfree(deck);
210 
211     /* Now reset everything.  Pop the control stack, and fix up the IO
212      * as it was before the source.
213      */
214     cp_popcontrol();
215     cp_curin = lastin;
216     cp_curout = lastout;
217     cp_curerr = lasterr;
218     return;
219 }
220 
221 
222 void
nutcom_source(wl)223 nutcom_source(wl)
224 
225 wordlist *wl;
226 
227 {
228     FILE *fp, *tp;
229     char buf[BSIZE_SP];
230     bool inter;
231     char *tempfile = NULL, *fname;
232     wordlist *owl, *ww, *wn;
233     int i;
234 
235     owl = wl;
236     wl = wl_copy(wl);
237     ww = wl;
238     for (; wl; wl = wn) {
239         wn = wl->wl_next;
240         if (*wl->wl_word != '-')
241             continue;
242         if (!strchr(wl->wl_word,'n') &&
243             !strchr(wl->wl_word,'c') &&
244             !strchr(wl->wl_word,'r'))
245             continue;
246         if (wl->wl_prev)
247             wl->wl_prev->wl_next = wl->wl_next;
248         if (wl->wl_next)
249             wl->wl_next->wl_prev = wl->wl_prev;
250         txfree(wl->wl_word);
251         if (ww == wl)
252             ww = wl->wl_next;
253         txfree((char*)wl);
254     }
255     wl = ww;
256 
257     inter = cp_interactive;
258     cp_interactive = false;
259     if (wl && wl->wl_next) {
260         /* There are several files -- put them into a temp file  */
261         tempfile = smktemp("sp");
262         if (!(fp = inp_pathopen(tempfile, "w+"))) {
263             perror(tempfile);
264             goto done;
265         }
266         while (wl) {
267             if (!(tp = inp_pathopen(wl->wl_word, "r"))) {
268                 perror(wl->wl_word);
269                 goto done;
270             }
271             while ((i = fread(buf, 1, BSIZE_SP, tp)) > 0)
272                 (void) fwrite(buf, 1, i, fp);
273             (void) fclose(tp);
274             wl = wl->wl_next;
275         }
276         (void) fseek(fp, (long) 0, 0);
277     }
278     else {
279         if (wl) {
280             if (!(fp = inp_pathopen(wl->wl_word, "r"))) {
281                 perror(wl->wl_word);
282                 goto done;
283             }
284         }
285         else
286             fp = stdin;
287     }
288 
289     if (tempfile)
290         fname = NULL;
291     else {
292         if (wl)
293             fname = wl->wl_word;
294         else
295             fname = NULL;
296     }
297 
298     /* Don't print the title if this is a .spiceinit file. */
299     if (substring(".spiceinit", owl->wl_word) ||
300             substring("spice.rc", owl->wl_word))
301         inp_nutsource(fp, true, fname);
302     else
303         inp_nutsource(fp,false,fname);
304     if (fp != stdin)
305         (void) fclose(fp);
306 
307 done:
308     cp_interactive = inter;
309 
310     if (tempfile) {
311         (void) unlink(tempfile);
312         txfree(tempfile);
313     }
314     wl_free(ww);
315     return;
316 }
317