Jspice3
main.c
Go to the documentation of this file.
1 /***************************************************************************
2 JSPICE3 adaptation of Spice3f2 - Copyright (c) Stephen R. Whiteley 1992
3 Copyright 1990 Regents of the University of California. All rights reserved.
4 Authors: 1985 Thomas L. Quarles
5  1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 /*
9  * The main routine for Jspice3 and nutmeg.
10  */
11 
12 #include "spice.h"
13 #include "misc.h"
14 #include "ftedefs.h"
15 #include "inpdefs.h"
16 #include "iferrmsg.h"
17 #include "plotdev.h"
18 #include "ftedebug.h"
19 #include "const.h"
20 #include "scedio.h"
21 #include <setjmp.h>
22 
23 #ifdef HAVE_GETPWUID
24 #include <pwd.h>
25 #endif
26 
27 #ifdef HAVE_SIGNAL
28 #include <sys/types.h>
29 #include <signal.h>
30 #endif
31 
32 #ifndef HAVE_GETRUSAGE
33 #ifdef HAVE_FTIME
34 #include <sys/types.h>
35 #include <sys/timeb.h>
36 #endif
37 #endif
38 
39 char *ft_rawfile = "rawspice.raw";
40 
41 char *errRtn;
42 char *errMsg;
43 char *cp_program;
44 char *cp_display;
45 
46 bool ft_servermode = false;
47 bool ft_intrpt = false; /* Set by the signal handlers. */
48 bool ft_setflag = false; /* Don't abort after an interrupt. */
49 
50 #ifdef __STDC__
51 struct variable *(*if_getparam)(char*,char**,char*,int,wordlist**);
52 #else
53 struct variable *(*if_getparam)();
54 #endif
55 
56 #ifdef BATCH
57 
58 DISPDEVICE device[ ] = {
59  {"", 0, 0, 0, 0, 0, 0,
60  0, 0, 0, 0,
61  0, 0, 0, 0,
62  0, 0, 0, 0,
63  0, 0, 0, 0 }
64  };
66 bool ft_nopage = false;
67 bool ft_parsedb = false;
68 bool ft_evdb = false;
69 bool ft_vecdb = false;
70 bool ft_grdb = false;
71 bool ft_gidb = false;
72 bool ft_controldb = false;
73 bool ft_asyncdb = false;
74 
75 bool ft_debug = false;
76 bool ft_batchmode = true;
77 bool ft_nospiceadd = true;
78 bool ft_simdb = false;
79 static char *usage = "Usage: %s [ - ] [ -r rawfile ] [ file ... ]\n";
80 FILE *cp_curin = 0;
81 FILE *cp_curout = 0;
82 FILE *cp_curerr = 0;
83 FILE *cp_in = 0;
84 FILE *cp_out = 0;
85 FILE *cp_err = 0;
86 bool gi_endpause = true;
87 
88 #ifndef SPICE2
89 bool ft_listprint = true;
90 bool ft_optsprint = false;
91 bool ft_nodesprint = false;
92 bool ft_acctprint = false;
93 struct plot *plot_list = NULL;
94 #endif
95 
96 #else
97 
98 bool ft_batchmode = false;
99 jmp_buf jbuf;
100 static char *usage =
101 "Usage: %s [-] [-b] [-i] [-s] [-n] [-o outfile] [-r rawfile]\n\
102 \t[-t term] [file ...]\n";
103 struct options *exitoption;
104 struct options *helpoption;
105 extern RETSIGTYPE ft_sigintr(), sigfloat(), sigstop(), sigquit();
106 extern RETSIGTYPE sigill(), sigbus(), sigsegv(), sig_sys();
107 
108 #endif
109 
110 static started = false;
112 
113 extern IFsimulator SIMinfo;
114 
115 /* for HLP */
116 char *hlp_filelist[] = {"spice", "sced", 0 };
117 
118 #ifdef SIMULATOR
119 
120 bool ft_nutmeg = false;
121 
122 #ifndef BATCH
123 extern struct comm spcp_coms[ ];
124 struct comm *cp_coms = spcp_coms;
125 #endif
126 extern int OUTstopnow(), OUTerror();
127 extern int OUTbeginPlot(), OUTdata(), OUTsetDims(), OUTendPlot();
128 extern int OUTendit;
129 static IFfrontEnd nutmeginfo = {
130  IFnewUid,
131  OUTstopnow,
132  seconds,
133  OUTerror,
134  OUTbeginPlot,
135  OUTdata,
136  OUTsetDims,
137  OUTendPlot,
138  &OUTendit
139 };
140 
141 static void clear_previous();
142 extern int InProgress(), IsIplot();
143 extern void ft_dosim(), inp_decksource();
144 extern void com_resume(), com_iplot(), com_delete();
145 
146 /* for SCED */
147 static struct sSCEDitf sc_itf =
148 {
149  InProgress,
150  ft_dosim,
153  com_resume,
154  IsIplot,
155  com_iplot,
156  com_delete
157 };
158 
159 #else
160 
161 bool ft_nutmeg = true;
162 extern struct comm nutcp_coms[ ];
163 struct comm *cp_coms = nutcp_coms;
165 
166 
167 /* for SCED */
168 static struct sSCEDitf sc_itf =
169 {
170  NULL,
171  NULL,
172  NULL,
173  NULL,
174  NULL,
175  NULL,
176  NULL,
177  NULL
178 };
179 
180 /*
181  * Misc globals we have to fake for nutmeg.
182  */
183 
184 struct circ *ft_curckt;
186 struct dbcomm *dbiplot = NULL; /* export for iplot */
187 
192 
193 /* ARGSUSED */
194 void
195 inp_spsource(fp,i,s) /* main.c */
196 FILE* fp;
197 bool i;
198 char *s;
199 { inp_nutsource(fp,i,s); }
200 
201 /* ARGSUSED */
202 void
203 inp_source(s) /* main.c */
204 char *s;
205 {
206  wordlist *wl;
207 
208  wl = cp_lexer(s);
209  nutcom_source(wl);
210  wl_free(wl);
211 }
212 
213 /* ARGSUSED */
214 void
215 ft_dorun(s) /* main.c */
216 char *s;
217 { return; }
218 
219 /* ARGSUSED */
220 void
221 ft_dotsaves() /* main.c */
222 { return; }
223 
224 /* ARGSUSED */
225 void
226 ft_savedotargs() /* main.c */
227 { return; }
228 
229 /* ARGSUSED */
230 void
231 ft_cktcoms(i) /* main.c */
232 bool i;
233 { return; }
234 
235 /* ARGSUSED */
236 char *
237 if_errstring(code) /* error.c */
238 { return ("spice error"); }
239 
240 /* ARGSUSED */
241 void
242 if_option(ckt, name, type, value) /* options.c */
243 char *name, *ckt, *value;
244 int type; { }
245 
246 /* ARGSUSED */
247 struct variable *
248 if_getstat(n, c, w) /* resource.c */
249 char *n, *c;
250 wordlist **w;
251 { return (NULL);}
252 
253 /* ARGSUSED */
254 wordlist *
255 GetAnalysisFromDeck() /* scedintr.c */
256 { return (NULL); }
257 
258 /* ARGSUSED */
259 void
260 inp_list(fp,l1,l2,i) /* argaf.c */
261 FILE *fp;
262 struct line *l1, *l2;
263 int i;
264 { return; }
265 
266 /* screen line editor for nutmeg, when not using X */
267 /* cursor height - 1 */
268 #define CURHT 0
269 #define FontWidth currentgraph->fontwidth
270 
271 static void
273 
274 int x,y;
275 {
276  DevBox(x,y-1,x+FontWidth,y+CURHT);
277 }
278 
279 char *
280 KbEdit(s,x,y,bg,fg,cc)
281 
282 /*
283  * s Initial string to edit.
284  * x,y Lower left coordinates.
285  * bg,fg Background and foreground colors.
286  * cc Background color at cursor location.
287  * Returns edited string (static!).
288  */
289 char *s;
290 int x, y, bg, fg, cc;
291 {
292  char tbuf[128];
293  int i, k;
294  char *end, ctmp[2];
295  int editX, editY, editFg, editCc;
296  char *editC;
297  static char editBuf[128];
298 
299  editFg = fg;
300  editCc = cc;
301  editX = x;
302  editY = y;
303 
304  DevSetColor(fg);
305  *editBuf = '\0';
306  if (s) {
307  /* s can be NULL */
308  DevText(s, editX, editY);
309  strcpy(editBuf,s);
310  }
311  ctmp[1] = '\0';
312  editC = editBuf;
313  end = strchr(editBuf,'\0');
314  *(end+1) = '\0';
315  ctmp[0] = *editC;
316  DevSetColor(cc);
317  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
318  DevSetColor(fg);
319  DevText(ctmp, editX + (int)(editC-editBuf)*FontWidth, editY);
320  for (;;) {
321  k = DevGetchar(NULL);
322  if ((char) k == '\r') break;
323  switch (k) {
324 
325  case 333: /* right arrow */
326  if (editC >= end) continue;
327  ctmp[0] = *editC;
328  DevSetColor(bg);
329  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
330  DevSetColor(fg);
331  DevText(ctmp,editX + (int)(editC-editBuf)*FontWidth,editY);
332  editC++;
333  ctmp[0] = *editC;
334  DevSetColor(cc);
335  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
336  DevSetColor(fg);
337  DevText(ctmp,editX + (int)(editC-editBuf)*FontWidth,editY);
338  continue;
339 
340  case 331: /* left arrow */
341  if (editC <= editBuf) continue;
342  ctmp[0] = *editC;
343  DevSetColor(bg);
344  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
345  DevSetColor(fg);
346  DevText(ctmp,editX + (int)(editC-editBuf)*FontWidth,editY);
347  editC--;
348  ctmp[0] = *editC;
349  DevSetColor(cc);
350  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
351  DevSetColor(fg);
352  DevText(ctmp,editX + (int)(editC-editBuf)*FontWidth,editY);
353  continue;
354 
355  case '\b':
356  if (editC == editBuf) continue;
357  DevSetColor(bg);
358  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
359  editC--;
360  DevText(editC,editX + (int)(editC-editBuf)*FontWidth,editY);
361  DevSetColor(fg);
362  *editC = '\0';
363  strcat(editBuf,++editC);
364  DevText(editC,editX + (int)(editC-editBuf)*FontWidth,editY);
365  editC--;
366  if (end > editBuf) end--;
367  ctmp[0] = *editC;
368  DevSetColor(cc);
369  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
370  DevSetColor(fg);
371  DevText(ctmp,editX + (int)(editC-editBuf)*FontWidth,editY);
372  continue;
373 
374  case 339: /* DEL, in DOS */
375  case 127:
376  if (editC == end) continue;
377  DevSetColor(bg);
378  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
379  DevText(editC,editX + (int)(editC-editBuf)*FontWidth,editY);
380  DevSetColor(fg);
381  *editC = '\0';
382  strcat(editBuf,++editC);
383  DevText(editC,editX + (int)(editC-editBuf)*FontWidth,editY);
384  editC--;
385  if (end > editBuf) end--;
386  ctmp[0] = *editC;
387  DevSetColor(cc);
388  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
389  DevSetColor(fg);
390  DevText(ctmp,editX + (int)(editC-editBuf)*FontWidth,editY);
391  continue;
392 
393  case '\025': /* ^U */
394  case '\030': /* ^X */
395  case '\033': /* ESC */
396  DevSetColor(bg);
397  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
398  DevText(editBuf,editX,editY);
399  editC = end = editBuf;
400  *editC = '\0';
401  if ((char) k == '\033') {
402  return (NULL);
403  }
404  DevSetColor(cc);
405  textcursor(editX,editY);
406  DevSetColor(fg);
407  continue;
408  default:
409  if (k > 255) continue;
410  if (((char) k < ' ') || ((char) k > '~')) continue;
411  DevSetColor(bg);
412  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
413  DevText(editC,editX + (int)(editC-editBuf)*FontWidth,editY);
414  strcpy(tbuf,editC);
415  *editC = (char) k;
416  sprintf(++editC,tbuf);
417  ctmp[0] = *editC;
418  DevSetColor(fg);
419  DevText(editC-1,
420  editX+(int)(editC-1-editBuf)*FontWidth,editY);
421  DevSetColor(cc);
422  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
423  DevSetColor(fg);
424  DevText(ctmp,editX + (int)(editC-editBuf)*FontWidth,editY);
425  end++;
426  *(end+1) = '\0';
427 
428  }
429  }
430  DevSetColor(bg);
431  textcursor(editX+(int)(editC-editBuf)*FontWidth,editY);
432  DevSetColor(fg);
433  ctmp[0] = *editC;
434  DevText(ctmp,editX + (int)(editC-editBuf)*FontWidth,editY);
435  return (editBuf);
436 }
437 #endif
438 
439 typedef RETSIGTYPE (*SigType)();
440 
442 
443 /* at last! */
444 int
445 main(ac, av)
446 
447 int ac;
448 char **av;
449 {
450  char **tv;
451  int tc, i;
452  int err;
453  bool gotone = false;
454  char *p;
455  char *cmd_line_term = 0, term_1stch;
456 
457 #ifdef BATCH
458  bool st = false;
459 #else
460 
461 #ifdef HAVE_GETPWUID
462  struct passwd *pw;
463 #endif
464  char buf[BSIZE_SP];
465  bool rflag = false, ciprefix();
466  bool istty = true, iflag = false, qflag = false;
467  bool readinit = true;
468  bool gdata = true;
469  bool read_err = false;
470  FILE *fp;
471  extern char *kw_mplot_cur;
472 
473 #endif
474 
475  /* MFB tends to jump to 0 on errors. This tends to catch it. */
476  if (started) {
477  fprintf(cp_err, "main: Internal Error: jump to zero\n");
478  fatal();
479  }
480  started = true;
481 
482  ivars( );
483 
484  cp_in = stdin;
485  cp_out = stdout;
486  cp_err = stderr;
487 
488 #ifdef BATCH
489 
490  cp_curin = stdin;
491  cp_curout = stdout;
492  cp_curerr = stderr;
493 
494 #else
495 
496 #ifdef MALLOCTRACE
497  mallocTraceInit("malloc.out");
498 #endif
499 #ifdef HAVE_ISATTY
500  istty = (bool) isatty(fileno(stdin));
501 #endif
502 
503  rusage_init();
504 #endif
505 
506  err = SIMinit(&nutmeginfo,&ft_sim);
507  if(err != OK) {
508  ft_sperror(err,"SIMinit");
509  return (EXIT_BAD);
510  }
511  cp_program = ft_sim->simulator;
512 
513 #ifdef HAVE_GETPID
514  srandom(getpid());
515 #else
516  srandom(17);
517 #endif
518 
519  tv = av;
520  tc = ac;
521 
522  /* Pass 1 -- get options. */
523  while (--tc > 0) {
524  tv++;
525  if (**tv == Spice_OptChar) { /* Option argument. */
526  switch ((*tv)[1]) {
527 
528 #ifndef BATCH
529  case '\0': /* No raw file. */
530  gdata = false;
531  break;
532 
533  case 'b': /* Batch mode. */
534  case 'B':
535  ft_batchmode = true;
536  break;
537 
538  case 's': /* Server mode. */
539  case 'S':
540  ft_servermode = true;
541  break;
542 
543  case 'i': /* Interactive mode. */
544  case 'I':
545  iflag = true;
546  break;
547 
548  case 'q': /* No command completion. */
549  case 'Q':
550  qflag = true;
551  break;
552 
553  case 'n': /* Don't read .spiceinit. */
554  case 'N':
555  readinit = false;
556  break;
557 
558  case 't': /* Terminal type. */
559  case 'T':
560  if (tc > 1) {
561  tc--;
562  tv++;
563  cmd_line_term = *tv;
564  term_1stch = **tv;
565  **tv = Spice_OptChar;
566  }
567  else {
568  fprintf(cp_err, usage, cp_program);
569  return (EXIT_BAD);
570  }
571  break;
572  case 'd': /* X display */
573  case 'D':
574  if (tc > 1) {
575  tc--;
576  tv++;
577  cp_display = copy(*tv);
578  **tv = Spice_OptChar;
579  }
580  else {
581  fprintf(cp_err, usage, cp_program);
582  return (EXIT_BAD);
583  }
584  break;
585  case 'r': /* The rawfile. */
586  case 'R':
587  if (tc > 1) {
588  tc--;
589  tv++;
590  ft_rawfile = copy(*tv);
591  cp_vset("rawfile", VT_STRING, *tv);
592  **tv = Spice_OptChar;
593  }
594  rflag = true;
595  break;
596 
597 #else /* if BATCH */
598  case 'r': /* The rawfile. */
599  case 'R':
600  if (tc > 1) {
601  tc--;
602  tv++;
603  ft_rawfile = copy(*tv);
604  **tv = Spice_OptChar;
605  }
606  else {
607  fprintf(cp_err, usage, cp_program);
608  return (EXIT_BAD);
609  }
610 #endif
611 
612  case 'o': /* Output file. */
613  case 'O':
614  if (tc > 1) {
615  tc--;
616  tv++;
617  if (!(freopen(*tv, "w", stdout))) {
618  perror(*tv);
619  return (EXIT_BAD);
620  }
621  **tv = Spice_OptChar;
622  }
623  else {
624  fprintf(cp_err, usage, av[0]);
625  return (EXIT_BAD);
626  }
627  break;
628 
629  default:
630  fprintf(cp_err, "Error: bad option %s\n", *tv);
631  fprintf(cp_err, usage, cp_program);
632  return (EXIT_BAD);
633  }
634  }
635  }
636 
637  if (!cp_display) {
638  cp_display = getenv("DISPLAY");
639  if (cp_display)
641  }
642 
643 #ifdef SIMULATOR
645 #else
647 #endif
648 
649 #ifndef BATCH
650 
651  if ((!iflag && !istty) || ft_servermode)
652  ft_batchmode = true;
653  if ((iflag && !istty) || qflag)
654  cp_nocc = true;
655  if (!istty || ft_batchmode)
656  out_moremode = false;
657  if (ft_servermode)
658  ft_rawfile = "";
659  cp_interactive = false;
660 
661 #ifdef HAVE_SIGNAL
662  /* Set up signal handling */
663  if (!ft_batchmode) {
664  (void) signal(SIGINT, (SigType)ft_sigintr);
665  (void) signal(SIGFPE, (SigType)sigfloat);
666 #ifdef SIGTSTP
667  (void) signal(SIGTSTP, (SigType)sigstop);
668 #endif
669  }
670  /* Set up signal handling for fatal errors. */
671  (void) signal(SIGILL, (SigType)sigill);
672 
673 #ifdef SIGBUS
674  (void) signal(SIGBUS, (SigType)sigbus);
675 #endif
676 #ifdef SIGSEGV
677  (void) signal(SIGSEGV, (SigType)sigsegv);
678 #endif
679 #ifdef SIGSYS
680  (void) signal(SIGSYS, (SigType)sig_sys);
681 #endif
682 #endif
683 
684  /* To catch interrupts during .spiceinit... */
685  if (setjmp(jbuf) == 1) {
686  read_err = true;
687  goto bot;
688  }
689 
690  /* init graphics, so we can setrdb in init file */
691  if (!ft_batchmode)
692  DevInit( );
693 
694  /* Have to initialize cp now. */
695  ft_cpinit(); /* this sources the spinit file */
696 
697  if (!ft_servermode && readinit) {
698 #ifdef HAVE_GETPWUID
699  /* Try to source either .spiceinit or ~/.spiceinit. */
700  if (access(".spiceinit", 0) == 0)
701  inp_source(".spiceinit");
702  else {
703  pw = getpwuid(getuid());
704  (void) strcpy(buf, pw->pw_dir);
705  (void) strcat(buf, "/.spiceinit");
706  if (access(buf, 0) == 0)
707  inp_source(buf);
708  }
709 #else
710  /* Try to source the file "spice.rc" in the current directory. */
711  if ((fp = fopen("spice.rc", "r")) != NULL) {
712  (void) fclose(fp);
713  inp_source("spice.rc");
714  }
715 #endif
716  }
717 
718 bot:
719 
720  if (cmd_line_term) {
721  *cmd_line_term = term_1stch;
722  /* XXX oh, gross!
723  * First char got squashed scanning the
724  * command line
725  */
726  cp_vset("term", VT_STRING, cmd_line_term);
727  *cmd_line_term = Spice_OptChar;
728  }
729 
730  if (!ft_batchmode) {
731  com_version(NULL);
732  if (News_File && *News_File) {
733  fp = fopen(cp_tildexpand(News_File), "r");
734  if (fp) {
735  while (fgets(buf, BSIZE_SP, fp))
736  fputs(buf, stdout);
737  (void) fclose(fp);
738  }
739  }
740  }
741  if (read_err)
742  fprintf(cp_err, "Warning: error executing init file.\n");
743 
744  /* Pass 2 -- get the filenames. If we are spice, then this means
745  * build a circuit for this file. If this is in server mode, don't
746  * process any of these args.
747  */
748 
749  if (setjmp(jbuf) == 1) {
750  goto evl;
751  }
752 
753 #endif /* not BATCH */
754 
755  if (!ft_servermode && !ft_nutmeg) {
756  FILE *file = NULL, *tp = NULL;
757  char *tempfile = NULL, buf[BSIZE_SP], *smktemp();
758 
759  for (tv = av + 1, i = 0; *tv; tv++)
760  if (**tv != Spice_OptChar)
761  i++;
762  if (i == 1) {
763  for (tv = av + 1, i = 0; *tv; tv++)
764  if (**tv != Spice_OptChar)
765  break;
766  if (!(file = fopen(*tv, "r"))) {
767  perror(*tv);
768  i = 0;
769  }
770  }
771  else if (i) {
772  tempfile = smktemp("sp");
773  if (!(file = fopen(tempfile, "w+"))) {
774  perror(tempfile);
775  return (EXIT_BAD);
776  }
777  for (tv = av + 1, i = 0; *tv; tv++)
778  if (**tv != Spice_OptChar) {
779  if (!(tp = fopen(*tv, "r"))) {
780  perror(*tv);
781  continue;
782  }
783  while ((i = fread(buf, 1, BSIZE_SP, tp)) > 0)
784  (void) fwrite(buf, i, 1, file);
785  (void) fclose(tp);
786  }
787  (void) fseek(file, (long) 0, 0);
788  }
789  if (file) {
790  inp_spsource(file, false, tempfile ? (char *) NULL : *tv);
791  (void) fclose(file);
792  gotone = true;
793  if (tempfile)
794  (void) unlink(tempfile);
795  }
796  }
797 
798  if (!gotone && ft_batchmode && !ft_nutmeg)
799  inp_spsource(stdin, false, (char *) NULL);
800 
801 #ifndef BATCH
802  if (ft_nutmeg && gdata) {
803  /* Read in the rawfiles */
804  for (av++; *av; av++)
805  if (**av != Spice_OptChar) {
806  ft_loadfile(*av);
807  gotone = true;
808  }
809  if (!gotone)
811  }
812 
813 evl:
814  if (ft_batchmode) {
815  /* If we get back here in batch mode then something is
816  * wrong, so exit.
817  */
818  bool st = false;
819 
820  (void) setjmp(jbuf);
821 
822  if (st == true)
823  return (EXIT_BAD);
824  st = true;
825 
826  if (ft_curckt == NULL) {
827  char p;
828  if (cp_getvar(kw_mplot_cur,VT_STRING,&p))
829  /* margin analysis performed */
830  return (EXIT_NORMAL);
831  fprintf(cp_err, "Error: no circuit loaded!\n");
832  return (EXIT_BAD);
833  }
834  else if (ft_curckt->ci_runonce)
835  /* already did it */
836  return (EXIT_NORMAL);
837 
838  if (ft_servermode) {
840  return (EXIT_NORMAL);
841  }
842  /* If -r is specified, then we don't bother with the dot
843  * cards. Otherwise, we use wrd_run, but we are careful
844  * not to save too much.
845  */
846  cp_interactive = false;
847  if (rflag) {
848  ft_dotsaves();
850  ft_cktcoms(true);
851  }
852  else {
853  ft_savedotargs();
854  ft_dorun((char *) NULL);
855  ft_cktcoms(false);
856  }
857  }
858  else {
859  (void) setjmp(jbuf);
860  cp_interactive = true;
861  while (cp_evloop((char *) NULL) == 1) ;
862  }
863 
864 #else /* if BATCH */
865 
866  if (st == true)
867  return (EXIT_BAD);
868  st = true;
869  if (ft_curckt == NULL) {
870  char p;
871  if (cp_getvar(kw_mplot_cur,VT_STRING,&p))
872  /* margin analysis performed */
873  return (EXIT_NORMAL);
874  fprintf(cp_err, "Error: no circuit loaded!\n");
875  return (EXIT_BAD);
876  }
877  else if (ft_curckt->ci_runonce)
878  /* already did it */
879  return (EXIT_NORMAL);
880 #ifdef SPICE2
881  ft_savedotargs( );
882  ft_dorun(NULL);
883  ft_cktcoms(false);
884 #else
885  ft_dotsaves( );
887  ft_cktcoms(false);
888 
889  fprintf(stderr,
890  "Note: \".plot\" or \".print\" lines ignored (rawfile only)\n");
891 #endif
892 
893 #endif
894 
895  return (EXIT_NORMAL);
896 }
897 
898 
899 static void
901 
902 {
903  /* for SCED, we don't save old circuits or plots */
904 #ifdef SIMULATOR
905  if_cktclear();
907 #endif
908 }
909 
910 
911 /* allocate space for global constants in 'CONST.h' */
912 
913 double CONSTroot2;
914 double CONSTvt0;
915 double CONSTKoverQ;
916 double CONSTe;
918 
919 int
920 SPIinit(frtEnd,description)
921 
922 IFfrontEnd *frtEnd;
923 IFsimulator **description;
924 {
925 
926  SPfrontEnd = frtEnd;
927  *description = &SIMinfo;
928  CONSTroot2 = sqrt(2.);
929  CONSTvt0 = CONSTboltz * (27 /* deg c */ + CONSTCtoK ) / CHARGE;
931  CONSTe = exp((double)1.0);
932  return (OK);
933 }
934 
935 /* XXX SIMinit and SPIinit ?? */
936 
937 int
938 SIMinit(frontEnd,simulator)
939 
940 IFfrontEnd *frontEnd;
941 IFsimulator **simulator;
942 {
943  return (SPIinit(frontEnd,simulator));
944 }
945 
946 #ifdef BATCH
947 /*
948  * Incredibly Ugly
949  */
950 
951 /* Now some misc junk that we need to fake */
952 
953 bool cp_nocc = true;
954 bool cp_debug = false;
955 int cp_maxhistlength;
956 char cp_chars[128];
957 
958 MFBHalt( ) { }
959 
960 #ifndef SPICE2
961 /* ARGSUSED */ char *cp_tildexpand(s) char *s; { return (s); }
962 /* ARGSUSED */ struct dvec *vec_fromplot(w, p) char *w; struct plot *p;
963  { return (NULL); }
964 void vec_new() {}
965 void plot_new() {}
966 void plot_setcur() {}
967 /* ARGSUSED */ struct plot *plot_alloc(name) char *name; { return (NULL); }
968 struct plot *plot_cur = NULL;
969 /* ARGSUSED */ void plot_docoms(wl) wordlist *wl; {}
970 void out_init() {}
971 /* PC defines out_printf to printf since vsprintf doesn't exist */
972 /* ARGSUSED */ /* VARARGS1 */ void out_printf(c) char *c; {}
973 /* ARGSUSED */ void out_send(s) char *s; {}
974 char out_pbuf[1];
975 /* ARGSUSED */ struct dvec *vec_get(word) char *word; { return (NULL); }
976 #endif
977 
978 /* ARGSUSED */ int cp_usrset(v, i) struct variable *v; bool i; {return(US_OK);}
979 void cp_pushcontrol() {}
980 void cp_popcontrol() {}
981 /* ARGSUSED */ void cp_addkword(class, word) int class; char *word; {}
982 struct circ *ft_circuits = 0, *ft_curckt = 0;
983 /* ARGSUSED */ char *cp_kwswitch(c, t) int c; char *t; { return (NULL); }
984 /* ARGSUSED */ bool ft_bpcheck(r, i) struct plot *r; int i; { return (true); }
985 /* ARGSUSED */ void cp_ccon(b) bool b; {}
986 
987 int currentgraph = 0;
988 /* ARGSUSED */ void Input(p, q) char *p, *q; {}
989 /* ARGSUSED */ void DevSwitch(i) int i; {}
990 /* ARGSUSED */ int *CopyGraph(i) int i; {}
991 /* ARGSUSED */ void DestroyGraph(i) int i; {}
992 /* ARGSUSED */ void NewViewport(i) int i; {}
993 
994 /* ARGSUSED */ void cp_remkword() { }
995 /* ARGSUSED */ void cp_resetcontrol() { }
996 
997 bool gr_init() {}
998 void gr_redraw() {}
999 /* ARGSUSED */ void gr_iplot(pl) struct plot *pl; {}
1000 /* ARGSUSED */ void gr_end_iplot(pl) struct plot *pl; {}
1001 /* ARGSUSED */ void gr_pmsg(text, more) char *text; bool more; {}
1002 /* ARGSUSED */ void gr_clean(intr) bool intr; {}
1003 /* ARGSUSED */ int cp_evloop(string) char *string; { return (0); }
1004 void ft_graf() {}
1005 void ft_trquery() {}
1006 /* ARGSUSED */ void ft_newcirc(ckt) struct circ *ckt; {}
1007 void cp_doquit() { exit(0); }
1008 /* ARGSUSED */ void cp_usrvars(v1, v2) struct variable **v1, **v2; { return; }
1009 /* ARGSUSED */ struct variable * cp_enqvar(word) char *word; { return (NULL); }
1010 /* ARGSUSED */ void cp_ccom(w, b, e) wordlist *w; char *b; bool e; { return; }
1011 
1012 void
1013 com_save(wl)
1014 wordlist *wl;
1015 {
1016  return;
1017 }
1018 
1019 int
1020 ft_getSaves(savesp)
1021 char ***savesp;
1022 {
1023  return (0);
1024 }
1025 
1026 /* This is from options.c */
1027 /* Extract the .option cards from the deck... */
1028 
1029 struct line *
1030 inp_getopts(deck)
1031 
1032 struct line *deck;
1033 {
1034  struct line *last = NULL, *opts = NULL, *dd, *next = NULL;
1035 
1036  for (dd = deck->li_next; dd; dd = next) {
1037  next = dd->li_next;
1038  if (ciprefix(".opt", dd->li_line)) {
1039  inp_casefix(dd->li_line);
1040  if (last)
1041  last->li_next = dd->li_next;
1042  else
1043  deck->li_next = dd->li_next;
1044  dd->li_next = opts;
1045  opts = dd;
1046  }
1047  else
1048  last = dd;
1049  }
1050  return (opts);
1051 }
1052 
1053 #ifndef SPICE2
1054 
1055 static wordlist *gettoks();
1056 
1057 /* This is from dotcards.c -- we don't want to include the whole file. */
1058 /* Extract all the .save cards */
1059 
1060 void
1061 ft_dotsaves()
1062 
1063 {
1064  wordlist *com, *wl = NULL;
1065  char *s;
1066 
1067  if (!ft_curckt) /* Shouldn't happen. */
1068  return;
1069 
1070  for (com = ft_curckt->ci_commands; com; com = com->wl_next) {
1071  if (ciprefix(".save", com->wl_word)) {
1072  s = com->wl_word;
1073  (void) gettok(&s);
1074  wl = wl_append(wl, gettoks(s));
1075  }
1076  }
1077 /* wrd_saves = wl; */
1078 
1079  com_save(wl);
1080 /* fprintf(stderr, "error, .save card code is broken\n"); */
1081  return;
1082 }
1083 
1084 /* This is also from dotcards.c. We should probably include the file. */
1085 /* Stripped down version. */
1086 
1087 /* Execute the .whatever cards found in the deck, after we are done running.
1088  * We'll be cheap and use cp_lexer to get the words... This should make us
1089  * spice-2 compatible. Is terse is true then there was a rawfile, so don't
1090  * print lots of junk.
1091  */
1092 
1093 void
1094 ft_cktcoms(terse)
1095 bool terse;
1096 
1097 {
1098  wordlist *coms, *command;
1099  char *plottype, *s;
1100  struct dvec *v;
1101  static wordlist twl = { "col", NULL, NULL } ;
1102  int i;
1103 
1104  if (!ft_curckt)
1105  return;
1106  if (!ft_curckt->ci_commands)
1107  goto nocmds;
1108  coms = ft_curckt->ci_commands;
1109  cp_interactive = false;
1110 
1111 nocmds:
1112  /* Circuit name */
1113  fprintf(cp_out, "Circuit: %s\nDate: %s\n\n", ft_curckt->ci_name,
1114  datestring());
1115  fprintf(cp_out, "\n");
1116 
1117  /* Listing if necessary... */
1118  if (ft_listprint)
1119  inp_list(cp_out, ft_curckt->ci_deck, ft_curckt->ci_options,
1120  LS_DECK);
1121 
1122  /* And finally the accounting info. */
1123  if (ft_acctprint) {
1124  static wordlist ww = { "everything", NULL, NULL } ;
1125  com_rusage(&ww);
1126  } else
1127  com_rusage((wordlist *) NULL);
1128 
1129  (void) putc('\n', cp_out);
1130  return;
1131 
1132 bad: fprintf(cp_err, "Internal Error: ft_cktcoms: bad commands\n");
1133  return;
1134 }
1135 
1136 
1137 static wordlist *
1138 gettoks(s)
1139 
1140 char *s;
1141 {
1142  char *t, *r, buf[64];
1143  wordlist *wl = NULL, *end = NULL;
1144  bool iflag;
1145 
1146  while (t = gettok(&s)) {
1147  if (*t == '(' /* ) */) {
1148  /* This is a (upper, lower) thing -- ignore. */
1149  continue;
1150  }
1151  else if (!index(t, '(' /*)*/ )) {
1152  if (end) {
1153  end->wl_next = alloc(struct wordlist);
1154  end->wl_next->wl_prev = end;
1155  end = end->wl_next;
1156  }
1157  else
1158  wl = end = alloc(struct wordlist);
1159  end->wl_word = copy(t);
1160  }
1161  else if (!index(t, ',')) {
1162  iflag = ((*t == 'i') || (*t == 'I')) ? true : false;
1163  while (*t != '(' /*)*/)
1164  t++;
1165  t++;
1166  for (r = t; *r && *r != /*(*/ ')'; r++)
1167  ;
1168  *r = '\0';
1169  if (end) {
1170  end->wl_next = alloc(struct wordlist);
1171  end->wl_next->wl_prev = end;
1172  end = end->wl_next;
1173  }
1174  else
1175  wl = end = alloc(struct wordlist);
1176  if (iflag) {
1177  (void) sprintf(buf, "%s#branch", t);
1178  t = buf;
1179  }
1180  end->wl_word = copy(t);
1181  }
1182  else {
1183  /* The painful case... */
1184  while (*t != '(' /*)*/)
1185  t++;
1186  t++;
1187  for (r = t; *r && *r != ','; r++)
1188  ;
1189  *r = '\0';
1190  if (end) {
1191  end->wl_next = alloc(struct wordlist);
1192  end->wl_next->wl_prev = end;
1193  end = end->wl_next;
1194  }
1195  else
1196  wl = end = alloc(struct wordlist);
1197  end->wl_word = copy(t);
1198  t = r + 1;
1199  for (r = t; *r && *r != /*(*/ ')'; r++)
1200  ;
1201  *r = '\0';
1202  if (end) {
1203  end->wl_next = alloc(struct wordlist);
1204  end->wl_next->wl_prev = end;
1205  end = end->wl_next;
1206  }
1207  else
1208  wl = end = alloc(struct wordlist);
1209  end->wl_word = copy(t);
1210  }
1211  }
1212  return (wl);
1213 }
1214 
1215 #endif
1216 
1217 #endif
bool ft_acctprint
Definition: main.c:191
#define US_OK
Definition: cpdefs.h:49
struct comm nutcp_coms[]
Definition: nutctab.c:21
bool ft_intrpt
Definition: main.c:47
static char buf[MAXPROMPT]
Definition: arg.c:18
struct dbcomm * dbiplot
Definition: main.c:186
char * gettok()
#define BSIZE_SP
Definition: misc.h:19
void inp_casefix()
DISPDEVICE device[]
Definition: display.c:24
char * if_errstring(code)
Definition: main.c:237
int ciprefix()
bool ft_asyncdb
Definition: options.c:31
void inp_list(FILE *fp, struct line *l1, struct line *l2, int i)
Definition: main.c:260
RETSIGTYPE sigbus()
RETSIGTYPE sigstop()
Definition: subckt.c:18
void cp_vset()
bool cp_getvar(char *n, int t, char *r)
Definition: help.c:184
bool ft_parsedb
Definition: options.c:24
struct plot * plot_alloc()
IFsimulator * ft_sim
Definition: main.c:111
bool ft_nospiceadd
void plot_new()
void plot_docoms()
void com_delete()
GRAPH * gr_init()
char * cp_tildexpand()
void com_rusage()
bool ft_simdb
Definition: options.c:26
char cp_chars[]
Definition: cshpar.c:79
double CONSTroot2
Definition: main.c:913
#define CURHT
Definition: main.c:268
void out_printf()
void ft_trquery()
Definition: breakp.c:641
char * strcpy()
Definition: ftedefs.h:25
Definition: cddefs.h:119
int IFnewUid()
char * hlp_filelist[]
Definition: main.c:116
RETSIGTYPE sigill()
struct plot * plot_cur
Definition: vectors.c:43
void DevSetColor()
struct variable * nutif_getparam()
struct comm spcp_coms[]
Definition: spcmdtab.c:27
void DevText()
void com_save()
DISPDEVICE * dispdev
Definition: display.c:112
struct line * ci_deck
Definition: ftedefs.h:30
#define EXIT_NORMAL
Definition: misc.h:25
static started
Definition: main.c:110
#define CONSTCtoK
Definition: const.h:11
#define CHARGE
Definition: const.h:10
void ft_dorun(char *s)
Definition: main.c:215
char * errMsg
Definition: main.c:42
struct line * ci_options
Definition: ftedefs.h:32
RETSIGTYPE sigsegv()
char * datestring()
Definition: time.c:37
int OUTerror()
#define FontWidth
Definition: main.c:269
static double e
Definition: vectors.c:17
IFsimulator SIMinfo
Definition: nconfig.c:12
FILE * cp_curerr
Definition: cshpar.c:77
FILE * p
Definition: proc2mod.c:48
IFfrontEnd * SPfrontEnd
Definition: main.c:917
bool ft_listprint
Definition: main.c:188
Definition: ftedata.h:61
static void textcursor(int x, int y)
Definition: main.c:272
void if_option(char *ckt, char *name, int type, char *value)
Definition: main.c:242
void com_version()
void ft_cpinit()
Definition: cpitf.c:21
Definition: cddefs.h:169
double CONSTKoverQ
Definition: main.c:915
#define LS_DECK
Definition: fteinp.h:26
Definition: library.c:18
struct line * inp_getopts()
char * simulator
Definition: ifsim.h:357
void ft_dosim()
static void clear_previous()
Definition: main.c:900
int InProgress()
Definition: spiceif.c:990
struct comm * cp_coms
Definition: main.c:163
int bool
Definition: cpstd.h:16
Definition: cpdefs.h:20
static struct sSCEDitf sc_itf
Definition: main.c:168
Definition: cddefs.h:215
RETSIGTYPE ft_sigintr()
struct variable *(* if_getparam)()
Definition: main.c:53
#define alloc(type)
Definition: cdmacs.h:21
RETSIGTYPE sig_sys()
bool ft_setflag
Definition: main.c:48
void com_resume()
char * copy()
char * getenv(char *c)
Definition: libfuncs.c:106
bool ft_bpcheck()
RETSIGTYPE sigquit()
int OUTendPlot()
FILE * cp_curin
Definition: cshpar.c:75
void wl_free()
int OUTbeginPlot()
char * ft_rawfile
Definition: main.c:39
void inp_spsource(FILE *fp, bool i, char *s)
Definition: main.c:195
FILE * cp_err
Definition: help.c:101
#define OK
Definition: iferrmsg.h:17
bool ft_controldb
Definition: options.c:30
Definition: fteinp.h:14
double CONSTe
Definition: main.c:916
#define CONSTboltz
Definition: const.h:12
struct circ * ft_circuits
Definition: main.c:185
void if_cktclear()
Definition: spiceif.c:476
void DevBox()
void cp_remkword()
void ivars()
Definition: ivars.c:51
void inp_source(char *s)
Definition: main.c:203
void rusage_init()
Definition: resource.c:142
RETSIGTYPE sigfloat()
bool cp_interactive
Definition: help.c:100
struct dvec * vec_get()
char * News_File
Definition: ivars.c:12
#define NULL
Definition: spdefs.h:121
Definition: types.c:18
struct circ * ft_curckt
Definition: main.c:184
void nutcom_source()
struct variable * if_getstat(char *n, char *c, wordlist **w)
Definition: main.c:248
FILE * cp_out
Definition: help.c:101
int unlink(char *fn)
Definition: libfuncs.c:96
static wordlist * gettoks()
void inp_decksource()
bool ft_servermode
Definition: main.c:46
bool OUTendit
Definition: outitf.c:60
void cp_doquit()
Definition: cpitf.c:329
void ft_newcirc()
wordlist * GetAnalysisFromDeck()
Definition: main.c:255
char * cp_program
Definition: main.c:43
GRAPH * CopyGraph()
wordlist * wl_append()
char * smktemp()
int access(char *pth, int m)
Definition: libfuncs.c:75
struct dvec * vec_fromplot()
void ft_sperror()
char * cp_display
Definition: main.c:44
static double c
Definition: vectors.c:16
int ft_getSaves()
#define VT_STRING
Definition: cpstd.h:63
char * KbEdit(char *s, int x, int y, int bg, int fg, int cc)
Definition: main.c:280
void perror()
struct variable * cp_enqvar()
static char * usage
Definition: main.c:100
Definition: ftedata.h:24
struct sSCEDitf * ft_sced
Definition: main.c:441
struct line * li_next
Definition: fteinp.h:18
wordlist * cp_lexer()
bool ci_runonce
Definition: ftedefs.h:35
struct options * exitoption
Definition: main.c:103
Definition: cpstd.h:21
void cp_usrvars()
void ft_cktcoms(bool i)
Definition: main.c:231
static IFfrontEnd nutmeginfo
Definition: main.c:164
char * kw_mplot_cur
Definition: options.c:376
int DestroyGraph()
Definition: cddefs.h:177
int DevGetchar()
void gr_iplot()
int IsIplot()
Definition: spiceif.c:997
bool ft_nodesprint
Definition: main.c:190
double seconds()
Definition: time.c:103
RETSIGTYPE(* SigType)()
Definition: main.c:439
void DevInit()
Definition: display.c:168
bool ft_evdb
Definition: options.c:27
int getpid()
Definition: libfuncs.c:137
Definition: netlist.c:477
bool cp_nocc
Definition: complete.c:75
bool ft_batchmode
Definition: main.c:98
struct plot * plot_list
Definition: vectors.c:44
char * errRtn
Definition: main.c:41
bool ft_optsprint
Definition: main.c:189
Definition: cddefs.h:162
double CONSTvt0
Definition: main.c:914
int cp_usrset()
bool ft_grdb
Definition: options.c:28
char * index(char *s, char c) const
Definition: string.c:294
void out_send()
bool ft_debug
struct wordlist * wl_next
Definition: cpstd.h:23
int cp_maxhistlength
Definition: history.c:35
int SPIinit(IFfrontEnd *frtEnd, IFsimulator **description)
Definition: main.c:920
void inp_nutsource()
bool ft_nutmeg
Definition: main.c:161
jmp_buf jbuf
Definition: main.c:99
char * ci_name
Definition: ftedefs.h:26
Definition: mfb.h:383
GRAPH * currentgraph
Definition: graphdb.c:21
struct variable * spif_getparam()
int MFBHalt()
Definition: mfbopen.c:232
char * wl_word
Definition: cpstd.h:22
wordlist * ci_commands
Definition: ftedefs.h:36
void cp_pushcontrol()
Definition: front.c:1066
int OUTdata()
void gr_end_iplot()
Definition: iplot.c:397
void cp_popcontrol()
Definition: front.c:1051
void fatal()
Definition: help.c:174
int cp_evloop()
int DevSwitch()
FILE * cp_curout
Definition: cshpar.c:76
FILE * cp_in
Definition: help.c:101
void cp_addkword()
bool ft_gidb
Definition: options.c:29
void plot_setcur()
#define EXIT_BAD
Definition: misc.h:26
void com_iplot()
int OUTsetDims()
void ft_loadfile()
Definition: cddefs.h:192
bool cp_debug
Definition: cshpar.c:61
void com_destroy()
void cp_resetcontrol()
Definition: front.c:1033
bool ft_nopage
Definition: options.c:23
Definition: cpstd.h:41
void cp_ccom()
void ft_dotsaves()
Definition: main.c:221
void ft_savedotargs()
Definition: main.c:226
char Spice_OptChar
bool out_moremode
Definition: output.c:44
void cp_ccon()
void out_init()
Definition: output.c:128
int SIMinit(IFfrontEnd *frontEnd, IFsimulator **simulator)
Definition: main.c:938
bool ft_vecdb
Definition: options.c:25
struct options * helpoption
Definition: main.c:104
int main(int ac, char **av)
Definition: main.c:445
int OUTstopnow()
Definition: outitf.c:1032
char * cp_kwswitch()