diff --git a/ChangeLog b/ChangeLog
index 9afaa36f4..aff4197ed 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2003-12-24 Paolo Nenzi
+
+ * src/maths/cmaths/cmath4.c: Applied
+ Vera Albrecht patch to enable interpolate
+ function.
+
+ * src/frontend/{come_let.c, control.c, evaluate.c, outitf.c, parse.c},
+ src/frontend/parser/lexical.c: Applied Vera Albrecht patch that
+ fixes ngspice bugs in its control language (c shell).
+
2003-12-08 Paolo Nenzi
* src/spicelib/devices/mos9/*: Added
diff --git a/src/frontend/com_let.c b/src/frontend/com_let.c
index ebf256b86..a9dc31286 100644
--- a/src/frontend/com_let.c
+++ b/src/frontend/com_let.c
@@ -22,7 +22,7 @@ com_let(wordlist *wl)
struct pnode *nn;
struct dvec *n, *t;
int i, cube;
- int depth;
+ int j, depth;
int newvec;
char *rhs;
@@ -63,7 +63,7 @@ com_let(wordlist *wl)
}
if (depth != 0 || !*q) {
- printf("syntax error specifyingstrchr\n");
+ printf("syntax error specifying index\n");
tfree(p);
return;
}
@@ -74,6 +74,31 @@ com_let(wordlist *wl)
need_open = 0;
if (*q)
*q++ = 0;
+
+ /* evaluate expression between s and q */
+ /* va, indexing */
+ fake_wl.wl_word = s;
+ nn = ft_getpnames(&fake_wl, TRUE);
+ t = ft_evaluate(nn);
+
+ if (!isreal(t) || t->v_link2 || t->v_length != 1 || !t->v_realdata)
+ {
+ fprintf(cp_err, "Error: index is not a scalar.\n");
+ goto quit;
+ }
+ j = (int)floor(t->v_realdata[0]+0.5); /* ignore sanity checks for now, va, which checks? */
+
+ if (j < 0) {
+ printf("negative index (%d) is not allowed\n", j);
+ goto quit;
+ }
+
+ indices[numdims++] = j;
+
+ /* va: garbage collection for t, if pnode nn is no simple value */
+ if (nn!=NULL && nn->pn_value==NULL && t!=NULL) vec_free(t);
+ free_pnode(nn); /* frees also t, if pnode nn is simple value */
+
for (s = q; *s && isspace(*s); s++)
;
}
@@ -148,8 +173,8 @@ com_let(wordlist *wl)
vec_new(n);
}
- /* fix-up dimensions */
- if (n->v_numdims < 1) {
+ /* fix-up dimensions; va, also for v_dims */
+ if (n->v_numdims < 1 || n->v_dims[0]==0 ) {
n->v_numdims = 1;
n->v_dims[0] = n->v_length;
}
@@ -204,7 +229,7 @@ com_let(wordlist *wl)
quit:
/* va: garbage collection for t, if pnode nn is no simple value */
- if (nn->pn_value==NULL && t!=NULL) vec_free(t);
+ if (nn!=NULL && nn->pn_value==NULL && t!=NULL) vec_free(t);
free_pnode(nn); /* frees also t, if pnode nn is simple value */
tfree(p);
return;
diff --git a/src/frontend/control.c b/src/frontend/control.c
index 2d9a99aa3..3f4c46357 100644
--- a/src/frontend/control.c
+++ b/src/frontend/control.c
@@ -237,8 +237,9 @@ docommand(wordlist *wlist)
}
} else if (nargs > command->co_maxargs) {
fprintf(cp_err, "%s: too many args.\n", s);
- } else
+ } else {
(*command->co_func) (wlist->wl_next);
+ }
}
/* Now fix the pointers and advance wlist. */
@@ -287,12 +288,12 @@ doblock(struct control *bl, int *num)
switch (bl->co_type) {
case CO_WHILE:
- if (!bl->co_children) {
+ if (!bl->co_children) {
fprintf(cp_err, "Warning: Executing empty 'while' block.\n");
fprintf(cp_err, " (Use a label statement as a no-op to suppress this warning.)\n");
}
while (bl->co_cond && cp_istrue(bl->co_cond)) {
- if (!bl->co_children) cp_periodic(); /*CDHW*/
+ if (!bl->co_children) cp_periodic(); /*CDHW*/
for (ch = bl->co_children; ch; ch = cn) {
cn = ch->co_next;
i = doblock(ch, &nn);
@@ -364,16 +365,16 @@ doblock(struct control *bl, int *num)
break;
case CO_REPEAT:
- if (!bl->co_children) {
+ if (!bl->co_children) {
fprintf(cp_err, "Warning: Executing empty 'repeat' block.\n");
fprintf(cp_err, " (Use a label statement as a no-op to suppress this warning.)\n");
}
- if (!bl->co_timestodo) bl->co_timestodo = bl->co_numtimes;
+ if (!bl->co_timestodo) bl->co_timestodo = bl->co_numtimes;
/*...CDHW*/
while ((bl->co_timestodo > 0) ||
(bl->co_timestodo == -1)) {
- if (bl->co_numtimes != -1)
- bl->co_numtimes--;
+ if (bl->co_numtimes != -1)
+ bl->co_numtimes--;
if (!bl->co_children) cp_periodic(); /*CDHW*/
@@ -597,6 +598,7 @@ cp_evloop(char *string)
}
if ((wlist->wl_word == NULL) || (*wlist->wl_word == '\0')) {
/* User just typed return. */
+ wl_free(wlist); /* va, avoid memory leak */
if (string)
return (1);
else {
@@ -618,7 +620,7 @@ cp_evloop(char *string)
* CO_UNFILLED, the last line was the beginning of a block,
* and this is the unfilled first statement.
*/
- /* va: TODO: free old structure and its content, before overwriting */
+ /* va: TODO: free old structure and its content, before overwriting */
if (cend[stackp] && (cend[stackp]->co_type != CO_UNFILLED)) {
cend[stackp]->co_next = alloc(struct control);
ZERO(cend[stackp]->co_next, struct control);
@@ -633,7 +635,7 @@ cp_evloop(char *string)
if (eq(wlist->wl_word, "while")) {
cend[stackp]->co_type = CO_WHILE;
- cend[stackp]->co_cond = wlist->wl_next;
+ cend[stackp]->co_cond = wl_copy(wlist->wl_next); /* va, wl_copy */
if (!cend[stackp]->co_cond) {
fprintf(stderr,
"Error: missing while condition, 'false' will be assumed.\n");
@@ -641,11 +643,11 @@ cp_evloop(char *string)
newblock;
} else if (eq(wlist->wl_word, "dowhile")) {
cend[stackp]->co_type = CO_DOWHILE;
- cend[stackp]->co_cond = wlist->wl_next;
+ cend[stackp]->co_cond = wl_copy(wlist->wl_next); /* va, wl_copy */
if (!cend[stackp]->co_cond) {
- /* va: prevent misinterpretation as trigraph sequence with \-sign */
+ /* va: prevent misinterpretation as trigraph sequence with \-sign */
fprintf(stderr,
- "Error: missing dowhile condition, '\?\?\?' will be assumed.\n");
+ "Error: missing dowhile condition, '?\?\?' will be assumed.\n");
}
newblock;
} else if (eq(wlist->wl_word, "repeat")) {
@@ -657,9 +659,9 @@ cp_evloop(char *string)
double *dd;
struct wordlist *t; /*CDHW*/
- /*CDHW wlist = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(wlist)))); Wrong order? Leak? CDHW*/
- t = cp_doglob(cp_bquote(cp_variablesubst(wl_copy(wlist)))); /*CDHW leak from cp_doglob? */
- s = t->wl_next->wl_word;
+ /*CDHW wlist = cp_variablesubst(cp_bquote(cp_doglob(wl_copy(wlist)))); Wrong order? Leak? CDHW*/
+ t = cp_doglob(cp_bquote(cp_variablesubst(wl_copy(wlist)))); /*CDHW leak from cp_doglob? */
+ s = t->wl_next->wl_word;
dd = ft_numparse(&s, FALSE);
if (dd) {
@@ -673,13 +675,13 @@ cp_evloop(char *string)
fprintf(cp_err,
"Error: bad repeat argument %s\n",
t->wl_next->wl_word); /* CDHW */
- wl_free(t); t = NULL; /* CDHW */
+ wl_free(t); t = NULL; /* CDHW */
}
newblock;
} else if (eq(wlist->wl_word, "if")) {
cend[stackp]->co_type = CO_IF;
- cend[stackp]->co_cond = wlist->wl_next;
+ cend[stackp]->co_cond = wl_copy(wlist->wl_next); /* va, wl_copy */
if (!cend[stackp]->co_cond) {
fprintf(stderr,
"Error: missing if condition.\n");
@@ -779,6 +781,7 @@ cp_evloop(char *string)
cend[stackp]->co_type = CO_STATEMENT;
cend[stackp]->co_text = wl_copy(wlist);
}
+
if (!cend[stackp]->co_parent) {
x = cend[stackp];
/* We have to toss this do-while loop in here so
@@ -807,21 +810,23 @@ cp_evloop(char *string)
} while (x);
}
wl_free(wlist); wlist = NULL;
- if (string)
+ if (string) {
return (1); /* The return value is irrelevant. */
+ }
}
- wl_free(wlist); wlist = NULL;
- return (0); /* va: which value? */
+ wl_free(wlist); wlist = NULL;
+ return (0); /* va: which value? */
}
/* This blows away the control structures... */
void
cp_resetcontrol(void)
{
- fprintf(cp_err, "Warning: clearing control structures\n");
+ fprintf(cp_err, "Warning: clearing control structures\n");
if (cend[stackp] && cend[stackp]->co_parent)
fprintf(cp_err, "Warning: EOF before block terminated\n");
/* We probably should free the control structures... */
+ cp_free_control(); /* va: free it */
control[0] = cend[0] = NULL;
stackp = 0;
cp_kwswitch(CT_LABEL, (char *) NULL);
@@ -837,8 +842,11 @@ cp_popcontrol(void)
fprintf(cp_err, "pop: stackp: %d -> %d\n", stackp, stackp - 1);
if (stackp < 1)
fprintf(cp_err, "cp_popcontrol: Internal Error: stack empty\n");
- else
+ else {
+ /* va: free unused control structure */
+ ctl_free(control[stackp]);
stackp--;
+ }
return;
}
@@ -870,3 +878,16 @@ cp_toplevel(void)
cend[stackp] = cend[stackp]->co_parent;
return;
}
+
+
+/* va: This totally frees the control structures */
+void cp_free_control(void)
+{
+ int i;
+
+ for (i=stackp; i>=0; i--) ctl_free(control[i]);
+
+ control[0] = cend[0] = NULL;
+ stackp = 0;
+}
+
diff --git a/src/frontend/evaluate.c b/src/frontend/evaluate.c
index 6f91dcbe2..d89528c62 100644
--- a/src/frontend/evaluate.c
+++ b/src/frontend/evaluate.c
@@ -40,8 +40,8 @@ sig_matherr(void)
/* Note that ft_evaluate will return NULL on invalid expressions. */
/* va: NOTE: ft_evaluate returns a new vector for expressions (func, op, ...)
- and an existing vector (node->pn_value) when node->pn_value != NULL.
- For garbage collection caller must vec_free() expression-vector. */
+ and an existing vector (node->pn_value) when node->pn_value != NULL.
+ For garbage collection caller must vec_free() expression-vector. */
struct dvec *
ft_evaluate(struct pnode *node)
{
@@ -57,21 +57,22 @@ ft_evaluate(struct pnode *node)
if (node->pn_op->op_arity == 1)
d = (struct dvec *)
((*node->pn_op->op_func) (node->pn_left));
- else if (node->pn_op->op_arity == 2)
+ else if (node->pn_op->op_arity == 2) {
d = (struct dvec *) ((*node->pn_op->op_func)
(node->pn_left, node->pn_right));
+ }
} else {
fprintf(cp_err, "ft_evaluate: Internal Error: bad node\n");
d = NULL;
}
- if (d == NULL) {
+ if (d==NULL) {
return NULL;
}
if (node->pn_name && !ft_evdb && d && !d->v_link2) {
- if(d->v_name)
- tfree(d->v_name);
+ if (d->v_name)
+ tfree(d->v_name); /* patch by Stefan Jones */
d->v_name = copy(node->pn_name);
}
@@ -295,7 +296,7 @@ doop(char what,
tfree(c2);
}
}
-
+
/* va: garbage collection */
if (arg1->pn_value==NULL && v1!=NULL) vec_free(v1);
if (arg2->pn_value==NULL && v2!=NULL) vec_free(v2);
@@ -498,10 +499,10 @@ op_range(struct pnode *arg1, struct pnode *arg2)
*/
vec_new(res);
-
+
/* va: garbage collection */
if (arg1->pn_value==NULL && v!=NULL) vec_free(v);
- if (arg1->pn_value==NULL && ind!=NULL) vec_free(ind);
+ if (arg1->pn_value==NULL && ind!=NULL) vec_free(ind);
return (res);
}
@@ -651,10 +652,10 @@ op_ind(struct pnode *arg1, struct pnode *arg2)
*/
vec_new(res);
-
+
/* va: garbage collection */
if (arg1->pn_value==NULL && v!=NULL) vec_free(v);
- if (arg1->pn_value==NULL && ind!=NULL) vec_free(ind);
+ if (arg1->pn_value==NULL && ind!=NULL) vec_free(ind);
return (res);
}
@@ -706,7 +707,8 @@ apply_func(struct func *func, struct pnode *arg)
}
(void) signal(SIGILL, (SIGNAL_FUNCTION) sig_matherr);
-#if 0
+#define INTERPOLATE 1 /* va, enable interpolate */
+#if INTERPOLATE
/* FIXME: The call to (*func->fu_func) has too many arguments;
hence the compiler quits. How to circumvent this (without
losing function prototypes)? For now, these functions have
@@ -714,13 +716,11 @@ apply_func(struct func *func, struct pnode *arg)
if (eq(func->fu_name, "interpolate")
|| eq(func->fu_name, "deriv")) /* Ack */
{
- data = ((*func->fu_func) ((isreal(v) ?
- (void *) v->v_realdata :
- (void *) v->v_compdata),
- (short) (isreal(v) ? VF_REAL :
- VF_COMPLEX),
- v->v_length, &len, &type,
- v->v_plot, plot_cur, v->v_dims[0]));
+ void *(*f)()=func->fu_func; /* va, a type cast, which loses function prototypes, a warning */
+ data = ((*f) ((isreal(v) ? (void *) v->v_realdata : (void *) v->v_compdata),
+ (short) (isreal(v) ? VF_REAL : VF_COMPLEX),
+ v->v_length, &len, &type,
+ v->v_plot, plot_cur, v->v_dims[0]));
} else {
#endif
data = ((*func->fu_func) ((isreal(v) ? (void *)
@@ -729,7 +729,7 @@ apply_func(struct func *func, struct pnode *arg)
(short) (isreal(v) ? VF_REAL :
VF_COMPLEX),
v->v_length, &len, &type));
-#if 0
+#if INTERPOLATE
}
#endif
/* Back to normal */
diff --git a/src/frontend/outitf.c b/src/frontend/outitf.c
index e396386f2..9414e0690 100644
--- a/src/frontend/outitf.c
+++ b/src/frontend/outitf.c
@@ -77,21 +77,22 @@ extern bool ft_getOutReq (FILE **fpp, struct plot **plotp, bool *binp, char *nam
int
OUTpBeginPlot(void *circuitPtr, void *analysisPtr, IFuid analName, IFuid refName, int refType, int numNames, IFuid *dataNames, int dataType, void **plotPtr)
{
- char *name;
+ char *name;
+
#ifdef PARALLEL_ARCH
if (ARCHme != 0) return(OK);
#endif /* PARALLEL_ARCH */
- if (ft_curckt->ci_ckt == circuitPtr)
- name = ft_curckt->ci_name;
- else
- name = "circuit name";
-
- return (beginPlot(analysisPtr, circuitPtr, name,
- (char *) analName, (char *) refName, refType, numNames,
- (char **) dataNames, dataType, FALSE,
- (runDesc **) plotPtr));
+ if (ft_curckt->ci_ckt == circuitPtr)
+ name = ft_curckt->ci_name;
+ else
+ name = "circuit name";
+
+ return (beginPlot(analysisPtr, circuitPtr, name,
+ (char *) analName, (char *) refName, refType, numNames,
+ (char **) dataNames, dataType, FALSE,
+ (runDesc **) plotPtr));
}
int
@@ -119,7 +120,7 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
char *ch, tmpname[BSIZE_SP];
bool saveall = TRUE;
bool savealli = FALSE;
- char *an_name;
+ char *an_name;
/*to resume a run saj
*All it does is reassign the file pointer and return (requires *runp to be NULL if this is not needed)
*/
@@ -130,7 +131,7 @@ beginPlot(void *analysisPtr, void *circuitPtr, char *cktName, char *analName, ch
} else {
/*end saj*/
-
+
/* Check to see if we want to print informational data. */
if (cp_getvar("printinfo", VT_BOOL, (char *) &printinfo))
fprintf(cp_err, "(debug printing enabled)\n");
@@ -533,10 +534,10 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
#ifndef HAS_WINDOWS
if ((currclock-lastclock)>(0.25*CLOCKS_PER_SEC)) {
if (run->isComplex) {
- fprintf(stderr, " Reference value : % 12.5e\r",
+ fprintf(stderr, " Reference value : % 12.5e\n",
refValue->cValue.real);
} else {
- fprintf(stderr, " Reference value : % 12.5e\r",
+ fprintf(stderr, " Reference value : % 12.5e\n",
refValue->rValue);
}
lastclock = currclock;
@@ -544,33 +545,33 @@ OUTpData(void *plotPtr, IFvalue *refValue, IFvalue *valuePtr)
#endif
for (i = 0; i < run->numData; i++) {
if (run->data[i].outIndex == -1) {
- if (run->data[i].type == IF_REAL)
- plotAddRealValue(&run->data[i],
- refValue->rValue);
- else if (run->data[i].type == IF_COMPLEX)
- plotAddComplexValue(&run->data[i],
- refValue->cValue);
+ if (run->data[i].type == IF_REAL)
+ plotAddRealValue(&run->data[i],
+ refValue->rValue);
+ else if (run->data[i].type == IF_COMPLEX)
+ plotAddComplexValue(&run->data[i],
+ refValue->cValue);
} else if (run->data[i].regular) {
- if (run->data[i].type == IF_REAL)
- plotAddRealValue(&run->data[i],
- valuePtr->v.vec.rVec
- [run->data[i].outIndex]);
- else if (run->data[i].type == IF_COMPLEX)
- plotAddComplexValue(&run->data[i],
- valuePtr->v.vec.cVec
- [run->data[i].outIndex]);
+ if (run->data[i].type == IF_REAL)
+ plotAddRealValue(&run->data[i],
+ valuePtr->v.vec.rVec
+ [run->data[i].outIndex]);
+ else if (run->data[i].type == IF_COMPLEX)
+ plotAddComplexValue(&run->data[i],
+ valuePtr->v.vec.cVec
+ [run->data[i].outIndex]);
} else {
- /* should pre-check instance */
- if (!getSpecial(&run->data[i], run, &val))
- continue;
- if (run->data[i].type == IF_REAL)
- plotAddRealValue(&run->data[i],
- val.rValue);
- else if (run->data[i].type == IF_COMPLEX)
- plotAddComplexValue(&run->data[i],
+ /* should pre-check instance */
+ if (!getSpecial(&run->data[i], run, &val))
+ continue;
+ if (run->data[i].type == IF_REAL)
+ plotAddRealValue(&run->data[i],
+ val.rValue);
+ else if (run->data[i].type == IF_COMPLEX)
+ plotAddComplexValue(&run->data[i],
val.cValue);
- else
- fprintf(stderr, "OUTpData: unsupported data type\n");
+ else
+ fprintf(stderr, "OUTpData: unsupported data type\n");
}
}
gr_iplot(run->runPlot);
@@ -934,6 +935,7 @@ plotAddRealValue(dataDesc *desc, double value)
v->v_compdata[v->v_length].cx_imag = (double) 0;
}
v->v_length++;
+ v->v_dims[0]=v->v_length; /* va, must be updated */
return;
}
@@ -948,6 +950,7 @@ plotAddComplexValue(dataDesc *desc, IFcomplex value)
v->v_compdata[v->v_length].cx_real = value.real;
v->v_compdata[v->v_length].cx_imag = value.imag;
v->v_length++;
+ v->v_dims[0]=v->v_length; /* va, must be updated */
return;
}
@@ -1096,9 +1099,7 @@ OUTstopnow(void)
static struct mesg {
char *string;
long flag;
-}
-
-msgs[] = {
+} msgs[] = {
{ "Warning", ERR_WARNING } ,
{ "Fatal error", ERR_FATAL } ,
{ "Panic", ERR_PANIC } ,
diff --git a/src/frontend/parse.c b/src/frontend/parse.c
index 3fb03d27c..18e2c793b 100644
--- a/src/frontend/parse.c
+++ b/src/frontend/parse.c
@@ -27,7 +27,9 @@ static struct pnode * mkunode(int op, struct pnode *arg);
static struct pnode * mkfnode(char *func, struct pnode *arg);
static struct pnode * mknnode(double number);
static struct pnode * mksnode(char *string);
-void print_elem(struct element *elem); /* va: for debugging */
+static void print_elem(struct element *elem); /* va: for debugging */
+static char * get_token_name(int e_token); /* va, for debugging */
+
static int lasttoken = END, lasttype;
static char *sbuf;
@@ -339,12 +341,13 @@ lexer(void)
/* It is bad how we have to recognise '[' -- sometimes
* it is part of a word, when it defines a parameter
* name, and otherwise it isn't.
+ * va, ']' too
*/
atsign = 0;
for (s = el.e_string; *s && !index(specials, *s); s++, sbuf++) {
if (*s == '@')
atsign = 1;
- else if (*s == '[' && !atsign)
+ else if (!atsign && ( *s == '[' || *s == ']' ) )
break;
}
if (*s)
@@ -401,46 +404,49 @@ static char prectable[23][23] = {
} ;
/* Return an expr. */
-
static struct pnode *
parse(void)
{
struct element stack[STACKSIZE];
- char *stringStack[STACKSIZE];
- int sp = 0, st, i, fsp = 0;
+ int sp = 0, st, i, spmax=0; /* va: spmax = maximal used stack */
struct element *top, *next;
struct pnode *pn, *lpn, *rpn;
char rel;
+ char * parse_string=sbuf; /* va, duplicate sbuf's pointer for error message only, no tfree */
stack[0].e_token = END;
next = lexer();
- if(next->e_token == VALUE && next->e_type == STRING)
- stringStack[fsp++] = next->e_string;
while ((sp > 1) || (next->e_token != END)) {
/* Find the top-most terminal. */
+ /* va: no stack understepping, because stack[0].e_token==END */
i = sp;
do {
top = &stack[i--];
- } while (top->e_token == VALUE);
+ } while (top->e_token == VALUE && i>=0); /* va: do not understep stack */
+ if (top->e_token == VALUE) {
+ fprintf(cp_err, "Error: in parse.c(parse) stack understep.\n");
+ return (NULL);
+ }
+//for (i=0; i<=sp; i++) print_elem(stack+i); printf("next: "); print_elem(next); printf("\n");
+
rel = prectable[top->e_token][next->e_token];
switch (rel) {
case L:
case E:
- /* Push the token read. */
- if (sp == (STACKSIZE - 1) || fsp == (STACKSIZE-1)) {
+ /* Push the token read. */
+ if (sp == (STACKSIZE - 1)) {
fprintf(cp_err, "Error: stack overflow\n");
return (NULL);
}
bcopy((char *) next, (char *) &stack[++sp],
sizeof (struct element));
+ if (spmaxe_token == VALUE && next->e_type == STRING)
- stringStack[fsp++] = next->e_string;
continue;
case R:
- fprintf(cp_err, "Syntax error: parsing expression.\n");
+ fprintf(cp_err, "Syntax error: parsing expression '%s'.\n", parse_string);
return (NULL);
case G:
@@ -449,6 +455,7 @@ parse(void)
* reduce, then try and do some stuff. When scanning
* back for a <, ignore VALUES.
*/
+
st = sp;
if (stack[sp].e_token == VALUE)
sp--;
@@ -509,7 +516,7 @@ parse(void)
tfree(lpn->pn_value);
}
free_pnode(lpn);
- }
+ }
} else { /* node op node */
lpn = makepnode(&stack[sp]);
rpn = makepnode(&stack[st]);
@@ -518,6 +525,15 @@ parse(void)
pn = mkbnode(stack[sp + 1].e_token,
lpn, rpn);
}
+ /* va: avoid memory leakage: tfree all old strings on stack,
+ copied up to now within lexer */
+ for (i=sp; i<=spmax; i++) {
+ if (stack[i].e_token==VALUE && stack[i].e_type==STRING) {
+ tfree(stack[i].e_string);
+ }
+ }
+ spmax=sp; /* up to there stack is now clean */
+
stack[sp].e_token = VALUE;
stack[sp].e_type = PNODE;
stack[sp].e_pnode = pn;
@@ -525,12 +541,22 @@ parse(void)
}
}
pn = makepnode(&stack[1]);
- for(i=0;ie_token == VALUE && next->e_type == STRING) {
+ tfree(next->e_string);
+ }
+
if (pn)
return (pn);
err:
- fprintf(cp_err, "Syntax error: expression not understood.\n");
+ fprintf(cp_err, "Syntax error: expression not understood '%s'.\n", parse_string);
return (NULL);
}
@@ -556,9 +582,39 @@ makepnode(struct element *elem)
}
}
-void print_elem(struct element *elem)
+static char * get_token_name(int e_token)
{
- printf("e_token = %d", elem->e_token);
+ /* see include/fteparse.h */
+ switch (e_token) {
+ case 0: return "END ";
+ case 1: return "PLUS ";
+ case 2: return "MINUS ";
+ case 3: return "TIMES ";
+ case 4: return "MOD ";
+ case 5: return "DIVIDE";
+ case 6: return "POWER ";
+ case 7: return "UMINUS";
+ case 8: return "LPAREN";
+ case 9: return "RPAREN";
+ case 10: return "COMMA ";
+ case 11: return "VALUE ";
+ case 12: return "EQ ";
+ case 13: return "GT ";
+ case 14: return "LT ";
+ case 15: return "GE ";
+ case 16: return "LE ";
+ case 17: return "NE ";
+ case 18: return "AND ";
+ case 19: return "OR ";
+ case 20: return "NOT ";
+ case 21: return "INDX ";
+ case 22: return "RANGE ";
+ default : return "UNKNOWN";
+ }
+}
+static void print_elem(struct element *elem)
+{
+ printf("e_token = %d(%s)", elem->e_token, get_token_name(elem->e_token));
if (elem->e_token == VALUE) {
printf(", e_type = %d", elem->e_type);
switch (elem->e_type) {
@@ -577,6 +633,7 @@ void print_elem(struct element *elem)
}
+
/* Some auxiliary functions for building the parse tree. */
static
@@ -643,11 +700,14 @@ struct func ft_funcs[] = {
{ "vecmin", cx_min } ,
{ "vecmax", cx_max } ,
{ "vecd", cx_d } ,
-#if 0
+#define INTERPOLATE 1 /* va, enable interpolate */
+#if INTERPOLATE
+ /* va, deactivate function prototype testing for this 2 functions, only. Gives a warning. */
+#define INTERPOL_FUNC (void *(*)())
/* These functions have been temporarily been disabled. See
their definitions for the reason. */
- { "interpolate",cx_interpolate } ,
- { "deriv", cx_deriv } ,
+ { "interpolate",INTERPOL_FUNC cx_interpolate } ,
+ { "deriv", INTERPOL_FUNC cx_deriv } ,
#endif
{ "v", NULL } ,
{ NULL, NULL }
@@ -850,7 +910,7 @@ mksnode(char *string)
nobody will free it elsewhere */
if (v && v->v_name && *v->v_name=='@' && isreal(v) && v->v_realdata) {
vec_free(v);
- }
+ }
return (p);
}
@@ -863,9 +923,9 @@ free_pnode(struct pnode *t)
free_pnode(t->pn_left);
free_pnode(t->pn_right);
free_pnode(t->pn_next);
- tfree(t->pn_name);
+ tfree(t->pn_name); /* va: it is a copy() of original string, can be free'd */
if (t->pn_value)
- vec_free(t->pn_value);
+ vec_free(t->pn_value); /* patch by Stefan Jones */
tfree(t);
}
diff --git a/src/frontend/parser/lexical.c b/src/frontend/parser/lexical.c
index 287436946..59cefb3ea 100644
--- a/src/frontend/parser/lexical.c
+++ b/src/frontend/parser/lexical.c
@@ -22,7 +22,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include
#endif
-#ifndef __MINGW32__
+#if !defined(__MINGW32__) && !defined(_MSC_VER)
/* MW. Linux has TIOCSTI, so we include all headers here */
#include
#endif
@@ -66,7 +66,7 @@ static int numeofs = 0;
/* Return a list of words, with backslash quoting and '' quoting done.
* Strings en(void) closed in "" or `` are made single words and returned,
* but with the "" or `` still present. For the \ and '' cases, the
- * 8th bit is turned on (as in csh) to prevent them from being recogized,
+ * 8th bit is turned on (as in csh) to prevent them from being recognized,
* and stripped off once all processing is done. We also have to deal with
* command, filename, and keyword completion here.
* If string is non-NULL, then use it instead of the fp. Escape and EOF
@@ -280,22 +280,33 @@ gotchar:
cp_ccom(wlist, buf, TRUE);
wl_free(wlist);
goto nloop;
- } /* Else fall through */
+ } goto ldefault; /* else continue with default ... */
case ',':
if (paren < 1 && i > 0) {
newword;
break;
- }
- case ';': /*CDHW semicolon inside parentheses is part of expression CDHW*/
- if (paren > 0) {
- buf[i++]=c;
- break;
- }
+ } goto ldefault;
+ case ';': /*CDHW semicolon inside parentheses is part of expression CDHW*/
+ if (paren > 0) {
+ buf[i++]=c;
+ break;
+ } goto ldefault;
+ case '&': /* va: $&name is one word */
+ if (i==1 && buf[i-1]=='$' && c=='&') {
+ buf[i++]=c;
+ break;
+ } goto ldefault; /* else continue with default ... */
+ case '<':
+ case '>': /* va: <=, >= are unbreakable words */
+ if (i==0 && *string=='=') {
+ buf[i++]=c;
+ break;
+ } goto ldefault; /* else continue with default ... */
default:
/* We have to remember the special case $<
* here
*/
- if ((cp_chars[c] & CPC_BRL) && (i > 0)) {
+ldefault: if ((cp_chars[c] & CPC_BRL) && (i > 0)) {
if ((c != '<') || (buf[i - 1] != '$')) {
newword;
}
diff --git a/src/maths/cmaths/cmath4.c b/src/maths/cmaths/cmath4.c
index aca045e7b..52a10fac0 100644
--- a/src/maths/cmaths/cmath4.c
+++ b/src/maths/cmaths/cmath4.c
@@ -28,6 +28,8 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "cmath.h"
#include "cmath4.h"
+#include "../../frontend/variable.h" /* for VT_NUM in cx_interpolate */
+
void *
cx_and(void *data1, void *data2, short int datatype1, short int datatype2, int length)
{
@@ -128,7 +130,8 @@ cx_not(void *data, short int type, int length, int *newlength, short int *newtyp
return ((void *) d);
}
-#if 0
+#define INTERPOLATE 1 /* va, enable interpolate */
+#if INTERPOLATE
/* These functions have been temporarily disabled. They contain code
only found in the frontend and their prototype does not conform to
the prototypes found for other complex functions. They will not be
@@ -284,7 +287,7 @@ cx_deriv(void *data, short int type, int length, int *newlength, short int *newt
ft_polyderiv(r_coefs, degree);
/* for loop gets the beginning part */
- for (j = k; j <= i + degree / 2; j++) {
+ for (j = k; j <= i - degree / 2; j++) {
x = scale[j + base];
c_outdata[j + base].cx_real =
ft_peval(x, r_coefs, degree - 1);