From ee2eb66c4504d86178c989641a8a5a1caff778d2 Mon Sep 17 00:00:00 2001 From: mhx Date: Fri, 1 Jan 2016 20:32:22 +0100 Subject: [PATCH] Fix variables so that they behave as described (or intended) in the ngspice-26plus manual. --- src/frontend/variable.c | 248 +++++++++++++++++++++------------------- src/frontend/vectors.c | 193 +++++++++++++++++++------------ 2 files changed, 252 insertions(+), 189 deletions(-) diff --git a/src/frontend/variable.c b/src/frontend/variable.c index 03523cdf5..8ade25583 100644 --- a/src/frontend/variable.c +++ b/src/frontend/variable.c @@ -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); diff --git a/src/frontend/vectors.c b/src/frontend/vectors.c index cbca13509..da100a145 100644 --- a/src/frontend/vectors.c +++ b/src/frontend/vectors.c @@ -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);