Jspice3
outitf.c
Go to the documentation of this file.
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: 1988 Wayne A. Christopher
5  1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 /*
9  * This module replaces the old "writedata" routines in nutmeg.
10  * Unlike the writedata routines, the OUT routines are only called by
11  * the simulator routines, and only call routines in nutmeg. The rest
12  * of nutmeg doesn't deal with OUT at all.
13  */
14 
15 #include "spice.h"
16 #include "ftedefs.h"
17 #include "inpdefs.h"
18 #include "ftegraph.h"
19 #include "spfteext.h"
20 #include "plotext.h"
21 #include "iferrmsg.h"
22 #include "outdata.h"
23 
24 #define DOUBLE_PRECISION 15
25 
26 typedef struct dataDesc {
27  char *name; /* The name of the vector. */
28  int type; /* The type. */
29  bool regular; /* Is this given to us? */
30  int outIndex; /* If regular then the index. */
31  char *specName; /* The device name if special. */
32  char *specParamName;/* The parameter name if special. */
33  int specIndex; /* For sensitivity, if special. */
34  int specType;
36  int refIndex; /* The index of our ref vector. */
37  struct dvec *vec;
38 } dataDesc;
39 
40 typedef struct runDesc {
43  char *name;
44  char *type;
45  int numData;
46  int refIndex;
48  bool writeOut;
49  bool binary;
50  struct plot *runPlot;
51  FILE *fp;
52  long pointPos; /* where to write pointCount */
53  int pointCount; /* running count of output points */
54  int numPoints; /* num points expected, -1 if not known */
55  int isComplex;
57 } runDesc;
58 
59 /* signal the simulator to end analysis as if finished */
60 bool OUTendit;
61 
62 static struct sOUTcontrol OUTcntrl;
63 
64 #ifdef __STDC__
65 static void out_destroy(void);
66 static int addDataDesc(runDesc*,char*,int,int);
67 static int addSpecialDesc(runDesc*,char*,char*,char*,int);
68 static void addPointToFile(runDesc*,IFvalue*,IFvalue*);
69 static void addPointToPlot(runDesc*,IFvalue*,IFvalue*,bool);
70 static void fileInit(runDesc*);
71 static void fileStartPoint(FILE*,bool,int);
72 static void fileAddRealValue(FILE*,bool,double);
73 static void fileAddComplexValue(FILE*,bool,IFcomplex);
74 static void fileEndPoint(FILE*,bool);
75 static void fileEnd(runDesc*);
76 static void plotInit(runDesc*,double,double,double,struct plot*);
77 static void plotAddRealValue(dataDesc*,double,bool);
78 static void plotAddComplexValue(dataDesc*,IFcomplex,bool);
79 static void plotEnd(runDesc*);
80 static bool parseSpecial(char*,char*,char*,char*);
81 static bool name_eq(char*,char*);
82 static bool getSpecial(dataDesc*,runDesc*,IFvalue*);
83 static void freeRun(runDesc*);
84 #else
85 static void out_destroy();
86 static int addDataDesc();
87 static int addSpecialDesc();
88 static void addPointToFile();
89 static void addPointToPlot();
90 static void fileInit();
91 static void fileStartPoint();
92 static void fileAddRealValue();
93 static void fileAddComplexValue();
94 static void fileEndPoint();
95 static void fileEnd();
96 static void plotInit();
97 static void plotAddRealValue();
98 static void plotAddComplexValue();
99 static void plotEnd();
100 static bool parseSpecial();
101 static bool name_eq();
102 static bool getSpecial();
103 static void freeRun();
104 #endif
105 
106 static bool shouldstop = false; /* Tell simulator to stop next time it asks. */
107 static bool printinfo = false; /* Print informational "error messages". */
108 
109 
110 char *
112 {
113  /* return the OUTcntrl structure */
116  OUTcntrl.out_check = false;
117  OUTcntrl.out_usecurplot = false;
118  OUTcntrl.out_keepplot = false;
120  OUTcntrl.out_index = 0;
121  OUTcntrl.out_max = 0;
122  OUTcntrl.out_fail = 0;
125  return (char *)&OUTcntrl;
126 }
127 
128 
129 static void
131 {
132  if (OUTcntrl.out_rundesc) {
135  }
136  OUTcntrl.out_check = false;
137  OUTcntrl.out_usecurplot = false;
138  OUTcntrl.out_keepplot = false;
140  OUTcntrl.out_index = 0;
141  OUTcntrl.out_max = 0;
142  OUTcntrl.out_fail = 0;
145 }
146 
147 
148 int
150 
151 GENERIC *outdp;
152 {
153  struct sOUTdata *outd = (struct sOUTdata*)outdp;
154  struct plot *plot = NULL;
155  runDesc *run;
156  char **saves;
157  char *cktName;
158  bool *savesused;
159  int numsaves;
160  int i, j, depind;
161  char namebuf[BSIZE_SP], parambuf[BSIZE_SP], depbuf[BSIZE_SP];
162  bool saveall = true;
163  extern char *kw_printinfo;
164 
165  shouldstop = false;
166 
167  if (OUTcntrl.out_check) {
168  OUTcntrl.out_index = 0;
169  }
170  if (OUTcntrl.out_usecurplot) {
171  plot = plot_cur;
172  }
174  *outd->plotPtr = (GENERIC*)OUTcntrl.out_rundesc;
175  return (OK);
176  }
177 
178  if (ft_curckt && ft_curckt->ci_ckt == outd->circuitPtr)
179  cktName = ft_curckt->ci_name;
180  else {
181  /* hack for test system interface */
182  if (outd->circuitPtr == NULL)
183  cktName = (char*)outd->refName + (strlen(outd->refName) + 1);
184  else
185  cktName = "circuit name";
186  }
187 
188  /* Check to see if we want to print informational data. */
189  if (cp_getvar(kw_printinfo, VT_BOOL, (char *) &printinfo))
190  fprintf(cp_err, "(debug printing enabled)\n");
191 
192  run = alloc(struct runDesc);
193  *outd->plotPtr = (GENERIC*)run;
194 
195  /* First fill in some general stuff. */
196  run->analysis = outd->analysisPtr;
197  run->circuit = outd->circuitPtr;
198  run->name = copy(cktName);
199  run->type = copy(outd->analName);
200  if (outd->numPts <= 0)
201  run->numPoints = 1;
202  else
203  run->numPoints = outd->numPts;
204 
205  if (OUTcntrl.out_check) {
206  run->numPoints = 1;
207  }
208  if (OUTcntrl.out_keepplot) {
209  OUTcntrl.out_rundesc = (char*)run;
210  }
211 
212  /* Now let's see which of these things we need. First toss in the
213  * reference vector. Then toss in anything that getSaves() tells
214  * us to save that we can find in the name list. Finally unpack
215  * the remaining saves into parameters.
216  */
217  numsaves = ft_getSaves(&saves);
218  if (numsaves) {
219  savesused = (bool *) tmalloc(sizeof (bool) * numsaves);
220  saveall = false;
221  for (i = 0; i < numsaves; i++)
222  if (cieq(saves[i], "all")) {
223  saveall = true;
224  savesused[i] = true;
225  break;
226  }
227  }
228 
229  /* Pass 0. */
230  if (outd->refName) {
231  addDataDesc(run, outd->refName, outd->refType, -1);
232  for (i = 0; i < numsaves; i++)
233  if (name_eq(saves[i], outd->refName)) {
234  savesused[i] = true;
235  }
236  }
237  else {
238  run->refIndex = -1;
239  }
240 
241  /* Pass 1. */
242  if (numsaves && !saveall) {
243  for (i = 0; i < numsaves; i++) {
244  for (j = 0; j < outd->numNames; j++)
245  if (name_eq(saves[i], outd->dataNames[j])) {
246  addDataDesc(run, outd->dataNames[j],
247  outd->dataType, j);
248  savesused[i] = true;
249  break;
250  }
251  }
252  }
253  else {
254  for (i = 0; i < outd->numNames; i++)
255  if (!outd->refName ||
256  !name_eq(outd->dataNames[i], outd->refName)) {
257  addDataDesc(run, outd->dataNames[i], outd->dataType, i);
258  }
259  }
260 
261  /* Pass 2. */
262  for (i = 0; i < numsaves; i++) {
263  if (savesused[i])
264  continue;
265  if (!parseSpecial(saves[i], namebuf, parambuf, depbuf)) {
266  if (numsaves == 1 && !saves[0])
267  fprintf(cp_err, "Warning: no variables saved\n");
268  else
269  fprintf(cp_err, "Warning: can't parse '%s': ignored\n",
270  saves[i]);
271  continue;
272  }
273  /* Now, if there's a dep variable, do we already have it? */
274  if (*depbuf) {
275  for (j = 0; j < run->numData; j++)
276  if (name_eq(depbuf, run->data[j].name))
277  break;
278  if (j == run->numData) {
279  /* Better add it. */
280  for (j = 0; j < outd->numNames; j++)
281  if (name_eq(depbuf, outd->dataNames[j]))
282  break;
283  if (j == outd->numNames) {
284  fprintf(cp_err,
285  "Warning: can't find '%s': value '%s' ignored\n",
286  depbuf, saves[i]);
287  continue;
288  }
289  addDataDesc(run, outd->dataNames[j], outd->dataType, j);
290  savesused[i] = true;
291  depind = j;
292  }
293  else
294  depind = run->data[j].outIndex;
295  }
296  addSpecialDesc(run, saves[i], namebuf, parambuf, depind);
297  }
298 
299  if (numsaves)
300  txfree((char*)savesused);
301 
302  /* Now that we have our own data structures built up, let's see what
303  * nutmeg wants us to do.
304  */
305  run->writeOut = ft_getOutReq(&run->fp, &run->runPlot, &run->binary,
306  run->type, run->name);
307 
308  if (run->writeOut)
309  fileInit(run);
310  else
311  plotInit(run,outd->initValue,outd->finalValue,outd->step,plot);
312 
313  if (outd->refName && run->runPlot)
314  run->runPlot->pl_ndims = 1;
315 
316  return (OK);
317 }
318 
319 
320 static int
321 addDataDesc(run, name, type, ind)
322 
323 runDesc *run;
324 char *name;
325 int type;
326 int ind;
327 {
328  dataDesc *data;
329 
330  if (!run->numData)
331  run->data = (dataDesc *) tmalloc(sizeof (dataDesc));
332  else
333  run->data = (dataDesc *) trealloc((char *) run->data,
334  sizeof (dataDesc) * (run->numData + 1));
335  data = &run->data[run->numData];
336  /* so freeRun will get nice NULL pointers for the fields we don't set */
337  bzero(data, sizeof(dataDesc));
338 
339  data->name = copy(name);
340  data->type = type;
341  data->regular = true;
342  data->outIndex = ind;
343 
344  if (ind == -1) {
345  /* It's the reference vector. */
346  run->refIndex = run->numData;
347  }
348 
349  run->numData++;
350 
351  return (OK);
352 }
353 
354 
355 static int
356 addSpecialDesc(run, name, devname, param, depind)
357 
358 runDesc *run;
359 char *name;
360 char *devname;
361 char *param;
362 int depind;
363 {
364  dataDesc *data;
365  char *unique; /* unique char * from back-end */
366 
367  if (!run->numData)
368  run->data = (dataDesc *) tmalloc(sizeof (dataDesc));
369  else
370  run->data = (dataDesc *) trealloc((char *) run->data,
371  sizeof (dataDesc) * (run->numData + 1));
372  data = &run->data[run->numData];
373  /* so freeRun will get nice NULL pointers for the fields we don't set */
374  bzero(data, sizeof(dataDesc));
375 
376  data->name = copy(name);
377 
378  unique = devname;
379  INPinsert(&unique, (INPtables *) ft_curckt->ci_symtab);
380  data->specName = unique;
381 
382  data->specParamName = copy(param);
383 
384  data->specIndex = depind;
385  data->specType = -1;
386  data->specFast = NULL;
387  data->regular = false;
388 
389  run->numData++;
390 
391  return (OK);
392 }
393 
394 
395 int
396 OUTdata(plotPtr, refValue, valuePtr)
397 
398 GENERIC *plotPtr;
399 IFvalue *refValue;
400 IFvalue *valuePtr;
401 {
402  runDesc *run = (runDesc *) plotPtr;
403 
404  if (OUTcntrl.out_check) {
405 
406  if (refValue->rValue < OUTcntrl.out_points[OUTcntrl.out_index])
407  return (OK);
408 
409  addPointToPlot(run,refValue,valuePtr,false);
412  else
413  OUTcntrl.out_fail = false;
414 
417  OUTendit = true;
418  }
419  return (OK);
420  }
421 
422  run->pointCount++;
423 
424  if (run->writeOut) {
425  addPointToFile(run,refValue,valuePtr);
426  }
427  else {
428  addPointToPlot(run,refValue,valuePtr,true);
429  gr_iplot(run->runPlot);
430  }
431 
432  if (ft_bpcheck(run->runPlot, run->pointCount) == false)
433  shouldstop = true;
434 
435  vec_gc();
436  return (OK);
437 }
438 
439 
440 int
441 OUTsetDims(plotPtr,dims,numDims)
442 
443 GENERIC *plotPtr;
444 int *dims, numDims;
445 {
446  runDesc *run = (runDesc *) plotPtr;
447  struct dvec *v;
448  int i, j;
449 
450  if (OUTcntrl.out_check) {
451  OUTcntrl.out_index = 0;
452  if (OUTcntrl.out_fail)
453  OUTendit = true;
454  return (OK);
455  }
456 
457  if (run->writeOut)
458  return (OK);
459 
460  for (i = 0; i < run->numData; i++) {
461  v = run->data[i].vec;
462  for (j = 0; j < numDims; j++)
463  v->v_dims[j] = dims[j];
464  v->v_numdims = numDims;
465  }
466  return (OK);
467 }
468 
469 
470 static void
471 addPointToFile(run,refValue,valuePtr)
472 
473 runDesc *run;
474 IFvalue *refValue;
475 IFvalue *valuePtr;
476 {
477  int i;
478  IFvalue val;
479 
480  fileStartPoint(run->fp, run->binary, run->pointCount);
481 
482  if (run->refIndex != -1) {
483  if (run->isComplex)
484  fileAddComplexValue(run->fp, run->binary, refValue->cValue);
485  else
486  fileAddRealValue(run->fp, run->binary, refValue->rValue);
487  }
488 
489  for (i = 0; i < run->numData; i++) {
490  /* we've already printed reference vec first */
491  if (run->data[i].outIndex == -1) continue;
492 
493  if (run->data[i].regular) {
494  if(run->data[i].type == IF_REAL)
495  fileAddRealValue(run->fp, run->binary,
496  valuePtr->v.vec.rVec
497  [run->data[i].outIndex]);
498  else if (run->data[i].type == IF_COMPLEX)
499  fileAddComplexValue(run->fp, run->binary,
500  valuePtr->v.vec.cVec
501  [run->data[i].outIndex]);
502  else
503  fprintf(stderr, "OUTdata: unsupported data type\n");
504  }
505  else {
506  /* should pre-check instance */
507  if (!getSpecial(&run->data[i], run, &val))
508  continue;
509  if (run->data[i].type == IF_REAL)
510  fileAddRealValue(run->fp, run->binary,
511  val.rValue);
512  else if (run->data[i].type == IF_COMPLEX)
513  fileAddComplexValue(run->fp, run->binary,
514  val.cValue);
515  else
516  fprintf(stderr, "OUTdata: unsupported data type\n");
517  }
518  }
519  fileEndPoint(run->fp, run->binary);
520 }
521 
522 
523 static void
524 addPointToPlot(run,refValue,valuePtr,inc)
525 
526 runDesc *run;
527 IFvalue *refValue;
528 IFvalue *valuePtr;
529 bool inc; /* increment dvec length if true */
530 {
531  int i;
532  IFvalue val;
533 
534  for (i = 0; i < run->numData; i++) {
535  if (run->data[i].outIndex == -1) {
536  if (run->data[i].type == IF_REAL)
537  plotAddRealValue(&run->data[i],
538  refValue->rValue,inc);
539  else if (run->data[i].type == IF_COMPLEX)
540  plotAddComplexValue(&run->data[i],
541  refValue->cValue,inc);
542  }
543  else if (run->data[i].regular) {
544  if (run->data[i].type == IF_REAL)
545  plotAddRealValue(&run->data[i],
546  valuePtr->v.vec.rVec
547  [run->data[i].outIndex],inc);
548  else if (run->data[i].type == IF_COMPLEX)
549  plotAddComplexValue(&run->data[i],
550  valuePtr->v.vec.cVec
551  [run->data[i].outIndex],inc);
552  }
553  else {
554  /* should pre-check instance */
555  if (!getSpecial(&run->data[i], run, &val))
556  continue;
557  if (run->data[i].type == IF_REAL)
558  plotAddRealValue(&run->data[i],
559  val.rValue,inc);
560  else if (run->data[i].type == IF_COMPLEX)
561  plotAddComplexValue(&run->data[i],
562  val.cValue,inc);
563  else
564  fprintf(stderr, "OUTdata: unsupported data type\n");
565  }
566  }
567 }
568 
569 
570 int
571 OUTendPlot(plotPtr)
572 
573 GENERIC *plotPtr;
574 {
575  runDesc *run = (runDesc *) plotPtr;
576 
577  if (OUTcntrl.out_check) {
578  if (OUTcntrl.out_end)
579  (*OUTcntrl.out_end)();
580  OUTendit = false;
581  return (OK);
582  }
583  else if (OUTcntrl.out_keepplot) {
584  return (OK);
585  }
586 
587  if (run->writeOut)
588  fileEnd(run);
589  else {
590  gr_end_iplot();
591  plotEnd(run);
592  }
593 
594  freeRun(run);
595 
596  return (OK);
597 }
598 
599 
600 /* The file writing routines. */
601 
602 static void
604 
605 runDesc *run;
606 {
607  int i;
608  char *name, buf[BSIZE_SP];
609  int type;
610 
611  /* This is a hack. */
612  run->isComplex = false;
613  for (i = 0; i < run->numData; i++)
614  if (run->data[i].type == IF_COMPLEX)
615  run->isComplex = true;
616 
617  fprintf(run->fp, "Title: %s\n", run->name);
618  fprintf(run->fp, "Date: %s\n", datestring());
619  fprintf(run->fp, "Plotname: %s\n", run->type);
620  fprintf(run->fp, "Flags: %s\n", run->isComplex ? "complex" : "real");
621  fprintf(run->fp, "No. Variables: %d\n", run->numData);
622  fprintf(run->fp, "No. Points: ");
623 
624  fflush(run->fp); /* Gotta do this for LATTICE. */
625  run->pointPos = ftell(run->fp);
626  fprintf(run->fp, "0 \n"); /* Save 8 spaces here. */
627 
628  fprintf(run->fp, "Command: version %s\n", ft_sim->version);
629  fprintf(run->fp, "Variables:\n");
630 
631  for (i = 0; i < run->numData; i++) {
632  if (isdigit(*run->data[i].name)) {
633  (void) sprintf(buf, "v(%s)", run->data[i].name);
634  name = buf;
635  }
636  else {
637  name = run->data[i].name;
638  }
639  if (substring("#branch", name))
640  type = SV_CURRENT;
641  else if (cieq(name, "time"))
642  type = SV_TIME;
643  else if (cieq(name, "frequency"))
644  type = SV_FREQUENCY;
645  else
646  type = SV_VOLTAGE;
647  fprintf(run->fp, "\t%d\t%s\t%s\n", i, name,
648  ft_typenames(type));
649  }
650 
651  fprintf(run->fp, "%s:\n", run->binary ? "Binary" : "Values");
652 
653  return;
654 }
655 
656 
657 static void
658 fileStartPoint(fp, bin, num)
659 
660 FILE *fp;
661 bool bin;
662 int num;
663 {
664  if (!bin)
665  fprintf(fp, "%d", num - 1);
666 
667  return;
668 }
669 
670 
671 static void
672 fileAddRealValue(fp, bin, value)
673 
674 FILE *fp;
675 bool bin;
676 double value;
677 {
678  if (bin)
679  fwrite((char *) &value, sizeof (double), 1, fp);
680  else
681  fprintf(fp, "\t%.*e\n", DOUBLE_PRECISION, value);
682 
683  return;
684 }
685 
686 
687 static void
688 fileAddComplexValue(fp, bin, value)
689 
690 FILE *fp;
691 bool bin;
692 IFcomplex value;
693 {
694 
695  if (bin) {
696  fwrite((char *) &value.real, sizeof (double), 1, fp);
697  fwrite((char *) &value.imag, sizeof (double), 1, fp);
698  }
699  else {
700  fprintf(fp, "\t%.*e,%.*e\n", DOUBLE_PRECISION, value.real,
701  DOUBLE_PRECISION, value.imag);
702  }
703 
704 }
705 
706 
707 /* ARGSUSED */ /* until some code gets written */
708 static void
709 fileEndPoint(fp, bin)
710 
711 FILE *fp;
712 bool bin;
713 {
714  return;
715 }
716 
717 
718 /* Here's the hack... Run back and fill in the number of points. */
719 
720 static void
722 
723 runDesc *run;
724 {
725  long place;
726 
727  if (run->fp == stdout)
728  return;
729  fflush(run->fp); /* For LATTICE... */
730  place = ftell(run->fp);
731  fseek(run->fp, run->pointPos, 0);
732  fprintf(run->fp, "%d", run->pointCount);
733  fseek(run->fp, place, 0);
734  fflush(run->fp);
735 
736  return;
737 }
738 
739 
740 /* The plot maintenance routines. */
741 
742 static void
743 plotInit(run,tstart,tstop,tstep,plot)
744 
745 runDesc *run;
746 double tstart, tstop, tstep;
747 struct plot *plot;
748 {
749  struct plot *pl;
750  char buf[100];
751  struct dvec *v;
752  dataDesc *dd;
753  int i;
754 
755  if (plot == NULL) {
756  pl = plot_alloc(run->type);
757  plot_new(pl);
759  }
760  else
761  pl = plot;
762  pl->pl_title = copy(run->name);
763  pl->pl_name = copy(run->type);
764  pl->pl_date = copy(datestring( ));
765  pl->pl_ndims = 0;
766  pl->pl_start = tstart;
767  pl->pl_stop = tstop;
768  pl->pl_step = tstep;
769  run->runPlot = pl;
770 
771  /* This is a hack. */
772  /* if any of them are complex, make them all complex */
773  run->isComplex = false;
774  for (i = 0; i < run->numData; i++) {
775  if (run->data[i].type == IF_COMPLEX) run->isComplex = true;
776  }
777 
778  for (i = 0; i < run->numData; i++) {
779  dd = &run->data[i];
780  v = alloc(struct dvec);
781  if (isdigit(*dd->name)) {
782  (void) sprintf(buf, "v(%s)", dd->name);
783  v->v_name = copy(buf);
784  }
785  else
786  v->v_name = copy(dd->name);
787  if (substring("#branch", v->v_name) || eq(v->v_name,"isweep"))
788  v->v_type = SV_CURRENT;
789  else if (cieq(v->v_name, "time"))
790  v->v_type = SV_TIME;
791  else if (cieq(v->v_name, "frequency"))
792  v->v_type = SV_FREQUENCY;
793  else
794  v->v_type = SV_VOLTAGE;
795  v->v_length = 0;
796  v->v_rlength = run->numPoints;
797  v->v_scale = NULL;
798 
799  if (!run->isComplex) {
800  v->v_flags = VF_REAL;
801  v->v_realdata = (double *)
802  tmalloc(v->v_rlength * sizeof(double));
803  }
804  else {
805  v->v_flags = VF_COMPLEX;
806  v->v_compdata = (complex *)
807  tmalloc(v->v_rlength * sizeof(complex));
808  }
809  vec_newperm(v);
810  dd->vec = v;
811  }
812 }
813 
814 
815 static void
816 plotAddRealValue(desc, value, inc)
817 
818 dataDesc *desc;
819 double value;
820 bool inc;
821 {
822  struct dvec *v = desc->vec;
823 
824  if (isreal(v)) {
825  if (!inc) {
826  v->v_realdata[0] = value;
827  v->v_length = 1;
828  return;
829  }
830  if (v->v_length >= v->v_rlength) {
831  v->v_realdata = (double *) trealloc((char *) v->v_realdata,
832  sizeof (double) * (v->v_length + 1));
833  v->v_rlength = v->v_length + 1;
834  }
835  v->v_realdata[v->v_length] = value;
836  }
837  else {
838  /* a real parading as a VF_COMPLEX */
839  if (!inc) {
840  v->v_compdata[0].cx_real = value;
841  v->v_compdata[0].cx_imag = (double) 0;
842  v->v_length = 1;
843  return;
844  }
845  if (v->v_length >= v->v_rlength) {
846  v->v_compdata = (complex *) trealloc((char *) v->v_compdata,
847  sizeof (complex) * (v->v_length + 1));
848  v->v_rlength = v->v_length + 1;
849  }
850  v->v_compdata[v->v_length].cx_real = value;
851  v->v_compdata[v->v_length].cx_imag = (double) 0;
852  }
853  v->v_length++;
854 
855  return;
856 }
857 
858 
859 static void
860 plotAddComplexValue(desc, value, inc)
861 
862 dataDesc *desc;
863 IFcomplex value;
864 bool inc;
865 {
866  struct dvec *v = desc->vec;
867 
868  if (!inc) {
869  v->v_compdata[0].cx_real = value.real;
870  v->v_compdata[0].cx_imag = value.imag;
871  v->v_length = 1;
872  return;
873  }
874  if (v->v_length >= v->v_rlength) {
875  v->v_compdata = (complex *) trealloc((char *) v->v_compdata,
876  sizeof (complex) * (v->v_length + 1));
877  v->v_rlength = v->v_length + 1;
878  }
879  v->v_compdata[v->v_length].cx_real = value.real;
880  v->v_compdata[v->v_length].cx_imag = value.imag;
881  v->v_length++;
882 
883  return;
884 }
885 
886 
887 /* ARGSUSED */ /* until some code gets written */
888 static void
890 
891 runDesc *run;
892 {
893  return;
894 }
895 
896 
897 /* ParseSpecial takes something of the form "@name[param,index]" and rips
898  * out name, param, and index.
899  */
900 
901 static bool
902 parseSpecial(name, dev, param, ind)
903 
904 char *name;
905 char *dev;
906 char *param;
907 char *ind;
908 {
909  char *s;
910 
911  *dev = *param = *ind = '\0';
912 
913  if (*name != '@')
914  return (false);
915  name++;
916 
917  s = dev;
918  while (*name && (*name != '['))
919  *s++ = *name++;
920  *s = '\0';
921  if (!*name)
922  return (true);
923  name++;
924 
925  s = param;
926  while (*name && (*name != ',') && (*name != ']'))
927  *s++ = *name++;
928  *s = '\0';
929  if (*name == ']')
930  return (!name[1] ? true : false);
931  else if (!*name)
932  return (false);
933  name++;
934 
935  s = ind;
936  while (*name && (*name != ']'))
937  *s++ = *name++;
938  *s = '\0';
939  if (*name && !name[1])
940  return (true);
941  else
942  return (false);
943 }
944 
945 
946 /* This routine must match two names with or without a V() around them. */
947 
948 static bool
949 name_eq(n1, n2)
950 
951 char *n1, *n2;
952 {
953  char *s;
954 
955  if (!n1 || !n2)
956  return (false);
957  s = strchr(n1,'(');
958  if (s)
959  n1 = s+1;
960  s = strchr(n2,'(');
961  if (s)
962  n2 = s+1;
963 
964  for ( ; ; n1++,n2++) {
965  if ((*n1 == 0 || *n1 == ')') && (*n2 == 0 || *n2 == ')'))
966  return (true);
967  if (*n1 != *n2)
968  break;
969  }
970  return (false);
971 }
972 
973 
974 static bool
975 getSpecial(desc, run, val)
976 
977 dataDesc *desc;
978 runDesc *run;
979 IFvalue *val;
980 {
981  IFvalue selector;
982  struct variable *vv;
983 
984  selector.iValue = desc->specIndex;
985  if (INPaName(desc->specParamName, val, run->circuit, &desc->specType,
986  desc->specName, &desc->specFast, ft_sim, &desc->type,
987  &selector) == OK) {
988  desc->type &= (IF_REAL | IF_COMPLEX); /* mask out other bits */
989  return (true);
990  }
991  if (vv = if_getstat(run->circuit, &desc->name[1],
992  (wordlist **)NULL)) {
993  /* skip @ sign */
994  desc->type = IF_REAL;
995  if (vv->va_type == VT_REAL)
996  val->rValue = vv->va_real;
997  else if (vv->va_type == VT_NUM)
998  val->rValue = vv->va_num;
999  else if (vv->va_type == VT_BOOL)
1000  val->rValue = (vv->va_bool ? 1.0 : 0.0);
1001  else {
1002  return (false); /* not a real */
1003  }
1004  tfree(vv);
1005  return (true);
1006  }
1007  return (false);
1008 }
1009 
1010 
1011 static void
1013 
1014 runDesc *run;
1015 {
1016 
1017  int i;
1018 
1019  for (i = 0; i < run->numData; i++) {
1020  txfree(run->data[i].name);
1021  txfree(run->data[i].specParamName);
1022  }
1023  txfree((char*)run->data);
1024  txfree(run->type);
1025  txfree(run->name);
1026  txfree((char*)run);
1027 
1028 }
1029 
1030 
1031 int
1033 {
1034  static REQUEST reqst = { checkup_option, 0 };
1035 
1036  if (!ft_batchmode)
1037  DevInput(&reqst, 0);
1038  if (ft_intrpt || shouldstop) {
1039  ft_intrpt = shouldstop = false;
1040  return (1);
1041  }
1042  else
1043  return (0);
1044 }
1045 
1046 
1047 /* Print out error messages. */
1048 
1049 static struct mesg {
1050  char *string;
1051  long flag;
1052 } msgs[] = {
1053  { "Warning", ERR_WARNING } ,
1054  { "Fatal error", ERR_FATAL } ,
1055  { "Panic", ERR_PANIC } ,
1056  { "Note", ERR_INFO } ,
1057  { NULL, 0 }
1058 } ;
1059 
1060 
1061 int
1062 OUTerror(flags,format,names)
1063 
1064 int flags;
1065 char *format;
1066 IFuid *names;
1067 {
1068 
1069  struct mesg *m;
1070  char buf[BSIZE_SP], *s, *bptr;
1071  int nindex = 0;
1072 
1073  if ((flags == ERR_INFO) && !printinfo)
1074  return (OK);
1075 
1076  for (m = msgs; m->flag; m++)
1077  if (flags & m->flag)
1078  fprintf(cp_err, "%s: ", m->string);
1079 
1080  for (s = format, bptr = buf; *s; s++) {
1081  if (*s == '%' && (s == format || *(s-1) != '%') && *(s+1) == 's') {
1082  strcpy(bptr, names[nindex]);
1083  bptr += strlen(names[nindex]);
1084  s++;
1085  nindex++;
1086  }
1087  else {
1088  *bptr++ = *s;
1089  }
1090  }
1091  *bptr = '\0';
1092  fprintf(cp_err, "%s\n", buf);
1093  fflush(cp_err);
1094  return (OK);
1095 }
FILE * fp
Definition: outitf.c:51
int isComplex
Definition: outitf.c:55
bool ft_intrpt
Definition: main.c:47
static char buf[MAXPROMPT]
Definition: arg.c:18
int numPts
Definition: outdata.h:22
int OUTbeginPlot(GENERIC *outdp)
Definition: outitf.c:149
#define BSIZE_SP
Definition: misc.h:19
Definition: outitf.c:1049
#define eq(a, b)
Definition: misc.h:29
double initValue
Definition: outdata.h:24
int out_max
Definition: outdata.h:42
#define IF_COMPLEX
Definition: ifsim.h:109
bool regular
Definition: outitf.c:29
static bool name_eq()
static void addPointToFile()
bool cp_getvar(char *n, int t, char *r)
Definition: help.c:184
struct plot * plot_alloc()
int v_rlength
Definition: ftedata.h:35
int out_keepplot
Definition: outdata.h:39
IFsimulator * ft_sim
Definition: main.c:111
void plot_new()
static void fileAddComplexValue()
int out_index
Definition: outdata.h:41
char * pl_typename
Definition: ftedata.h:65
char * pl_date
Definition: ftedata.h:63
#define VF_REAL
Definition: fteconst.h:39
#define DOUBLE_PRECISION
Definition: outitf.c:24
#define ERR_PANIC
Definition: ifsim.h:519
static void fileStartPoint()
int cieq()
bool writeOut
Definition: outitf.c:48
char * pl_title
Definition: ftedata.h:62
int out_usecurplot
Definition: outdata.h:38
GENERIC * circuit
Definition: outitf.c:42
char * strcpy()
int refType
Definition: outdata.h:17
char * pl_name
Definition: ftedata.h:64
char * kw_printinfo
Definition: options.c:406
Definition: cddefs.h:119
double pl_step
Definition: ftedata.h:78
IFuid * dataNames
Definition: outdata.h:19
struct plot * plot_cur
Definition: vectors.c:43
IFuid analName
Definition: outdata.h:15
union uIFvalue::@13::@14 vec
GENERIC * analysis
Definition: outitf.c:41
int numNames
Definition: outdata.h:18
#define ERR_FATAL
Definition: ifsim.h:518
int type
Definition: outitf.c:28
char * name
Definition: outitf.c:27
static struct mesg msgs[]
int outIndex
Definition: outitf.c:30
void vec_gc()
Definition: vectors.c:681
double cx_imag
Definition: cpstd.h:31
char * datestring()
Definition: time.c:37
dataDesc * data
Definition: outitf.c:47
Definition: cpstd.h:29
char * ci_ckt
Definition: ftedefs.h:27
#define SV_VOLTAGE
Definition: fteconst.h:14
Definition: ftedata.h:61
static void fileAddRealValue()
int OUTsetDims(GENERIC *plotPtr, int *dims, int numDims)
Definition: outitf.c:441
double step
Definition: outdata.h:26
int v_dims[MAXDIMS]
Definition: ftedata.h:41
Definition: outitf.c:40
int specType
Definition: outitf.c:34
int windowCount
Definition: outitf.c:56
char * specParamName
Definition: outitf.c:32
char * OUTcntrlInit()
Definition: outitf.c:111
char * out_rundesc
Definition: outdata.h:44
int iValue
Definition: ifsim.h:232
static void fileInit()
int numPoints
Definition: outitf.c:54
double rValue
Definition: ifsim.h:233
int bzero(char *ptr, int num)
Definition: string.c:357
#define alloc(type)
Definition: cdmacs.h:21
FILE * m
Definition: proc2mod.c:47
complex * v_compdata
Definition: ftedata.h:29
static bool parseSpecial()
int numData
Definition: outitf.c:45
char * copy()
bool ft_bpcheck()
#define ERR_INFO
Definition: ifsim.h:520
double cx_real
Definition: cpstd.h:30
static int addDataDesc()
char va_type
Definition: cpstd.h:42
int INPinsert()
void(* out_destroy)()
Definition: outdata.h:52
IFcomplex cValue
Definition: ifsim.h:234
FILE * cp_err
Definition: help.c:101
#define OK
Definition: iferrmsg.h:17
char * tmalloc()
long pointPos
Definition: outitf.c:52
double * out_points
Definition: outdata.h:40
GENERIC * IFuid
Definition: ifsim.h:72
struct runDesc runDesc
int substring()
static void plotInit()
static void addPointToPlot()
#define tfree(x)
Definition: cdmacs.h:22
struct plot * runPlot
Definition: outitf.c:50
void txfree()
static void fileEnd()
#define NULL
Definition: spdefs.h:121
Definition: types.c:18
void vec_newperm()
struct circ * ft_curckt
Definition: main.c:184
struct variable * if_getstat(char *n, char *c, wordlist **w)
Definition: main.c:248
GENERIC * specFast
Definition: outitf.c:35
GENERIC * circuitPtr
Definition: outdata.h:13
#define VT_NUM
Definition: cpstd.h:61
char * type
Definition: outitf.c:44
bool ft_getOutReq(FILE **fpp, struct plot **plotp, bool *binp, char *name, char *title)
Definition: runcoms.c:385
struct dvec * v_scale
Definition: ftedata.h:45
static struct sOUTcontrol OUTcntrl
Definition: outitf.c:62
int OUTstopnow()
Definition: outitf.c:1032
int ft_getSaves()
int OUTerror(int flags, char *format, IFuid *names)
Definition: outitf.c:1062
#define ERR_WARNING
Definition: ifsim.h:517
#define isreal(v)
Definition: ftedata.h:54
int pointCount
Definition: outitf.c:53
Definition: ftedata.h:24
int specIndex
Definition: outitf.c:33
bool OUTendit
Definition: outitf.c:60
char * v_name
Definition: ftedata.h:25
#define VT_BOOL
Definition: cpstd.h:60
char * ft_typenames()
int pl_ndims
Definition: ftedata.h:74
Definition: cpstd.h:21
#define SV_CURRENT
Definition: fteconst.h:15
#define IF_REAL
Definition: ifsim.h:108
char * specName
Definition: outitf.c:31
double finalValue
Definition: outdata.h:25
static void plotAddComplexValue()
void DevInput()
void gr_iplot()
return(True)
int v_type
Definition: ftedata.h:26
static bool shouldstop
Definition: outitf.c:106
int OUTendPlot(GENERIC *plotPtr)
Definition: outitf.c:571
int OUTdata(GENERIC *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
Definition: outitf.c:396
bool binary
Definition: outitf.c:49
static void freeRun()
bool ft_batchmode
Definition: main.c:98
double pl_start
Definition: ftedata.h:76
int out_fail
Definition: outdata.h:43
GENERIC * analysisPtr
Definition: outdata.h:14
static bool printinfo
Definition: outitf.c:107
char * name
Definition: outitf.c:43
struct _complex complex
Definition: cpstd.h:33
#define VT_REAL
Definition: cpstd.h:62
struct dvec * vec
Definition: outitf.c:37
static void fileEndPoint()
int v_numdims
Definition: ftedata.h:40
char * ci_symtab
Definition: ftedefs.h:28
int refIndex
Definition: outitf.c:46
char * ci_name
Definition: ftedefs.h:26
int refIndex
Definition: outitf.c:36
struct uIFvalue::@13 v
int INPaName()
static void out_destroy()
Definition: outitf.c:130
void gr_end_iplot()
Definition: iplot.c:397
int v_length
Definition: ftedata.h:34
double pl_stop
Definition: ftedata.h:77
long flag
Definition: outitf.c:1051
short v_flags
Definition: ftedata.h:27
double * v_realdata
Definition: ftedata.h:28
char * version
Definition: ifsim.h:359
void plot_setcur()
double imag
Definition: ifsim.h:227
int out_check
Definition: outdata.h:37
static void plotAddRealValue()
#define SV_FREQUENCY
Definition: fteconst.h:13
char * string
Definition: outitf.c:1050
GENERIC ** plotPtr
Definition: outdata.h:21
void(* out_end)()
Definition: outdata.h:51
#define VF_COMPLEX
Definition: fteconst.h:40
static void plotEnd()
IFuid refName
Definition: outdata.h:16
int(* out_evaluate)()
Definition: outdata.h:50
char * trealloc()
Definition: cpstd.h:41
#define SV_TIME
Definition: fteconst.h:12
struct dataDesc dataDesc
double real
Definition: ifsim.h:226
char GENERIC
Definition: ifsim.h:27
int dataType
Definition: outdata.h:20
static bool getSpecial()
static int addSpecialDesc()