Cleaned up code to locate a vector in a plot by name. The code was made more modular, and special names like allv are handled more efficiently
This commit is contained in:
parent
8285bd107a
commit
ba29c514f9
|
|
@ -23,6 +23,17 @@ Author: 1985 Wayne A. Christopher, U. C. Berkeley CAD Group
|
|||
#include "ngspice/dstring.h"
|
||||
#include "plotting/plotting.h"
|
||||
|
||||
|
||||
static struct dvec *findvec_all(struct plot *pl);
|
||||
static struct dvec *findvec_allv(struct plot *pl);
|
||||
static struct dvec *findvec_alli(struct plot *pl);
|
||||
static struct dvec *findvec_ally(struct plot *pl);
|
||||
static struct dvec *find_permanent_vector_by_name(
|
||||
NGHASHPTR pl_lookup_table, char *name);
|
||||
static enum ALL_TYPE_ENUM get_all_type(const char *word);
|
||||
static bool plot_prefix(const char *pre, const char *str);
|
||||
|
||||
|
||||
#ifdef XSPICE
|
||||
/* gtri - begin - add function prototype for EVTfindvec */
|
||||
struct dvec *EVTfindvec(char *node);
|
||||
|
|
@ -30,8 +41,7 @@ struct dvec *EVTfindvec(char *node);
|
|||
#endif
|
||||
|
||||
|
||||
static void
|
||||
vec_rebuild_lookup_table(struct plot *pl)
|
||||
static void vec_rebuild_lookup_table(struct plot *pl)
|
||||
{
|
||||
if (pl->pl_lookup_table) { /* existing table */
|
||||
nghash_empty(pl->pl_lookup_table, NULL, NULL);
|
||||
|
|
@ -63,112 +73,107 @@ vec_rebuild_lookup_table(struct plot *pl)
|
|||
ds_free(&dbuf);
|
||||
}
|
||||
|
||||
pl->pl_lookup_valid = TRUE;
|
||||
pl->pl_lookup_valid = TRUE; /* now lookup table valid */
|
||||
} /* end of function vec_rebuild_lookup_table */
|
||||
|
||||
|
||||
|
||||
enum ALL_TYPE_ENUM {
|
||||
ALL_TYPE_NONE,
|
||||
ALL_TYPE_ALL,
|
||||
ALL_TYPE_ALLV,
|
||||
ALL_TYPE_ALLI,
|
||||
ALL_TYPE_ALLY
|
||||
};
|
||||
|
||||
|
||||
/* Efficient identification of "all", "allv", "alli", "ally", and anything
|
||||
* else */
|
||||
static enum ALL_TYPE_ENUM get_all_type(const char *word)
|
||||
{
|
||||
/* Check for start of "all" */
|
||||
if (tolower(word[0] != 'a')) {
|
||||
return ALL_TYPE_NONE;
|
||||
}
|
||||
if (tolower(word[1] != 'l')) {
|
||||
return ALL_TYPE_NONE;
|
||||
}
|
||||
if (tolower(word[2] != 'l')) {
|
||||
return ALL_TYPE_NONE;
|
||||
}
|
||||
|
||||
/* It may be some type of all */
|
||||
switch (tolower(word[3])) {
|
||||
case '\0':
|
||||
return ALL_TYPE_ALL;
|
||||
case 'v':
|
||||
if (word[4] == '\0') {
|
||||
return ALL_TYPE_ALLV;
|
||||
}
|
||||
else {
|
||||
return ALL_TYPE_NONE;
|
||||
}
|
||||
case 'i':
|
||||
if (word[4] == '\0') {
|
||||
return ALL_TYPE_ALLI;
|
||||
}
|
||||
else {
|
||||
return ALL_TYPE_NONE;
|
||||
}
|
||||
case 'y':
|
||||
if (word[4] == '\0') {
|
||||
return ALL_TYPE_ALLY;
|
||||
}
|
||||
else {
|
||||
return ALL_TYPE_NONE;
|
||||
}
|
||||
default:
|
||||
return ALL_TYPE_NONE;
|
||||
} /* end of swith over char after "all" */
|
||||
} /* end of function get_all_type */
|
||||
|
||||
|
||||
|
||||
/* 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) {
|
||||
struct dvec *d, *newv = NULL, *end = NULL, *v;
|
||||
|
||||
if (pl == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (cieq(word, "all")) {
|
||||
for (d = pl->pl_dvecs; d; d = d->v_next) {
|
||||
if (d->v_flags & VF_PERMANENT) {
|
||||
if (d->v_link2) {
|
||||
v = vec_copy(d);
|
||||
vec_new(v);
|
||||
} else {
|
||||
v = d;
|
||||
}
|
||||
if (end)
|
||||
end->v_link2 = v;
|
||||
else
|
||||
newv = v;
|
||||
end = v;
|
||||
}
|
||||
}
|
||||
return (newv);
|
||||
static struct dvec *findvec(char *word, struct plot *pl)
|
||||
{
|
||||
/* If no plot, cannot find */
|
||||
if (pl == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (cieq(word, "allv")) {
|
||||
for (d = pl->pl_dvecs; d; d = d->v_next) {
|
||||
if ((d->v_flags & VF_PERMANENT) && (d->v_type == SV_VOLTAGE)) {
|
||||
if (d->v_link2) {
|
||||
v = vec_copy(d);
|
||||
vec_new(v);
|
||||
} else {
|
||||
v = d;
|
||||
}
|
||||
if (end)
|
||||
end->v_link2 = v;
|
||||
else
|
||||
newv = v;
|
||||
end = v;
|
||||
}
|
||||
}
|
||||
return (newv);
|
||||
/* Identify and handle special cases all, allv, alli, ally */
|
||||
switch (get_all_type(word)) {
|
||||
case ALL_TYPE_ALL:
|
||||
return findvec_all(pl);
|
||||
case ALL_TYPE_ALLV:
|
||||
return findvec_allv(pl);
|
||||
case ALL_TYPE_ALLI:
|
||||
return findvec_alli(pl);
|
||||
case ALL_TYPE_ALLY:
|
||||
return findvec_ally(pl);
|
||||
default: /* case ALL_TYPE_NOT_ALL -- not some type of ALL */
|
||||
break;
|
||||
}
|
||||
|
||||
if (cieq(word, "alli")) {
|
||||
for (d = pl->pl_dvecs; d; d = d->v_next) {
|
||||
if ((d->v_flags & VF_PERMANENT) && (d->v_type == SV_CURRENT)) {
|
||||
if (d->v_link2) {
|
||||
v = vec_copy(d);
|
||||
vec_new(v);
|
||||
} else {
|
||||
v = d;
|
||||
}
|
||||
if (end)
|
||||
end->v_link2 = v;
|
||||
else
|
||||
newv = v;
|
||||
end = v;
|
||||
}
|
||||
}
|
||||
return (newv);
|
||||
}
|
||||
|
||||
if (cieq(word, "ally")) {
|
||||
for (d = pl->pl_dvecs; d; d = d->v_next) {
|
||||
if ((d->v_flags & VF_PERMANENT) && (!cieq(d->v_name, pl->pl_scale->v_name))) {
|
||||
if (d->v_link2) {
|
||||
v = vec_copy(d);
|
||||
vec_new(v);
|
||||
} else {
|
||||
v = d;
|
||||
}
|
||||
if (end)
|
||||
end->v_link2 = v;
|
||||
else
|
||||
newv = v;
|
||||
end = v;
|
||||
}
|
||||
}
|
||||
return (newv);
|
||||
}
|
||||
|
||||
if (!pl->pl_lookup_valid)
|
||||
/* The find is not for one of the "all" cases */
|
||||
if (!pl->pl_lookup_valid) {
|
||||
/* Table lookup not valid, so rebuild to make valid */
|
||||
vec_rebuild_lookup_table(pl);
|
||||
}
|
||||
|
||||
DS_CREATE(dbuf, 200); /* make dynamic buffer */
|
||||
if (ds_cat_str_case(&dbuf, word, ds_case_lower) != DS_E_OK) {
|
||||
controlled_exit(-1);
|
||||
}
|
||||
char * const lower_name = ds_get_buf(&dbuf);
|
||||
NGHASHPTR pl_lookup_table = pl->pl_lookup_table;
|
||||
struct dvec *d = find_permanent_vector_by_name(pl_lookup_table,
|
||||
lower_name);
|
||||
|
||||
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 the vector was not using the lowercased name, try finding it as
|
||||
* v(lowercased name) */
|
||||
if (!d) {
|
||||
ds_clear(&dbuf);
|
||||
bool f_ok = ds_cat_str(&dbuf, "v(") == DS_E_OK;
|
||||
|
|
@ -179,12 +184,7 @@ findvec(char *word, struct plot *pl) {
|
|||
controlled_exit(-1);
|
||||
}
|
||||
char * const node_name = ds_get_buf(&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;
|
||||
}
|
||||
d = find_permanent_vector_by_name(pl_lookup_table, node_name);
|
||||
}
|
||||
|
||||
ds_free(&dbuf);
|
||||
|
|
@ -192,8 +192,9 @@ findvec(char *word, struct plot *pl) {
|
|||
#ifdef XSPICE
|
||||
/* gtri - begin - Add processing for getting event-driven vector */
|
||||
|
||||
if (!d)
|
||||
if (!d) {
|
||||
d = EVTfindvec(word);
|
||||
}
|
||||
|
||||
/* gtri - end - Add processing for getting event-driven vector */
|
||||
#endif
|
||||
|
|
@ -207,11 +208,72 @@ findvec(char *word, struct plot *pl) {
|
|||
|
||||
|
||||
|
||||
/* Macro taking a function name and vector filter as arguments that
|
||||
* generates the function that applies the filter */
|
||||
#define FINDVEC_ALL_GEN(fun_name, filter)\
|
||||
static struct dvec *fun_name(struct plot *pl)\
|
||||
{\
|
||||
struct dvec *d, *newv = NULL, *end = NULL, *v;\
|
||||
for (d = pl->pl_dvecs; d; d = d->v_next) {\
|
||||
if (filter) {\
|
||||
if (d->v_link2) {\
|
||||
v = vec_copy(d);\
|
||||
vec_new(v);\
|
||||
}\
|
||||
else {\
|
||||
v = d;\
|
||||
}\
|
||||
if (end) {\
|
||||
end->v_link2 = v;\
|
||||
}\
|
||||
else {\
|
||||
newv = v;\
|
||||
}\
|
||||
end = v;\
|
||||
}\
|
||||
} /* end of loop over vectors in plot */\
|
||||
\
|
||||
return newv;\
|
||||
} /* end of function */
|
||||
|
||||
/* Generate the functions for each filter */
|
||||
FINDVEC_ALL_GEN(findvec_all, d->v_flags & VF_PERMANENT)
|
||||
FINDVEC_ALL_GEN(findvec_allv,
|
||||
(d->v_flags & VF_PERMANENT) && (d->v_type == SV_VOLTAGE))
|
||||
FINDVEC_ALL_GEN(findvec_alli,
|
||||
(d->v_flags & VF_PERMANENT) && (d->v_type == SV_CURRENT))
|
||||
FINDVEC_ALL_GEN(findvec_ally,
|
||||
(d->v_flags & VF_PERMANENT) &&
|
||||
(!cieq(d->v_name, pl->pl_scale->v_name)))
|
||||
|
||||
|
||||
|
||||
/* Find a permanent vector with the given name */
|
||||
static struct dvec *find_permanent_vector_by_name(
|
||||
NGHASHPTR pl_lookup_table, char *name)
|
||||
{
|
||||
struct dvec *d;
|
||||
|
||||
/* Find the first vector with the given name and then find others
|
||||
* until one having the VF_PERMANENT flag set is found. */
|
||||
for (d = nghash_find(pl_lookup_table, name);
|
||||
d;
|
||||
d = nghash_find_again(pl_lookup_table, name)) {
|
||||
if (d->v_flags & VF_PERMANENT) {
|
||||
/* A "permanent" vector was found with the name, so done */
|
||||
return d;
|
||||
}
|
||||
} /* end of loop over vectors in the plot having this name */
|
||||
|
||||
return (struct dvec *) NULL; /* not found */
|
||||
} /* end of function find_permanent_vector_by_name */
|
||||
|
||||
|
||||
|
||||
/* 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;
|
||||
|
||||
|
|
@ -373,38 +435,44 @@ vec_remove(const char *name)
|
|||
* it checks for pre-defined vectors.
|
||||
*/
|
||||
|
||||
struct dvec *
|
||||
vec_fromplot(char *word, struct plot *plot) {
|
||||
struct dvec *d;
|
||||
char buf[BSIZE_SP], buf2[BSIZE_SP], cc, *s;
|
||||
|
||||
d = findvec(word, plot);
|
||||
if (!d) {
|
||||
(void) strcpy(buf, word);
|
||||
strtolower(buf);
|
||||
d = findvec(buf, plot);
|
||||
}
|
||||
if (!d) {
|
||||
(void) strcpy(buf, word);
|
||||
strtoupper(buf);
|
||||
d = findvec(buf, plot);
|
||||
struct dvec *vec_fromplot(char *word, struct plot *plot) {
|
||||
struct dvec *d = findvec(word, plot);
|
||||
if (d != (struct dvec *) NULL) {
|
||||
return d;
|
||||
}
|
||||
|
||||
/* 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 = '\0';
|
||||
if (prefix("i(", word) || prefix("I(", word)) {
|
||||
/* Spice dependency... */
|
||||
(void) sprintf(buf2, "%s#branch", buf);
|
||||
(void) strcpy(buf, buf2);
|
||||
/* Consider forms I(node) and i(node) -> node#branch */
|
||||
if (tolower(word[0]) != (int) 'i') { /* Not i of I.* */
|
||||
return (struct dvec *) NULL;
|
||||
}
|
||||
|
||||
if (word[1] != '(') { /* Not i or I(.* */
|
||||
return (struct dvec *) NULL;
|
||||
}
|
||||
|
||||
{
|
||||
const char * const p_node = word + 2;
|
||||
const char *p_end = p_node + strlen(p_node);
|
||||
if (*--p_end != ')') { /* Not i or I then '(' with a closing ')' */
|
||||
return (struct dvec *) NULL;
|
||||
}
|
||||
d = findvec(buf, plot);
|
||||
}
|
||||
|
||||
return (d);
|
||||
}
|
||||
/* Form is correct, so see if node#branch exists */
|
||||
DS_CREATE(ds, 100);
|
||||
if (ds_cat_mem(&ds, p_node, p_end - p_node) != DS_E_OK) {
|
||||
controlled_exit(-1);
|
||||
}
|
||||
if (ds_cat_str(&ds, "#branch") != DS_E_OK) {
|
||||
controlled_exit(-1);
|
||||
}
|
||||
|
||||
d = findvec(ds_get_buf(&ds), plot);
|
||||
ds_free(&ds);
|
||||
|
||||
return d;
|
||||
}
|
||||
} /* end of function vec_fromplot */
|
||||
|
||||
|
||||
|
||||
/* This is the main lookup routine for names. The possible types of names are:
|
||||
|
|
@ -484,7 +552,7 @@ vec_get(const char *vec_name) {
|
|||
}
|
||||
}
|
||||
|
||||
if (!d && (*word == SPECCHAR)) {
|
||||
if (!d && (*word == SPECCHAR)) { /* "@" */
|
||||
/* This is a special quantity... */
|
||||
if (ft_nutmeg) {
|
||||
fprintf(cp_err,
|
||||
|
|
@ -579,30 +647,37 @@ vec_get(const char *vec_name) {
|
|||
*/
|
||||
struct variable *nv;
|
||||
|
||||
/* Count the number of nodes in the list */
|
||||
i = 0;
|
||||
for (nv = vv->va_vlist; nv; nv = nv->va_next)
|
||||
for (nv = vv->va_vlist; nv; nv = nv->va_next) {
|
||||
i++;
|
||||
}
|
||||
|
||||
dvec_realloc(d, i, NULL);
|
||||
dvec_realloc(d, i, NULL); /* Resize to # nodes */
|
||||
|
||||
/* Step through the list again, setting values this time */
|
||||
i = 0;
|
||||
for (nv = vv->va_vlist; nv; nv = nv->va_next)
|
||||
for (nv = vv->va_vlist; nv; nv = nv->va_next) {
|
||||
d->v_realdata[i++] = nv->va_real;
|
||||
}
|
||||
|
||||
/* To be able to identify the vector to represent
|
||||
* belongs to a special "conunto" and should be printed in a
|
||||
* special way.
|
||||
*/
|
||||
d->v_dims[1] = 1;
|
||||
} else if (vv->va_type == CP_NUM) { /* Variable is an integer */
|
||||
}
|
||||
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 */
|
||||
}
|
||||
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 {
|
||||
/* Real data set
|
||||
* When you print a model @ [all]
|
||||
* Just print numerical values, not the string
|
||||
|
|
@ -632,8 +707,9 @@ vec_get(const char *vec_name) {
|
|||
}
|
||||
nv = nv->va_next;
|
||||
|
||||
if (!nv)
|
||||
if (!nv) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* To distinguish those does not take anything for print screen to
|
||||
|
|
@ -648,7 +724,7 @@ vec_get(const char *vec_name) {
|
|||
tfree(wd);
|
||||
vec_new(d);
|
||||
tfree(whole);
|
||||
return (d);
|
||||
return d;
|
||||
}
|
||||
|
||||
tfree(wd);
|
||||
|
|
@ -676,27 +752,29 @@ plot_docoms(wordlist *wl)
|
|||
}
|
||||
|
||||
|
||||
/* Create a copy of a vector. */
|
||||
|
||||
struct dvec *
|
||||
vec_copy(struct dvec *v) {
|
||||
/* Create a copy of a vector. The vector is not "permananent" */
|
||||
struct dvec *vec_copy(struct dvec *v) {
|
||||
struct dvec *nv;
|
||||
int i;
|
||||
|
||||
if (!v)
|
||||
return (NULL);
|
||||
if (!v) {
|
||||
return (struct dvec *) NULL;
|
||||
}
|
||||
|
||||
/* Make a copy with the VF_PERMANENT bit cleared in v_flags */
|
||||
nv = dvec_alloc(copy(v->v_name),
|
||||
v->v_type,
|
||||
v->v_flags & ~VF_PERMANENT,
|
||||
v->v_length, NULL);
|
||||
|
||||
if (isreal(v))
|
||||
memcpy(nv->v_realdata, v->v_realdata,
|
||||
/* Copy the data to the new vector */
|
||||
if (isreal(v)) {
|
||||
(void) memcpy(nv->v_realdata, v->v_realdata,
|
||||
sizeof(double) * (size_t) v->v_length);
|
||||
else
|
||||
memcpy(nv->v_compdata, v->v_compdata,
|
||||
}
|
||||
else {
|
||||
(void) memcpy(nv->v_compdata, v->v_compdata,
|
||||
sizeof(ngcomplex_t) * (size_t) v->v_length);
|
||||
}
|
||||
|
||||
nv->v_minsignal = v->v_minsignal;
|
||||
nv->v_maxsignal = v->v_maxsignal;
|
||||
|
|
@ -719,23 +797,26 @@ 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];
|
||||
|
||||
/* Copy defined dimensions */
|
||||
(void) memcpy(nv->v_dims, v->v_dims, v->v_numdims * sizeof *v->v_dims);
|
||||
|
||||
nv->v_plot = v->v_plot;
|
||||
nv->v_next = NULL;
|
||||
nv->v_link2 = NULL;
|
||||
nv->v_scale = v->v_scale;
|
||||
|
||||
return (nv);
|
||||
}
|
||||
return nv;
|
||||
} /* end of function vec_copy */
|
||||
|
||||
|
||||
|
||||
/* 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 * plot_alloc(char *name)
|
||||
{
|
||||
struct plot *pl = TMALLOC(struct plot, 1), *tp;
|
||||
char *s;
|
||||
struct ccom *ccom;
|
||||
|
|
@ -841,71 +922,93 @@ 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))
|
||||
/* Do not free if NULL or name is NULL. The second possibility is a
|
||||
* special case */
|
||||
if ((v == NULL) || (v->v_name == NULL)) {
|
||||
return;
|
||||
pl = v->v_plot;
|
||||
}
|
||||
struct plot * const 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 at head of list of vectors in the plot, make the next one
|
||||
* the new head of the list */
|
||||
if (pl->pl_dvecs == v) {
|
||||
pl->pl_dvecs = v->v_next;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
/* Not at head of list so must locate and fix links */
|
||||
struct dvec *lv = pl->pl_dvecs;
|
||||
if (lv)
|
||||
for (; lv->v_next; lv = lv->v_next)
|
||||
if (lv->v_next == v)
|
||||
if (lv) { /* the plot has at least one vector */
|
||||
for ( ; lv->v_next; lv = lv->v_next) {
|
||||
if (lv->v_next == v) { /* found prev vector */
|
||||
break;
|
||||
if (lv && lv->v_next)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If found in the list, link prev vector to next one */
|
||||
if (lv && lv->v_next) {
|
||||
lv->v_next = v->v_next;
|
||||
else
|
||||
fprintf(cp_err,
|
||||
}
|
||||
else {
|
||||
(void) fprintf(cp_err,
|
||||
"vec_free: Internal Error: %s not in plot\n",
|
||||
v->v_name);
|
||||
}
|
||||
}
|
||||
} /* end of case that vector being freed is not at head of list */
|
||||
|
||||
if (pl->pl_scale == v) {
|
||||
if (pl->pl_dvecs)
|
||||
if (pl->pl_dvecs) {
|
||||
pl->pl_scale = pl->pl_dvecs; /* Random one... */
|
||||
else
|
||||
}
|
||||
else {
|
||||
pl->pl_scale = NULL;
|
||||
}
|
||||
}
|
||||
} /* end of case that have a plot */
|
||||
|
||||
dvec_free(v);
|
||||
} /* end of function vec_free_x */
|
||||
|
||||
|
||||
|
||||
/* This function returns TRUE if every element of v and every element of
|
||||
* every vector linked to v through v_link2 is zero and FALSE otherwise. */
|
||||
bool vec_iszero(const struct dvec *v)
|
||||
{
|
||||
for (; v; v = v->v_link2) { /* step through linked vectors */
|
||||
if (isreal(v)) { /* current vector is real */
|
||||
const int n = v->v_length;
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (v->v_realdata[i] != 0.0) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else { /* current vector is complex */
|
||||
const int n = v->v_length;
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (realpart(v->v_compdata[i]) != 0.0) {
|
||||
return FALSE;
|
||||
}
|
||||
if (imagpart(v->v_compdata[i]) != 0.0) {
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dvec_free(v);
|
||||
}
|
||||
return TRUE; /* every value tested was 0.0 */
|
||||
} /* end of function vec_iszero */
|
||||
|
||||
|
||||
/*
|
||||
* return TRUE if every vector element is zero
|
||||
*/
|
||||
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
/* This is something we do in a few places... Since vectors get copied a lot,
|
||||
* we can't just compare pointers to tell if two vectors are 'really' the same.
|
||||
|
|
@ -962,15 +1065,20 @@ vec_basename(struct dvec *v)
|
|||
}
|
||||
|
||||
/* get address of plot named 'name' */
|
||||
struct plot *
|
||||
get_plot(char* name) {
|
||||
struct plot *get_plot(char* name)
|
||||
|
||||
|
||||
{
|
||||
struct plot *pl;
|
||||
for (pl = plot_list; pl; pl = pl->pl_next)
|
||||
if (plot_prefix(name, pl->pl_typename))
|
||||
for (pl = plot_list; pl; pl = pl->pl_next) {
|
||||
if (plot_prefix(name, pl->pl_typename)) {
|
||||
return pl;
|
||||
}
|
||||
}
|
||||
fprintf(cp_err, "Error: no such plot named %s\n", name);
|
||||
return NULL;
|
||||
}
|
||||
return (struct plot *) NULL;
|
||||
} /* end of function get_plot */
|
||||
|
||||
|
||||
|
||||
/* Make a plot the current one. This gets called by cp_usrset() when one
|
||||
|
|
@ -1177,16 +1285,16 @@ vec_mkfamily(struct dvec *v) {
|
|||
|
||||
|
||||
/* This function will match "op" with "op1", but not "op1" with "op12". */
|
||||
|
||||
bool
|
||||
plot_prefix(char *pre, char *str)
|
||||
static bool plot_prefix(const char *pre, const char *str)
|
||||
{
|
||||
if (!*pre)
|
||||
return (TRUE);
|
||||
if (!*pre) { /* prefix is empty string */
|
||||
return TRUE; /* Define "" to be prefix */
|
||||
}
|
||||
|
||||
while (*pre && *str) {
|
||||
if (*pre != *str)
|
||||
if (*pre != *str) { /* stop at first mismatch */
|
||||
break;
|
||||
}
|
||||
pre++;
|
||||
str++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -336,7 +336,7 @@ extern int ft_typnum(char *);
|
|||
|
||||
/* vectors.c */
|
||||
|
||||
extern bool vec_iszero(struct dvec *v);
|
||||
extern bool vec_iszero(const struct dvec *v);
|
||||
extern bool vec_eq(struct dvec *v1, struct dvec *v2);
|
||||
extern int plot_num;
|
||||
extern struct dvec *vec_fromplot(char *word, struct plot *plot);
|
||||
|
|
@ -363,7 +363,6 @@ extern void plot_setcur(char *name);
|
|||
extern struct plot *get_plot(char* name);
|
||||
extern void plot_new(struct plot *pl);
|
||||
extern char *vec_basename(struct dvec *v);
|
||||
extern bool plot_prefix(char *pre, char *str);
|
||||
extern void vec_transpose(struct dvec *v);
|
||||
|
||||
/* main.c */
|
||||
|
|
|
|||
Loading…
Reference in New Issue