diff --git a/src/frontend/dvec.c b/src/frontend/dvec.c index 6da1d44a3..f837f17e3 100644 --- a/src/frontend/dvec.c +++ b/src/frontend/dvec.c @@ -7,35 +7,51 @@ dvec_alloc(char *name, int type, short flags, int length, void *storage) { struct dvec *rv = TMALLOC(struct dvec, 1); - if (!rv) + /* If the allocation failed, return NULL as a failure flag. + * As of 2019-03, TMALLOC will not return on failure, so this check is + * redundant, but it may be useful if it is decided to allow the + * allocation functions to return NULL on failure and handle recovery + * by the calling functions */ + if (!rv) { return NULL; + } + /* Set all fields to 0 */ ZERO(rv, struct dvec); + /* Set information on the vector from parameters. Note that storage for + * the name string belongs to the dvec when this function returns. */ rv->v_name = name; rv->v_type = type; rv->v_flags = flags; rv->v_length = length; rv->v_alloc_length = length; - if (!length) { + if (length == 0) { /* Redundant due to ZERO() call above */ rv->v_realdata = NULL; rv->v_compdata = NULL; - } else if (flags & VF_REAL) { + } + else if (flags & VF_REAL) { + /* Vector consists of real data. Use the supplied storage if given + * or allocate if not */ rv->v_realdata = storage ? (double *) storage : TMALLOC(double, length); rv->v_compdata = NULL; - } else if (flags & VF_COMPLEX) { + } + else if (flags & VF_COMPLEX) { + /* Vector holds complex data. Perform actions as for real data */ rv->v_realdata = NULL; rv->v_compdata = storage ? (ngcomplex_t *) storage : TMALLOC(ngcomplex_t, length); } + /* Set remaining fields to none/unknown. Again not required due to + * the ZERO() call */ rv->v_plot = NULL; rv->v_scale = NULL; - rv->v_numdims = 0; + rv->v_numdims = 0; /* Really "unknown" */ return rv; } diff --git a/src/frontend/parser/complete.c b/src/frontend/parser/complete.c index 59b1252ce..794ae3b3a 100644 --- a/src/frontend/parser/complete.c +++ b/src/frontend/parser/complete.c @@ -73,8 +73,8 @@ static void printem(wordlist *wl); #endif static wordlist *cctowl(struct ccom *cc, bool sib); -static struct ccom *clookup(register char *word, struct ccom **dd, bool pref, - bool create); +static struct ccom *clookup(register const char *word, struct ccom **dd, bool pref, + bool create); /* MW. I need top node in cdelete */ static void cdelete(struct ccom *node, struct ccom **top); @@ -515,7 +515,7 @@ cp_destroy_keywords(void) /* Remove a keyword from the database. */ void -cp_remkword(int kw_class, char *word) +cp_remkword(int kw_class, const char *word) { struct ccom *cc; @@ -583,7 +583,7 @@ throwaway(struct ccom *dbase) */ static struct ccom * -clookup(register char *word, struct ccom **dd, bool pref, bool create) +clookup(register const char *word, struct ccom **dd, bool pref, bool create) { register struct ccom *place = *dd, *tmpc; int ind = 0, i; diff --git a/src/frontend/vectors.c b/src/frontend/vectors.c index f58d61141..dc1001f1b 100644 --- a/src/frontend/vectors.c +++ b/src/frontend/vectors.c @@ -339,7 +339,7 @@ plot_add(struct plot *pl) /* Remove a vector from the database, if it is there. */ void -vec_remove(char *name) +vec_remove(const char *name) { struct dvec *ov; @@ -769,12 +769,20 @@ vec_new(struct dvec *d) plot_cur->pl_scale = d; if (!d->v_plot) d->v_plot = plot_cur; + + /* This code appears to be a patch for incorrectly specified vectors */ if (d->v_numdims < 1) { d->v_numdims = 1; d->v_dims[0] = d->v_length; } - d->v_next = d->v_plot->pl_dvecs; - d->v_plot->pl_dvecs = d; + + { + /* Make this vector the first plot vector and link the old first plot + * vector via its next pointer */ + struct plot *v_plot = d->v_plot; + d->v_next = v_plot->pl_dvecs; + v_plot->pl_dvecs = d; + } } diff --git a/src/include/ngspice/cpextern.h b/src/include/ngspice/cpextern.h index 314d6ae5f..fd079bb84 100644 --- a/src/include/ngspice/cpextern.h +++ b/src/include/ngspice/cpextern.h @@ -43,7 +43,7 @@ extern void cp_ccom(wordlist *wlist, char *buf, bool esc); extern void cp_ccon(bool on); extern void cp_ccrestart(bool kwords); extern void cp_remcomm(char *word); -extern void cp_remkword(int kw_class, char *word); +extern void cp_remkword(int kw_class, const char *word); extern void cp_destroy_keywords(void); extern wordlist *cp_cctowl(struct ccom *stuff); diff --git a/src/include/ngspice/fteext.h b/src/include/ngspice/fteext.h index 699090c6b..d8b5aafd6 100644 --- a/src/include/ngspice/fteext.h +++ b/src/include/ngspice/fteext.h @@ -357,7 +357,7 @@ extern void vec_gc(void); extern void ft_loadfile(char *file); extern void vec_new(struct dvec *d); extern void plot_docoms(wordlist *wl); -extern void vec_remove(char *name); +extern void vec_remove(const char *name); extern void plot_setcur(char *name); extern struct plot *get_plot(char* name); extern void plot_new(struct plot *pl); diff --git a/src/misc/string.c b/src/misc/string.c index 5279c4a43..ed89a3582 100644 --- a/src/misc/string.c +++ b/src/misc/string.c @@ -75,22 +75,34 @@ tvprintf(const char *fmt, va_list args) if (nchars == -1) { // compatibility to old implementations size *= 2; - } else if (size < nchars + 1) { - size = nchars + 1; - } else { + } + else if (nchars >= size) { + /* Output was truncated. Returned value is the number of chars + * that would have been written if the buffer were large enough + * excluding the terminiating null. */ + size = nchars + 1; /* min required allocation size */ + } + else { /* String formatted OK */ break; } + /* Allocate a larger buffer */ if (p == buf) p = TMALLOC(char, size); else p = TREALLOC(char, p, size); } + /* Return the formatted string, making a copy on the heap if the + * stack's buffer (buf) contains the string */ return (p == buf) ? copy(p) : p; -} +} /* end of function tvprintf */ + +/* This function returns an allocation containing the string formatted + * according to fmt and the variadic argument list provided. It is a wrapper + * around tvprintf() which processes the argumens as a va_list. */ char * tprintf(const char *fmt, ...) { @@ -102,7 +114,7 @@ tprintf(const char *fmt, ...) va_end(ap); return rv; -} +} /* end of function tprintf */ /* Determine whether sub is a substring of str. */