If new parameter 'plain' is added to the 'plot' command,

all expression handling is skipped, vectors are plotting as is.
This allows nodes names with vectors like v(+vs) or /out
to be plotted without need resorting to double quotes.
This commit is contained in:
Holger Vogt 2020-10-29 09:26:36 +01:00
parent 84d3d8c143
commit f0090508b0
1 changed files with 113 additions and 86 deletions

View File

@ -283,13 +283,14 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
static bool nointerp = FALSE; static bool nointerp = FALSE;
static bool kicad = FALSE; static bool kicad = FALSE;
static bool plain = FALSE;
static GRIDTYPE gtype = GRID_LIN; static GRIDTYPE gtype = GRID_LIN;
static PLOTTYPE ptype = PLOT_LIN; static PLOTTYPE ptype = PLOT_LIN;
bool gfound = FALSE, pfound = FALSE, oneval = FALSE; bool gfound = FALSE, pfound = FALSE, oneval = FALSE;
double ylims[2], xlims[2]; double ylims[2], xlims[2];
struct pnode *pn, *names; struct pnode *pn, *names = NULL;
struct dvec *d = NULL, *vecs = NULL, *lv, *lastvs = NULL; struct dvec *d = NULL, *vecs = NULL, *lv = NULL, *lastvs = NULL;
char *xn; char *xn;
int i, xt; int i, xt;
wordlist *wwl; wordlist *wwl;
@ -702,111 +703,137 @@ bool plotit(wordlist *wl, const char *hcopy, const char *devname)
kicad = TRUE; kicad = TRUE;
} }
if (!sameflag) {
plain = getflag(wl, "plain");
}
else if (getflag(wl, "plain")) {
plain = TRUE;
}
if (!wl->wl_next) { if (!wl->wl_next) {
fprintf(cp_err, "Error: no vectors given\n"); fprintf(cp_err, "Error: no vectors given\n");
goto quit1; goto quit1;
} }
/* kicad will generate vector names containing '/'. If compatibilty flag /* if plain is set, we skip all function parsing and just plot the
'ki' is set in .spiceinit or plot line flag 'kicad' is set, vectors by name. vc1 vs vc2 is also not supported.
we will place " around this vector name. Division in the plot command Thus we may plot vecs with node names containing + - / etc.
will then work only if spaces are around ' / '.*/ Note: Evaluating the wordlist starting at wl->wl_next since the first
if (kicad || newcompat.ki) { node is a dummy node.*/
wordlist* wlk; if(plain) {
for (wlk = wl->wl_next; wlk; wlk = wlk->wl_next) { wordlist* wli;
char* wlkword = strchr(wlk->wl_word, '/'); for (wli = wl->wl_next; wli; wli = wli->wl_next) {
if (wlkword) { d = vec_get(wli->wl_word);
/* already " around token */ if (!d)
if (*(wlk->wl_word) == '"') goto quit;
continue; if (vecs)
/* just '/' */ lv->v_link2 = d;
if (*(wlkword + 1) == '\0') else
continue; vecs = d;
else { for (lv = d; lv->v_link2; lv = lv->v_link2)
char* newword = tprintf("\"%s\"", wlk->wl_word); ;
tfree(wlk->wl_word); }
wlk->wl_word = newword; }
else {
/* kicad will generate vector names containing '/'. If compatibilty flag
'ki' is set in .spiceinit or plot line flag 'kicad' is set,
we will place " around this vector name. Division in the plot command
will then work only if spaces are around ' / '.*/
if (kicad || newcompat.ki) {
wordlist* wlk;
for (wlk = wl->wl_next; wlk; wlk = wlk->wl_next) {
char* wlkword = strchr(wlk->wl_word, '/');
if (wlkword) {
/* already " around token */
if (*(wlk->wl_word) == '"')
continue;
/* just '/' */
if (*(wlkword + 1) == '\0')
continue;
else {
char* newword = tprintf("\"%s\"", wlk->wl_word);
tfree(wlk->wl_word);
wlk->wl_word = newword;
}
} }
} }
} }
}
/* Now parse the vectors. We have a list of the form
* "a b vs c d e vs f g h". Since it's a bit of a hassle for
* us to parse the vector boundaries here, we do this -- call
* ft_getpnames() without the check flag, and then look for 0-length
* vectors with the name "vs"... This is a sort of a gross hack,
* since we have to check for 0-length vectors ourselves after
* evaulating the pnodes...
*
* Note: Evaluating the wordlist starting at wl->wl_next since the first
* node is a dummy node.
*/
/* Now parse the vectors. We have a list of the form names = ft_getpnames(wl->wl_next, FALSE);
* "a b vs c d e vs f g h". Since it's a bit of a hassle for if (names == (struct pnode*)NULL) {
* us to parse the vector boundaries here, we do this -- call goto quit1;
* ft_getpnames() without the check flag, and then look for 0-length }
* vectors with the name "vs"... This is a sort of a gross hack,
* since we have to check for 0-length vectors ourselves after
* evaulating the pnodes...
*
* Note: Evaluating the wordlist starting at wl->wl_next since the first
* node is a dummy node.
*/
names = ft_getpnames(wl->wl_next, FALSE); /* Now evaluate the names. */
if (names == (struct pnode *) NULL) { for (pn = names, lv = NULL; pn; pn = pn->pn_next) {
goto quit1; struct dvec* pn_value = pn->pn_value;
}
/* Now evaluate the names. */ /* Test for a vs b construct */
for (pn = names, lv = NULL; pn; pn = pn->pn_next) { if (pn_value && (pn_value->v_length == 0) &&
struct dvec *pn_value = pn->pn_value;
/* Test for a vs b construct */
if (pn_value && (pn_value->v_length == 0) &&
eq(pn_value->v_name, "vs")) { eq(pn_value->v_name, "vs")) {
struct dvec *dv; struct dvec* dv;
if (!lv) { /* e.g. "plot vs b" */ if (!lv) { /* e.g. "plot vs b" */
fprintf(cp_err, "Error: misplaced vs arg\n"); fprintf(cp_err, "Error: misplaced vs arg\n");
goto quit; goto quit;
} }
if ((pn = pn->pn_next) == NULL) { /* "plot a vs" */ if ((pn = pn->pn_next) == NULL) { /* "plot a vs" */
fprintf(cp_err, "Error: missing vs arg\n"); fprintf(cp_err, "Error: missing vs arg\n");
goto quit; goto quit;
} }
dv = ft_evaluate(pn); dv = ft_evaluate(pn);
if (!dv) { if (!dv) {
goto quit; goto quit;
} }
if (lastvs) { if (lastvs) {
lv = lastvs->v_link2; lv = lastvs->v_link2;
} }
else { else {
lv = vecs; lv = vecs;
} }
while (lv) { while (lv) {
lv->v_scale = dv; lv->v_scale = dv;
lastvs = lv; lastvs = lv;
lv = lv->v_link2; lv = lv->v_link2;
} }
}
else { /* An explicit scale vector is not given ("plot a") */
struct dvec * const dv = ft_evaluate(pn);
if (!dv) {
goto quit;
} }
else { /* An explicit scale vector is not given ("plot a") */
struct dvec* const dv = ft_evaluate(pn);
if (!dv) {
goto quit;
}
if (!d) { if (!d) {
vecs = dv; vecs = dv;
} }
else { else {
d->v_link2 = dv; d->v_link2 = dv;
} }
for (d = dv; d->v_link2; d = d->v_link2) { for (d = dv; d->v_link2; d = d->v_link2) {
; ;
}
lv = dv;
} }
} /* end of loop evaluating the names */
lv = dv; d->v_link2 = NULL; /* terminate list */
} } /* if not plain */
} /* end of loop evaluating the names */
d->v_link2 = NULL; /* terminate list */
/* Now check for 0-length vectors. */ /* Now check for 0-length vectors. */
for (d = vecs; d; d = d->v_link2) { for (d = vecs; d; d = d->v_link2) {