|
|
@ -23,7 +23,7 @@ static INPparseNode *mkcon(double value); |
|
|
static INPparseNode *mkb(int type, INPparseNode * left, |
|
|
static INPparseNode *mkb(int type, INPparseNode * left, |
|
|
INPparseNode * right); |
|
|
INPparseNode * right); |
|
|
static INPparseNode *mkf(int type, INPparseNode * arg); |
|
|
static INPparseNode *mkf(int type, INPparseNode * arg); |
|
|
static int PTcheck(INPparseNode * p); |
|
|
|
|
|
|
|
|
static int PTcheck(INPparseNode * p, char* tline); |
|
|
static INPparseNode *mkvnode(char *name); |
|
|
static INPparseNode *mkvnode(char *name); |
|
|
static INPparseNode *mkinode(char *name); |
|
|
static INPparseNode *mkinode(char *name); |
|
|
|
|
|
|
|
|
@ -195,6 +195,7 @@ INPgetTree(char **line, INPparseTree ** pt, CKTcircuit *ckt, INPtables * tab) |
|
|
{ |
|
|
{ |
|
|
INPparseNode *p = NULL; |
|
|
INPparseNode *p = NULL; |
|
|
int i, rv; |
|
|
int i, rv; |
|
|
|
|
|
char* treeline = *line; |
|
|
|
|
|
|
|
|
values = NULL; |
|
|
values = NULL; |
|
|
types = NULL; |
|
|
types = NULL; |
|
|
@ -209,7 +210,7 @@ INPgetTree(char **line, INPparseTree ** pt, CKTcircuit *ckt, INPtables * tab) |
|
|
|
|
|
|
|
|
rv = PTparse(line, &p, ckt); |
|
|
rv = PTparse(line, &p, ckt); |
|
|
|
|
|
|
|
|
if (rv || !p || !PTcheck(p)) { |
|
|
|
|
|
|
|
|
if (rv || !p || !PTcheck(p, treeline)) { |
|
|
|
|
|
|
|
|
*pt = NULL; |
|
|
*pt = NULL; |
|
|
release_tree(p); |
|
|
release_tree(p); |
|
|
@ -898,10 +899,13 @@ static INPparseNode *mkf(int type, INPparseNode * arg) |
|
|
return (p); |
|
|
return (p); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* Check for remaining PT_PLACEHOLDERs in the parse tree. Returns 1 if ok. */ |
|
|
|
|
|
|
|
|
/* Check for remaining PT_PLACEHOLDERs in the parse tree. Returns 1 if ok. |
|
|
|
|
|
Returns 0 and error message containing expression to parsed, if not ok. */ |
|
|
|
|
|
|
|
|
static int PTcheck(INPparseNode * p) |
|
|
|
|
|
|
|
|
static int PTcheck(INPparseNode * p, char *tline) |
|
|
{ |
|
|
{ |
|
|
|
|
|
int ret; |
|
|
|
|
|
static bool msgsent = FALSE; |
|
|
switch (p->type) { |
|
|
switch (p->type) { |
|
|
case PT_PLACEHOLDER: |
|
|
case PT_PLACEHOLDER: |
|
|
return (0); |
|
|
return (0); |
|
|
@ -914,7 +918,12 @@ static int PTcheck(INPparseNode * p) |
|
|
return (1); |
|
|
return (1); |
|
|
|
|
|
|
|
|
case PT_FUNCTION: |
|
|
case PT_FUNCTION: |
|
|
return (PTcheck(p->left)); |
|
|
|
|
|
|
|
|
ret = (PTcheck(p->left, tline)); |
|
|
|
|
|
if (ret == 0 && !msgsent) { |
|
|
|
|
|
fprintf(stderr, "\nError: The internal check of parse tree \n%s\nfailed\n", tline); |
|
|
|
|
|
msgsent = TRUE; |
|
|
|
|
|
} |
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
case PT_PLUS: |
|
|
case PT_PLUS: |
|
|
case PT_MINUS: |
|
|
case PT_MINUS: |
|
|
@ -922,9 +931,19 @@ static int PTcheck(INPparseNode * p) |
|
|
case PT_DIVIDE: |
|
|
case PT_DIVIDE: |
|
|
case PT_POWER: |
|
|
case PT_POWER: |
|
|
case PT_COMMA: |
|
|
case PT_COMMA: |
|
|
return (PTcheck(p->left) && PTcheck(p->right)); |
|
|
|
|
|
|
|
|
ret = (PTcheck(p->left, tline) && PTcheck(p->right, tline)); |
|
|
|
|
|
if (ret == 0 && !msgsent) { |
|
|
|
|
|
fprintf(stderr, "\nError: The internal check of parse tree \n%s\nfailed\n", tline); |
|
|
|
|
|
msgsent = TRUE; |
|
|
|
|
|
} |
|
|
|
|
|
return ret; |
|
|
case PT_TERN: |
|
|
case PT_TERN: |
|
|
return (PTcheck(p->left) && PTcheck(p->right->left) && PTcheck(p->right->right)); |
|
|
|
|
|
|
|
|
ret = (PTcheck(p->left, tline) && PTcheck(p->right->left, tline) && PTcheck(p->right->right, tline)); |
|
|
|
|
|
if (ret == 0 && !msgsent) { |
|
|
|
|
|
fprintf(stderr, "\nError: The internal check of parse tree \n%s\nfailed\n", tline); |
|
|
|
|
|
msgsent = TRUE; |
|
|
|
|
|
} |
|
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
default: |
|
|
default: |
|
|
fprintf(stderr, "Internal error: bad node type %d\n", p->type); |
|
|
fprintf(stderr, "Internal error: bad node type %d\n", p->type); |
|
|
|