diff --git a/src/frontend/com_compose.c b/src/frontend/com_compose.c index 099e68c8b..7d2249a70 100644 --- a/src/frontend/com_compose.c +++ b/src/frontend/com_compose.c @@ -11,6 +11,7 @@ #include "ngspice/fteext.h" #include "ngspice/cpextern.h" #include "ngspice/randnumb.h" +#include "ngspice/evtproto.h" #include "com_compose.h" #include "completion.h" @@ -225,9 +226,26 @@ com_compose(wordlist *wl) } length *= blocksize; - } - else { +#ifdef XSPICE + } else if (eq(wl->wl_word, "xspice")) { + /* Make vectors from an event node. */ + + result = EVTfindvec(resname); + if (result == NULL) { + fprintf(cp_err, "There is no event node %s or it has no data\n", + resname); + goto done; + } + result->v_flags |= VF_PERMANENT; + result->v_scale->v_flags |= VF_PERMANENT; + vec_new(result->v_scale); + cp_addkword(CT_VECTOR, result->v_scale->v_name); + txfree(resname); // It was copied + goto finished; +#endif + } else { /* Parse the line... */ + while (wl) { char *s, *var, *val; if ((s = strchr(wl->wl_word, '=')) != NULL && s[1]) { @@ -600,6 +618,7 @@ com_compose(wordlist *wl) /* The allocation for resname has been assigned to the result vector, so * set to NULL so that it is not freed */ + finished: resname = NULL; /* Set dimension info */ diff --git a/src/frontend/com_setscale.c b/src/frontend/com_setscale.c index 024bb043d..254b65c39 100644 --- a/src/frontend/com_setscale.c +++ b/src/frontend/com_setscale.c @@ -9,30 +9,64 @@ #include "plotting/pvec.h" #include "ngspice/fteext.h" +static struct dvec *find_vec(wordlist *wl) +{ + struct dvec *d; + char *s; + + s = cp_unquote(wl->wl_word); + if (s) { + d = vec_get(s); + tfree(s); /*DG to avoid the cp_unquote memory leak */ + } else { + d = NULL; + } + + if (d == NULL) + fprintf(cp_err, "Error: no such vector as %s.\n", wl->wl_word); + return d; +} /* Set the default scale to the named vector. If no vector named, * find and print the default scale. */ + void com_setscale(wordlist *wl) { - struct dvec *d; - char *s; + struct dvec *d, *ds; - if (plot_cur) { - if (wl) { - s = cp_unquote(wl->wl_word); - d = vec_get(s); - if (s) - tfree(s);/*DG to avoid the cp_unquote memory leak */ - - if (d == NULL) - fprintf(cp_err, "Error: no such vector as %s.\n", wl->wl_word); - else - plot_cur->pl_scale = d; - } else if (plot_cur->pl_scale) { - pvec(plot_cur->pl_scale); - } - } else { + if (!plot_cur) { fprintf(cp_err, "Error: no current plot.\n"); + return; + } + + if (!wl) { + if (plot_cur->pl_scale) + pvec(plot_cur->pl_scale); + return; + } + + d = find_vec(wl); + if (d == NULL) + return; + + /* Two-word form for altering the scale of a specific vector? + * Keyword "none" clears the scale so that the plot's default scale + * will be used. + */ + + wl = wl->wl_next; + if (wl) { + if (!strcmp(wl->wl_word, "none")) { + d->v_scale = NULL; + return; + } + + ds = find_vec(wl); + if (ds == NULL) + return; + d->v_scale = ds; + } else { + plot_cur->pl_scale = d; } } diff --git a/src/frontend/commands.c b/src/frontend/commands.c index 225dbf884..3966a9197 100644 --- a/src/frontend/commands.c +++ b/src/frontend/commands.c @@ -195,9 +195,10 @@ struct comm spcp_coms[] = { NULL, "[circuit name] : Change the current circuit." } , { "setscale", com_setscale, FALSE, FALSE, - { 040000, 0, 0, 0 }, E_DEFHMASK, 0, 1, + { 040000, 0, 0, 0 }, E_DEFHMASK, 0, 2, NULL, - "[vecname] : Change default scale of current working plot." } , + "[vecname [vecname]] : Change default scale of current working plot" + "\n or set/clear the scale for a single vector." } , { "setseed", com_sseed, FALSE, FALSE, { 04, 0, 0, 0 }, E_DEFHMASK, 0, 1, NULL, diff --git a/src/frontend/plotting/plotit.c b/src/frontend/plotting/plotit.c index 5d4d245bf..0b8b9a951 100644 --- a/src/frontend/plotting/plotit.c +++ b/src/frontend/plotting/plotit.c @@ -859,7 +859,11 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname) int ii = 0, jj = 0; for (d = vecs; d; d = d->v_link2) { - if (d->v_scale && eq(d->v_scale->v_name, "step") && (d->v_scale->v_type == SV_TIME) && (d->v_type == SV_VOLTAGE) && (d->v_length > 1)) { + if ((d->v_flags & VF_EVENT_NODE) && + !(d->v_flags & VF_PERMANENT) && + d->v_scale && (d->v_scale->v_flags & VF_EVENT_NODE) && + (d->v_scale->v_type == SV_TIME) && (d->v_type == SV_VOLTAGE) && + (d->v_length > 1)) { for (ii = 0; ii < d->v_length; ii++) { d->v_realdata[ii] += nn; } diff --git a/src/include/ngspice/dvec.h b/src/include/ngspice/dvec.h index ea0a9b83c..558eb6929 100644 --- a/src/include/ngspice/dvec.h +++ b/src/include/ngspice/dvec.h @@ -16,7 +16,8 @@ enum dvec_flags { VF_PRINT = (1 << 4), /* writedata should print this vector. */ VF_MINGIVEN = (1 << 5), /* The v_minsignal value is valid. */ VF_MAXGIVEN = (1 << 6), /* The v_maxsignal value is valid. */ - VF_PERMANENT = (1 << 7) /* Don't garbage collect this vector. */ + VF_PERMANENT = (1 << 7), /* Don't garbage collect this vector. */ + VF_EVENT_NODE = (1 << 8) /* Derived from and XSPICE event node. */ }; diff --git a/src/xspice/evt/evtplot.c b/src/xspice/evt/evtplot.c index af5c50792..a4d17842f 100644 --- a/src/xspice/evt/evtplot.c +++ b/src/xspice/evt/evtplot.c @@ -206,14 +206,15 @@ struct dvec *EVTfindvec( /* Allocate dvec structures and assign the vectors into them. */ /* See FTE/OUTinterface.c:plotInit() for initialization example. */ - scale = dvec_alloc(MIFcopy("step"), + ptr = tprintf("%s_steps", name); + scale = dvec_alloc(ptr, SV_TIME, - VF_REAL & ~VF_PERMANENT, + (VF_REAL | VF_EVENT_NODE) & ~VF_PERMANENT, i, anal_point_vec); d = dvec_alloc(name, SV_VOLTAGE, - VF_REAL & ~VF_PERMANENT, + (VF_REAL | VF_EVENT_NODE) & ~VF_PERMANENT, i, value_vec); d->v_scale = scale;