Made cp_enqvar() mode modular by adding a separate function to handle the case of a vector. Lists are more efficiently handled by moving common comparisons out of the loop over elements. The first argument of cp_enqvar() is changed from char * to const char * since the name of the variable being found is not altered by the function.
This commit is contained in:
parent
72801b1ab1
commit
ad970ae4e7
|
|
@ -21,14 +21,14 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
||||||
#include "control.h"
|
#include "control.h"
|
||||||
#include "spiceif.h"
|
#include "spiceif.h"
|
||||||
|
|
||||||
|
|
||||||
static void setdb(char *str);
|
|
||||||
|
|
||||||
bool ft_acctprint = FALSE, ft_noacctprint = FALSE, ft_listprint = FALSE;
|
bool ft_acctprint = FALSE, ft_noacctprint = FALSE, ft_listprint = FALSE;
|
||||||
bool ft_nodesprint = FALSE, ft_optsprint = FALSE, ft_noinitprint = FALSE;
|
bool ft_nodesprint = FALSE, ft_optsprint = FALSE, ft_noinitprint = FALSE;
|
||||||
bool ft_norefprint = FALSE;
|
bool ft_norefprint = FALSE;
|
||||||
bool ft_ngdebug = FALSE, ft_stricterror = FALSE;
|
bool ft_ngdebug = FALSE, ft_stricterror = FALSE;
|
||||||
|
|
||||||
|
static void setdb(char *str);
|
||||||
|
static struct variable *cp_enqvec_as_var(const char *vec_name,
|
||||||
|
int *p_f_found);
|
||||||
|
|
||||||
/* The user-supplied routine to query the address of a variable, if its
|
/* The user-supplied routine to query the address of a variable, if its
|
||||||
* name is given. This recognises the $&varname notation, and also
|
* name is given. This recognises the $&varname notation, and also
|
||||||
|
|
@ -36,87 +36,156 @@ bool ft_ngdebug = FALSE, ft_stricterror = FALSE;
|
||||||
* tbfreed is set to 1, if the variable is malloced here and may safely
|
* tbfreed is set to 1, if the variable is malloced here and may safely
|
||||||
* be freed, and is set to 0 if plot and circuit environment variables
|
* be freed, and is set to 0 if plot and circuit environment variables
|
||||||
* are returned.
|
* are returned.
|
||||||
|
*
|
||||||
|
* Note that if tbfreed is set to 1 that any changes will have no effect
|
||||||
|
* on the original variable. The variables that are copied are as follows:
|
||||||
|
* "curplotname", "curplottitle", "curplotdate", "curplot", and
|
||||||
|
* "plots".
|
||||||
|
*
|
||||||
|
* The $&v notation returns the values of a real vector v or the real part
|
||||||
|
* of a complex vector v. If there is only a single element, it is returned
|
||||||
|
* as a CP_REAL variable; otherwise a list is returned. In either case,
|
||||||
|
* tbfreed is set to 1 for this case.
|
||||||
*/
|
*/
|
||||||
|
struct variable *cp_enqvar(const char *word, int *tbfreed)
|
||||||
struct variable *
|
|
||||||
cp_enqvar(char *word, int *tbfreed)
|
|
||||||
{
|
{
|
||||||
struct dvec *d;
|
if (*word == '&') { /* The variable is a vector */
|
||||||
struct variable *vv;
|
return cp_enqvec_as_var(word + 1, tbfreed);
|
||||||
|
|
||||||
if (*word == '&') {
|
|
||||||
|
|
||||||
word++;
|
|
||||||
*tbfreed = 1;
|
|
||||||
|
|
||||||
d = vec_get(word);
|
|
||||||
if (!d)
|
|
||||||
return (NULL);
|
|
||||||
|
|
||||||
if (d->v_link2)
|
|
||||||
fprintf(cp_err,
|
|
||||||
"Warning: only one vector may be accessed with the $& notation.\n");
|
|
||||||
|
|
||||||
if (d->v_length == 1) {
|
|
||||||
double value = isreal(d)
|
|
||||||
? d->v_realdata[0]
|
|
||||||
: realpart(d->v_compdata[0]);
|
|
||||||
return var_alloc_real(copy(word), value, NULL);
|
|
||||||
} else {
|
|
||||||
struct variable *list = NULL;
|
|
||||||
int i;
|
|
||||||
for (i = d->v_length; --i >= 0;) {
|
|
||||||
double value = isreal(d)
|
|
||||||
? d->v_realdata[i]
|
|
||||||
: realpart(d->v_compdata[i]);
|
|
||||||
list = var_alloc_real(NULL, value, list);
|
|
||||||
}
|
|
||||||
return var_alloc_vlist(copy(word), list, NULL);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plot_cur) {
|
if (plot_cur) { /* a current plot is defined */
|
||||||
*tbfreed = 0;
|
struct variable *vv;
|
||||||
for (vv = plot_cur->pl_env; vv; vv = vv->va_next)
|
for (vv = plot_cur->pl_env; vv; vv = vv->va_next) {
|
||||||
if (eq(vv->va_name, word))
|
if (eq(vv->va_name, word)) {
|
||||||
return (vv);
|
*tbfreed = 0;
|
||||||
|
return vv;
|
||||||
|
}
|
||||||
|
} /* end of loop over variables of the current plot */
|
||||||
|
|
||||||
*tbfreed = 1;
|
*tbfreed = 1;
|
||||||
if (eq(word, "curplotname"))
|
/* Look for the variables beginning with curplot:
|
||||||
return var_alloc_string(copy(word), copy(plot_cur->pl_name), NULL);
|
* curplot, curplotname, curplottitle, and curplotdate */
|
||||||
if (eq(word, "curplottitle"))
|
if (strncmp(word, "curplot", 7) == 0) { /* begins with curplot */
|
||||||
return var_alloc_string(copy(word), copy(plot_cur->pl_title), NULL);
|
const char * const rest = word + 7;
|
||||||
if (eq(word, "curplotdate"))
|
if (*rest == '\0') { /* curplot */
|
||||||
return var_alloc_string(copy(word), copy(plot_cur->pl_date), NULL);
|
return var_alloc_string(copy(word),
|
||||||
if (eq(word, "curplot"))
|
copy(plot_cur->pl_typename), NULL);
|
||||||
return var_alloc_string(copy(word), copy(plot_cur->pl_typename), NULL);
|
}
|
||||||
if (eq(word, "plots")) {
|
else if (eq(rest, "name")) { /* curplotname */
|
||||||
|
return var_alloc_string(copy(word),
|
||||||
|
copy(plot_cur->pl_name), NULL);
|
||||||
|
}
|
||||||
|
else if (eq(rest, "title")) { /* curplottitle */
|
||||||
|
return var_alloc_string(copy(word),
|
||||||
|
copy(plot_cur->pl_title), NULL);
|
||||||
|
}
|
||||||
|
else if (eq(rest, "date")) { /* curplotname */
|
||||||
|
return var_alloc_string(copy(word),
|
||||||
|
copy(plot_cur->pl_date), NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eq(word, "plots")) { /* list of defined plots */
|
||||||
struct variable *list = NULL;
|
struct variable *list = NULL;
|
||||||
struct plot *pl;
|
struct plot *pl;
|
||||||
for (pl = plot_list; pl; pl = pl->pl_next)
|
for (pl = plot_list; pl; pl = pl->pl_next)
|
||||||
list = var_alloc_string(NULL, copy(pl->pl_typename), list);
|
list = var_alloc_string(NULL,
|
||||||
|
copy(pl->pl_typename), list);
|
||||||
return var_alloc_vlist(copy(word), list, NULL);
|
return var_alloc_vlist(copy(word), list, NULL);
|
||||||
}
|
}
|
||||||
|
} /* end of case that a current plot is defined */
|
||||||
|
|
||||||
|
*tbfreed = 0;
|
||||||
|
if (ft_curckt) { /* a current circuit is defined */
|
||||||
|
struct variable *vv;
|
||||||
|
for (vv = ft_curckt->ci_vars; vv; vv = vv->va_next) {
|
||||||
|
if (eq(vv->va_name, word)) {
|
||||||
|
return vv;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*tbfreed = 0;
|
return (struct variable *) NULL;
|
||||||
if (ft_curckt)
|
} /* end of function cp_enqvar */
|
||||||
for (vv = ft_curckt->ci_vars; vv; vv = vv->va_next)
|
|
||||||
if (eq(vv->va_name, word))
|
|
||||||
return (vv);
|
|
||||||
|
|
||||||
return (NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Return $plots, $curplot, $curplottitle, $curplotname, $curplotdate */
|
|
||||||
|
|
||||||
|
/* This functon returns the contents of a vector as a variable.
|
||||||
|
* If the vector has more than one element, it is returned as a list.
|
||||||
|
* The "shape" of the vector (number of dimensions and number of
|
||||||
|
* elements per dimension) has no effect on the returned list.
|
||||||
|
*
|
||||||
|
* Paramters
|
||||||
|
* vec_name: Name of vector
|
||||||
|
* p_f_found: Address to receive 1 if the vector was found and
|
||||||
|
* the corresponding variable must be freed and 0 if the vector
|
||||||
|
* was not found.
|
||||||
|
*
|
||||||
|
* Return values
|
||||||
|
* The address of the created list variable or NULL if none
|
||||||
|
* was found.
|
||||||
|
*
|
||||||
|
* Remarks
|
||||||
|
* The name of the created variable is the same as that of the vector.
|
||||||
|
*/
|
||||||
|
static struct variable *cp_enqvec_as_var(const char *vec_name,
|
||||||
|
int *p_f_found)
|
||||||
|
{
|
||||||
|
const struct dvec * const d = vec_get(vec_name); /* locate vector */
|
||||||
|
if (!d) { /* not found */
|
||||||
|
*p_f_found = 0;
|
||||||
|
return (struct variable *) NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Variables from vectors are always copies since variable
|
||||||
|
* structures must be created. */
|
||||||
|
*p_f_found = 1;
|
||||||
|
|
||||||
|
if (d->v_link2) {
|
||||||
|
/* The vector has other vectors linked to it via the v_link2
|
||||||
|
* pointer. That is OK, but a warning is printed that other
|
||||||
|
* vectors will not be returned */
|
||||||
|
fprintf(cp_err,
|
||||||
|
"Warning: only one vector may be accessed with the $& notation.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (d->v_length == 1) { /* 1 element, so return as a CP_REAL */
|
||||||
|
double value = isreal(d)
|
||||||
|
? d->v_realdata[0]
|
||||||
|
: realpart(d->v_compdata[0]);
|
||||||
|
return var_alloc_real(copy(vec_name), value, NULL);
|
||||||
|
}
|
||||||
|
else { /* >1 element, so return as a list of all CP_REALs */
|
||||||
|
struct variable *list = NULL;
|
||||||
|
if (isreal(d)) {
|
||||||
|
int i;
|
||||||
|
double *realdata = d->v_realdata;
|
||||||
|
for (i = d->v_length; --i >= 0;) {
|
||||||
|
list = var_alloc_real(NULL, realdata[i], list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
int i;
|
||||||
|
ngcomplex_t *compdata = d->v_compdata;
|
||||||
|
for (i = d->v_length; --i >= 0;) {
|
||||||
|
list = var_alloc_real(NULL, realpart(compdata[i]), list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return var_alloc_vlist(copy(vec_name), list, NULL);
|
||||||
|
}
|
||||||
|
} /* end of function cp_enqvec_as_var */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Return $plots, $curplot, $curplottitle, $curplotname, and
|
||||||
|
* $curplotdate as a linked list of variables in that order */
|
||||||
struct variable *
|
struct variable *
|
||||||
cp_usrvars(void)
|
cp_usrvars(void)
|
||||||
{
|
{
|
||||||
struct variable *v, *tv;
|
struct variable *v, *tv;
|
||||||
int tbfreed;
|
int tbfreed;
|
||||||
|
|
||||||
v = NULL;
|
v = (struct variable *) NULL;
|
||||||
|
|
||||||
if ((tv = cp_enqvar("plots", &tbfreed)) != NULL) {
|
if ((tv = cp_enqvar("plots", &tbfreed)) != NULL) {
|
||||||
tv->va_next = v;
|
tv->va_next = v;
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ extern void cp_periodic(void);
|
||||||
extern void ft_cpinit(void);
|
extern void ft_cpinit(void);
|
||||||
extern struct comm *cp_coms;
|
extern struct comm *cp_coms;
|
||||||
extern char *cp_program;
|
extern char *cp_program;
|
||||||
extern struct variable *cp_enqvar(char *word, int *tbfreed);
|
extern struct variable *cp_enqvar(const char *word, int *tbfreed);
|
||||||
extern struct variable *cp_usrvars(void);
|
extern struct variable *cp_usrvars(void);
|
||||||
int cp_usrset(struct variable *var, bool isset);
|
int cp_usrset(struct variable *var, bool isset);
|
||||||
extern void fatal(void);
|
extern void fatal(void);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue