📄 vectors.c
字号:
/**********Copyright 1990 Regents of the University of California. All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group **********//* * Routines for dealing with the vector database. */#include "spice.h"#include "misc.h"#include "util.h"#include "cpdefs.h"#include "ftedefs.h"#include "ftedata.h"#include "suffix.h"static double boltz;static double c;static double e;static double echarge;static complex ii;static double kelvin;static double pi;static double planck;static int namecmp();static int veccmp();static struct dvec *findvec();static struct dvec *sortvecs();/* Where 'constants' go when defined on initialization. */static struct plot constantplot = { "Constant values", "Sat Aug 16 10:55:15 PDT 1986", "constants", "const", NULL, NULL, NULL, NULL, NULL, NULL, true} ;struct plot *plot_cur = &constantplot;struct plot *plot_list = &constantplot;int plotl_changed; /* true after a load */int plot_num = 1;/* Load in a rawfile. */voidft_loadfile(file) char *file;{ struct plot *pl, *np, *pp; fprintf(cp_out, "Loading raw data file (\"%s\") . . . ", file); pl = raw_read(file); if (pl) fprintf(cp_out, "done.\n"); else fprintf(cp_out, "no data read.\n"); /* This is a minor annoyance -- we should reverse the plot list so * they get numbered in the correct order. */ for (pp = pl, pl = NULL; pp; pp = np) { np = pp->pl_next; pp->pl_next = pl; pl = pp; } for (; pl; pl = np) { np = pl->pl_next; plot_add(pl); /* Don't want to get too many "plot not written" messages. */ pl->pl_written = true; } plot_num++; plotl_changed = true; return;}voidplot_add(pl) struct plot *pl;{ struct dvec *v; struct plot *tp; char *s, buf[BSIZE_SP]; fprintf(cp_out, "Title: %s\nName: %s\nDate: %s\n\n", pl->pl_title, pl->pl_name, pl->pl_date); if (plot_cur) plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom); for (v = pl->pl_dvecs; v; v = v->v_next) cp_addkword(CT_VECTOR, v->v_name); cp_addkword(CT_VECTOR, "all"); if (!(s = ft_plotabbrev(pl->pl_name))) s = "unknown"; do { (void) sprintf(buf, "%s%d", s, plot_num); for (tp = plot_list; tp; tp = tp->pl_next) if (cieq(tp->pl_typename, buf)) { plot_num++; break; } } while (tp); pl->pl_typename = copy(buf); plot_new(pl); cp_addkword(CT_PLOT, buf); pl->pl_ccom = cp_kwswitch(CT_VECTOR, (char *) NULL); plot_setcur(pl->pl_typename); return;}/* Remove a vector from the database, if it is there. */voidvec_remove(name) char *name;{ struct dvec *ov; for (ov = plot_cur->pl_dvecs; ov; ov = ov->v_next) { if (cieq(name, ov->v_name) && (ov->v_flags & VF_PERMANENT)) break; } if (!ov) return; ov->v_flags &= ~VF_PERMANENT; /* Remove from the keyword list. */ cp_remkword(CT_VECTOR, name); return;}/* Get a vector by name. This deals with v(1), etc. almost properly. Also, * it checks for pre-defined vectors. */struct dvec *vec_fromplot(word, plot) char *word; struct plot *plot;{ struct dvec *d; char buf[BSIZE_SP], buf2[BSIZE_SP], cc, *s; d = findvec(word, plot); if (!d) { (void) strcpy(buf, word); for (s = buf; *s; s++) if (isupper(*s)) *s = tolower(*s); d = findvec(buf, plot); } if (!d) { (void) strcpy(buf, word); for (s = buf; *s; s++) if (islower(*s)) *s = *s - 'a' + 'A'; d = findvec(buf, plot); } /* scanf("%c(%s)" doesn't do what it should do. ) */ if (!d && (sscanf(word, "%c(%s", /* ) */ &cc, buf) == 2) && /* ( */ ((s = rindex(buf, ')')) != NULL) && (*(s + 1) == '\0')) { *s = '\0'; if (prefix("i(", /* ) */ word)) { /* Spice dependency... */ (void) sprintf(buf2, "%s#branch", buf); (void) strcpy(buf, buf2); } d = findvec(buf, plot); } return (d);}/* This is the main lookup routine for names. The possible types of names are: * name An ordinary vector. * plot.name A vector from a particular plot. * @device[parm] A device parameter. * @model[parm] A model parameter. * @param A circuit parameter. * For the @ cases, we construct a dvec with length 1 to hold the value. * In the other two cases, either the plot or the name can be "all", a * wildcard. * The vector name may have imbedded dots -- if the first component is a plot * name, it is considered the plot, otherwise the current plot is used. */#define SPECCHAR '@'struct dvec *vec_get(word) char *word;{ struct dvec *d, *end = NULL, *newv = NULL; struct plot *pl; char buf[BSIZE_SP], *s, *wd, *whole, *name, *param; int i = 0; struct variable *vv; wd = word = copy(word); /* Gets mangled below... */ if (index(word, '.')) { /* Snag the plot... */ for (i = 0, s = word; *s != '.'; i++, s++) buf[i] = *s; buf[i] = '\0'; if (cieq(buf, "all")) { word = ++s; pl = NULL; /* NULL pl signifies a wildcard. */ } else { for (pl = plot_list; pl && !plot_prefix(buf, pl->pl_typename); pl = pl->pl_next) ; if (pl) { word = ++s; } else { /* This used to be an error... */ pl = plot_cur; } } } else pl = plot_cur; if (pl) { d = vec_fromplot(word, pl); if (!d) d = vec_fromplot(word, &constantplot); } else { for (pl = plot_list; pl; pl = pl->pl_next) { if (cieq(pl->pl_typename, "const")) continue; d = vec_fromplot(word, pl); if (d) { if (end) end->v_link2 = d; else newv = d; for (end = d; end->v_link2; end = end->v_link2) ; } } d = newv; if (!d) { fprintf(cp_err, "Error: plot wildcard (name %s) matches nothing\n", word); return (NULL); } } if (!d && (*word == SPECCHAR)) { /* This is a special quantity... */ if (ft_nutmeg) { fprintf(cp_err, "Error: circuit parameters only available with spice\n"); return (false); } whole = copy(word); name = ++word; for (param = name; *param && (*param != '['); param++) ; if (*param) { *param++ = '\0'; for (s = param; *s && *s != ']'; s++) ; *s = '\0'; } else param = NULL; if (ft_curckt) { vv = (*if_getparam)(ft_curckt->ci_ckt, &name, param, 0, 0); if (!vv) { tfree(whole); tfree(wd); return (NULL); } } else { fprintf(cp_err, "Error: No circuit loaded.\n"); tfree(whole); tfree(wd); return (NULL); } d = alloc(struct dvec); ZERO(d, struct dvec); d->v_name = copy(whole); d->v_type = SV_NOTYPE; d->v_flags |= VF_REAL; /* No complex values yet... */ d->v_realdata = (double *) tmalloc(sizeof (double)); d->v_length = 1; *d->v_realdata = vv->va_real; vec_new(d); tfree(whole); tfree(wd); return (d); } tfree(wd); return (sortvecs(d));}/* Find a named vector in a plot. We are careful to copy the vector * if v_link2 is set, because otherwise we will get screwed up. */static struct dvec *findvec(word, pl) char *word; struct plot *pl;{ struct dvec *d, *newv = NULL, *end = NULL, *v; char buf[BSIZE_SP]; if (pl == NULL) return (NULL); if (cieq(word, "all")) { for (d = pl->pl_dvecs; d; d = d->v_next) { if (d->v_flags & VF_PERMANENT) { if (d->v_link2) { v = vec_copy(d); vec_new(v); } else v = d; if (end) end->v_link2 = v; else newv = v; end = v; } } return (newv); } for (d = pl->pl_dvecs; d; d = d->v_next) if (cieq(word, d->v_name) && (d->v_flags & VF_PERMANENT)) break; if (!d) { (void) sprintf(buf, "v(%s)", word); for (d = pl->pl_dvecs; d; d = d->v_next) if (cieq(buf, d->v_name) && (d->v_flags & VF_PERMANENT)) break; } if (d && d->v_link2) { d = vec_copy(d); vec_new(d); } return (d);}/* Execute the commands for a plot. This is done whenever a plot becomes * the current plot. */voidplot_docoms(wl) wordlist *wl;{ bool inter; inter = cp_interactive; cp_interactive = false; while (wl) { (void) cp_evloop(wl->wl_word); wl = wl->wl_next; } cp_resetcontrol(); cp_interactive = inter; return;}/* Create a copy of a vector. */struct dvec *vec_copy(v) struct dvec *v;{ struct dvec *nv; int i; if (!v) return (NULL); nv = alloc(struct dvec); nv->v_name = copy(v->v_name); nv->v_type = v->v_type; nv->v_flags = v->v_flags & ~VF_PERMANENT; if (isreal(v)) { nv->v_realdata = (double *) tmalloc(sizeof (double) * v->v_length); bcopy((char *) v->v_realdata, (char *) nv->v_realdata, sizeof (double) * v->v_length); nv->v_compdata = NULL; } else { nv->v_realdata = NULL; nv->v_compdata = (complex *) tmalloc(sizeof (complex) * v->v_length); bcopy((char *) v->v_compdata, (char *) nv->v_compdata, sizeof (complex) * v->v_length); } nv->v_minsignal = v->v_minsignal; nv->v_maxsignal = v->v_maxsignal; nv->v_gridtype = v->v_gridtype; nv->v_plottype = v->v_plottype; nv->v_length = v->v_length; nv->v_rlength = 0; /*XXX???*/ nv->v_outindex = 0; /*XXX???*/ nv->v_linestyle = 0; /*XXX???*/ nv->v_color = 0; /*XXX???*/ nv->v_defcolor = v->v_defcolor; nv->v_numdims = v->v_numdims; for (i = 0; i < v->v_numdims; i++) nv->v_dims[i] = v->v_dims[i]; nv->v_plot = v->v_plot; nv->v_next = NULL; nv->v_link2 = NULL; nv->v_scale = v->v_scale; return (nv);}/* Create a new plot structure. This just fills in the typename and sets up * the ccom struct. */struct plot *plot_alloc(name) char *name;{ struct plot *pl = alloc(struct plot), *tp; char *s; char buf[BSIZE_SP]; ZERO(pl, struct plot); if (!(s = ft_plotabbrev(name))) s = "unknown"; do { (void) sprintf(buf, "%s%d", s, plot_num); for (tp = plot_list; tp; tp = tp->pl_next) if (cieq(tp->pl_typename, buf)) { plot_num++; break; } } while (tp); pl->pl_typename = copy(buf); cp_addkword(CT_PLOT, buf); s = cp_kwswitch(CT_VECTOR, (char *) NULL); cp_addkword(CT_VECTOR, "all"); pl->pl_ccom = cp_kwswitch(CT_VECTOR, s);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -