Allow math characters in node names
Add a function ft_getpnames_quotes()
It puts quotes " around tokens xxx, when these are enclosed as
V(xxx) and contain arithmetic characters. V(R*C) becomes
V("R*C"). After settig up the parse tree, the quotes are removed again.
Thus these math character remain part of the node name and are not
parsed as parts of an equation.
This commit is contained in:
parent
d5dc757288
commit
e93a19e3e8
|
|
@ -13,6 +13,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "ngspice/fteparse.h"
|
||||
#include "ngspice/fteext.h"
|
||||
#include "ngspice/sim.h"
|
||||
#include "numparam/general.h"
|
||||
|
||||
#include "evaluate.h"
|
||||
#include "parse.h"
|
||||
|
|
@ -27,6 +28,7 @@ extern int PPparse(char **, struct pnode **);
|
|||
#endif
|
||||
|
||||
void db_print_pnode_tree(struct pnode *p, char *print);
|
||||
struct pnode* ft_getpnames_quotes(wordlist* wl, bool check);
|
||||
|
||||
|
||||
struct pnode *ft_getpnames_from_string(const char *sz, bool check)
|
||||
|
|
@ -71,6 +73,136 @@ ft_getpnames(const wordlist *wl, bool check)
|
|||
|
||||
|
||||
|
||||
static bool is_all_digits(char* tstr)
|
||||
{
|
||||
while (*tstr != '\0') {
|
||||
if (!isdigit_c(*tstr))
|
||||
return FALSE;
|
||||
tstr++;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static bool has_arith_char(char* tstr)
|
||||
{
|
||||
while (*tstr != '\0') {
|
||||
if (is_arith_char(*tstr))
|
||||
return TRUE;
|
||||
tstr++;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* writing, printing or plotting will fail when the node name starts with
|
||||
a number or math character, even when enclosed in V() like V(2p). So
|
||||
automatically place "" around, like V("2p"). Returns the parse tree. Multiple
|
||||
v() may occur in a row. Remove "" again after the tree is set up.
|
||||
*/
|
||||
struct pnode* ft_getpnames_quotes(wordlist* wl, bool check)
|
||||
{
|
||||
struct pnode* names = NULL, * tmpnode = NULL;
|
||||
char* sz = wl_flatten(wl);
|
||||
if ((strstr(sz, "v(") || strstr(sz, "V(")) && !cp_getvar("noquotesinoutput", CP_BOOL, NULL, 0))
|
||||
{
|
||||
char* tmpstr;
|
||||
char* nsz = tmpstr = stripWhiteSpacesInsideParens(sz);
|
||||
DS_CREATE(ds1, 100); /* the new name string*/
|
||||
/* put double quotes around tokens which start with number chars or include a math char */
|
||||
while (*tmpstr != '\0') {
|
||||
/*check if we have v(something) at the beginning, after arithchar, after space,
|
||||
or after dot. Skip V(" because it is already quoted. */
|
||||
if ((tmpstr[0] == 'v' || tmpstr[0] == 'V') && tmpstr[1] == '(' && tmpstr[2] != '\"' &&
|
||||
(nsz == tmpstr || isspace_c(tmpstr[-1]) || is_arith_char(tmpstr[-1]) || tmpstr[-1] == '.')) {
|
||||
char* tmpstr2, * partoken2 = NULL;
|
||||
tmpstr += 2;
|
||||
/* get the complete zzz of v(zzz) */
|
||||
char* tpartoken = tmpstr2 = gettok_char(&tmpstr, ')', FALSE, FALSE);
|
||||
/* check if this is v(zzz) or v(xx,yy) */
|
||||
char* partoken1 = gettok_char(&tpartoken, ',', FALSE, FALSE);
|
||||
sadd(&ds1, "v(");
|
||||
if (partoken1) {
|
||||
/* we have a xx and yy */
|
||||
partoken2 = copy(tpartoken + 1);
|
||||
bool hac1 = has_arith_char(partoken1);
|
||||
bool hac2 = has_arith_char(partoken2);
|
||||
if (is_all_digits(partoken1)) {
|
||||
sadd(&ds1, partoken1);
|
||||
}
|
||||
else if (isdigit_c(*partoken1) || hac1) {
|
||||
cadd(&ds1, '\"');
|
||||
sadd(&ds1, partoken1);
|
||||
cadd(&ds1, '\"');
|
||||
}
|
||||
else
|
||||
sadd(&ds1, partoken1);
|
||||
cadd(&ds1, ',');
|
||||
if (is_all_digits(partoken2)) {
|
||||
sadd(&ds1, partoken2);
|
||||
}
|
||||
else if (isdigit_c(*partoken2) || hac2) {
|
||||
cadd(&ds1, '\"');
|
||||
sadd(&ds1, partoken2);
|
||||
cadd(&ds1, '\"');
|
||||
}
|
||||
else
|
||||
sadd(&ds1, partoken2);
|
||||
}
|
||||
else {
|
||||
bool hac = has_arith_char(tmpstr2);
|
||||
if (is_all_digits(tmpstr2)) {
|
||||
sadd(&ds1, tmpstr2);
|
||||
}
|
||||
else if (isdigit_c(*tmpstr2) || hac) {
|
||||
cadd(&ds1, '\"');
|
||||
sadd(&ds1, tmpstr2);
|
||||
cadd(&ds1, '\"');
|
||||
}
|
||||
else
|
||||
sadd(&ds1, tmpstr2);
|
||||
}
|
||||
|
||||
tfree(tmpstr2);
|
||||
tfree(partoken1);
|
||||
tfree(partoken2);
|
||||
}
|
||||
cadd(&ds1, *tmpstr);
|
||||
tmpstr++;
|
||||
}
|
||||
|
||||
char* newline = ds_get_buf(&ds1);
|
||||
names = ft_getpnames_from_string(newline, check);
|
||||
ds_free(&ds1);
|
||||
tfree(nsz);
|
||||
/* restore the old node name after parsing */
|
||||
for (tmpnode = names; tmpnode; tmpnode = tmpnode->pn_next) {
|
||||
if (strstr(tmpnode->pn_name, "v(\"")) {
|
||||
char newstr[100];
|
||||
char* tmp = tmpnode->pn_name;
|
||||
int ii = 0;
|
||||
// copy to newstr without double quotes
|
||||
while (*tmp && ii < 99) {
|
||||
if (*(tmp) == '\"') {
|
||||
tmp++;
|
||||
continue;
|
||||
}
|
||||
newstr[ii] = *(tmp++);
|
||||
ii++;
|
||||
}
|
||||
newstr[ii] = '\0';
|
||||
tfree(tmpnode->pn_name);
|
||||
tmpnode->pn_name = copy(newstr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
names = ft_getpnames_from_string(sz, check);
|
||||
}
|
||||
tfree(sz);
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* See if there are any variables around which have length 0 and are
|
||||
* not named 'list'. There should really be another flag for this...
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -279,6 +279,7 @@ extern struct pnode *alloc_pnode(void);
|
|||
ptr = NULL; \
|
||||
} while(0)
|
||||
extern void free_pnode_x(struct pnode *t);
|
||||
extern struct pnode* ft_getpnames_quotes(wordlist* wl, bool check);
|
||||
|
||||
/* plotcurve.c */
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue