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

📄 plotit.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
/* $Id: plotit.c,v 1.6 2005/05/28 17:31:49 sjborley Exp $ */#include <ngspice.h>#include <bool.h>#include <wordlist.h>#include <graph.h>#include <cpdefs.h>#include <pnode.h>#include <sim.h>#include <fteext.h>#include <circuits.h>#include <variable.h>#include "plotit.h"#include "agraf.h"#include "xgraph.h"#include "graf.h"static wordlist *wl_root;static bool sameflag;/* This routine gets parameters from the command line, which are of * the form "name number ..." It returns a pointer to the parameter * values.  */static double *getlims(wordlist *wl, char *name, int number){    double *d, *td;    wordlist *beg, *wk;    char *ss;    int n;    for (beg = wl; beg; beg = beg->wl_next) {        if (eq(beg->wl_word, name)) {            if (beg == wl) {                fprintf(cp_err,			"Syntax error: looking for plot parameters \"%s\".\n",			name);                return (NULL);            }            wk = beg;            if (number) {                d = (double *) tmalloc(sizeof (double) *                        number);                for (n = 0; n < number; n++) {                    wk = wk->wl_next;                    if (!wk) {                        fprintf(cp_err,                            "Syntax error: not enough parameters for \"%s\".\n",			    name);                        return (NULL);                    }                    ss = wk->wl_word;                    td = ft_numparse(&ss, FALSE);                    if (td == NULL)                        goto bad;                    d[n] = *td;                }            } else                /* Minor hack... */                d = (double  *) 1;            if (beg->wl_prev)                beg->wl_prev->wl_next = wk->wl_next;            if (wk->wl_next) {                wk->wl_next->wl_prev = beg->wl_prev;                wk->wl_next = NULL;            }	    if (beg != wl_root)		wl_free(beg);            return (d);        }    }    return (NULL);bad:    fprintf(cp_err, "Syntax error: bad parameters for \"%s\".\n", name);    return (NULL);}/* Extend a data vector to length by replicating the last element, or * truncate it if it is too long.  */static voidxtend(struct dvec *v, int length){    int i;    complex c, *oc;    double d, *od;    if (v->v_length == length)        return;    if (v->v_length > length) {        v->v_length = length;        return;    }    if (isreal(v)) {        od = v->v_realdata;        v->v_realdata = (double *) tmalloc(length * sizeof (double));        for (i = 0; i < v->v_length; i++)            v->v_realdata[i] = od[i];        d = od[--i];        while (i < length)            v->v_realdata[i++] = d;        tfree(od);    } else {        oc = v->v_compdata;        v->v_compdata = (complex *) tmalloc(length * sizeof (complex));        for (i = 0; i < v->v_length; i++) {            realpart(&v->v_compdata[i]) = realpart(&oc[i]);            imagpart(&v->v_compdata[i]) = imagpart(&oc[i]);        }        realpart(&c) = realpart(&oc[--i]);        imagpart(&c) = imagpart(&oc[i]);        while (i < length) {            realpart(&v->v_compdata[i]) = realpart(&c);            imagpart(&v->v_compdata[i++]) = imagpart(&c);        tfree(oc);        }    }    v->v_length = length;    return;}/* Collapse every *xcomp elements into one, and use only the elements * between xind[0] and xind[1]. */static voidcompress(struct dvec *d, double *xcomp, double *xind){    int cfac, ihi, ilo, newlen, i;    int sz = isreal(d) ? sizeof (double) : sizeof (complex);    double *dd;    complex *cc;    if (xind) {        ilo = (int) xind[0];        ihi = (int) xind[1];        if ((ilo <= ihi) && (ilo > 0) && (ilo < d->v_length) &&                (ihi > 1) && (ihi <= d->v_length)) {            newlen = ihi - ilo;            dd = (double *) tmalloc(newlen * sz);            cc = (complex *) dd;            if (isreal(d)) {                bcopy((char *) (d->v_realdata + ilo),                        (char *) dd, newlen * sz);                tfree(d->v_realdata);                d->v_realdata = dd;            } else {                bcopy((char *) (d->v_compdata + ilo),                        (char *) cc, newlen * sz);                tfree(d->v_compdata);                d->v_compdata = cc;            }            d->v_length = newlen;        }    }    if (xcomp) {        cfac = (int) *xcomp;        if ((cfac > 1) && (cfac < d->v_length)) {            for (i = 0; i * cfac < d->v_length; i++)                if (isreal(d))                    d->v_realdata[i] =                             d->v_realdata[i * cfac];                else                    d->v_compdata[i] =                             d->v_compdata[i * cfac];            d->v_length = i;        }    }    return;}/* Check for and remove a one-word keyword. */static boolgetflag(wordlist *wl, char *name){    while (wl) {        if (eq(wl->wl_word, name)) {            if (wl->wl_prev)                wl->wl_prev->wl_next = wl->wl_next;            if (wl->wl_next)                wl->wl_next->wl_prev = wl->wl_prev;            return (TRUE);        }        wl = wl->wl_next;    }    return (FALSE);}/* Return a parameter of the form "xlabel foo" */static char *getword(wordlist *wl, char *name){    wordlist *beg;    char *s;    for (beg = wl; beg; beg = beg->wl_next) {        if (eq(beg->wl_word, name)) {            if ((beg == wl) || !beg->wl_next) {                fprintf(cp_err,			"Syntax error: looking for plot keyword at \"%s\".\n",			name);                return (NULL);            }            s = copy(beg->wl_next->wl_word);            beg->wl_prev->wl_next = beg->wl_next->wl_next;            if (beg->wl_next->wl_next)                beg->wl_next->wl_next->wl_prev = beg->wl_prev;            beg->wl_next->wl_next = NULL;            wl_free(beg);            return (s);        }    }    return (NULL);}/* The common routine for all plotting commands. This does hardcopy * and graphics plotting.  */boolplotit(wordlist *wl, char *hcopy, char *devname){    /* All these things are static so that "samep" will work. */    static double *xcompress = NULL, *xindices = NULL;    static double *xlim = NULL, *ylim = NULL;    static double *xdelta = NULL, *ydelta = NULL;    static char *xlabel = NULL, *ylabel = NULL, *title = NULL;    static bool nointerp = FALSE;    static GRIDTYPE gtype = GRID_LIN;    static PLOTTYPE ptype = PLOT_LIN;    bool gfound = FALSE, pfound = FALSE, oneval = FALSE;    double *dd, ylims[2], xlims[2];    struct pnode *n, *names;    struct dvec *dv, *d = NULL, *vecs = NULL, *lv, *lastvs = NULL;    char *xn;    int i, j, xt;    double tt, mx, my, rad;    wordlist *wwl, *tw;    char cline[BSIZE_SP], buf[BSIZE_SP], *pname;    int newlen;    struct dvec *v, *newv_scale;    double *newdata, *newscale;    double tstep, tstart, tstop, ttime;        /* return value, error by default */    bool rtn = FALSE;    if (!wl)	goto quit1;    wl_root = wl;    /* First get the command line, without the limits. */    wwl = wl_copy(wl);    (void) getlims(wwl, "xl", 2);    (void) getlims(wwl, "xlimit", 2);    (void) getlims(wwl, "yl", 2);    (void) getlims(wwl, "ylimit", 2);    pname = wl_flatten(wwl);    (void) sprintf(cline, "plot %s", pname);    tfree(pname);    wl_free(wwl);    /* Now extract all the parameters. */    /* In case the parameter is the first on the line, we need a     * "buffer" word. Use previous word up the chain if available,     * Otherwise create one.     */    if(wl->wl_prev) {	wl = wl->wl_prev;	tw = NULL;  /* Not used, so must be NULL */    } else {	tw = alloc(struct wordlist);	wl->wl_prev = tw;	tw->wl_next = wl;	wl = tw;	tw->wl_word = "";    }    sameflag = getflag(wl, "samep");    if (!sameflag || !xlim) {        xlim = getlims(wl, "xl", 2);        if (!xlim)            xlim = getlims(wl, "xlimit", 2);    } else {        (void) getlims(wl, "xl", 2);        (void) getlims(wl, "xlimit", 2);    }    if (!sameflag || !ylim) {        ylim = getlims(wl, "yl", 2);        if (!ylim)            ylim = getlims(wl, "ylimit", 2);    } else {        (void) getlims(wl, "yl", 2);        (void) getlims(wl, "ylimit", 2);    }    if (!sameflag || !xcompress) {        xcompress = getlims(wl, "xcompress", 1);        if (!xcompress)            xcompress = getlims(wl, "xcomp", 1);    } else {        (void) getlims(wl, "xcompress", 1);        (void) getlims(wl, "xcomp", 1);    }    if (!sameflag || !xindices) {        xindices = getlims(wl, "xindices", 2);        if (!xindices)            xindices = getlims(wl, "xind", 2);    } else {        (void) getlims(wl, "xindices", 2);        (void) getlims(wl, "xind", 2);    }    if (!sameflag || !xdelta) {        xdelta = getlims(wl, "xdelta", 1);        if (!xdelta)            xdelta = getlims(wl, "xdel", 1);    } else {        (void) getlims(wl, "xdelta", 1);        (void) getlims(wl, "xdel", 1);    }    if (!sameflag || !ydelta) {        ydelta = getlims(wl, "ydelta", 1);        if (!ydelta)            ydelta = getlims(wl, "ydel", 1);    } else {        (void) getlims(wl, "ydelta", 1);        (void) getlims(wl, "ydel", 1);    }        /* Get the grid type and the point type.  Note we can't do if-else     * here because we want to catch all the grid types.     */    if (getflag(wl, "lingrid")) {        if (gfound)            fprintf(cp_err,                 "Warning: too many grid types given\n");        else {            gtype = GRID_LIN;            gfound = TRUE;        }    }    if (getflag(wl, "loglog")) {        if (gfound)            fprintf(cp_err,                 "Warning: too many grid types given\n");        else {            gtype = GRID_LOGLOG;            gfound = TRUE;        }    }    if (getflag(wl, "nogrid")) {        if (gfound)            fprintf(cp_err,                 "Warning: too many grid types given\n");        else {            gtype = GRID_NONE;            gfound = TRUE;        }    }    if (getflag(wl, "linear")) {        if (gfound)            fprintf(cp_err,                 "Warning: too many grid types given\n");        else {            gtype = GRID_LIN;            gfound = TRUE;        }    }    if (getflag(wl, "xlog")) {        if (gfound)            fprintf(cp_err,                 "Warning: too many grid types given\n");        else {            gtype = GRID_XLOG;            gfound = TRUE;        }    }    if (getflag(wl, "ylog")) {        if (gfound)            fprintf(cp_err,                 "Warning: too many grid types given\n");        else {            gtype = GRID_YLOG;            gfound = TRUE;        }    }    if (getflag(wl, "polar")) {        if (gfound)            fprintf(cp_err,                 "Warning: too many grid types given\n");        else {            gtype = GRID_POLAR;            gfound = TRUE;        }    }    if (getflag(wl, "smith")) {        if (gfound)            fprintf(cp_err,                 "Warning: too many grid types given\n");        else {            gtype = GRID_SMITH;            gfound = TRUE;        }    }    if (getflag(wl, "smithgrid")) {        if (gfound)            fprintf(cp_err,                 "Warning: too many grid types given\n");        else {            gtype = GRID_SMITHGRID;            gfound = TRUE;        }    }    if (!sameflag && !gfound) {        if (cp_getvar("gridstyle", VT_STRING, buf)) {            if (eq(buf, "lingrid"))                gtype = GRID_LIN;            else if (eq(buf, "loglog"))                gtype = GRID_LOGLOG;            else if (eq(buf, "xlog"))                gtype = GRID_XLOG;            else if (eq(buf, "ylog"))                gtype = GRID_YLOG;            else if (eq(buf, "smith"))                gtype = GRID_SMITH;            else if (eq(buf, "smithgrid"))                gtype = GRID_SMITHGRID;            else if (eq(buf, "polar"))                gtype = GRID_POLAR;            else if (eq(buf, "nogrid"))                gtype = GRID_NONE;            else {                fprintf(cp_err,                    "Warning: strange grid type %s\n",                    buf);                gtype = GRID_LIN;            }            gfound = TRUE;        } else            gtype = GRID_LIN;    }    /* Now get the point type.  */    if (getflag(wl, "linplot")) {        if (pfound)            fprintf(cp_err,                 "Warning: too many plot types given\n");        else {            ptype = PLOT_LIN;            pfound = TRUE;        }    }    if (getflag(wl, "combplot")) {        if (pfound)            fprintf(cp_err,                 "Warning: too many plot types given\n");        else {            ptype = PLOT_COMB;            pfound = TRUE;        }    }    if (getflag(wl, "pointplot")) {        if (pfound)            fprintf(cp_err,                 "Warning: too many plot types given\n");        else {            ptype = PLOT_POINT;            pfound = TRUE;        }    }    if (!sameflag && !pfound) {        if (cp_getvar("plotstyle", VT_STRING, buf)) {            if (eq(buf, "linplot"))                ptype = PLOT_LIN;            else if (eq(buf, "combplot"))                ptype = PLOT_COMB;            else if (eq(buf, "pointplot"))

⌨️ 快捷键说明

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