Jspice3
vectors.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: 1985 Wayne A. Christopher
5  1992 Stephen R. Whiteley
6 ****************************************************************************/
7 
8 /*
9  * Routines for dealing with the vector database.
10  */
11 
12 #include "spice.h"
13 #include "ftedefs.h"
14 
15 static double boltz;
16 static double c;
17 static double e;
18 static double echarge;
19 static complex ii;
20 static double kelvin;
21 static double pi;
22 static double planck;
23 
24 #ifdef __STDC__
25 static void vecfree(struct dvec*);
26 static struct dvec *findvec(char*,struct plot*);
27 static int veccmp(struct dvec**,struct dvec**);
28 static int namecmp(char*,char*);
29 #else
30 static void vecfree();
31 static struct dvec *findvec();
32 static int veccmp();
33 static int namecmp();
34 #endif
35 
36 /* Where 'constants' go when defined on initialization. */
37 
38 static struct plot constantplot = {
39  "Constant values", "Sat Aug 16 10:55:15 PDT 1986", "constants",
40  "constants", NULL, NULL, NULL, NULL, NULL, NULL, NULL, true
41 } ;
42 
45 
46 
47 void
49 
50 /* Load in a rawfile. */
51 char *file;
52 {
53  struct plot *pl, *np, *pp;
54 
55  out_printf("Loading raw data file (\"%s\") . . . ", file);
56  pl = raw_read(file);
57  if (pl)
58  out_printf("done.\n");
59  else
60  out_printf("no data read.\n");
61 
62  /* This is a minor annoyance -- we should reverse the plot list so
63  * they get numbered in the correct order.
64  */
65  for (pp = pl, pl = NULL; pp; pp = np) {
66  np = pp->pl_next;
67  pp->pl_next = pl;
68  pl = pp;
69  }
70  for (; pl; pl = np) {
71  np = pl->pl_next;
72  plot_add(pl);
73  /* Don't want to get too many "plot not written" messages. */
74  pl->pl_written = true;
75  }
76 }
77 
78 
79 void
81 
82 struct plot *pl;
83 {
84  struct dvec *v;
85  struct plot *tp;
86  char *s, buf[BSIZE_SP];
87  wordlist *wl, *wl0;
88  int plot_num, n;
89 
90  out_printf("Title: %s\nName: %s\nDate: %s\n\n", pl->pl_title,
91  pl->pl_name, pl->pl_date);
92 
93  if (plot_cur)
94  plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom);
95 
96  wl = wl0 = (wordlist*)htab_wl(pl->pl_hashtab);
97  while (wl) {
99  wl = wl->wl_next;
100  }
101  wl_free(wl0);
102  cp_addkword(CT_VECTOR, "all");
103  plot_num = 1;
104  if (!(s = ft_plotabbrev(pl->pl_name)))
105  s = "unknown";
106  for (tp = plot_list; tp; tp = tp->pl_next) {
107  if (ciprefix(s,tp->pl_typename)) {
108  n = atoi(tp->pl_typename + strlen(s));
109  if (n >= plot_num)
110  plot_num = n+1;
111  }
112  }
113  (void) sprintf(buf, "%s%d", s, plot_num);
114  pl->pl_typename = copy(buf);
115  plot_new(pl);
116  cp_addkword(CT_PLOT, buf);
117  pl->pl_ccom = cp_kwswitch(CT_VECTOR, (char *) NULL);
118  plot_setcur(pl->pl_typename);
119 }
120 
121 
122 void
124 
125 /* Add a plot to the plot list. This is different from plot_add() in that
126  * all this does is update the list and the variable $plots.
127  */
128 struct plot *pl;
129 {
130  pl->pl_next = plot_list;
131  plot_list = pl;
132 
133  return;
134 }
135 
136 
137 void
139 
140 struct plot *pl;
141 {
142  struct dvec *v, *nv;
143  struct plot *op;
144  wordlist *wl0, *wl;
145 
146  if (eq(pl->pl_typename, "constants")) {
147  fprintf(cp_err, "Error: can't destroy the constant plot\n");
148  return;
149  }
150 
151  /* clear temporary dvecs */
152  for (v = pl->pl_dvecs; v; v = nv) {
153  nv = v->v_next;
154  vecfree(v);
155  }
156 
157  /* clear permanent dvecs */
158  wl0 = (wordlist*)htab_list(pl->pl_hashtab);
159  for (wl = wl0; wl; wl = wl->wl_next) {
160  v = (struct dvec *)((char**)wl->wl_word)[1];
161  vecfree(v);
162  }
163  wl_free(wl0);
164  htab_free(pl->pl_hashtab,false);
165  txfree((char*)pl->pl_hashtab);
166 
167  va_free(pl->pl_env);
168  if (pl == plot_list) {
169  plot_list = pl->pl_next;
170  if (pl == plot_cur) {
171  plot_cur = plot_list;
172  pl->pl_ccom = cp_kwswitch(CT_VECTOR,plot_cur->pl_ccom);
173  }
174  }
175  else {
176  for (op = plot_list; op; op = op->pl_next)
177  if (op->pl_next == pl)
178  break;
179  if (!op) {
180  fprintf(cp_err,
181  "Internal Error: kill plot -- not in list\n");
182  goto xxx;
183  }
184  op->pl_next = pl->pl_next;
185  if (pl == plot_cur) {
186  plot_cur = op;
187  pl->pl_ccom = cp_kwswitch(CT_VECTOR,plot_cur->pl_ccom);
188  }
189  }
190 xxx:
191  cp_ccfreetrie(pl->pl_ccom);
192  txfree(pl->pl_title);
193  txfree(pl->pl_date);
194  txfree(pl->pl_name);
195  txfree(pl->pl_typename);
196  wl_free(pl->pl_commands);
197  txfree((char*)pl);
198 
199  return;
200 }
201 
202 
203 void
205 
206 /* Make a plot the current one. This gets called by cp_usrset() when one
207  * does a 'set curplot = name'.
208  */
209 char *name;
210 {
211  struct plot *pl;
212 
213  if (cieq(name, "new")) {
214  pl = plot_alloc("unknown");
215  pl->pl_title = copy("Anonymous");
216  pl->pl_name = copy("unknown");
217  pl->pl_date = copy(datestring( ));
218  plot_new(pl);
219  plot_cur = pl;
220  return;
221  }
222  for (pl = plot_list; pl; pl = pl->pl_next)
223  if (plot_prefix(name, pl->pl_typename))
224  break;
225  if (!pl) {
226  fprintf(cp_err, "Error: no such plot named %s\n", name);
227  return;
228  }
229  if (plot_cur)
230  plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom);
231  plot_cur = pl;
232  return;
233 }
234 
235 
236 void
238 
239 /* Execute the commands for a plot. This is done whenever a plot becomes
240  * the current plot.
241  */
242 wordlist *wl;
243 {
244  bool inter;
245 
246  inter = cp_interactive;
247  cp_interactive = false;
248  cp_pushcontrol();
249  while (wl) {
250  (void) cp_evloop(wl->wl_word);
251  wl = wl->wl_next;
252  }
253  cp_popcontrol();
254  cp_interactive = inter;
255  return;
256 }
257 
258 
259 struct plot *
261 
262 /* Create a new plot structure. This just fills in the typename and sets up
263  * the ccom struct.
264  */
265 char *name;
266 {
267  struct plot *pl = alloc(struct plot), *tp;
268  char *s;
269  char buf[BSIZE_SP];
270  int plot_num, n;
271 
272  if (!(s = ft_plotabbrev(name)))
273  s = "unknown";
274  plot_num = 1;
275  for (tp = plot_list; tp; tp = tp->pl_next) {
276  if (ciprefix(s,tp->pl_typename)) {
277  n = atoi(tp->pl_typename + strlen(s));
278  if (n >= plot_num)
279  plot_num = n+1;
280  }
281  }
282  (void) sprintf(buf, "%s%d", s, plot_num);
283  pl->pl_typename = copy(buf);
284  cp_addkword(CT_PLOT, buf);
285  s = cp_kwswitch(CT_VECTOR, (char *) NULL);
286  cp_addkword(CT_VECTOR, "all");
287  pl->pl_ccom = cp_kwswitch(CT_VECTOR, s);
288  return (pl);
289 }
290 
291 
292 bool
293 plot_prefix(pre, str)
294 
295 /* This function will match "op" with "op1", but not "op1" with "op12". */
296 char *pre, *str;
297 {
298  if (!*pre)
299  return (true);
300  while (*pre && *str) {
301  if (*pre != *str)
302  break;
303  pre++; str++;
304  }
305  if (*pre || (*str && isdigit(pre[-1])))
306  return (false);
307  else
308  return (true);
309 }
310 
311 
312 void
314 
315 struct dvec *d;
316 {
317 #ifdef FTEDEBUG
318  if (ft_vecdb)
319  fprintf(cp_err, "new temporary vector %s\n", d->v_name);
320 #endif
321  d->v_flags &= ~VF_PERMANENT;
322  if (!d->v_plot)
323  d->v_plot = plot_cur;
324  d->v_next = d->v_plot->pl_dvecs;
325  d->v_plot->pl_dvecs = d;
326  return;
327 }
328 
329 
330 void
332 
333 struct dvec *d;
334 {
335 #ifdef FTEDEBUG
336  if (ft_vecdb)
337  fprintf(cp_err, "new permanent vector %s\n", d->v_name);
338 #endif
339  d->v_flags |= VF_PERMANENT;
340  if (plot_cur->pl_scale == NULL)
341  plot_cur->pl_scale = d;
342  if (!d->v_plot)
343  d->v_plot = plot_cur;
344  if (plot_cur->pl_hashtab == NULL)
345  plot_cur->pl_hashtab = htab_init();
346  htab_add(d->v_name,(void*)d,plot_cur->pl_hashtab);
347  return;
348 }
349 
350 
351 void
353 
354 /* Remove a vector from the current plot, if it is there. */
355 char *name;
356 {
357  struct dvec *v;
358 
359  v = (struct dvec *)htab_get(name,plot_cur->pl_hashtab);
360  if (!v)
361  return;
362  htab_delete(name,plot_cur->pl_hashtab);
363  if (v->v_plot && v->v_plot->pl_scale == v)
364  v->v_plot->pl_scale = NULL;
365  vecfree(v);
366 
367  /* Remove from the keyword list. */
368  cp_remkword(CT_VECTOR, name);
369  return;
370 }
371 
372 
373 static void
375 
376 struct dvec *v;
377 {
378  txfree(v->v_name);
379  vec_dlfree(v->v_link2);
380  if (isreal(v)) {
381  txfree((char*)v->v_realdata);
382  }
383  else {
384  txfree((char*)v->v_compdata);
385  }
386  txfree((char*)v);
387 }
388 
389 
390 void
392 
393 struct dvlist *dl;
394 {
395  struct dvlist *dn;
396 
397  for (; dl; dl = dn) {
398  dn = dl->dl_next;
399  txfree((char*)dl);
400  }
401 }
402 
403 
404 struct dvec *
406 
407 /* Get a vector by name. This deals with v(1), etc. almost properly. Also,
408  * it checks for pre-defined vectors.
409  */
410 char *word;
411 struct plot *plot;
412 {
413  struct dvec *d;
414  char buf[BSIZE_SP], buf2[BSIZE_SP], cc, *s;
415 
416  d = findvec(word, plot);
417 
418  /* scanf("%c(%s)" doesn't do what it should do. ) */
419  if (!d && (sscanf(word, "%c(%s", /* ) */ &cc, buf) == 2) &&
420  /* ( */ ((s = strrchr(buf, ')')) != NULL) &&
421  (*(s + 1) == '\0')) {
422  *s = '\0';
423  if (prefix("i(", /* ) */ word)) {
424  /* Spice dependency... */
425  (void) sprintf(buf2, "%s#branch", buf);
426  (void) strcpy(buf, buf2);
427  }
428  d = findvec(buf, plot);
429  }
430  return (d);
431 }
432 
433 
434 #define SPECCHAR '@'
435 
436 
437 struct dvec *
438 vec_get(word)
439 
440 /* This is the main lookup routine for names. The possible types of names are:
441  * name An ordinary vector.
442  * plot.name A vector from a particular plot.
443  * @device[parm] A device parameter.
444  * @model[parm] A model parameter.
445  * @param A circuit parameter.
446  * For the @ cases, we construct a dvec with length 1 to hold the value.
447  * In the other two cases, either the plot or the name can be "all", a
448  * wildcard.
449  * The vector name may have imbedded dots -- if the first component is a plot
450  * name, it is considered the plot, otherwise the current plot is used.
451  */
452 char *word;
453 {
454  struct dvec *d;
455  struct plot *pl;
456  char buf[BSIZE_SP], *s, *wd, *name, *param;
457  int i = 0;
458  struct variable *vv;
459  struct dvlist *dl0, *dl, *dll;
460 
461  wd = word = copy(word); /* Gets mangled below... */
462 
463  if (strchr(word, '.')) {
464  /* Snag the plot... */
465  for (i = 0, s = word; *s != '.'; i++, s++)
466  buf[i] = *s;
467  buf[i] = '\0';
468  if (cieq(buf, "all")) {
469  word = ++s;
470  pl = NULL; /* NULL pl signifies a wildcard. */
471  }
472  else {
473  for (pl = plot_list; pl && !plot_prefix(buf,
474  pl->pl_typename); pl = pl->pl_next)
475  ;
476  if (pl) {
477  word = ++s;
478  }
479  else {
480  /* This used to be an error... */
481  pl = plot_cur;
482  }
483  }
484  }
485  else
486  pl = plot_cur;
487 
488  if (pl) {
489  d = vec_fromplot(word, pl);
490  if (!d)
491  d = vec_fromplot(word, &constantplot);
492  }
493  else {
494  dl0 = NULL;
495  for (pl = plot_list; pl; pl = pl->pl_next) {
496  if (cieq(pl->pl_typename, "constants"))
497  continue;
498  d = vec_fromplot(word, pl);
499  if (d) {
500  if (dl0 == NULL)
501  dl0 = dl = alloc(struct dvlist);
502  else {
503  dl->dl_next = alloc(struct dvlist);
504  dl = dl->dl_next;
505  }
506  if (d->v_link2) {
507  for (dll = d->v_link2; dll; dll = dll->dl_next) {
508  dl->dl_dvec = dll->dl_dvec;
509  if (dll->dl_next) {
510  dl->dl_next = alloc(struct dvlist);
511  dl = dl->dl_next;
512  }
513  }
514  }
515  else
516  dl->dl_dvec = d;
517  }
518  }
519  if (!dl0) {
520  fprintf(cp_err,
521  "Error: plot wildcard (name %s) matches nothing\n", word);
522  txfree(wd);
523  return (NULL);
524  }
525  d = alloc(struct dvec);
526  vec_newtemp(d);
527  d->v_link2 = dl0;
528  d->v_name = copy("list");
529  vec_sort(d);
530  txfree(wd);
531  return (d);
532  }
533  if (!d && (*word == SPECCHAR)) {
534  /* This is a special quantity... */
535  if (ft_nutmeg) {
536  fprintf(cp_err,
537  "Error: circuit parameters only available with spice\n");
538  txfree(wd);
539  return (false);
540  }
541  name = ++word;
542  for (param = name; *param && (*param != '['); param++)
543  ;
544  if (*param) {
545  *param++ = '\0';
546  for (s = param; *s && *s != ']'; s++)
547  ;
548  *s = '\0';
549  }
550  else
551  param = NULL;
552  vv = (*if_getparam)(ft_curckt->ci_ckt, &name,
553  param, 0,(wordlist**)NULL);
554  if (!vv) {
555  txfree(wd);
556  return (NULL);
557  }
558  d = alloc(struct dvec);
559  d->v_name = copy(word);
560  d->v_type = SV_NOTYPE;
561  d->v_flags |= VF_REAL; /* No complex values yet... */
562  d->v_realdata = (double *) tmalloc(sizeof (double));
563  d->v_length = 1;
564  *d->v_realdata = vv->va_real;
565  vec_newtemp(d);
566  va_free(vv);
567  txfree(wd);
568  return (d);
569  }
570  txfree(wd);
571  return (d);
572 }
573 
574 
575 static struct dvec *
576 findvec(word, pl)
577 
578 /* Find a named vector in a plot. */
579 char *word;
580 struct plot *pl;
581 {
582  struct dvec *d;
583  char buf[BSIZE_SP], *s;
584  wordlist *wl, *wl0;
585  struct dvlist *dl, *dl0;
586 
587  if (pl == NULL)
588  return (NULL);
589 
590  if (word && *word) {
591 
592  if (cieq(word, "all")) {
593 
594  /* create a dummy vector with link2 pointing at dvlist */
595  wl0 = (wordlist*)htab_list(pl->pl_hashtab);
596  if (wl0 == NULL)
597  return (NULL);
598  dl0 = NULL;
599  for (wl = wl0; wl; wl = wl->wl_next) {
600  d = (struct dvec*)((char**)wl->wl_word)[1];
601  if (!dl0)
602  dl = dl0 = alloc(struct dvlist);
603  else {
604  dl->dl_next = alloc(struct dvlist);
605  dl = dl->dl_next;
606  }
607  dl->dl_dvec = d;
608  }
609  if (dl0) {
610  d = alloc(struct dvec);
611  vec_newtemp(d);
612  d->v_name = copy("list");
613  d->v_link2 = dl0;
614  wl_free(wl0);
615  return (d);
616  }
617  return (NULL);
618  }
619 
620  d = (struct dvec *)htab_get(word,pl->pl_hashtab);
621  if (!d) {
622  buf[0] = 'v';
623  buf[1] = '(';
624  s = buf+2;
625  while (*word)
626  *s++ = *word++;
627  *s++ = ')';
628  *s = '\0';
629  d = (struct dvec *)htab_get(buf,pl->pl_hashtab);
630  }
631  return (d);
632  }
633  return (NULL);
634 }
635 
636 
637 /* Create a copy of a vector. */
638 
639 struct dvec *
641 
642 struct dvec *v;
643 {
644  struct dvec *nv;
645  int i;
646 
647  if (!v)
648  return (NULL);
649  nv = alloc(struct dvec);
650  nv->v_name = copy(v->v_name);
651  nv->v_type = v->v_type;
652  nv->v_flags = v->v_flags;
653  nv->v_length = v->v_length;
654  nv->v_plot = v->v_plot;
655  nv->v_minsignal = v->v_minsignal;
656  nv->v_maxsignal = v->v_maxsignal;
657  nv->v_defcolor = v->v_defcolor;
658  nv->v_gridtype = v->v_gridtype;
659  nv->v_plottype = v->v_plottype;
660  nv->v_scale = v->v_scale;
661  nv->v_numdims = v->v_numdims;
662  for (i = 0; i < v->v_numdims; i++)
663  nv->v_dims[i] = v->v_dims[i];
664  if (v->v_length) {
665  if (isreal(v)) {
666  nv->v_realdata =
667  (double *) tmalloc(sizeof(double) * v->v_length);
668  DCOPY(v->v_realdata, nv->v_realdata, v->v_length);
669  }
670  else {
671  nv->v_compdata =
672  (complex *) tmalloc(sizeof(complex) * v->v_length);
673  CCOPY(v->v_compdata, nv->v_compdata, v->v_length);
674  }
675  }
676  return (nv);
677 }
678 
679 
680 void
682 
683 /* Clear out the temporary vectors linked into the plot */
684 {
685  struct plot *pl;
686  struct dvec *d, *nd;
687 
688  for (pl = plot_list; pl; pl = pl->pl_next) {
689  for (d = pl->pl_dvecs; d; d = nd) {
690  nd = d->v_next;
691 
692  if (ft_vecdb)
693  fprintf(cp_err,"vec_gc: throwing away %s.%s\n",
694  pl->pl_typename, d->v_name);
695  if (pl->pl_scale == d) /* this shouldn't happen */
696  pl->pl_scale = NULL;
697  vecfree(d);
698  }
699  pl->pl_dvecs = NULL;
700  }
701 }
702 
703 
704 bool
705 vec_eq(v1, v2)
706 
707 /* This is something we do in a few places... Since vectors get copied a
708  * lot, we can't just compare pointers to tell if two vectors are 'really'
709  * the same.
710  */
711 struct dvec *v1, *v2;
712 {
713  char *s1, *s2;
714  bool i;
715 
716  if (v1->v_plot != v2->v_plot)
717  return (false);
718 
719  s1 = vec_basename(v1);
720  s2 = vec_basename(v2);
721 
722  i = cieq(s1, s2);
723  txfree(s1);
724  txfree(s2);
725 
726  return (i);
727 }
728 
729 
730 char *
732 
733 /* Return the name of the vector with the plot prefix stripped off. This
734  * is no longer trivial since '.' doesn't always mean 'plot prefix'.
735  */
736 struct dvec *v;
737 {
738  char buf[BSIZE_SP], *t, *s;
739  int i;
740 
741  if (strchr(v->v_name, '.')) {
742  for (t = v->v_name, i = 0; *t && *t != '.'; t++)
743  buf[i++] = *t;
744  buf[i] = '\0';
745  if (cieq(v->v_plot->pl_typename, buf))
746  (void) strcpy(buf, t + 1);
747  else
748  (void) strcpy(buf, v->v_name);
749  }
750  else
751  (void) strcpy(buf, v->v_name);
752 
753  for (t = buf; isspace(*t); t++)
754  ;
755  s = t;
756  for (t = s; *t; t++)
757  ;
758  while ((t > s) && isspace(t[-1]))
759  *--t = '\0';
760  return (copy(s));
761 }
762 
763 
764 void
766 
767 /* Sort all the vectors in d, first by plot name and then by vector name.
768  * Do the right thing with numbers.
769  */
770 struct dvec *d;
771 {
772  struct dvec **array;
773  struct dvlist *dl;
774  int i;
775 
776  for (i = 0,dl = d->v_link2; dl; i++,dl = dl->dl_next) ;
777  if (i < 2)
778  return;
779  array = (struct dvec **) tmalloc(i * sizeof (struct dvec *));
780  for (i = 0,dl = d->v_link2; dl; i++,dl = dl->dl_next)
781  array[i] = dl->dl_dvec;
782 
783  qsort((char *) array, i, sizeof (struct dvec *),
784 #ifdef __STDC__
785  (int(*)(const void*,const void*))veccmp);
786 #else
787  veccmp);
788 #endif
789 
790  /* Now string everything back together... */
791  for (i = 0,dl = d->v_link2; dl; i++,dl = dl->dl_next)
792  dl->dl_dvec = array[i];
793  txfree((char*)array);
794  return;
795 }
796 
797 
798 static int
799 veccmp(d1, d2)
800 
801 struct dvec **d1, **d2;
802 {
803  int i;
804 
805  if ((i = namecmp((*d1)->v_plot->pl_typename,
806  (*d2)->v_plot->pl_typename)) != 0)
807  return (i);
808  return (namecmp((*d1)->v_name, (*d2)->v_name));
809 }
810 
811 
812 static int
814 
815 /* If there are imbedded numeric strings, compare them numerically, not
816  * alphabetically.
817  */
818 char *s, *t;
819 {
820  int i, j;
821 
822  for (;;) {
823  while ((*s == *t) && !isdigit(*s) && *s)
824  s++, t++;
825  if (!*s)
826  return (0);
827  if ((*s != *t) && (!isdigit(*s) || !isdigit(*t)))
828  return (*s - *t);
829 
830  /* The beginning of a number... Grab the two numbers
831  * and then compare them...
832  */
833  for (i = 0; isdigit(*s); s++)
834  i = i * 10 + *s - '0';
835  for (j = 0; isdigit(*t); t++)
836  j = j * 10 + *t - '0';
837 
838  if (i != j)
839  return (i - j);
840  }
841 }
842 
843 
844 struct dvec *
846 
847 /* This routine takes a multi-dimensional vector and turns it into a family
848  * of 1-d vectors, linked together with v_link2. It is here so that plot
849  * can do intelligent things.
850  */
851 struct dvec *v;
852 {
853  int size, numvecs, i, j, count[MAXDIMS];
854  struct dvec *vecs, *d;
855  struct dvlist *dl, *dl0;
856  char buf[BSIZE_SP];
857 
858  if (v->v_numdims < 2)
859  return (v);
860 
861  size = v->v_dims[v->v_numdims - 1];
862  numvecs = v->v_length/size;
863 
864  for (i = 0, dl = dl0 = NULL; i < numvecs; i++) {
865  if (!dl0)
866  dl0 = dl = alloc(struct dvlist);
867  else {
868  dl->dl_next = alloc(struct dvlist);
869  dl = dl->dl_next;
870  }
871  dl->dl_dvec = alloc(struct dvec);
872  vec_newtemp(dl->dl_dvec);
873  }
874  for (i = 0; i < MAXDIMS; i++)
875  count[i] = 0;
876  for (dl = dl0, j = 0; j < numvecs; j++, dl = dl->dl_next) {
877  d = dl->dl_dvec;
878  (void) strcpy(buf, v->v_name);
879  for (i = 0; i < v->v_numdims - 1; i++)
880  (void) sprintf(buf + strlen(buf), "[%d]", count[i]);
881  d->v_name = copy(buf);
882  d->v_type = v->v_type;
883  d->v_flags = v->v_flags;
884  d->v_minsignal = v->v_minsignal;
885  d->v_maxsignal = v->v_maxsignal;
886  d->v_gridtype = v->v_gridtype;
887  d->v_plottype = v->v_plottype;
888  d->v_scale = v->v_scale;
889  /* Don't copy the default color, since there will be many
890  * of these things...
891  */
892  d->v_numdims = 1;
893  d->v_length = size;
894 
895  if (isreal(v)) {
896  d->v_realdata =
897  (double *) tmalloc(sizeof(double) * size);
898  DCOPY(v->v_realdata + size * j, d->v_realdata, size);
899  }
900  else {
901  d->v_compdata =
902  (complex *) tmalloc(sizeof(complex) * size);
903  CCOPY(v->v_compdata + size * j, d->v_compdata, size);
904  }
905 
906  for (i = v->v_numdims - 2; i >= 0; i--) {
907  if (count[i]++ < v->v_dims[i])
908  break;
909  else
910  count[i] = 0;
911  }
912  if (i < 0)
913  break;
914  }
915  if (dl0) {
916  vecs = alloc(struct dvec);
917  vec_newtemp(vecs);
918  vecs->v_name = copy("list");
919  vecs->v_link2 = dl0;
920  return (vecs);
921  }
922  return (NULL);
923 }
924 
struct plot * plot_list
Definition: vectors.c:44
static int veccmp()
struct plot * plot_alloc(char *name)
Definition: vectors.c:260
static char buf[MAXPROMPT]
Definition: arg.c:18
#define BSIZE_SP
Definition: misc.h:19
#define eq(a, b)
Definition: misc.h:29
double v_minsignal
Definition: ftedata.h:30
Definition: variable.c:632
int ciprefix()
Definition: subckt.c:18
void ft_loadfile(char *file)
Definition: vectors.c:48
void vec_remove(char *name)
Definition: vectors.c:352
char * pl_typename
Definition: ftedata.h:65
char * pl_date
Definition: ftedata.h:63
#define VF_REAL
Definition: fteconst.h:39
struct dvlist * v_link2
Definition: ftedata.h:44
int cieq()
char * pl_title
Definition: ftedata.h:62
#define prefix(x, y)
Definition: readhelp.c:39
void out_printf()
char * strcpy()
char * pl_name
Definition: ftedata.h:64
Definition: cddefs.h:119
void htab_delete()
static complex ii
Definition: vectors.c:19
Definition: objects.c:1183
if(TDesc==NULL)
Definition: cd.c:1326
struct dvec * pl_dvecs
Definition: ftedata.h:67
Definition: ftedata.h:49
void vec_newtemp(struct dvec *d)
Definition: vectors.c:313
struct dvec * vec_fromplot(char *word, struct plot *plot)
Definition: vectors.c:405
void plot_setcur(char *name)
Definition: vectors.c:204
char * datestring()
Definition: time.c:37
#define CT_PLOT
Definition: fteconst.h:90
Definition: cpstd.h:29
static double e
Definition: vectors.c:17
char * ci_ckt
Definition: ftedefs.h:27
Definition: ftedata.h:61
struct plot * raw_read()
Definition: library.c:18
static void vecfree()
int v_dims[MAXDIMS]
Definition: ftedata.h:41
#define VF_PERMANENT
Definition: fteconst.h:46
struct dvec * v_next
Definition: ftedata.h:43
char * vec_basename(struct dvec *v)
Definition: vectors.c:731
void * pl_hashtab
Definition: ftedata.h:66
char * ft_plotabbrev()
#define alloc(type)
Definition: cdmacs.h:21
complex * v_compdata
Definition: ftedata.h:29
void va_free()
#define DCOPY(s, d, n)
Definition: ftedefs.h:55
#define CCOPY(s, d, n)
Definition: ftedefs.h:59
char * copy()
#define SPECCHAR
Definition: vectors.c:434
void * htab_wl()
char * pl_ccom
Definition: ftedata.h:72
struct dvec * vec_mkfamily(struct dvec *v)
Definition: vectors.c:845
bool vec_eq(struct dvec *v1, struct dvec *v2)
Definition: vectors.c:705
struct dvlist * dl_next
Definition: ftedata.h:51
static double echarge
Definition: vectors.c:18
void wl_free()
FILE * cp_err
Definition: help.c:101
char * tmalloc()
void * htab_init()
Definition: hash.c:27
struct plot * plot_cur
Definition: vectors.c:43
static struct dvec * findvec()
void cp_remkword()
Definition: cddefs.h:237
bool cp_interactive
Definition: help.c:100
void htab_free()
double v_maxsignal
Definition: ftedata.h:31
#define MAXDIMS
Definition: ftedata.h:22
void txfree()
struct dvec * pl_scale
Definition: ftedata.h:68
#define NULL
Definition: spdefs.h:121
struct circ * ft_curckt
Definition: main.c:184
GRIDTYPE v_gridtype
Definition: ftedata.h:32
bool pl_written
Definition: ftedata.h:73
struct plot * v_plot
Definition: ftedata.h:42
char * v_defcolor
Definition: ftedata.h:39
void plot_delete(struct plot *pl)
Definition: vectors.c:138
struct dvec * v_scale
Definition: ftedata.h:45
static double c
Definition: vectors.c:16
void vec_gc()
Definition: vectors.c:681
void vec_newperm(struct dvec *d)
Definition: vectors.c:331
#define isreal(v)
Definition: ftedata.h:54
Definition: ftedata.h:24
struct dvec * dl_dvec
Definition: ftedata.h:50
Definition: fteparse.h:28
char * v_name
Definition: ftedata.h:25
Definition: cpstd.h:21
qsort()
Definition: string.c:375
void plot_docoms(wordlist *wl)
Definition: vectors.c:237
struct plot * pl_next
Definition: ftedata.h:69
int v_type
Definition: ftedata.h:26
void htab_add()
void * htab_get()
struct wordlist * wl_next
Definition: cpstd.h:23
static double planck
Definition: vectors.c:22
void plot_new(struct plot *pl)
Definition: vectors.c:123
int v_numdims
Definition: ftedata.h:40
void cp_ccfreetrie()
bool ft_nutmeg
Definition: main.c:161
PLOTTYPE v_plottype
Definition: ftedata.h:33
int count
Definition: output.c:152
char * wl_word
Definition: cpstd.h:22
static int namecmp()
void vec_sort(struct dvec *d)
Definition: vectors.c:765
void cp_pushcontrol()
Definition: front.c:1066
static struct plot constantplot
Definition: vectors.c:38
static double boltz
Definition: vectors.c:15
void cp_popcontrol()
Definition: front.c:1051
int v_length
Definition: ftedata.h:34
int cp_evloop()
short v_flags
Definition: ftedata.h:27
double * v_realdata
Definition: ftedata.h:28
void cp_addkword()
struct dvec * vec_get(char *word)
Definition: vectors.c:438
struct dvec * vec_copy(struct dvec *v)
Definition: vectors.c:640
static double pi
Definition: vectors.c:21
Definition: cddefs.h:192
Definition: cpstd.h:41
void * htab_list()
bool ft_vecdb
Definition: options.c:25
void vec_dlfree(struct dvlist *dl)
Definition: vectors.c:391
static double kelvin
Definition: vectors.c:20
void plot_add(struct plot *pl)
Definition: vectors.c:80
#define CT_VECTOR
Definition: fteconst.h:96
char * cp_kwswitch()
#define SV_NOTYPE
Definition: fteconst.h:11
bool plot_prefix(char *pre, char *str)
Definition: vectors.c:293