unwanted style changes, distrcation, CAREFULL important stuff might still be hidden here, instead of being in the real commit
This commit is contained in:
parent
8ca0b944df
commit
719496c2a3
|
|
@ -1,7 +1,7 @@
|
|||
/**********
|
||||
/*********************************************************************************
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
**********/
|
||||
*********************************************************************************/
|
||||
|
||||
#include "ngspice/ngspice.h"
|
||||
#include "ngspice/bool.h"
|
||||
|
|
@ -26,9 +26,7 @@ bool cp_echo = FALSE; /* CDHW */
|
|||
|
||||
struct variable *variables = NULL;
|
||||
|
||||
wordlist *
|
||||
cp_varwl(struct variable *var)
|
||||
{
|
||||
wordlist *cp_varwl(struct variable *var) {
|
||||
wordlist *wl = NULL, *w, *wx = NULL;
|
||||
char buf[BSIZE_SP], *copystring;
|
||||
struct variable *vt;
|
||||
|
|
@ -55,7 +53,8 @@ cp_varwl(struct variable *var)
|
|||
w = cp_varwl(vt);
|
||||
if (wl == NULL) {
|
||||
wl = wx = w;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
wx->wl_next = w;
|
||||
w->wl_prev = wx;
|
||||
wx = w;
|
||||
|
|
@ -63,9 +62,7 @@ cp_varwl(struct variable *var)
|
|||
}
|
||||
return (wl);
|
||||
default:
|
||||
fprintf(cp_err,
|
||||
"cp_varwl: INTERNAL ERROR: bad variable type %d\n",
|
||||
var->va_type);
|
||||
fprintf(cp_err, "cp_varwl: INTERNAL ERROR: bad variable type %d\n", var->va_type);
|
||||
return NULL;
|
||||
}
|
||||
wl = wl_cons(copy(buf), NULL);
|
||||
|
|
@ -73,9 +70,7 @@ cp_varwl(struct variable *var)
|
|||
}
|
||||
|
||||
/* Set a variable. */
|
||||
void
|
||||
cp_vset(char *varname, enum cp_types type, void *value)
|
||||
{
|
||||
void cp_vset(char *varname, enum cp_types type, void *value) {
|
||||
struct variable *v, *u, *w;
|
||||
int i;
|
||||
bool alreadythere = FALSE, v_free = FALSE;
|
||||
|
|
@ -140,25 +135,15 @@ cp_vset(char *varname, enum cp_types type, void *value)
|
|||
* 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"))
|
||||
cp_noglob = TRUE;
|
||||
else if (eq(copyvarname, "nonomatch"))
|
||||
cp_nonomatch = TRUE;
|
||||
else if (eq(copyvarname, "history") && (type == CP_NUM))
|
||||
cp_maxhistlength = v->va_num;
|
||||
else if (eq(copyvarname, "history") && (type == CP_REAL))
|
||||
cp_maxhistlength = (int)floor(v->va_real + 0.5);
|
||||
else if (eq(copyvarname, "noclobber"))
|
||||
cp_noclobber = TRUE;
|
||||
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;
|
||||
}
|
||||
if (eq(copyvarname, "noglob")) cp_noglob = TRUE;
|
||||
else if (eq(copyvarname, "nonomatch")) cp_nonomatch = TRUE;
|
||||
else if (eq(copyvarname, "history") && (type == CP_NUM)) cp_maxhistlength = v->va_num;
|
||||
else if (eq(copyvarname, "history") && (type == CP_REAL)) cp_maxhistlength = (int)floor(v->va_real + 0.5);
|
||||
else if (eq(copyvarname, "noclobber")) cp_noclobber = TRUE;
|
||||
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;
|
||||
|
||||
switch (i = cp_usrset(v, TRUE)) {
|
||||
case US_OK:
|
||||
|
|
@ -171,24 +156,20 @@ 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 `don't 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);
|
||||
if (alreadythere)
|
||||
fprintf(cp_err, "cp_vset: INTERNAL ERROR: "
|
||||
"it was already there too!!\n");
|
||||
fprintf(cp_err, "cp_vset: INTERNAL ERROR: it was already there too!!\n");
|
||||
break;
|
||||
case US_SIMVAR:
|
||||
if (alreadythere) {
|
||||
/* somehow it got into the front-end list of variables */
|
||||
if (w) {
|
||||
if (w)
|
||||
w->va_next = v->va_next;
|
||||
} else {
|
||||
variables = v->va_next;
|
||||
}
|
||||
else variables = v->va_next;
|
||||
}
|
||||
alreadythere = FALSE;
|
||||
if (ft_curckt) {
|
||||
|
|
@ -200,12 +181,11 @@ cp_vset(char *varname, enum cp_types type, void *value)
|
|||
if (!alreadythere) {
|
||||
v->va_next = ft_curckt->ci_vars;
|
||||
ft_curckt->ci_vars = v;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* va: avoid memory leak within bcopy */
|
||||
if (u->va_type == CP_STRING)
|
||||
tfree(u->va_string);
|
||||
else if (u->va_type == CP_LIST)
|
||||
tfree(u->va_vlist);
|
||||
if (u->va_type == CP_STRING) tfree(u->va_string);
|
||||
else if (u->va_type == CP_LIST) tfree(u->va_vlist);
|
||||
u->va_V = v->va_V;
|
||||
u->va_type = v->va_type;
|
||||
tfree(v);
|
||||
|
|
@ -233,9 +213,7 @@ cp_vset(char *varname, enum cp_types type, void *value)
|
|||
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)
|
||||
{
|
||||
struct variable *cp_setparse(wordlist *wl) {
|
||||
char *name = NULL, *val, *copyval, *s, *ss;
|
||||
double *td;
|
||||
bool isstring;
|
||||
|
|
@ -243,8 +221,7 @@ cp_setparse(wordlist *wl)
|
|||
struct variable *vars = NULL;
|
||||
int balance;
|
||||
while (wl) {
|
||||
if (name)
|
||||
tfree(name);
|
||||
if (name) tfree(name);
|
||||
name = cp_unquote(wl->wl_word);
|
||||
wl = wl->wl_next;
|
||||
if ((!wl || (*wl->wl_word != '=')) && !strchr(name, '=')) { /* 'name ccccc' */
|
||||
|
|
@ -268,29 +245,31 @@ cp_setparse(wordlist *wl)
|
|||
}
|
||||
val = wl->wl_word;
|
||||
wl = wl->wl_next;
|
||||
} else if (wl && (*wl->wl_word == '=')) { /* name =' */
|
||||
}
|
||||
else if (wl && (*wl->wl_word == '=')) { /* name =' */
|
||||
val = wl->wl_word + 1;
|
||||
wl = wl->wl_next;
|
||||
} else if ((s = strchr(name, '=')) != NULL) {
|
||||
}
|
||||
else if ((s = strchr(name, '=')) != NULL) {
|
||||
val = s + 1;
|
||||
*s = '\0';
|
||||
if (*val == '\0') {
|
||||
if (!wl) {
|
||||
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);
|
||||
if (ft_stricterror) controlled_exit(EXIT_BAD);
|
||||
return NULL;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
val = wl->wl_word;
|
||||
wl = wl->wl_next;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
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);
|
||||
if (ft_stricterror) controlled_exit(EXIT_BAD);
|
||||
return NULL;
|
||||
}
|
||||
/* val = cp_unquote(val); DG: bad old val is lost*/
|
||||
|
|
@ -305,44 +284,30 @@ cp_setparse(wordlist *wl)
|
|||
balance = 1;
|
||||
while (wl && wl->wl_word) {
|
||||
bool isstringc;
|
||||
if (eq(wl->wl_word, "(")) {
|
||||
balance++;
|
||||
} else if (eq(wl->wl_word, ")")) {
|
||||
if (!--balance)
|
||||
break;
|
||||
}
|
||||
if (eq(wl->wl_word, "(")) { balance++; }
|
||||
else if (eq(wl->wl_word, ")")) if (!--balance) break;
|
||||
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 {
|
||||
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;
|
||||
vv->va_real = *td;
|
||||
} 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);
|
||||
}
|
||||
if (td) { vv->va_type = CP_REAL; vv->va_real = *td; }
|
||||
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) {
|
||||
lv->va_next = vv;
|
||||
lv = vv;
|
||||
} else {
|
||||
listv = lv = vv;
|
||||
}
|
||||
else listv = lv = vv;
|
||||
wl = wl->wl_next;
|
||||
}
|
||||
if (balance && !wl) {
|
||||
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);
|
||||
if (ft_stricterror) controlled_exit(EXIT_BAD);
|
||||
return NULL;
|
||||
}
|
||||
vv = alloc(struct variable);
|
||||
|
|
@ -355,52 +320,37 @@ cp_setparse(wordlist *wl)
|
|||
continue;
|
||||
}
|
||||
/* there shouldn't be quotes around val at this point? */
|
||||
if (*val == '"')
|
||||
isstring |= TRUE; /* mhx: is this sufficient? */
|
||||
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 (isstring) {
|
||||
vv->va_type = CP_STRING;
|
||||
vv->va_string = copy(val);
|
||||
} 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);
|
||||
}
|
||||
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 */
|
||||
}
|
||||
if (name)
|
||||
tfree(name);
|
||||
if (name) tfree(name);
|
||||
return vars;
|
||||
}
|
||||
|
||||
/* free the struct variable. The type of the union is given by va_type */
|
||||
void
|
||||
free_struct_variable(struct variable *v)
|
||||
{
|
||||
void free_struct_variable(struct variable *v) {
|
||||
while (v) {
|
||||
struct variable *next_v = v->va_next;
|
||||
if (v->va_type == CP_LIST)
|
||||
free_struct_variable(v->va_vlist);
|
||||
if (v->va_type == CP_STRING)
|
||||
tfree(v->va_string);
|
||||
if (v->va_type == CP_LIST) free_struct_variable(v->va_vlist);
|
||||
if (v->va_type == CP_STRING) tfree(v->va_string);
|
||||
tfree(v);
|
||||
v = next_v;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
cp_remvar(char *varname)
|
||||
{
|
||||
void cp_remvar(char *varname) {
|
||||
struct variable *v, *u, *lv = NULL;
|
||||
struct variable *uv1, *uv2;
|
||||
bool found = TRUE;
|
||||
|
|
@ -408,16 +358,14 @@ cp_remvar(char *varname)
|
|||
cp_usrvars(&uv1, &uv2);
|
||||
for (v = variables; v; v = v->va_next) {
|
||||
var_index = 0;
|
||||
if (eq(v->va_name, varname))
|
||||
break;
|
||||
if (eq(v->va_name, varname)) break;
|
||||
lv = v;
|
||||
}
|
||||
if (v == NULL) {
|
||||
var_index = 1;
|
||||
lv = NULL;
|
||||
for (v = uv1; v; v = v->va_next) {
|
||||
if (eq(v->va_name, varname))
|
||||
break;
|
||||
if (eq(v->va_name, varname)) break;
|
||||
lv = v;
|
||||
}
|
||||
}
|
||||
|
|
@ -425,8 +373,7 @@ cp_remvar(char *varname)
|
|||
var_index = 2;
|
||||
lv = NULL;
|
||||
for (v = uv2; v; v = v->va_next) {
|
||||
if (eq(v->va_name, varname))
|
||||
break;
|
||||
if (eq(v->va_name, varname)) break;
|
||||
lv = v;
|
||||
}
|
||||
}
|
||||
|
|
@ -439,52 +386,35 @@ cp_remvar(char *varname)
|
|||
v->va_num = 0;
|
||||
found = FALSE;
|
||||
}
|
||||
/* Note that 'unset history' doesn't do anything here... Causes
|
||||
* trouble... */
|
||||
if (eq(varname, "noglob"))
|
||||
cp_noglob = FALSE;
|
||||
else if (eq(varname, "nonomatch"))
|
||||
cp_nonomatch = FALSE;
|
||||
else if (eq(varname, "noclobber"))
|
||||
cp_noclobber = FALSE;
|
||||
else if (eq(varname, "echo"))
|
||||
cp_echo = FALSE;
|
||||
else if (eq(varname, "prompt"))
|
||||
cp_promptstring = NULL;
|
||||
else if (eq(varname, "cpdebug"))
|
||||
cp_debug = FALSE;
|
||||
else if (eq(varname, "ignoreeof"))
|
||||
cp_ignoreeof = FALSE;
|
||||
else if (eq(varname, "program"))
|
||||
cp_program = "";
|
||||
|
||||
/* Note that 'unset history' doesn't do anything here... Causes trouble... */
|
||||
if (eq(varname, "noglob")) cp_noglob = FALSE;
|
||||
else if (eq(varname, "nonomatch")) cp_nonomatch = FALSE;
|
||||
else if (eq(varname, "noclobber")) cp_noclobber = FALSE;
|
||||
else if (eq(varname, "echo")) cp_echo = FALSE;
|
||||
else if (eq(varname, "prompt")) cp_promptstring = NULL;
|
||||
else if (eq(varname, "cpdebug")) cp_debug = FALSE;
|
||||
else if (eq(varname, "ignoreeof")) cp_ignoreeof = FALSE;
|
||||
else if (eq(varname, "program")) cp_program = "";
|
||||
switch (i = cp_usrset(v, FALSE)) {
|
||||
case US_OK:
|
||||
/* Normal case. */
|
||||
if (found) {
|
||||
if (lv)
|
||||
lv->va_next = v->va_next;
|
||||
if (lv) lv->va_next = v->va_next;
|
||||
else
|
||||
if (var_index == 0) {
|
||||
variables = v->va_next;
|
||||
} else if (var_index == 1) {
|
||||
uv1 = v->va_next;
|
||||
} else {
|
||||
ft_curckt->ci_vars = v->va_next;
|
||||
}
|
||||
if (var_index == 0) variables = v->va_next;
|
||||
else if (var_index == 1) uv1 = v->va_next;
|
||||
else ft_curckt->ci_vars = v->va_next;
|
||||
}
|
||||
break;
|
||||
case US_DONTRECORD:
|
||||
/* Do nothing... */
|
||||
if (found)
|
||||
fprintf(cp_err, "cp_remvar: INTERNAL ERROR: var %d\n", *varname);
|
||||
if (found) 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);
|
||||
if (found)
|
||||
fprintf(cp_err, "cp_remvar: INTERNAL ERROR: var %d\n", *varname);
|
||||
if (found) fprintf(cp_err, "cp_remvar: INTERNAL ERROR: var %d\n", *varname);
|
||||
break;
|
||||
|
||||
case US_SIMVAR:
|
||||
|
|
@ -492,22 +422,19 @@ cp_remvar(char *varname)
|
|||
lv = NULL;
|
||||
if (ft_curckt) {
|
||||
for (u = ft_curckt->ci_vars; u; u = u->va_next) {
|
||||
if (eq(varname, u->va_name))
|
||||
break;
|
||||
if (eq(varname, u->va_name)) break;
|
||||
lv = u;
|
||||
}
|
||||
if (u) {
|
||||
if (lv)
|
||||
lv->va_next = u->va_next;
|
||||
else
|
||||
ft_curckt->ci_vars = u->va_next;
|
||||
else ft_curckt->ci_vars = u->va_next;
|
||||
tfree(u);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
fprintf(cp_err, "cp_remvar: INTERNAL ERROR: US val %d\n", i);
|
||||
default: fprintf(cp_err, "cp_remvar: INTERNAL ERROR: US val %d\n", i);
|
||||
break;
|
||||
}
|
||||
v->va_next = NULL;
|
||||
|
|
@ -520,44 +447,23 @@ 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...
|
||||
*/
|
||||
bool
|
||||
cp_getvar(char *name, enum cp_types type, void *retval)
|
||||
{
|
||||
bool cp_getvar(char *name, enum cp_types type, void *retval) {
|
||||
struct variable *v;
|
||||
struct variable *uv1, *uv2;
|
||||
cp_usrvars(&uv1, &uv2);
|
||||
for (v = variables; v && !eq(name, v->va_name); v = v->va_next)
|
||||
;
|
||||
if (v == NULL)
|
||||
for (v = uv1; v && !eq(name, v->va_name); v = v->va_next)
|
||||
;
|
||||
if (v == NULL)
|
||||
for (v = uv2; v && !eq(name, v->va_name); v = v->va_next)
|
||||
;
|
||||
for (v = variables; v && !eq(name, v->va_name); v = v->va_next);
|
||||
if (v == NULL) for (v = uv1; v && !eq(name, v->va_name); v = v->va_next);
|
||||
if (v == NULL) for (v = uv2; v && !eq(name, v->va_name); v = v->va_next);
|
||||
if (v == NULL) {
|
||||
if (type == CP_BOOL && retval)
|
||||
* (bool *) retval = FALSE;
|
||||
if (type == CP_BOOL && retval) *(bool *) retval = FALSE;
|
||||
free_struct_variable(uv1);
|
||||
return FALSE;
|
||||
}
|
||||
if (v->va_type == type) {
|
||||
switch (type) {
|
||||
case CP_BOOL:
|
||||
if (retval)
|
||||
* (bool *) retval = TRUE;
|
||||
break;
|
||||
case CP_NUM: {
|
||||
int *i;
|
||||
i = (int *) retval;
|
||||
*i = v->va_num;
|
||||
break;
|
||||
}
|
||||
case CP_REAL: {
|
||||
double *d;
|
||||
d = (double *) retval;
|
||||
*d = v->va_real;
|
||||
break;
|
||||
}
|
||||
case CP_BOOL: if (retval) *(bool *) retval = TRUE; break;
|
||||
case CP_NUM: { int *i; i = (int *) retval; *i = v->va_num; break; }
|
||||
case CP_REAL: { double *d; d = (double *) retval; *d = v->va_real; break; }
|
||||
case CP_STRING: { /* Gotta be careful to have room. */
|
||||
char *s;
|
||||
s = cp_unquote(v->va_string);
|
||||
|
|
@ -573,13 +479,13 @@ cp_getvar(char *name, enum cp_types type, void *retval)
|
|||
break;
|
||||
}
|
||||
default:
|
||||
fprintf(cp_err,
|
||||
"cp_getvar: INTERNAL ERROR: bad var type %d.\n", type);
|
||||
fprintf(cp_err, "cp_getvar: INTERNAL ERROR: bad var type %d.\n", type);
|
||||
break;
|
||||
}
|
||||
free_struct_variable(uv1);
|
||||
return TRUE;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* Try to coerce it.. */
|
||||
if ((type == CP_NUM) && (v->va_type == CP_REAL)) {
|
||||
int *i;
|
||||
|
|
@ -626,41 +532,27 @@ char cp_dol = '$';
|
|||
|
||||
#define VALIDCHARS "$-_<#?@.()[]&"
|
||||
|
||||
char *
|
||||
span_var_expr(char *t)
|
||||
{
|
||||
char * span_var_expr(char *t) {
|
||||
int parenthesis = 0;
|
||||
int brackets = 0;
|
||||
while (*t && (isalphanum((int)*t) || strchr(VALIDCHARS, *t)))
|
||||
switch (*t++)
|
||||
{
|
||||
case '[':
|
||||
brackets++;
|
||||
break;
|
||||
case '(':
|
||||
parenthesis++;
|
||||
break;
|
||||
switch (*t++) {
|
||||
case '[': brackets++; break;
|
||||
case '(': parenthesis++; break;
|
||||
case ']':
|
||||
if (brackets <= 0)
|
||||
return t-1;
|
||||
if (--brackets <= 0)
|
||||
return t;
|
||||
if (brackets <= 0) return t-1;
|
||||
if (--brackets <= 0) return t;
|
||||
break;
|
||||
case ')':
|
||||
if (parenthesis <= 0)
|
||||
return t-1;
|
||||
if (--parenthesis <= 0)
|
||||
return t;
|
||||
break;
|
||||
default:
|
||||
if (parenthesis <= 0) return t-1;
|
||||
if (--parenthesis <= 0) return t;
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
wordlist *
|
||||
cp_variablesubst(wordlist *wlist)
|
||||
{
|
||||
wordlist * cp_variablesubst(wordlist *wlist) {
|
||||
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 */
|
||||
|
|
@ -670,16 +562,14 @@ cp_variablesubst(wordlist *wlist)
|
|||
t = wl->wl_word;
|
||||
i = 0;
|
||||
while ((s = strchr(t, cp_dol)) != NULL) {
|
||||
while (t < s)
|
||||
wbuf[i++] = *t++;
|
||||
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++;
|
||||
while (t < end) *s++ = *t++;
|
||||
}
|
||||
*s = '\0';
|
||||
nwl = vareval(buf);
|
||||
|
|
@ -689,9 +579,7 @@ cp_variablesubst(wordlist *wlist)
|
|||
(void) strcat(buf, nwl->wl_word);
|
||||
tfree(nwl->wl_word);
|
||||
nwl->wl_word = copy(buf);
|
||||
} else {
|
||||
nwl = wl_cons(copy(buf), NULL);
|
||||
}
|
||||
} 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*/
|
||||
|
|
@ -699,8 +587,7 @@ cp_variablesubst(wordlist *wlist)
|
|||
return NULL;
|
||||
}
|
||||
/* This is bad... */
|
||||
for (wlist = wl; wlist->wl_prev; wlist = wlist->wl_prev)
|
||||
;
|
||||
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 */
|
||||
|
|
@ -708,17 +595,14 @@ cp_variablesubst(wordlist *wlist)
|
|||
wl->wl_word = copy(buf);
|
||||
t = &wl->wl_word[i];
|
||||
s = wl->wl_word;
|
||||
for (i = 0; s < t; s++)
|
||||
wbuf[i++] = *s;
|
||||
for (i = 0; s < t; s++) wbuf[i++] = *s;
|
||||
}
|
||||
}
|
||||
return wlist;
|
||||
}
|
||||
|
||||
/* Evaluate a variable. */
|
||||
wordlist *
|
||||
vareval(char *string)
|
||||
{
|
||||
wordlist * vareval(char *string) {
|
||||
struct variable *v;
|
||||
wordlist *wl;
|
||||
char buf[BSIZE_SP], *s;
|
||||
|
|
@ -742,42 +626,31 @@ vareval(char *string)
|
|||
clearerr(cp_in);
|
||||
(void) strcpy(buf, "EOF");
|
||||
}
|
||||
for (s = buf; *s && (*s != '\n'); s++)
|
||||
;
|
||||
for (s = buf; *s && (*s != '\n'); s++) ;
|
||||
*s = '\0';
|
||||
wl = cp_lexer(buf);
|
||||
/* This is a hack. */
|
||||
if (!wl->wl_word)
|
||||
wl->wl_word = copy("");
|
||||
if (!wl->wl_word) wl->wl_word = copy("");
|
||||
tfree(oldstring);
|
||||
return (wl);
|
||||
case '?':
|
||||
string++;
|
||||
for (v = variables; v; v = v->va_next)
|
||||
if (eq(v->va_name, string))
|
||||
break;
|
||||
if (!v)
|
||||
v = cp_enqvar(string);
|
||||
for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break;
|
||||
if (!v) v = cp_enqvar(string);
|
||||
wl = wl_cons(copy(v ? "1" : "0"), NULL);
|
||||
tfree(oldstring);
|
||||
return (wl);
|
||||
case '#':
|
||||
string++;
|
||||
for (v = variables; v; v = v->va_next)
|
||||
if (eq(v->va_name, string))
|
||||
break;
|
||||
if (!v)
|
||||
v = cp_enqvar(string);
|
||||
for (v = variables; v; v = v->va_next) if (eq(v->va_name, string)) break;
|
||||
if (!v) v = cp_enqvar(string);
|
||||
if (!v) {
|
||||
fprintf(cp_err, "ERROR: %s: no such variable.\n", string);
|
||||
tfree(oldstring);
|
||||
return NULL;
|
||||
}
|
||||
if (v->va_type == CP_LIST)
|
||||
for (v = v->va_vlist, i = 0; v; v = v->va_next)
|
||||
i++;
|
||||
else
|
||||
i = (v->va_type != CP_BOOL);
|
||||
if (v->va_type == CP_LIST) for (v = v->va_vlist, i = 0; v; v = v->va_next) i++;
|
||||
else i = (v->va_type != CP_BOOL);
|
||||
(void) sprintf(buf, "%d", i);
|
||||
wl = wl_cons(copy(buf), NULL);
|
||||
tfree(oldstring);
|
||||
|
|
@ -792,12 +665,10 @@ vareval(char *string)
|
|||
* (e.g, device parameter) variable, it could be anything...
|
||||
*/
|
||||
for (v = variables; v; v = v->va_next)
|
||||
if (eq(v->va_name, string))
|
||||
break;
|
||||
if (eq(v->va_name, string)) break;
|
||||
if (!v && isdigit((int)*string)) {
|
||||
for (v = variables; v; v = v->va_next)
|
||||
if (eq(v->va_name, "argv"))
|
||||
break;
|
||||
if (eq(v->va_name, "argv")) break;
|
||||
range = string;
|
||||
}
|
||||
if (!v) {
|
||||
|
|
@ -822,10 +693,8 @@ vareval(char *string)
|
|||
wordlist *r = NULL;
|
||||
if (*range == '$') {
|
||||
char *t = ++range;
|
||||
if (*t == '&')
|
||||
t++;
|
||||
while (isalphanum((int)*t))
|
||||
t++;
|
||||
if (*t == '&') t++;
|
||||
while (isalphanum((int)*t)) t++;
|
||||
*t = '\0';
|
||||
r = vareval(range);
|
||||
if (!r || r->wl_next) {
|
||||
|
|
@ -836,15 +705,11 @@ vareval(char *string)
|
|||
}
|
||||
range = r->wl_word;
|
||||
}
|
||||
for (low = 0; isdigit((int)*range); range++)
|
||||
low = low * 10 + *range - '0';
|
||||
for (low = 0; isdigit((int)*range); range++) low = low * 10 + *range - '0';
|
||||
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);
|
||||
else
|
||||
up = low;
|
||||
for (up = 0, range++; isdigit((int)*range); range++) up = up * 10 + *range - '0';
|
||||
else if (*range == '-') up = wl_length(wl);
|
||||
else up = low;
|
||||
up--, low--;
|
||||
wl = wl_range(wl, low, up);
|
||||
wl_free(r);
|
||||
|
|
@ -853,22 +718,16 @@ vareval(char *string)
|
|||
return wl;
|
||||
}
|
||||
|
||||
static int
|
||||
vcmp(const void *a, const void *b)
|
||||
{
|
||||
static int vcmp(const void *a, const void *b) {
|
||||
int i;
|
||||
struct xxx *v1 = (struct xxx *) a;
|
||||
struct xxx *v2 = (struct xxx *) b;
|
||||
if ((i = strcmp(v1->x_v->va_name, v2->x_v->va_name)) != 0)
|
||||
return (i);
|
||||
else
|
||||
return (v1->x_char - v2->x_char);
|
||||
if ((i = strcmp(v1->x_v->va_name, v2->x_v->va_name)) != 0) return (i);
|
||||
else return (v1->x_char - v2->x_char);
|
||||
}
|
||||
|
||||
/* Print the values of currently defined variables. */
|
||||
void
|
||||
cp_vprint(void)
|
||||
{
|
||||
void cp_vprint(void) {
|
||||
struct variable *v;
|
||||
struct variable *uv1, *uv2;
|
||||
wordlist *wl;
|
||||
|
|
@ -876,12 +735,9 @@ cp_vprint(void)
|
|||
char *s;
|
||||
struct xxx *vars;
|
||||
cp_usrvars(&uv1, &uv2);
|
||||
for (v = uv1, i = 0; v; v = v->va_next)
|
||||
i++;
|
||||
for (v = uv2; v; v = v->va_next)
|
||||
i++;
|
||||
for (v = variables; v; v = v->va_next)
|
||||
i++;
|
||||
for (v = uv1, i = 0; v; v = v->va_next) i++;
|
||||
for (v = uv2; v; v = v->va_next) i++;
|
||||
for (v = variables; v; v = v->va_next) i++;
|
||||
vars = TMALLOC(struct xxx, i);
|
||||
out_init();
|
||||
for (v = variables, i = 0; v; v = v->va_next, i++) {
|
||||
|
|
@ -898,19 +754,15 @@ cp_vprint(void)
|
|||
}
|
||||
qsort(vars, (size_t) i, sizeof(*vars), vcmp);
|
||||
for (j = 0; j < i; j++) {
|
||||
if (j && eq(vars[j].x_v->va_name, vars[j-1].x_v->va_name))
|
||||
continue;
|
||||
if (j && eq(vars[j].x_v->va_name, vars[j-1].x_v->va_name)) continue;
|
||||
v = vars[j].x_v;
|
||||
if (v->va_type == CP_BOOL) {
|
||||
out_printf("%c %s\n", vars[j].x_char, v->va_name);
|
||||
} else {
|
||||
if (v->va_type == CP_BOOL) out_printf("%c %s\n", vars[j].x_char, v->va_name);
|
||||
else {
|
||||
out_printf("%c %s\t", vars[j].x_char, v->va_name);
|
||||
wl = vareval(v->va_name);
|
||||
s = wl_flatten(wl);
|
||||
if (v->va_type == CP_LIST)
|
||||
out_printf("( %s )\n", s);
|
||||
else
|
||||
out_printf("%s\n", s);
|
||||
if (v->va_type == CP_LIST) out_printf("( %s )\n", s);
|
||||
else out_printf("%s\n", s);
|
||||
}
|
||||
}
|
||||
tfree(vars);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
/**********
|
||||
/*******************************************************************************
|
||||
Copyright 1990 Regents of the University of California. All rights reserved.
|
||||
Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||
**********/
|
||||
*******************************************************************************/
|
||||
|
||||
/*
|
||||
* Routines for dealing with the vector database.
|
||||
|
|
@ -24,21 +24,17 @@
|
|||
|
||||
struct dvec *EVTfindvec(char *node);
|
||||
|
||||
static void
|
||||
vec_rebuild_lookup_table(struct plot *pl)
|
||||
{
|
||||
static void vec_rebuild_lookup_table(struct plot *pl) {
|
||||
int cnt; /* count entries */
|
||||
struct dvec *d; /* dynamic vector */
|
||||
NGHASHPTR lookup_p; /* lookup table for speed */
|
||||
SPICE_DSTRING dbuf; /* dynamic buffer */
|
||||
char *lower_name; /* lower case name */
|
||||
|
||||
if (pl->pl_lookup_table) {
|
||||
nghash_empty(pl->pl_lookup_table, NULL, NULL);
|
||||
} else {
|
||||
if (pl->pl_lookup_table) nghash_empty(pl->pl_lookup_table, NULL, NULL);
|
||||
else {
|
||||
cnt = 0;
|
||||
for (d = pl->pl_dvecs; d; d = d->v_next)
|
||||
cnt++;
|
||||
for (d = pl->pl_dvecs; d; d = d->v_next) cnt++;
|
||||
pl->pl_lookup_table = nghash_init(cnt);
|
||||
/* allow multiple entries */
|
||||
nghash_unique(pl->pl_lookup_table, FALSE);
|
||||
|
|
@ -56,16 +52,13 @@ vec_rebuild_lookup_table(struct plot *pl)
|
|||
|
||||
/* Find a named vector in a plot. We are careful to copy the vector if
|
||||
* v_link2 is set, because otherwise we will get screwed up. */
|
||||
static struct dvec *
|
||||
findvec(char *word, struct plot *pl)
|
||||
{
|
||||
static struct dvec *findvec(char *word, struct plot *pl) {
|
||||
SPICE_DSTRING dbuf; /* dynamic buffer */
|
||||
char *lower_name; /* lower case name */
|
||||
char *node_name;
|
||||
struct dvec *d, *newv = NULL, *end = NULL, *v;
|
||||
|
||||
if (pl == NULL)
|
||||
return NULL;
|
||||
if (pl == NULL) return NULL;
|
||||
|
||||
if (cieq(word, "all")) {
|
||||
for (d = pl->pl_dvecs; d; d = d->v_next) {
|
||||
|
|
@ -73,13 +66,10 @@ findvec(char *word, struct plot *pl)
|
|||
if (d->v_link2) {
|
||||
v = vec_copy(d);
|
||||
vec_new(v);
|
||||
} else {
|
||||
v = d;
|
||||
}
|
||||
if (end)
|
||||
end->v_link2 = v;
|
||||
else
|
||||
newv = v;
|
||||
else v = d;
|
||||
if (end) end->v_link2 = v;
|
||||
else newv = v;
|
||||
end = v;
|
||||
}
|
||||
}
|
||||
|
|
@ -92,13 +82,10 @@ findvec(char *word, struct plot *pl)
|
|||
if (d->v_link2) {
|
||||
v = vec_copy(d);
|
||||
vec_new(v);
|
||||
} else {
|
||||
v = d;
|
||||
}
|
||||
if (end)
|
||||
end->v_link2 = v;
|
||||
else
|
||||
newv = v;
|
||||
else v = d;
|
||||
if (end) end->v_link2 = v;
|
||||
else newv = v;
|
||||
end = v;
|
||||
}
|
||||
}
|
||||
|
|
@ -111,13 +98,10 @@ findvec(char *word, struct plot *pl)
|
|||
if (d->v_link2) {
|
||||
v = vec_copy(d);
|
||||
vec_new(v);
|
||||
} else {
|
||||
v = d;
|
||||
}
|
||||
if (end)
|
||||
end->v_link2 = v;
|
||||
else
|
||||
newv = v;
|
||||
else v = d;
|
||||
if (end) end->v_link2 = v;
|
||||
else newv = v;
|
||||
end = v;
|
||||
}
|
||||
}
|
||||
|
|
@ -130,32 +114,23 @@ findvec(char *word, struct plot *pl)
|
|||
if (d->v_link2) {
|
||||
v = vec_copy(d);
|
||||
vec_new(v);
|
||||
} else {
|
||||
v = d;
|
||||
}
|
||||
if (end)
|
||||
end->v_link2 = v;
|
||||
else
|
||||
newv = v;
|
||||
else v = d;
|
||||
if (end) end->v_link2 = v;
|
||||
else newv = v;
|
||||
end = v;
|
||||
}
|
||||
}
|
||||
return newv;
|
||||
}
|
||||
|
||||
if (!pl->pl_lookup_valid)
|
||||
vec_rebuild_lookup_table(pl);
|
||||
if (!pl->pl_lookup_valid) vec_rebuild_lookup_table(pl);
|
||||
|
||||
spice_dstring_init(&dbuf);
|
||||
lower_name = spice_dstring_append_lower(&dbuf, word, -1);
|
||||
|
||||
for (d = nghash_find(pl->pl_lookup_table, lower_name);
|
||||
d;
|
||||
d = nghash_find_again(pl->pl_lookup_table, lower_name))
|
||||
{
|
||||
if (d->v_flags & VF_PERMANENT)
|
||||
break;
|
||||
}
|
||||
for (d = nghash_find(pl->pl_lookup_table, lower_name); d; d = nghash_find_again(pl->pl_lookup_table, lower_name))
|
||||
if (d->v_flags & VF_PERMANENT) break;
|
||||
|
||||
if (!d) {
|
||||
spice_dstring_reinit(&dbuf);
|
||||
|
|
@ -163,19 +138,13 @@ findvec(char *word, struct plot *pl)
|
|||
spice_dstring_append_lower(&dbuf, word, -1);
|
||||
node_name = spice_dstring_append_char(&dbuf, ')');
|
||||
|
||||
for (d = nghash_find(pl->pl_lookup_table, node_name);
|
||||
d;
|
||||
d = nghash_find_again(pl->pl_lookup_table, node_name))
|
||||
{
|
||||
if (d->v_flags & VF_PERMANENT)
|
||||
break;
|
||||
}
|
||||
for (d = nghash_find(pl->pl_lookup_table, node_name); d; d = nghash_find_again(pl->pl_lookup_table, node_name))
|
||||
if (d->v_flags & VF_PERMANENT) break;
|
||||
}
|
||||
|
||||
spice_dstring_free(&dbuf);
|
||||
|
||||
if (!d)
|
||||
d = EVTfindvec(word);
|
||||
if (!d) d = EVTfindvec(word);
|
||||
|
||||
if (d && d->v_link2) {
|
||||
d = vec_copy(d);
|
||||
|
|
@ -188,68 +157,50 @@ findvec(char *word, struct plot *pl)
|
|||
/* If there are imbedded numeric strings, compare them numerically, not
|
||||
* alphabetically.
|
||||
*/
|
||||
static int
|
||||
namecmp(const void *a, const void *b)
|
||||
{
|
||||
static int namecmp(const void *a, const void *b) {
|
||||
int i, j;
|
||||
|
||||
const char *s = (const char *) a;
|
||||
const char *t = (const char *) b;
|
||||
|
||||
for (;;) {
|
||||
while ((*s == *t) && !isdigit((int)*s) && *s)
|
||||
s++, t++;
|
||||
if (!*s)
|
||||
return 0;
|
||||
if ((*s != *t) && (!isdigit((int)*s) || !isdigit((int)*t)))
|
||||
return (*s - *t);
|
||||
while ((*s == *t) && !isdigit((int)*s) && *s) s++, t++;
|
||||
if (!*s) return 0;
|
||||
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((int)*s); s++)
|
||||
i = i * 10 + *s - '0';
|
||||
for (j = 0; isdigit((int)*t); t++)
|
||||
j = j * 10 + *t - '0';
|
||||
for (i = 0; isdigit((int)*s); s++) i = i * 10 + *s - '0';
|
||||
for (j = 0; isdigit((int)*t); t++) j = j * 10 + *t - '0';
|
||||
|
||||
if (i != j)
|
||||
return (i - j);
|
||||
if (i != j) return (i - j);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
veccmp(const void *a, const void *b)
|
||||
{
|
||||
static int veccmp(const void *a, const void *b) {
|
||||
int i;
|
||||
struct dvec **d1 = (struct dvec **) a;
|
||||
struct dvec **d2 = (struct dvec **) b;
|
||||
|
||||
if ((i = namecmp((*d1)->v_plot->pl_typename,
|
||||
(*d2)->v_plot->pl_typename)) != 0)
|
||||
return i;
|
||||
if ((i = namecmp((*d1)->v_plot->pl_typename, (*d2)->v_plot->pl_typename)) != 0) return i;
|
||||
return namecmp((*d1)->v_name, (*d2)->v_name);
|
||||
}
|
||||
|
||||
/* Sort all the vectors in d, first by plot name and then by vector
|
||||
* name. Do the right thing with numbers. */
|
||||
static struct dvec *
|
||||
sortvecs(struct dvec *d)
|
||||
{
|
||||
static struct dvec *sortvecs(struct dvec *d) {
|
||||
struct dvec **array, *t;
|
||||
int i, j;
|
||||
|
||||
for (t = d, i = 0; t; t = t->v_link2)
|
||||
i++;
|
||||
if (i < 2)
|
||||
return d;
|
||||
for (t = d, i = 0; t; t = t->v_link2) i++;
|
||||
if (i < 2) return d;
|
||||
array = TMALLOC(struct dvec *, i);
|
||||
for (t = d, i = 0; t; t = t->v_link2)
|
||||
array[i++] = t;
|
||||
for (t = d, i = 0; t; t = t->v_link2) array[i++] = t;
|
||||
|
||||
qsort(array, (size_t) i, sizeof(struct dvec *), veccmp);
|
||||
|
||||
/* Now string everything back together... */
|
||||
for (j = 0; j < i - 1; j++)
|
||||
array[j]->v_link2 = array[j + 1];
|
||||
for (j = 0; j < i - 1; j++) array[j]->v_link2 = array[j + 1];
|
||||
array[j]->v_link2 = NULL;
|
||||
d = array[0];
|
||||
tfree(array);
|
||||
|
|
@ -257,17 +208,13 @@ sortvecs(struct dvec *d)
|
|||
}
|
||||
|
||||
/* Load in a rawfile. */
|
||||
void
|
||||
ft_loadfile(char *file)
|
||||
{
|
||||
void ft_loadfile(char *file) {
|
||||
struct plot *pl, *np, *pp;
|
||||
|
||||
fprintf(cp_out, "Loading raw data file (\"%s\") . . . ", file);
|
||||
pl = raw_read(file);
|
||||
if (pl)
|
||||
fprintf(cp_out, "done.\n");
|
||||
else
|
||||
fprintf(cp_out, "no data read.\n");
|
||||
if (pl) fprintf(cp_out, "done.\n");
|
||||
else fprintf(cp_out, "no data read.\n");
|
||||
|
||||
/* This is a minor annoyance -- we should reverse the plot list so
|
||||
* they get numbered in the correct order.
|
||||
|
|
@ -287,24 +234,18 @@ ft_loadfile(char *file)
|
|||
plotl_changed = TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
plot_add(struct plot *pl)
|
||||
{
|
||||
void plot_add(struct plot *pl) {
|
||||
struct dvec *v;
|
||||
struct plot *tp;
|
||||
char *s, buf[BSIZE_SP];
|
||||
|
||||
fprintf(cp_out, "Title: %s\nName: %s\nDate: %s\n\n", pl->pl_title,
|
||||
pl->pl_name, pl->pl_date);
|
||||
if (plot_cur)
|
||||
plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom);
|
||||
fprintf(cp_out, "Title: %s\nName: %s\nDate: %s\n\n", pl->pl_title, pl->pl_name, pl->pl_date);
|
||||
if (plot_cur) plot_cur->pl_ccom = cp_kwswitch(CT_VECTOR, pl->pl_ccom);
|
||||
|
||||
for (v = pl->pl_dvecs; v; v = v->v_next)
|
||||
cp_addkword(CT_VECTOR, v->v_name);
|
||||
for (v = pl->pl_dvecs; v; v = v->v_next) cp_addkword(CT_VECTOR, v->v_name);
|
||||
cp_addkword(CT_VECTOR, "all");
|
||||
|
||||
if ((s = ft_plotabbrev(pl->pl_name)) == NULL)
|
||||
s = "unknown";
|
||||
if ((s = ft_plotabbrev(pl->pl_name)) == NULL) s = "unknown";
|
||||
do {
|
||||
(void) sprintf(buf, "%s%d", s, plot_num);
|
||||
for (tp = plot_list; tp; tp = tp->pl_next)
|
||||
|
|
@ -312,7 +253,8 @@ plot_add(struct plot *pl)
|
|||
plot_num++;
|
||||
break;
|
||||
}
|
||||
} while (tp);
|
||||
}
|
||||
while (tp);
|
||||
|
||||
pl->pl_typename = copy(buf);
|
||||
plot_new(pl);
|
||||
|
|
@ -322,15 +264,10 @@ plot_add(struct plot *pl)
|
|||
}
|
||||
|
||||
/* Remove a vector from the database, if it is there. */
|
||||
void
|
||||
vec_remove(char *name)
|
||||
{
|
||||
void vec_remove(char *name) {
|
||||
struct dvec *ov;
|
||||
for (ov = plot_cur->pl_dvecs; ov; ov = ov->v_next)
|
||||
if (cieq(name, ov->v_name) && (ov->v_flags & VF_PERMANENT))
|
||||
break;
|
||||
if (!ov)
|
||||
return;
|
||||
for (ov = plot_cur->pl_dvecs; ov; ov = ov->v_next) if (cieq(name, ov->v_name) && (ov->v_flags & VF_PERMANENT)) break;
|
||||
if (!ov) return;
|
||||
ov->v_flags &= ~VF_PERMANENT;
|
||||
/* Remove from the keyword list. */
|
||||
cp_remkword(CT_VECTOR, name);
|
||||
|
|
@ -339,9 +276,7 @@ vec_remove(char *name)
|
|||
/* Get a vector by name. This deals with v(1), etc. almost properly. Also,
|
||||
* it checks for pre-defined vectors.
|
||||
*/
|
||||
struct dvec *
|
||||
vec_fromplot(char *word, struct plot *plot)
|
||||
{
|
||||
struct dvec *vec_fromplot(char *word, struct plot *plot) {
|
||||
struct dvec *d;
|
||||
char buf[BSIZE_SP], buf2[BSIZE_SP], cc, *s;
|
||||
|
||||
|
|
@ -359,8 +294,7 @@ 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) &&
|
||||
(s[1] == '\0')) {
|
||||
/* ( */ ((s = strrchr(buf, ')')) != NULL) && (s[1] == '\0')) {
|
||||
*s = '\0';
|
||||
if (prefix("i(", /* ) */ word) || prefix("I(", /* ) */ word)) {
|
||||
/* Spice dependency... */
|
||||
|
|
@ -387,9 +321,7 @@ vec_fromplot(char *word, struct plot *plot)
|
|||
|
||||
#define SPECCHAR '@'
|
||||
|
||||
struct dvec *
|
||||
vec_get(const char *vec_name)
|
||||
{
|
||||
struct dvec *vec_get(const char *vec_name) {
|
||||
struct dvec *d, *end = NULL, *newv = NULL;
|
||||
struct plot *pl;
|
||||
char buf[BSIZE_SP], *s, *wd, *word, *whole, *name = NULL, *param;
|
||||
|
|
@ -401,64 +333,43 @@ vec_get(const char *vec_name)
|
|||
|
||||
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 (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++)
|
||||
buf[i] = *s;
|
||||
for (i = 0, s = word; *s != '.'; i++, s++) buf[i] = *s;
|
||||
buf[i] = '\0';
|
||||
if (cieq(buf, "all")) {
|
||||
word = ++s;
|
||||
pl = NULL; /* NULL pl signifies a wildcard. */
|
||||
} else {
|
||||
for (pl = plot_list;
|
||||
pl && !plot_prefix(buf, pl->pl_typename);
|
||||
pl = pl->pl_next)
|
||||
;
|
||||
if (pl) {
|
||||
word = ++s;
|
||||
} else {
|
||||
/* This used to be an error... */
|
||||
pl = plot_cur;
|
||||
}
|
||||
else {
|
||||
for (pl = plot_list; pl && !plot_prefix(buf, pl->pl_typename); pl = pl->pl_next) ;
|
||||
if (pl) word = ++s;
|
||||
else pl = plot_cur; /* This used to be an error... */
|
||||
}
|
||||
} else {
|
||||
pl = plot_cur;
|
||||
}
|
||||
else pl = plot_cur;
|
||||
|
||||
if (pl) {
|
||||
d = vec_fromplot(word, pl);
|
||||
if (!d)
|
||||
d = vec_fromplot(word, &constantplot);
|
||||
} else {
|
||||
if (!d) d = vec_fromplot(word, &constantplot);
|
||||
}
|
||||
else {
|
||||
for (pl = plot_list; pl; pl = pl->pl_next) {
|
||||
if (cieq(pl->pl_typename, "const"))
|
||||
continue;
|
||||
if (cieq(pl->pl_typename, "const")) continue;
|
||||
d = vec_fromplot(word, pl);
|
||||
if (d) {
|
||||
if (end)
|
||||
end->v_link2 = d;
|
||||
else
|
||||
newv = d;
|
||||
for (end = d; end->v_link2; end = end->v_link2)
|
||||
;
|
||||
if (end) end->v_link2 = d;
|
||||
else newv = d;
|
||||
for (end = d; end->v_link2; end = end->v_link2) ;
|
||||
}
|
||||
}
|
||||
d = newv;
|
||||
if (!d) {
|
||||
fprintf(cp_err,
|
||||
"ERROR: plot wildcard (name %s) matches nothing\n",
|
||||
word);
|
||||
fprintf(cp_err, "ERROR: plot wildcard (name %s) matches nothing\n", word);
|
||||
tfree(wd);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -483,25 +394,21 @@ vec_get(const char *vec_name)
|
|||
if (!d && (*word == SPECCHAR)) {
|
||||
/* This is a special quantity... */
|
||||
if (ft_nutmeg) {
|
||||
fprintf(cp_err,
|
||||
"ERROR: circuit parameters only available with spice\n");
|
||||
fprintf(cp_err, "ERROR: circuit parameters only available with spice\n");
|
||||
tfree(wd); /* MW. Memory leak fixed again */
|
||||
return NULL; /* va: use NULL */
|
||||
}
|
||||
|
||||
whole = copy(word);
|
||||
name = ++word;
|
||||
for (param = name; *param && (*param != '['); param++)
|
||||
;
|
||||
for (param = name; *param && (*param != '['); param++) ;
|
||||
|
||||
if (*param) {
|
||||
*param++ = '\0';
|
||||
for (s = param; *s && *s != ']'; s++)
|
||||
;
|
||||
for (s = param; *s && *s != ']'; s++) ;
|
||||
*s = '\0';
|
||||
} else {
|
||||
param = NULL;
|
||||
}
|
||||
else param = NULL;
|
||||
|
||||
if (ft_curckt) {
|
||||
/*
|
||||
|
|
@ -516,7 +423,8 @@ vec_get(const char *vec_name)
|
|||
tfree(wd);
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
fprintf(cp_err, "ERROR: No circuit loaded.\n");
|
||||
tfree(whole);
|
||||
tfree(wd);
|
||||
|
|
@ -584,8 +492,7 @@ vec_get(const char *vec_name)
|
|||
list = TREALLOC(double, list, i);
|
||||
list[i-1] = nv->va_real;
|
||||
nv = nv->va_next;
|
||||
if (!nv)
|
||||
break;
|
||||
if (!nv) break;
|
||||
}
|
||||
d->v_realdata = list;
|
||||
d->v_length = i;
|
||||
|
|
@ -594,15 +501,13 @@ vec_get(const char *vec_name)
|
|||
* special way.
|
||||
*/
|
||||
d->v_dims[1] = 1;
|
||||
} else if (vv->va_type == CP_NUM) { /* Variable is an integer */
|
||||
*d->v_realdata = (double) vv->va_num;
|
||||
} else if (vv->va_type == CP_REAL) { /* Variable is a real */
|
||||
if (!(vv->va_next)) {
|
||||
/* Only a real data
|
||||
* usually normal
|
||||
*/
|
||||
*d->v_realdata = vv->va_real;
|
||||
} else {
|
||||
}
|
||||
else if (vv->va_type == CP_NUM) { /* Variable is an integer */ *d->v_realdata = (double) vv->va_num;
|
||||
}
|
||||
else if (vv->va_type == CP_REAL) {
|
||||
/* Variable is a real */
|
||||
if (!(vv->va_next)) *d->v_realdata = vv->va_real; /* Only a real data. usually normal */
|
||||
else {
|
||||
/* Real data set
|
||||
* When you print a model @ [all]
|
||||
* Just print numerical values, not the string
|
||||
|
|
@ -616,23 +521,16 @@ vec_get(const char *vec_name)
|
|||
nv = vv;
|
||||
for (i = 1; ; i++) {
|
||||
switch (nv->va_type) {
|
||||
case CP_REAL:
|
||||
fprintf(stdout, "%s=%g\n", nv->va_name, nv->va_real);
|
||||
break;
|
||||
case CP_STRING:
|
||||
fprintf(stdout, "%s=%s\n", nv->va_name, nv->va_string);
|
||||
break;
|
||||
case CP_NUM:
|
||||
fprintf(stdout, "%s=%d\n", nv->va_name, nv->va_num);
|
||||
break;
|
||||
case CP_REAL: fprintf(stdout, "%s=%g\n", nv->va_name, nv->va_real); break;
|
||||
case CP_STRING: fprintf(stdout, "%s=%s\n", nv->va_name, nv->va_string); break;
|
||||
case CP_NUM: fprintf(stdout, "%s=%d\n", nv->va_name, nv->va_num); break;
|
||||
default: {
|
||||
fprintf(stderr, "ERROR: enumeration value `CP_BOOL' or `CP_LIST' not handled in vec_get\nAborting...\n");
|
||||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
nv = nv->va_next;
|
||||
if (!nv)
|
||||
break;
|
||||
if (!nv) break;
|
||||
}
|
||||
/* To distinguish those does not take anything for print screen to
|
||||
* make a print or M1 @ @ M1 [all] leaving only the correct data
|
||||
|
|
@ -655,9 +553,7 @@ vec_get(const char *vec_name)
|
|||
/* Execute the commands for a plot. This is done whenever a plot becomes
|
||||
* the current plot.
|
||||
*/
|
||||
void
|
||||
plot_docoms(wordlist *wl)
|
||||
{
|
||||
void plot_docoms(wordlist *wl) {
|
||||
bool inter;
|
||||
|
||||
inter = cp_interactive;
|
||||
|
|
@ -671,14 +567,11 @@ plot_docoms(wordlist *wl)
|
|||
}
|
||||
|
||||
/* Create a copy of a vector. */
|
||||
struct dvec *
|
||||
vec_copy(struct dvec *v)
|
||||
{
|
||||
struct dvec *vec_copy(struct dvec *v) {
|
||||
struct dvec *nv;
|
||||
int i;
|
||||
|
||||
if (!v)
|
||||
return NULL;
|
||||
if (!v) return NULL;
|
||||
|
||||
nv = alloc(struct dvec);
|
||||
nv->v_name = copy(v->v_name);
|
||||
|
|
@ -687,14 +580,12 @@ vec_copy(struct dvec *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);
|
||||
bcopy(v->v_realdata, nv->v_realdata, sizeof(double) * (size_t) v->v_length);
|
||||
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);
|
||||
bcopy(v->v_compdata, nv->v_compdata, sizeof(ngcomplex_t) * (size_t) v->v_length);
|
||||
}
|
||||
|
||||
nv->v_minsignal = v->v_minsignal;
|
||||
|
|
@ -719,8 +610,7 @@ vec_copy(struct dvec *v)
|
|||
nv->v_color = 0; /*XXX???*/
|
||||
nv->v_defcolor = v->v_defcolor;
|
||||
nv->v_numdims = v->v_numdims;
|
||||
for (i = 0; i < v->v_numdims; i++)
|
||||
nv->v_dims[i] = v->v_dims[i];
|
||||
for (i = 0; i < v->v_numdims; i++) nv->v_dims[i] = v->v_dims[i];
|
||||
nv->v_plot = v->v_plot;
|
||||
nv->v_next = NULL;
|
||||
nv->v_link2 = NULL;
|
||||
|
|
@ -729,20 +619,16 @@ vec_copy(struct dvec *v)
|
|||
return nv;
|
||||
}
|
||||
|
||||
/* Create a new plot structure. This just fills in the typename and sets up
|
||||
* the ccom struct.
|
||||
*/
|
||||
struct plot *
|
||||
plot_alloc(char *name)
|
||||
{
|
||||
/* Create a new plot structure. This just fills in the typename and sets up the ccom struct. */
|
||||
|
||||
struct plot *plot_alloc(char *name) {
|
||||
struct plot *pl = alloc(struct plot), *tp;
|
||||
char *s;
|
||||
struct ccom *ccom;
|
||||
char buf[BSIZE_SP];
|
||||
|
||||
ZERO(pl, struct plot);
|
||||
if ((s = ft_plotabbrev(name)) == NULL)
|
||||
s = "unknown";
|
||||
if ((s = ft_plotabbrev(name)) == NULL) s = "unknown";
|
||||
do {
|
||||
(void) sprintf(buf, "%s%d", s, plot_num);
|
||||
for (tp = plot_list; tp; tp = tp->pl_next)
|
||||
|
|
@ -750,7 +636,8 @@ plot_alloc(char *name)
|
|||
plot_num++;
|
||||
break;
|
||||
}
|
||||
} while (tp);
|
||||
}
|
||||
while (tp);
|
||||
pl->pl_typename = copy(buf);
|
||||
cp_addkword(CT_PLOT, buf);
|
||||
/* va: create a new, empty keyword tree for class CT_VECTOR, s=old tree */
|
||||
|
|
@ -762,19 +649,15 @@ plot_alloc(char *name)
|
|||
}
|
||||
|
||||
/* Stick a new vector in the proper place in the plot list. */
|
||||
void
|
||||
vec_new(struct dvec *d)
|
||||
{
|
||||
void vec_new(struct dvec *d) {
|
||||
/* Note that this can't happen. */
|
||||
if (plot_cur == NULL) {
|
||||
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))
|
||||
plot_cur->pl_scale = d;
|
||||
if (!d->v_plot)
|
||||
d->v_plot = plot_cur;
|
||||
if ((d->v_flags & VF_PERMANENT) && (plot_cur->pl_scale == NULL)) plot_cur->pl_scale = d;
|
||||
if (!d->v_plot) d->v_plot = plot_cur;
|
||||
if (d->v_numdims < 1) {
|
||||
d->v_numdims = 1;
|
||||
d->v_dims[0] = d->v_length;
|
||||
|
|
@ -790,9 +673,7 @@ vec_new(struct dvec *d)
|
|||
* clears the v_link2 pointer.
|
||||
*/
|
||||
|
||||
void
|
||||
vec_gc(void)
|
||||
{
|
||||
void vec_gc(void) {
|
||||
struct dvec *d, *nd;
|
||||
struct plot *pl;
|
||||
|
||||
|
|
@ -800,16 +681,12 @@ vec_gc(void)
|
|||
for (d = pl->pl_dvecs; d; d = nd) {
|
||||
nd = d->v_next;
|
||||
if (!(d->v_flags & VF_PERMANENT)) {
|
||||
if (ft_vecdb)
|
||||
fprintf(cp_err,
|
||||
"vec_gc: throwing away %s.%s\n",
|
||||
pl->pl_typename, d->v_name);
|
||||
if (ft_vecdb) fprintf(cp_err, "vec_gc: throwing away %s.%s\n", pl->pl_typename, d->v_name);
|
||||
vec_free(d);
|
||||
}
|
||||
}
|
||||
for (pl = plot_list; pl; pl = pl->pl_next)
|
||||
for (d = pl->pl_dvecs; d; d = d->v_next)
|
||||
d->v_link2 = NULL;
|
||||
for (d = pl->pl_dvecs; d; d = d->v_next) d->v_link2 = NULL;
|
||||
}
|
||||
|
||||
/* Free a dvector. This is sort of a pain because we also have to make sure
|
||||
|
|
@ -820,69 +697,50 @@ vec_gc(void)
|
|||
* in a plot are gone it stays around...
|
||||
*/
|
||||
|
||||
void
|
||||
vec_free_x(struct dvec *v)
|
||||
{
|
||||
void vec_free_x(struct dvec *v) {
|
||||
struct plot *pl;
|
||||
|
||||
if ((v == NULL) || (v->v_name == NULL))
|
||||
return;
|
||||
if ((v == NULL) || (v->v_name == NULL)) return;
|
||||
pl = v->v_plot;
|
||||
|
||||
/* Now we have to take this dvec out of the plot list. */
|
||||
if (pl != NULL) {
|
||||
pl->pl_lookup_valid = FALSE;
|
||||
if (pl->pl_dvecs == v) {
|
||||
pl->pl_dvecs = v->v_next;
|
||||
} else {
|
||||
if (pl->pl_dvecs == v) pl->pl_dvecs = v->v_next;
|
||||
else {
|
||||
struct dvec *lv = pl->pl_dvecs;
|
||||
if (lv)
|
||||
for (; lv->v_next; lv = lv->v_next)
|
||||
if (lv->v_next == v)
|
||||
break;
|
||||
if (lv && lv->v_next)
|
||||
lv->v_next = v->v_next;
|
||||
else
|
||||
fprintf(cp_err,
|
||||
"vec_free: INTERNAL ERROR: %s not in plot\n",
|
||||
v->v_name);
|
||||
if (lv->v_next == v) break;
|
||||
if (lv && lv->v_next) lv->v_next = v->v_next;
|
||||
else fprintf(cp_err, "vec_free: INTERNAL ERROR: %s not in plot\n", v->v_name);
|
||||
}
|
||||
if (pl->pl_scale == v) {
|
||||
if (pl->pl_dvecs)
|
||||
pl->pl_scale = pl->pl_dvecs; /* Random one... */
|
||||
else
|
||||
pl->pl_scale = NULL;
|
||||
else pl->pl_scale = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (v->v_name)
|
||||
tfree(v->v_name);
|
||||
if (v->v_realdata)
|
||||
tfree(v->v_realdata);
|
||||
if (v->v_compdata)
|
||||
tfree(v->v_compdata);
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* return TRUE if every vector element is zero
|
||||
*/
|
||||
BOOL
|
||||
vec_iszero(struct dvec *v)
|
||||
{
|
||||
BOOL vec_iszero(struct dvec *v) {
|
||||
int i;
|
||||
for (; v; v = v->v_link2)
|
||||
if (isreal(v))
|
||||
for (i = 0; i < v->v_length; i++) {
|
||||
if (v->v_realdata[i] != 0.0)
|
||||
return FALSE;
|
||||
if (v->v_realdata[i] != 0.0) return FALSE;
|
||||
}
|
||||
else
|
||||
for (i = 0; i < v->v_length; i++) {
|
||||
if (realpart(v->v_compdata[i]) != 0.0)
|
||||
return FALSE;
|
||||
if (imagpart(v->v_compdata[i]) != 0.0)
|
||||
return FALSE;
|
||||
else for (i = 0; i < v->v_length; i++) {
|
||||
if (realpart(v->v_compdata[i]) != 0.0) return FALSE;
|
||||
if (imagpart(v->v_compdata[i]) != 0.0) return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
|
@ -891,22 +749,18 @@ vec_iszero(struct dvec *v)
|
|||
* we can't just compare pointers to tell if two vectors are 'really' the same.
|
||||
*/
|
||||
|
||||
bool
|
||||
vec_eq(struct dvec *v1, struct dvec *v2)
|
||||
{
|
||||
bool vec_eq(struct dvec *v1, struct dvec *v2) {
|
||||
char *s1, *s2;
|
||||
bool rtn;
|
||||
|
||||
if (v1->v_plot != v2->v_plot)
|
||||
return FALSE;
|
||||
if (v1->v_plot != v2->v_plot) return FALSE;
|
||||
|
||||
s1 = vec_basename(v1);
|
||||
s2 = vec_basename(v2);
|
||||
|
||||
if (cieq(s1, s2))
|
||||
rtn = TRUE;
|
||||
else
|
||||
rtn = FALSE;
|
||||
else rtn = FALSE;
|
||||
|
||||
tfree(s1);
|
||||
tfree(s2);
|
||||
|
|
@ -918,40 +772,29 @@ vec_eq(struct dvec *v1, struct dvec *v2)
|
|||
* is no longer trivial since '.' doesn't always mean 'plot prefix'.
|
||||
*/
|
||||
|
||||
char *
|
||||
vec_basename(struct dvec *v)
|
||||
{
|
||||
char * vec_basename(struct dvec *v) {
|
||||
char buf[BSIZE_SP], *t, *s;
|
||||
|
||||
if (strchr(v->v_name, '.')) {
|
||||
if (cieq(v->v_plot->pl_typename, v->v_name))
|
||||
(void) strcpy(buf, v->v_name + strlen(v->v_name) + 1);
|
||||
else
|
||||
(void) strcpy(buf, v->v_name);
|
||||
} else {
|
||||
(void) strcpy(buf, v->v_name);
|
||||
}
|
||||
else (void) strcpy(buf, v->v_name);
|
||||
} else (void) strcpy(buf, v->v_name);
|
||||
|
||||
strtolower(buf);
|
||||
for (t = buf; isspace((int)*t); t++)
|
||||
;
|
||||
for (t = buf; isspace((int)*t); t++) ;
|
||||
s = t;
|
||||
for (t = s; *t; t++)
|
||||
;
|
||||
while ((t > s) && isspace((int)t[-1]))
|
||||
*--t = '\0';
|
||||
for (t = s; *t; t++) ;
|
||||
while ((t > s) && isspace((int)t[-1])) *--t = '\0';
|
||||
return copy(s);
|
||||
}
|
||||
|
||||
/* Make a plot the current one. This gets called by cp_usrset() when one
|
||||
* does a 'set curplot = name'.
|
||||
* va: ATTENTION: has unlinked old keyword-class-tree from keywords[CT_VECTOR]
|
||||
* (potentially memory leak)
|
||||
* va: ATTENTION: has unlinked old keyword-class-tree from keywords[CT_VECTOR] (potentially memory leak)
|
||||
*/
|
||||
|
||||
void
|
||||
plot_setcur(char *name)
|
||||
{
|
||||
void plot_setcur(char *name) {
|
||||
struct plot *pl;
|
||||
|
||||
if (cieq(name, "new")) {
|
||||
|
|
@ -964,8 +807,7 @@ plot_setcur(char *name)
|
|||
return;
|
||||
}
|
||||
for (pl = plot_list; pl; pl = pl->pl_next)
|
||||
if (plot_prefix(name, pl->pl_typename))
|
||||
break;
|
||||
if (plot_prefix(name, pl->pl_typename)) break;
|
||||
if (!pl) {
|
||||
fprintf(cp_err, "ERROR: no such plot named %s\n", name);
|
||||
return;
|
||||
|
|
@ -987,9 +829,7 @@ plot_setcur(char *name)
|
|||
* all this does is update the list and the variable $plots.
|
||||
*/
|
||||
|
||||
void
|
||||
plot_new(struct plot *pl)
|
||||
{
|
||||
void plot_new(struct plot *pl) {
|
||||
pl->pl_next = plot_list;
|
||||
plot_list = pl;
|
||||
}
|
||||
|
|
@ -1000,16 +840,13 @@ plot_new(struct plot *pl)
|
|||
* The data array is replaced with a new one that has the elements
|
||||
* in the proper order. Otherwise the transposition is done in place.
|
||||
*/
|
||||
void
|
||||
vec_transpose(struct dvec *v)
|
||||
{
|
||||
void vec_transpose(struct dvec *v) {
|
||||
int dim0, dim1, nummatrices;
|
||||
int i, j, k, joffset, koffset, blocksize;
|
||||
double *newreal, *oldreal;
|
||||
ngcomplex_t *newcomp, *oldcomp;
|
||||
|
||||
if (v->v_numdims < 2 || v->v_length <= 1)
|
||||
return;
|
||||
if (v->v_numdims < 2 || v->v_length <= 1) return;
|
||||
|
||||
dim0 = v->v_dims[v->v_numdims-1];
|
||||
dim1 = v->v_dims[v->v_numdims-2];
|
||||
|
|
@ -1037,17 +874,15 @@ vec_transpose(struct dvec *v)
|
|||
for (k = 0; k < nummatrices; k++) {
|
||||
joffset = 0;
|
||||
for (j = 0; j < dim0; j++) {
|
||||
for (i = 0; i < dim1; i++) {
|
||||
newreal[ koffset + joffset + i ] =
|
||||
oldreal[ koffset + i*dim0 + j ];
|
||||
}
|
||||
for (i = 0; i < dim1; i++) newreal[ koffset + joffset + i ] = oldreal[ koffset + i*dim0 + j ];
|
||||
joffset += dim1; /* joffset = j*dim0 */
|
||||
}
|
||||
koffset += blocksize; /* koffset = k*blocksize = k*dim0*dim1 */
|
||||
}
|
||||
tfree(oldreal);
|
||||
v->v_realdata = newreal;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
newcomp = TMALLOC(ngcomplex_t, v->v_length);
|
||||
oldcomp = v->v_compdata;
|
||||
koffset = 0;
|
||||
|
|
@ -1055,10 +890,8 @@ vec_transpose(struct dvec *v)
|
|||
joffset = 0;
|
||||
for (j = 0; j < dim0; j++) {
|
||||
for (i = 0; i < dim1; i++) {
|
||||
realpart(newcomp[ koffset + joffset + i ]) =
|
||||
realpart(oldcomp[ koffset + i*dim0 + j ]);
|
||||
imagpart(newcomp[ koffset + joffset + i ]) =
|
||||
imagpart(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 */
|
||||
}
|
||||
|
|
@ -1074,30 +907,26 @@ vec_transpose(struct dvec *v)
|
|||
* of 1-d vectors, linked together with v_link2. It is here so that plot
|
||||
* can do intelligent things.
|
||||
*/
|
||||
struct dvec *
|
||||
vec_mkfamily(struct dvec *v)
|
||||
{
|
||||
struct dvec * vec_mkfamily(struct dvec *v) {
|
||||
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;
|
||||
if (v->v_numdims < 2) return 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, 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 {
|
||||
}
|
||||
else {
|
||||
d = vecs = alloc(struct dvec);
|
||||
ZERO(d, struct dvec);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAXDIMS; i++)
|
||||
count[i] = 0;
|
||||
for (i = 0; i < MAXDIMS; i++) count[i] = 0;
|
||||
for (d = vecs, j = 0; d; j++, d = d->v_link2) {
|
||||
indexstring(count, v->v_numdims - 1, buf2);
|
||||
(void) sprintf(buf, "%s%s", v->v_name, buf2);
|
||||
|
|
@ -1118,7 +947,8 @@ vec_mkfamily(struct dvec *v)
|
|||
if (isreal(v)) {
|
||||
d->v_realdata = TMALLOC(double, size);
|
||||
bcopy(v->v_realdata + size*j, d->v_realdata, (size_t) size * sizeof(double));
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
d->v_compdata = TMALLOC(ngcomplex_t, size);
|
||||
bcopy(v->v_compdata + size*j, d->v_compdata, (size_t) size * sizeof(ngcomplex_t));
|
||||
}
|
||||
|
|
@ -1126,27 +956,21 @@ vec_mkfamily(struct dvec *v)
|
|||
(void) incindex(count, v->v_numdims - 1, v->v_dims, v->v_numdims);
|
||||
}
|
||||
|
||||
for (d = vecs; d; d = d->v_link2)
|
||||
vec_new(d);
|
||||
for (d = vecs; d; d = d->v_link2) vec_new(d);
|
||||
return vecs;
|
||||
}
|
||||
|
||||
/* This function will match "op" with "op1", but not "op1" with "op12". */
|
||||
bool
|
||||
plot_prefix(char *pre, char *str)
|
||||
{
|
||||
if (!*pre)
|
||||
return TRUE;
|
||||
bool plot_prefix(char *pre, char *str) {
|
||||
if (!*pre) return TRUE;
|
||||
|
||||
while (*pre && *str) {
|
||||
if (*pre != *str)
|
||||
break;
|
||||
if (*pre != *str) break;
|
||||
pre++;
|
||||
str++;
|
||||
}
|
||||
|
||||
if (*pre || (*str && isdigit((int)pre[-1])))
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
else return TRUE;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue