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

📄 vectors.c

📁 ngspice又一个电子CAD仿真软件代码.功能更全
💻 C
📖 第 1 页 / 共 2 页
字号:
/**********Copyright 1990 Regents of the University of California.  All rights reserved.Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group $Id: vectors.c,v 1.8 2005/05/26 19:29:52 sjborley Exp $**********//* * Routines for dealing with the vector database. */#include <ngspice.h>#include <cpdefs.h>#include <ftedefs.h>#include <dvec.h>#include <sim.h>#include "circuits.h"#include "completion.h"#include "variable.h"#include "vectors.h"#include "plotting/plotting.h"#ifdef XSPICE/* gtri - begin - add function prototype for EVTfindvec */struct dvec *EVTfindvec(char *node);/* gtri - end   - add function prototype for EVTfindvec */#endif/* 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(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;    }#ifdef XSPICE/* gtri - begin - Add processing for getting event-driven vector */    if(!d)      d = EVTfindvec(word);/* gtri - end   - Add processing for getting event-driven vector */#endif    if (d && d->v_link2) {        d = vec_copy(d);        vec_new(d);    }    return (d);}/* If there are imbedded numeric strings, compare them numerically, not * alphabetically. */static intnamecmp(const void *a, const void *b){    int i, j;    char *s = (char *) a;    char *t = (char *) b;    for (;;) {        while ((*s == *t) && !isdigit(*s) && *s)            s++, t++;        if (!*s)            return (0);        if ((*s != *t) && (!isdigit(*s) || !isdigit(*t)))            return (*s - *t);                /* The beginning of a number... Grab the two numbers and then         * compare them...  */        for (i = 0; isdigit(*s); s++)            i = i * 10 + *s - '0';        for (j = 0; isdigit(*t); t++)            j = j * 10 + *t - '0';                if (i != j)            return (i - j);    }}static intveccmp(const void *a, const void *b){    int i;    struct dvec **d1 = (struct dvec **) a;    struct dvec **d2 = (struct dvec **) b;    if ((i = namecmp((*d1)->v_plot->pl_typename,            (*d2)->v_plot->pl_typename)) != 0)        return (i);    return (namecmp((*d1)->v_name, (*d2)->v_name));}/* Sort all the vectors in d, first by plot name and then by vector * name.  Do the right thing with numbers.  */static struct dvec *sortvecs(struct dvec *d){    struct dvec **array, *t;    int i, j;    for (t = d, i = 0; t; t = t->v_link2)        i++;    if (i < 2)        return (d);    array = (struct dvec **) tmalloc(i * sizeof (struct dvec *));    for (t = d, i = 0; t; t = t->v_link2)        array[i++] = t;        qsort((char *) array, i, sizeof (struct dvec *), veccmp);    /* Now string everything back together... */    for (j = 0; j < i - 1; j++)        array[j]->v_link2 = array[j + 1];    array[j]->v_link2 = NULL;    d = array[0];    tfree(array);    return (d);}/* Load in a rawfile. */voidft_loadfile(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(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(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(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 =strrchr(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(char *word){    struct dvec *d, *end = NULL, *newv = NULL;    struct plot *pl;    char buf[BSIZE_SP], *s, *wd, *whole, *name = NULL, *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);            tfree(wd); /* MW. I don't want core leaks here */            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");            tfree(wd); 	/* MW. Memory leak fixed again */       		            return (NULL); /* va: use NULL */        }                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); /* MW. The same as word before */        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;                tfree(vv->va_name);        tfree(vv); /* va: tfree vv->va_name and vv (avoid memory leakages) */        tfree(wd);	        vec_new(d);	tfree(whole);        return (d);    }    tfree(wd);    return (sortvecs(d));}/* Execute the commands for a plot. This is done whenever a plot becomes * the current plot. */voidplot_docoms(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(struct dvec *v){    struct dvec *nv;    int i;        if (!v)        return (NULL);    nv = alloc(struct dvec);

⌨️ 快捷键说明

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