⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 postcoms.c

📁 spice中支持多层次元件模型仿真的可单独运行的插件源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group **********//* * Various post-processor commands having to do with vectors. */#include "spice.h"#include "util.h"#include "misc.h"#include "cpdefs.h"#include "ftedefs.h"#include "fteparse.h"#include "ftedata.h"#include "suffix.h"static int dcomp();static void pvec();static void killplot( );voidcom_let(wl)    wordlist *wl;{    char *p, *q, *s;    int	indices[MAXDIMS];    int	numdims;    wordlist fake_wl;    int need_open;    int offset, length;    struct pnode *nn;    struct dvec *n, *t;    int i, cube;    int j, depth;    int newvec;    char *rhs;    fake_wl.wl_next = NULL;    if (!wl) {        com_display((wordlist *) NULL);        return;    }    p = wl_flatten(wl);    /* extract indices */    numdims = 0;    if (rhs = index(p, '=')) {	*rhs++ = 0;    } else {	fprintf(cp_err, "Error: bad let syntax\n");	return;    }    if (s = index(p, '[')) {	need_open = 0;	*s++ = 0;	while (!need_open || *s == '[') {	    depth = 0;	    if (need_open)		s++;	    for (q = s; *q && (*q != ']' && *q != ',' || depth > 0); q++) {		switch (*q) {		case '[':		    depth += 1;		    break;		case ']':		    depth -= 1;		    break;		}	    }	    if (depth != 0 || !*q) {		printf("syntax error specifying index\n");		return;	    }	    if (*q == ']')		need_open = 1;	    else		need_open = 0;	    if (*q)	        *q++ = 0;	    /* evaluate expression between s and q */	    fake_wl.wl_word = s;	    nn = ft_getpnames(&fake_wl, true);	    t = ft_evaluate(nn);	    free_pnode(nn);	    if (!isreal(t) || t->v_link2 || t->v_length != 1 || !t->v_realdata)	    {		fprintf(cp_err, "Error: index is not a scalar.\n");		tfree(p);		return;	    }	    j = t->v_realdata[0]; /* ignore sanity checks for now */	    if (j < 0) {		printf("negative index (%d) is not allowed\n", j);		tfree(p);		/* XXX free data */		return;	    }	    indices[numdims++] = j;	    for (s = q; *s && isspace(*s); s++)		;	}    }    /* vector name at p */    for (q = p + strlen(p) - 1; *q <= ' ' && p <= q; q--)	;    *++q = 0;    /* sanity check */    if (eq(p, "all") || index(p, '@')) {        fprintf(cp_err, "Error: bad variable name %s\n", p);        return;    }    /* evaluate rhs */    fake_wl.wl_word = rhs;    nn = ft_getpnames(&fake_wl, true);    if (nn == NULL) {	/* XXX error message */        tfree(p);        return;    }    t = ft_evaluate(nn);    if (!t) {	/* XXX error message */        tfree(p);        return;    }    if (t->v_link2)        fprintf(cp_err, "Warning: extra wildcard values ignored\n");    n = vec_get(p);    if (n) {	/* re-allocate? */	/* vec_free(n); */	newvec = 0;    } else {	if (numdims) {	    fprintf(cp_err, "Can't assign into a subindex of a new vector\n");	    tfree(p);	    return;	}	/* create and assign a new vector */	n = alloc(struct dvec);	ZERO(n, struct dvec);	n->v_name = copy(p);	n->v_type = t->v_type;	n->v_flags = (t->v_flags | VF_PERMANENT);	n->v_length = t->v_length;	if (!t->v_numdims) {	    n->v_numdims = 1;	    n->v_dims[0] = n->v_length;	} else {	    n->v_numdims = t->v_numdims;	    for (i = 0; i < t->v_numdims; i++)		n->v_dims[i] = t->v_dims[i];	}	if (isreal(t))	    n->v_realdata = (double *) tmalloc(n->v_length * sizeof(double));	else	    n->v_compdata = (complex *) tmalloc(n->v_length * sizeof(complex));	newvec = 1;	vec_new(n);    }    /* fix-up dimensions */    if (n->v_numdims < 1) {	n->v_numdims = 1;	n->v_dims[0] = n->v_length;    }    /* Compare dimensions */    offset = 0;    length = n->v_length;    cube = 1;    for (i = n->v_numdims - 1; i >= numdims; i--)	cube *= n->v_dims[i];    for (i = numdims - 1; i >= 0; i--) {	offset += cube * indices[i];	if (i < n->v_numdims) {	    cube *= n->v_dims[i];	    length /= n->v_dims[i];	}    }    /* length is the size of the unit refered to */    /* cube ends up being the length */    if (length > t->v_length) {	fprintf(cp_err, "left-hand expression is too small (need %d)\n",		length * cube);	if (newvec)	    n->v_flags &= ~VF_PERMANENT;	tfree(p);	return;    }    if (isreal(t) != isreal(n)) {	fprintf(cp_err,		"Types of vectors are not the same (real vs. complex)\n");	if (newvec)	    n->v_flags &= ~VF_PERMANENT;	tfree(p);	return;    } else if (isreal(t)) {	bcopy((char *) t->v_realdata, (char *) (n->v_realdata + offset),		length * sizeof (double));    } else {	bcopy((char *) t->v_compdata, (char *) (n->v_compdata + offset),		length * sizeof (complex));    }    n->v_minsignal = 0.0; /* How do these get reset ??? */    n->v_maxsignal = 0.0;    n->v_scale = t->v_scale;    if (newvec)	cp_addkword(CT_VECTOR, n->v_name);    /* XXXX Free t !?! */    tfree(p);    return;}/* Undefine vectors. */voidcom_unlet(wl)    wordlist *wl;{    while (wl) {        vec_remove(wl->wl_word);        wl = wl->wl_next;    }    return;}/* Load in a file. */voidcom_load(wl)    wordlist *wl;{    if (!wl)        ft_loadfile(ft_rawfile);    else        while (wl) {            ft_loadfile(cp_unquote(wl->wl_word));            wl = wl->wl_next;        }    /* note: default is to display the vectors in the last (current) plot */    com_display(NULL);    return;}/* Print out the value of an expression. When we are figuring out what to * print, link the vectors we want with v_link2... This has to be done * because of the way temporary vectors are linked together with permanent * ones under the plot. */voidcom_print(wl)    wordlist *wl;{    struct dvec *v, *lv, *bv, *nv, *vecs = NULL;    int i, j, ll, width = DEF_WIDTH, height = DEF_HEIGHT, npoints, lineno;    struct pnode *nn;    struct plot *p;    bool col = true, nobreak = false, noprintscale, plotnames = false;    bool optgiven = false;    char *s, buf[BSIZE_SP], buf2[BSIZE_SP];    int ngood;    if (wl == NULL)        return;    if (eq(wl->wl_word, "col")) {        col = true;        optgiven = true;        wl = wl->wl_next;    } else if (eq(wl->wl_word, "line")) {        col = false;        optgiven = true;        wl = wl->wl_next;    }    ngood = 0;    for (nn = ft_getpnames(wl, true); nn; nn = nn->pn_next) {        if (!(v = ft_evaluate(nn)))	    continue;	if (!vecs)	    vecs = lv = v;	else	    lv->v_link2 = v;	for (lv = v; lv->v_link2; lv = lv->v_link2)	    ;	ngood += 1;    }    if (!ngood)	return;    /* See whether we really have to print plot names. */    for (v = vecs; v; v = v->v_link2)        if (vecs->v_plot != v->v_plot) {            plotnames = true;            break;        }        if (!optgiven) {        /* Figure out whether col or line should be used... */        col = false;        for (v = vecs; v; v = v->v_link2)            if (v->v_length > 1) {                col = true;                break;            }    }    out_init();    if (!col) {        for (v = vecs; v; v = v->v_link2) {            if (plotnames) {                (void) sprintf(buf, "%s.%s", v->v_plot->pl_typename,                        vec_basename(v));            } else {                (void) strcpy(buf, vec_basename(v));            }            for (s = buf; *s; s++)                ;            s--;            while (isspace(*s)) {                *s = '\0';                s--;            }            ll = 10;            if (v->v_length == 1) {                if (isreal(v)) {                    out_printf("%s = %s\n", buf,                        printnum(*v->v_realdata));                } else {                    out_printf("%s = %s,%s\n", buf,                        copy(printnum(realpart(v->v_compdata))),                        copy(printnum(imagpart(v->v_compdata))));                }            } else {                out_printf("%s = (  ", buf);                for (i = 0; i < v->v_length; i++)                    if (isreal(v)) {                        (void) strcpy(buf,                           printnum(v->v_realdata[i]));                        out_send(buf);                        ll += strlen(buf);                        ll = (ll + 7) / 8;                        ll = ll * 8 + 1;                        if (ll > 60) {                            out_send("\n\t");                            ll = 9;                        } else                            out_send("\t");                    } else {                        (void) sprintf(buf, "%s,%s",                            copy(printnum(realpart(&v->v_compdata[i]))),                            copy(printnum(imagpart(&v->v_compdata[i]))));                        out_send(buf);                        ll += strlen(buf);                        ll = (ll + 7) / 8;                        ll = ll * 8 + 1;                        if (ll > 60) {                            out_send("\n\t");                            ll = 9;                        } else                            out_send("\t");                    }                out_send(")\n");            }        }    } else {    /* Print in columns. */        if (cp_getvar("width", VT_NUM, (char *) &i))            width = i;        if (width < 40)            width = 40;        if (cp_getvar("height", VT_NUM, (char *) &i))            height = i;        if (height < 20)            height = 20;        if (!cp_getvar("nobreak", VT_BOOL, (char *) &nobreak) && !ft_nopage)            nobreak = false;	else	    nobreak = true;        (void) cp_getvar("noprintscale", VT_BOOL, (char *)                 &noprintscale);        bv = vecs;nextpage:        /* Make the first vector of every page be the scale... */	/* XXX But what if there is no scale?  e.g. op, pz */        if (!noprintscale && bv->v_plot->pl_ndims) {            if (bv->v_plot->pl_scale && !vec_eq(bv, bv->v_plot->pl_scale)) {                nv = vec_copy(bv->v_plot->pl_scale);                vec_new(nv);                nv->v_link2 = bv;                bv = nv;            }        }        ll = 8;        for (lv = bv; lv; lv = lv->v_link2) {            if (isreal(lv))                ll += 16;   /* Two tabs for real, */            else                ll += 32;   /* 4 for complex. */            /* Make sure we have at least 2 vectors per page... */            if ((ll > width) && (lv != bv) && (lv != bv->v_link2))                break;        }        /* Print the header on the first page only. */        p = bv->v_plot;        j = (width - (int) strlen(p->pl_title)) / 2;	/* Yes, keep "(int)" */	if (j < 0)		j = 0;        for (i = 0; i < j; i++)            buf2[i] = ' ';        buf2[j] = '\0';        out_send(buf2);        out_send(p->pl_title);        out_send("\n");        out_send(buf2);        (void) sprintf(buf, "%s  %s", p->pl_name, p->pl_date);        j = (width - strlen(buf)) / 2;        out_send(buf);        out_send("\n");        for (i = 0; i < width; i++)            buf2[i] = '-';        buf2[width] = '\n';        buf2[width+1] = '\0';        out_send(buf2);        (void) sprintf(buf, "Index   ");        for (v = bv; v && (v != lv); v = v->v_link2) {            if (isreal(v))                (void) sprintf(buf2, "%-16.15s", v->v_name);            else                (void) sprintf(buf2, "%-32.31s", v->v_name);            (void) strcat(buf, buf2);           }        lineno = 3;        j = 0;        npoints = 0;        for (v = bv; (v && (v != lv)); v = v->v_link2)            if (v->v_length > npoints)                npoints = v->v_length;pbreak:     /* New page. */        out_send(buf);        out_send("\n");        for (i = 0; i < width; i++)            buf2[i] = '-';        buf2[width] = '\n';        buf2[width+1] = '\0';        out_send(buf2);        lineno += 2;loop:        while ((j < npoints) && (lineno < height)) {/*            out_printf("%d\t", j); */	    sprintf(out_pbuf, "%d\t", j);	    out_send(out_pbuf);            for (v = bv; (v && (v != lv)); v = v->v_link2) {                if (v->v_length <= j) {                    if (isreal(v))                        out_send("\t\t");                    else                        out_send("\t\t\t\t");                } else {                    if (isreal(v)) {                        sprintf(out_pbuf, "%e\t",                         	v->v_realdata[j]);			out_send(out_pbuf);                    } else {                        sprintf(out_pbuf, "%e,\t%e\t",                        	realpart(&v->v_compdata[j]),                        	imagpart(&v->v_compdata[j]));			out_send(out_pbuf);		    }                }            }            out_send("\n");            j++;            lineno++;        }        if ((j == npoints) && (lv == NULL)) /* No more to print. */            goto done;        if (j == npoints) { /* More vectors to print. */            bv = lv;            out_send("\f\n");   /* Form feed. */            goto nextpage;        }        /* Otherwise go to a new page. */        lineno = 0;        if (nobreak)            goto loop;        else            out_send("\f\n");   /* Form feed. */        goto pbreak;    }done:    /* Get rid of the vectors. */    return;}/* Write out some data. write filename expr ... Some cleverness here is * required.  If the user mentions a few vectors from various plots, * probably he means for them to be written out seperate plots.  In any * case, we have to be sure to write out the scales for everything we * write... */voidcom_write(wl)       wordlist *wl;{    char *file, buf[BSIZE_SP];    struct pnode *n;    struct dvec *d, *vecs = NULL, *lv = NULL, *end, *vv;    static wordlist all = { "all", NULL, NULL } ;    struct pnode *names;    bool ascii = AsciiRawFile;    bool scalefound, appendwrite;    struct plot *tpl, newplot;    if (wl) {        file = wl->wl_word;        wl = wl->wl_next;    } else        file = ft_rawfile;    if (cp_getvar("filetype", VT_STRING, buf)) {        if (eq(buf, "binary"))            ascii = false;        else if (eq(buf, "ascii"))            ascii = true;	else            fprintf(cp_err, "Warning: strange file type %s\n", buf);    }    (void) cp_getvar("appendwrite", VT_BOOL, (char *) &appendwrite);    if (wl)        names = ft_getpnames(wl, true);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -