Fix variables so that they behave as described (or intended) in the ngspice-26plus manual.

This commit is contained in:
mhx 2016-01-01 20:32:22 +01:00 committed by rlar
parent 9d32a0a5a9
commit ee2eb66c45
2 changed files with 252 additions and 189 deletions

View File

@ -33,23 +33,26 @@ wordlist *
cp_varwl(struct variable *var)
{
wordlist *wl = NULL, *w, *wx = NULL;
char *buf;
char buf[BSIZE_SP], *copystring;
struct variable *vt;
switch (var->va_type) {
case CP_BOOL:
/* Can't ever be FALSE. */
buf = copy(var->va_bool ? "TRUE" : "FALSE");
sprintf(buf, "%s", var->va_bool ? "TRUE" : "FALSE");
break;
case CP_NUM:
buf = tprintf("%d", var->va_num);
sprintf(buf, "%d", var->va_num);
break;
case CP_REAL:
/* This is a case where printnum isn't too good... */
buf = tprintf("%G", var->va_real);
sprintf(buf, "%G", var->va_real);
break;
case CP_STRING:
buf = cp_unquote(var->va_string);
/*strcpy(buf, cp_unquote(var->va_string)); DG: memory leak here*/
copystring = cp_unquote(var->va_string); /*DG*/
strcpy(buf, copystring);
tfree(copystring);
break;
case CP_LIST: /* The tricky case. */
for (vt = var->va_vlist; vt; vt = vt->va_next) {
@ -65,12 +68,13 @@ cp_varwl(struct variable *var)
return (wl);
default:
fprintf(cp_err,
"cp_varwl: Internal Error: bad variable type %d\n",
"cp_varwl: INTERNAL ERROR: bad variable type %d\n",
var->va_type);
return (NULL);
}
return wl_cons(buf, NULL);
wl = wl_cons(copy(buf), NULL);
return wl;
}
@ -143,7 +147,7 @@ cp_vset(char *varname, enum cp_types type, void *value)
default:
fprintf(cp_err,
"cp_vset: Internal Error: bad variable type %d.\n",
"cp_vset: INTERNAL ERROR: bad variable type %d.\n",
type);
tfree(copyvarname);
return;
@ -152,7 +156,7 @@ cp_vset(char *varname, enum cp_types type, void *value)
v->va_type = type;
/* Now, see if there is anything interesting going on. We
* recognise these special variables: noglob, nonomatch, history,
* recognize these special variables: noglob, nonomatch, history,
* echo, noclobber, prompt, and verbose. cp_remvar looks for these
* variables too. The host program will get any others. */
if (eq(copyvarname, "noglob"))
@ -165,18 +169,14 @@ cp_vset(char *varname, enum cp_types type, void *value)
cp_maxhistlength = (int)floor(v->va_real + 0.5);
else if (eq(copyvarname, "noclobber"))
cp_noclobber = TRUE;
else if (eq(varname, "echo")) /*CDHW*/
cp_echo = TRUE; /*CDHW*/
else if (eq(varname, "echo"))
cp_echo = TRUE;
else if (eq(copyvarname, "prompt") && (type == CP_STRING))
cp_promptstring = v->va_string;
else if (eq(copyvarname, "ignoreeof"))
cp_ignoreeof = TRUE;
else if (eq(copyvarname, "cpdebug")) {
cp_debug = TRUE;
#ifndef CPDEBUG
fprintf(cp_err,
"Warning: program not compiled with cshpar debug messages\n");
#endif
}
switch (i = cp_usrset(v, TRUE)) {
@ -192,15 +192,15 @@ cp_vset(char *varname, enum cp_types type, void *value)
case US_DONTRECORD:
/* Do nothing... */
if (alreadythere) {
fprintf(cp_err, "cp_vset: Internal Error: "
"%s already there, but 'dont record'\n", v->va_name);
fprintf(cp_err, "cp_vset: INTERNAL ERROR: "
"%s already there, but `don't record'\n", v->va_name);
}
break;
case US_READONLY:
fprintf(cp_err, "Error: %s is a read-only variable.\n", v->va_name);
fprintf(cp_err, "ERROR: %s is a read-only variable.\n", v->va_name);
if (alreadythere)
fprintf(cp_err, "cp_vset: Internal Error: "
fprintf(cp_err, "cp_vset: INTERNAL ERROR: "
"it was already there too!!\n");
break;
@ -230,16 +230,8 @@ cp_vset(char *varname, enum cp_types type, void *value)
else if (u->va_type == CP_LIST)
tfree(u->va_vlist);
u->va_V = v->va_V;
/* va_name is the same string */
u->va_type = v->va_type;
/* va_next left unchanged */
// tfree(v->va_name);
tfree(v);
/* va: old version with memory leaks
w = u->va_next;
bcopy(v, u, sizeof(*u));
u->va_next = w;
*/
}
}
break;
@ -251,24 +243,28 @@ cp_vset(char *varname, enum cp_types type, void *value)
break;
default:
fprintf(cp_err, "cp_vset: Internal Error: bad US val %d\n", i);
fprintf(cp_err, "cp_vset: INTERNAL ERROR: bad US val %d\n", i);
break;
}
/* if (v_free) {
tfree(v->va_name);
tfree(v);
} */
tfree(copyvarname);
}
/*CDHW This needs leak checking carefully CDHW*/
/* CDHW This needs leak checking carefully CDHW */
/* mhx: Uses ft_numparse, which interprets SPICE numbers. Therefore it worked incorrectly
for com_set: it prevented e.g. set ape="1MEG" (ape became CP_NUM 1e6 instead of CP_STRING '1meg').
Therefore I changed the function to FIRST check if the rhs is a string (look for quotes), and only
if it is not, continue with ft_numparse.
Note: cp_setparse is used by com_set and com_option, where this new behavior should be ok.
cp_setparse is used in inp.c (4) for .option scale=xxx. Assumed new behavior will be ok.
cp_setparse is used in rawfile.c (2) to parse "option: xxx". Assumed new behavior will be ok.
*/
struct variable *
cp_setparse(wordlist *wl)
{
char *name = NULL, *val, *copyval, *s, *ss;
double *td;
bool isstring;
struct variable *listv = NULL, *vv, *lv = NULL;
struct variable *vars = NULL;
int balance;
@ -281,7 +277,7 @@ cp_setparse(wordlist *wl)
name = cp_unquote(wl->wl_word);
wl = wl->wl_next;
if ((!wl || (*wl->wl_word != '=')) && !strchr(name, '=')) {
if ((!wl || (*wl->wl_word != '=')) && !strchr(name, '=')) { /* 'name ccccc' */
vv = alloc(struct variable);
vv->va_name = copy(name);
vv->va_type = CP_BOOL;
@ -292,10 +288,10 @@ cp_setparse(wordlist *wl)
continue;
}
if (wl && eq(wl->wl_word, "=")) {
if (wl && eq(wl->wl_word, "=")) { /* 'name =' */
wl = wl->wl_next;
if (wl == NULL) {
fprintf(cp_err, "Error: bad set form.\n");
fprintf(cp_err, "ERROR: bad set form.\n");
tfree(name); /*DG: cp_unquote Memory leak*/
if (ft_stricterror)
controlled_exit(EXIT_BAD);
@ -303,7 +299,7 @@ cp_setparse(wordlist *wl)
}
val = wl->wl_word;
wl = wl->wl_next;
} else if (wl && (*wl->wl_word == '=')) {
} else if (wl && (*wl->wl_word == '=')) { /* name =' */
val = wl->wl_word + 1;
wl = wl->wl_next;
} else if ((s = strchr(name, '=')) != NULL) {
@ -311,7 +307,7 @@ cp_setparse(wordlist *wl)
*s = '\0';
if (*val == '\0') {
if (!wl) {
fprintf(cp_err, "Error: %s equals what?.\n", name);
fprintf(cp_err, "ERROR: %s equals what?\n", name);
tfree(name); /*DG: cp_unquote Memory leak: free name before exiting*/
if (ft_stricterror)
controlled_exit(EXIT_BAD);
@ -322,7 +318,7 @@ cp_setparse(wordlist *wl)
}
}
} else {
fprintf(cp_err, "Error: bad set form.\n");
fprintf(cp_err, "ERROR: bad set form\n");
tfree(name); /*DG: cp_unquote Memory leak: free name befor exiting */
if (ft_stricterror)
controlled_exit(EXIT_BAD);
@ -330,6 +326,7 @@ cp_setparse(wordlist *wl)
}
/* val = cp_unquote(val); DG: bad old val is lost*/
isstring = (*val == '"'); /* mhx: is this sufficient? */
copyval = cp_unquote(val); /*DG*/
strcpy(val, copyval);
tfree(copyval);
@ -340,6 +337,7 @@ cp_setparse(wordlist *wl)
* ()'s, treat them as tokens... */
balance = 1;
while (wl && wl->wl_word) {
bool isstringc;
if (eq(wl->wl_word, "(")) {
balance++;
} else if (eq(wl->wl_word, ")")) {
@ -348,7 +346,12 @@ cp_setparse(wordlist *wl)
}
vv = alloc(struct variable);
vv->va_next = NULL;
isstringc = (*wl->wl_word == '"'); /* mhx: is this sufficient? */
copyval = ss = cp_unquote(wl->wl_word);
if (isstringc) {
vv->va_type = CP_STRING;
vv->va_string = copy(ss);
} else {
td = ft_numparse(&ss, FALSE);
if (td) {
vv->va_type = CP_REAL;
@ -356,6 +359,8 @@ cp_setparse(wordlist *wl)
} else {
vv->va_type = CP_STRING;
vv->va_string = copy(ss);
fprintf(cp_err, "cp_setparse() :: ft_numparse() didn't recognize `%s' for assignment to `%s' as CP_REAL, using CP_STRING.\n", ss, name);
}
}
tfree(copyval); /*DG: must free ss any way to avoid cp_unquote memory leak*/
if (listv) {
@ -367,7 +372,7 @@ cp_setparse(wordlist *wl)
wl = wl->wl_next;
}
if (balance && !wl) {
fprintf(cp_err, "Error: bad set form.\n");
fprintf(cp_err, "ERROR: bad set form\n");
tfree(name); /* va: cp_unquote memory leak: free name before exiting */
if (ft_stricterror)
controlled_exit(EXIT_BAD);
@ -385,19 +390,26 @@ cp_setparse(wordlist *wl)
continue;
}
copyval = ss = cp_unquote(val);
td = ft_numparse(&ss, FALSE);
/* there shouldn't be quotes around val at this point? */
if (*val == '"')
isstring |= TRUE; /* mhx: is this sufficient? */
copyval = ss = cp_unquote(val); /* 'name = ccccc' */
vv = alloc(struct variable);
vv->va_name = copy(name);
vv->va_next = vars;
vars = vv;
if (td) {
/*** We should try to get CP_NUM's... */
vv->va_type = CP_REAL;
vv->va_real = *td;
} else {
if (isstring) {
vv->va_type = CP_STRING;
vv->va_string = copy(val);
} else {
td = ft_numparse(&ss, FALSE); /* FALSE: because set x=1umeter should work and 'meter' ignored */
if (td) {
vv->va_type = CP_REAL;
vv->va_real = *td;
} else {
vv->va_type = CP_STRING;
vv->va_string = copy(val);
}
}
tfree(copyval); /*DG: must free ss any way to avoid cp_unquote memory leak */
tfree(name); /* va: cp_unquote memory leak: free name for every loop */
@ -477,8 +489,8 @@ cp_remvar(char *varname)
cp_nonomatch = FALSE;
else if (eq(varname, "noclobber"))
cp_noclobber = FALSE;
else if (eq(varname, "echo")) /*CDHW*/
cp_echo = FALSE; /*CDHW*/
else if (eq(varname, "echo"))
cp_echo = FALSE;
else if (eq(varname, "prompt"))
cp_promptstring = NULL;
else if (eq(varname, "cpdebug"))
@ -510,14 +522,14 @@ cp_remvar(char *varname)
case US_DONTRECORD:
/* Do nothing... */
if (found)
fprintf(cp_err, "cp_remvar: Internal Error: var %d\n", *varname);
fprintf(cp_err, "cp_remvar: INTERNAL ERROR: var %d\n", *varname);
break;
case US_READONLY:
/* Badness... */
fprintf(cp_err, "Error: %s is read-only.\n", v->va_name);
fprintf(cp_err, "ERROR: %s is read-only.\n", v->va_name);
if (found)
fprintf(cp_err, "cp_remvar: Internal Error: var %d\n", *varname);
fprintf(cp_err, "cp_remvar: INTERNAL ERROR: var %d\n", *varname);
break;
case US_SIMVAR:
@ -540,7 +552,7 @@ cp_remvar(char *varname)
break;
default:
fprintf(cp_err, "cp_remvar: Internal Error: US val %d\n", i);
fprintf(cp_err, "cp_remvar: INTERNAL ERROR: US val %d\n", i);
break;
}
@ -551,8 +563,10 @@ cp_remvar(char *varname)
}
/* Determine the value of a variable. Fail if the variable is unset,
* and if the type doesn't match, try and make it work... */
/*
* Determine the value of a variable. Fail if the variable is unset,
* and if the type doesn't match, try and make it work...
*/
bool
cp_getvar(char *name, enum cp_types type, void *retval)
{
@ -561,11 +575,6 @@ cp_getvar(char *name, enum cp_types type, void *retval)
cp_usrvars(&uv1, &uv2);
#ifdef TRACE
/* SDB debug statement */
fprintf(stderr, "in cp_getvar, trying to get value of variable %s.\n", name);
#endif
for (v = variables; v && !eq(name, v->va_name); v = v->va_next)
;
if (v == NULL)
@ -616,11 +625,10 @@ cp_getvar(char *name, enum cp_types type, void *retval)
}
default:
fprintf(cp_err,
"cp_getvar: Internal Error: bad var type %d.\n", type);
"cp_getvar: INTERNAL ERROR: bad var type %d.\n", type);
break;
}
free_struct_variable(uv1);
// tfree(uv2);
return (TRUE);
} else {
@ -678,7 +686,7 @@ span_var_expr(char *t)
int parenthesis = 0;
int brackets = 0;
while (*t && (isalphanum(*t) || strchr(VALIDCHARS, *t)))
while (*t && (isalphanum((int)*t) || strchr(VALIDCHARS, *t)))
switch (*t++)
{
case '[':
@ -707,55 +715,59 @@ span_var_expr(char *t)
}
/* Substitute variable name by its value and restore to wordlist */
wordlist *
cp_variablesubst(wordlist *wlist)
{
wordlist *wl;
wordlist *wl, *nwl;
char *s, *t, buf[BSIZE_SP], wbuf[BSIZE_SP], tbuf[BSIZE_SP];
/* MW. tbuf holds current word after wl_splice() calls free() on it */
int i;
for (wl = wlist; wl; wl = wl->wl_next) {
char *s_dollar;
int i = 0;
while ((s_dollar = strchr(wl->wl_word + i, cp_dol)) != NULL) {
int prefix_len = (int) (s_dollar - wl->wl_word);
char *tail = span_var_expr(s_dollar + 1);
char *var = copy_substring(s_dollar + 1, tail);
wordlist *nwl = vareval(var);
tfree(var);
if (nwl) {
char *x = nwl->wl_word;
char *tail_ = copy(tail);
nwl->wl_word = tprintf("%.*s%s", prefix_len, wl->wl_word, nwl->wl_word);
free(x);
if (wlist == wl)
wlist = nwl;
wl = wl_splice(wl, nwl);
i = (int) strlen(wl->wl_word);
x = wl->wl_word;
wl->wl_word = tprintf("%s%s", wl->wl_word, tail_);
free(x);
free(tail_);
} else if (prefix_len || *tail) {
char *x = wl->wl_word;
wl->wl_word = tprintf("%.*s%s", prefix_len, wl->wl_word, tail);
i = prefix_len;
free(x);
} else {
wordlist *next = wl->wl_next;
if (wlist == wl)
wlist = next;
wl_delete_slice(wl, next);
if (!next)
return wlist;
wl = next;
i = 0;
t = wl->wl_word;
i = 0;
while ((s = strchr(t, cp_dol)) != NULL) {
while (t < s)
wbuf[i++] = *t++;
wbuf[i] = '\0';
t++;
s = buf;
/* Get s and t past the end of the var name. */
{
char *end = span_var_expr(t);
while (t < end)
*s++ = *t++;
}
*s = '\0';
nwl = vareval(buf);
if (i) {
(void) strcpy(buf, wbuf);
if (nwl) {
(void) strcat(buf, nwl->wl_word);
tfree(nwl->wl_word);
nwl->wl_word = copy(buf);
} else {
nwl = wl_cons(copy(buf), NULL);
}
}
(void) strcpy(tbuf, t); /* MW. Save t*/
if ((wl = wl_splice(wl, nwl)) == NULL) {/*CDHW this frees wl CDHW*/
wl_free(nwl);
return NULL;
}
/* This is bad... */
for (wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev)
;
(void) strcpy(buf, wl->wl_word);
i = (int) strlen(buf);
(void) strcat(buf, tbuf); /* MW. tbuf is used here only */
tfree(wl->wl_word);
wl->wl_word = copy(buf);
t = &wl->wl_word[i];
s = wl->wl_word;
for (i = 0; s < t; s++)
wbuf[i++] = *s;
}
}
@ -783,7 +795,8 @@ vareval(char *string)
switch (*string) {
case '$':
wl = wl_cons(tprintf("%d", getpid()), NULL);
(void) sprintf(buf, "%d", getpid());
wl = wl_cons(copy(buf), NULL);
tfree(oldstring);
return (wl);
@ -822,7 +835,7 @@ vareval(char *string)
if (!v)
v = cp_enqvar(string);
if (!v) {
fprintf(cp_err, "Error: %s: no such variable.\n", string);
fprintf(cp_err, "ERROR: %s: no such variable.\n", string);
tfree(oldstring);
return (NULL);
}
@ -831,7 +844,8 @@ vareval(char *string)
i++;
else
i = (v->va_type != CP_BOOL);
wl = wl_cons(tprintf("%d", i), NULL);
(void) sprintf(buf, "%d", i);
wl = wl_cons(copy(buf), NULL);
tfree(oldstring);
return (wl);
@ -848,14 +862,14 @@ vareval(char *string)
for (v = variables; v; v = v->va_next)
if (eq(v->va_name, string))
break;
if (!v && isdigit(*string)) {
if (!v && isdigit((int)*string)) {
for (v = variables; v; v = v->va_next)
if (eq(v->va_name, "argv"))
break;
range = string;
}
if (!v) {
range = NULL;
// ? range = NULL;
string = oldstring;
v = cp_enqvar(string);
}
@ -865,7 +879,7 @@ vareval(char *string)
return (wl);
}
if (!v) {
fprintf(cp_err, "Error: %s: no such variable.\n", string);
fprintf(cp_err, "ERROR: %s: no such variable.\n", string);
tfree(oldstring);
return (NULL);
}
@ -879,22 +893,22 @@ vareval(char *string)
char *t = ++range;
if (*t == '&')
t++;
while (isalphanum(*t))
while (isalphanum((int)*t))
t++;
*t = '\0';
r = vareval(range);
if (!r || r->wl_next) {
fprintf(cp_err, "Error: %s: illegal index.\n", string);
fprintf(cp_err, "ERROR: %s: illegal index.\n", string);
tfree(oldstring);
wl_free(r);
return NULL;
}
range = r->wl_word;
}
for (low = 0; isdigit(*range); range++)
for (low = 0; isdigit((int)*range); range++)
low = low * 10 + *range - '0';
if ((*range == '-') && isdigit(range[1]))
for (up = 0, range++; isdigit(*range); range++)
if ((*range == '-') && isdigit((int)range[1]))
for (up = 0, range++; isdigit((int)*range); range++)
up = up * 10 + *range - '0';
else if (*range == '-')
up = wl_length(wl);

View File

@ -22,11 +22,7 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
#include "ngspice/dstring.h"
#include "plotting/plotting.h"
#ifdef XSPICE
/* gtri - begin - add function prototype for EVTfindvec */
struct dvec *EVTfindvec(char *node);
/* gtri - end - add function prototype for EVTfindvec */
#endif
static void
@ -180,14 +176,9 @@ findvec(char *word, struct plot *pl)
spice_dstring_free(&dbuf);
#ifdef XSPICE
/* gtri - begin - Add processing for getting event-driven vector */
if (!d)
d = EVTfindvec(word);
/* gtri - end - Add processing for getting event-driven vector */
#endif
if (d && d->v_link2) {
d = vec_copy(d);
vec_new(d);
@ -209,18 +200,18 @@ namecmp(const void *a, const void *b)
const char *t = (const char *) b;
for (;;) {
while ((*s == *t) && !isdigit(*s) && *s)
while ((*s == *t) && !isdigit((int)*s) && *s)
s++, t++;
if (!*s)
return (0);
if ((*s != *t) && (!isdigit(*s) || !isdigit(*t)))
if ((*s != *t) && (!isdigit((int)*s) || !isdigit((int)*t)))
return (*s - *t);
/* The beginning of a number... Grab the two numbers and then
* compare them... */
for (i = 0; isdigit(*s); s++)
for (i = 0; isdigit((int)*s); s++)
i = i * 10 + *s - '0';
for (j = 0; isdigit(*t); t++)
for (j = 0; isdigit((int)*t); t++)
j = j * 10 + *t - '0';
if (i != j)
@ -383,11 +374,11 @@ vec_fromplot(char *word, struct plot *plot)
}
/* scanf("%c(%s)" doesn't do what it should do. ) */
if (!d && (sscanf(word, "%c(%s", &cc, buf) == 2) &&
((s = strrchr(buf, ')')) != NULL) &&
if (!d && (sscanf(word, "%c(%s", /* ) */ &cc, buf) == 2) &&
/* ( */ ((s = strrchr(buf, ')')) != NULL) &&
(s[1] == '\0')) {
*s = '\0';
if (prefix("i(", word) || prefix("I(", word)) {
if (prefix("i(", /* ) */ word) || prefix("I(", /* ) */ word)) {
/* Spice dependency... */
(void) sprintf(buf2, "%s#branch", buf);
(void) strcpy(buf, buf2);
@ -422,9 +413,23 @@ vec_get(const char *vec_name)
char buf[BSIZE_SP], *s, *wd, *word, *whole, *name = NULL, *param;
int i = 0;
struct variable *vv;
int indexvar; /* mhx */
wd = word = copy(vec_name); /* Gets mangled below... */
if (*word != SPECCHAR) { /* mhx: eventually replace atoi() by full evaluate */
char *ps = strchr(wd, '['), *pe = strchr(wd, ']');
if (ps && pe && pe > ps) {
whole = copy(word);
*ps = '\0';
*pe = '\0';
indexvar = atoi(++ps);
} else {
whole = NULL;
indexvar = -1;
}
}
if (strchr(word, '.')) {
/* Snag the plot... */
for (i = 0, s = word; *s != '.'; i++, s++)
@ -470,18 +475,34 @@ vec_get(const char *vec_name)
d = newv;
if (!d) {
fprintf(cp_err,
"Error: plot wildcard (name %s) matches nothing\n",
"ERROR: plot wildcard (name %s) matches nothing\n",
word);
tfree(wd); /* MW. I don't want core leaks here */
tfree(wd);
return (NULL);
}
}
/* In case of data[ix] we must return a SINGLE value
(vector of length 1) instead of the vector.
Duplicates a lot of code that still follows :-( */
if (d && indexvar != -1) {
struct dvec *ad;
ad = alloc(struct dvec);
ZERO(ad, struct dvec);
ad->v_name = copy(whole); /* so the name could be data[2] or data[expression] :-) */
ad->v_type = d->v_type;
ad->v_flags = d->v_flags; /* VF_REAL; or complex? */
ad->v_length = 1;
ad->v_realdata = TMALLOC(double, 1);
*ad->v_realdata = *d->v_realdata;
tfree(whole);
}
if (!d && (*word == SPECCHAR)) {
/* This is a special quantity... */
if (ft_nutmeg) {
fprintf(cp_err,
"Error: circuit parameters only available with spice\n");
"ERROR: circuit parameters only available with spice\n");
tfree(wd); /* MW. Memory leak fixed again */
return (NULL); /* va: use NULL */
}
@ -516,16 +537,19 @@ vec_get(const char *vec_name)
return (NULL);
}
} else {
fprintf(cp_err, "Error: No circuit loaded.\n");
fprintf(cp_err, "ERROR: No circuit loaded.\n");
tfree(whole);
tfree(wd);
return (NULL);
}
d = dvec_alloc(copy(whole), /* MW. The same as word before */
SV_NOTYPE,
VF_REAL, /* No complex values yet... */
1, NULL);
d = alloc(struct dvec);
ZERO(d, struct dvec);
d->v_name = copy(whole); /* MW. The same as word before */
d->v_type = SV_NOTYPE;
d->v_flags |= VF_REAL; /* No complex values yet... */
d->v_realdata = TMALLOC(double, 1);
d->v_length = 1;
/* In case the represented variable is a REAL vector this takes
* the actual value of the first element of the linked list which
@ -538,8 +562,8 @@ vec_get(const char *vec_name)
* defined as IF_INTEGER are not given their value when using
* print @pot[pos_node]
* To fix this, it is necessary to define:
* OPU( "pos_node", POT_QUEST_POS_NODE, IF_REAL,"Positive node of potenciometer"),
* int POTnegNode; // number of negative node of potenciometer (Nodo_3)
* OPU( "pos_node", POT_QUEST_POS_NODE, IF_REAL,"Positive node of potentiometer"),
* int POTnegNode; // number of negative node of potentiometer (Node_3)
* case POT_QUEST_POS_NODE:
* value->rValue = (double)fast->POTposNode;
* return (OK);
@ -562,7 +586,7 @@ vec_get(const char *vec_name)
* CP_REAL,
* CP_STRING,
* CP_LIST
° };
* };
*/
/* The variable is a vector */
@ -572,16 +596,20 @@ vec_get(const char *vec_name)
*/
struct variable *nv;
i = 0;
for (nv = vv->va_vlist; nv; nv = nv->va_next)
i++;
dvec_realloc(d, i, NULL);
i = 0;
for (nv = vv->va_vlist; nv; nv = nv->va_next)
d->v_realdata[i++] = nv->va_real;
double *list;
list = TMALLOC(double, 1);
nv = alloc(struct variable);
nv = vv->va_vlist;
for (i = 1; ; i++) {
list = TREALLOC(double, list, i);
list[i-1] = nv->va_real;
nv = nv->va_next;
if (!nv)
break;
}
d->v_realdata = list;
d->v_length = i;
/* To be able to identify the vector to represent
* belongs to a special "conunto" and should be printed in a
* special way.
@ -681,22 +709,28 @@ vec_copy(struct dvec *v)
if (!v)
return (NULL);
nv = dvec_alloc(copy(v->v_name),
v->v_type,
v->v_flags & ~VF_PERMANENT,
v->v_length, NULL);
nv = alloc(struct dvec);
nv->v_name = copy(v->v_name);
nv->v_type = v->v_type;
nv->v_flags = v->v_flags & ~VF_PERMANENT;
if (isreal(v))
if (isreal(v)) {
nv->v_realdata = TMALLOC(double, v->v_length);
bcopy(v->v_realdata, nv->v_realdata,
sizeof(double) * (size_t) v->v_length);
else
nv->v_compdata = NULL;
} else {
nv->v_realdata = NULL;
nv->v_compdata = TMALLOC(ngcomplex_t, v->v_length);
bcopy(v->v_compdata, nv->v_compdata,
sizeof(ngcomplex_t) * (size_t) v->v_length);
}
nv->v_minsignal = v->v_minsignal;
nv->v_maxsignal = v->v_maxsignal;
nv->v_gridtype = v->v_gridtype;
nv->v_plottype = v->v_plottype;
nv->v_length = v->v_length;
/* Modified to copy the rlength of origin to destination vecor
* instead of always putting it to 0.
@ -764,13 +798,10 @@ plot_alloc(char *name)
void
vec_new(struct dvec *d)
{
#ifdef FTEDEBUG
if (ft_vecdb)
fprintf(cp_err, "new vector %s\n", d->v_name);
#endif
/* Note that this can't happen. */
if (plot_cur == NULL) {
fprintf(cp_err, "vec_new: Internal Error: no cur plot\n");
fprintf(cp_err, "vec_new: INTERNAL ERROR: no cur plot\n");
controlled_exit(1);
}
plot_cur->pl_lookup_valid = FALSE;
if ((d->v_flags & VF_PERMANENT) && (plot_cur->pl_scale == NULL))
@ -849,7 +880,7 @@ vec_free_x(struct dvec *v)
lv->v_next = v->v_next;
else
fprintf(cp_err,
"vec_free: Internal Error: %s not in plot\n",
"vec_free: INTERNAL ERROR: %s not in plot\n",
v->v_name);
}
if (pl->pl_scale == v) {
@ -860,7 +891,13 @@ vec_free_x(struct dvec *v)
}
}
dvec_free(v);
if (v->v_name)
tfree(v->v_name);
if (v->v_realdata)
tfree(v->v_realdata);
if (v->v_compdata)
tfree(v->v_compdata);
tfree(v);
}
@ -868,7 +905,7 @@ vec_free_x(struct dvec *v)
* return TRUE if every vector element is zero
*/
bool
BOOL
vec_iszero(struct dvec *v)
{
int i;
@ -937,12 +974,12 @@ vec_basename(struct dvec *v)
}
strtolower(buf);
for (t = buf; isspace(*t); t++)
for (t = buf; isspace((int)*t); t++)
;
s = t;
for (t = s; *t; t++)
;
while ((t > s) && isspace(t[-1]))
while ((t > s) && isspace((int)t[-1]))
*--t = '\0';
return (copy(s));
}
@ -972,7 +1009,7 @@ plot_setcur(char *name)
if (plot_prefix(name, pl->pl_typename))
break;
if (!pl) {
fprintf(cp_err, "Error: no such plot named %s\n", name);
fprintf(cp_err, "ERROR: no such plot named %s\n", name);
return;
}
/* va: we skip cp_kwswitch, because it confuses the keyword-tree management for
@ -1053,7 +1090,8 @@ vec_transpose(struct dvec *v)
}
koffset += blocksize; /* koffset = k*blocksize = k*dim0*dim1 */
}
dvec_realloc(v, v->v_length, newreal);
tfree(oldreal);
v->v_realdata = newreal;
} else {
newcomp = TMALLOC(ngcomplex_t, v->v_length);
oldcomp = v->v_compdata;
@ -1062,14 +1100,17 @@ vec_transpose(struct dvec *v)
joffset = 0;
for (j = 0; j < dim0; j++) {
for (i = 0; i < dim1; i++) {
newcomp[ koffset + joffset + i ] =
oldcomp[ koffset + i*dim0 + j ];
realpart(newcomp[ koffset + joffset + i ]) =
realpart(oldcomp[ koffset + i*dim0 + j ]);
imagpart(newcomp[ koffset + joffset + i ]) =
imagpart(oldcomp[ koffset + i*dim0 + j ]);
}
joffset += dim1; /* joffset = j*dim0 */
}
koffset += blocksize; /* koffset = k*blocksize = k*dim0*dim1 */
}
dvec_realloc(v, v->v_length, newcomp);
tfree(oldcomp);
v->v_compdata = newcomp;
}
}
@ -1082,9 +1123,9 @@ vec_transpose(struct dvec *v)
struct dvec *
vec_mkfamily(struct dvec *v)
{
int size, numvecs, i, count[MAXDIMS];
struct dvec *vecs, *d, **t;
char buf2[BSIZE_SP];
int size, numvecs, i, j, count[MAXDIMS];
struct dvec *vecs, *d;
char buf[BSIZE_SP], buf2[BSIZE_SP];
if (v->v_numdims < 2)
return (v);
@ -1092,16 +1133,25 @@ vec_mkfamily(struct dvec *v)
size = v->v_dims[v->v_numdims - 1];
for (i = 0, numvecs = 1; i < v->v_numdims - 1; i++)
numvecs *= v->v_dims[i];
for (i = 0, vecs = d = NULL; i < numvecs; i++) {
if (vecs) {
d = d->v_link2 = alloc(struct dvec);
ZERO(d, struct dvec);
} else {
d = vecs = alloc(struct dvec);
ZERO(d, struct dvec);
}
}
for (i = 0; i < MAXDIMS; i++)
count[i] = 0;
for (t = &vecs, i = 0; i < numvecs; i++) {
for (d = vecs, j = 0; d; j++, d = d->v_link2) {
indexstring(count, v->v_numdims - 1, buf2);
d = dvec_alloc(tprintf("%s%s", v->v_name, buf2),
v->v_type,
v->v_flags,
size, NULL);
(void) sprintf(buf, "%s%s", v->v_name, buf2);
d->v_name = copy(buf);
d->v_type = v->v_type;
d->v_flags = v->v_flags;
d->v_minsignal = v->v_minsignal;
d->v_maxsignal = v->v_maxsignal;
@ -1112,18 +1162,17 @@ vec_mkfamily(struct dvec *v)
* of these things...
*/
d->v_numdims = 1;
d->v_dims[0] = size;
d->v_length = size;
if (isreal(v)) {
bcopy(v->v_realdata + size*i, d->v_realdata, (size_t) size * sizeof(double));
d->v_realdata = TMALLOC(double, size);
bcopy(v->v_realdata + size*j, d->v_realdata, (size_t) size * sizeof(double));
} else {
bcopy(v->v_compdata + size*i, d->v_compdata, (size_t) size * sizeof(ngcomplex_t));
d->v_compdata = TMALLOC(ngcomplex_t, size);
bcopy(v->v_compdata + size*j, d->v_compdata, (size_t) size * sizeof(ngcomplex_t));
}
/* Add one to the counter. */
(void) incindex(count, v->v_numdims - 1, v->v_dims, v->v_numdims);
*t = d;
t = &(d->v_link2);
}
for (d = vecs; d; d = d->v_link2)
@ -1148,7 +1197,7 @@ plot_prefix(char *pre, char *str)
str++;
}
if (*pre || (*str && isdigit(pre[-1])))
if (*pre || (*str && isdigit((int)pre[-1])))
return (FALSE);
else
return (TRUE);