From befcc6cf3da9cd4d545e95f685d992e4070d8722 Mon Sep 17 00:00:00 2001 From: Stefan Rueger Date: Fri, 10 May 2024 18:38:28 +0100 Subject: [PATCH] Provide and use str_ccprintf() for temporary strings in closed-circuit space --- src/avrftdi.c | 15 ++++++--------- src/libavrdude.h | 7 ++++++- src/strutil.c | 45 ++++++++++++++++++++++++++++++++++----------- src/term.c | 13 ++++--------- 4 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/avrftdi.c b/src/avrftdi.c index 8adede7d..271c933c 100644 --- a/src/avrftdi.c +++ b/src/avrftdi.c @@ -176,22 +176,19 @@ static int set_frequency(avrftdi_t* ftdi, uint32_t freq) } if (divisor < 0) { - char *f = str_frq(freq, 6), *h = str_frq(clock/2.0, 6); - pmsg_warning("frequency %s too high, resetting to %s\n", f, h); - mmt_free(f); mmt_free(h); + pmsg_warning("frequency %s too high, resetting to %s\n", + str_ccfrq(freq, 6), str_ccfrq(clock/2.0, 6)); divisor = 0; } if (divisor > 65535) { - char *f = str_frq(freq, 6), *l = str_frq(clock/2.0 / 65536, 6); - pmsg_warning("frequency %s too low, resetting to %s\n", f, l); - mmt_free(f); mmt_free(l); + pmsg_warning("frequency %s too low, resetting to %s\n", + str_ccfrq(freq, 6), str_ccfrq(clock/2.0 / 65536, 6)); divisor = 65535; } - char *f = str_frq(clock/2.0 / (divisor + 1), 6); - imsg_notice(" - frequency %s (clock divisor %d = 0x%04x)\n", f, divisor, divisor); - mmt_free(f); + imsg_notice(" - frequency %s (clock divisor %d = 0x%04x)\n", + str_ccfrq(clock/2.0 / (divisor + 1), 6), divisor, divisor); *ptr++ = TCK_DIVISOR; *ptr++ = (uint8_t)(divisor & 0xff); diff --git a/src/libavrdude.h b/src/libavrdude.h index 9f49fc7d..5705e049 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -1478,6 +1478,11 @@ char *str_sprintf(const char *fmt, ...) __attribute__ ((format (printf, 1, 2))) #endif ; +const char *str_ccprintf(const char *fmt, ...) +#if defined(__GNUC__) + __attribute__ ((format (printf, 1, 2))) +#endif +; char *str_fgets(FILE *fp, const char **errpp); char *str_lc(char *s); char *str_uc(char *s); @@ -1498,7 +1503,7 @@ void str_freedata(Str2data *sd); unsigned long long int str_int(const char *str, int type, const char **errpp); int str_membuf(const char *str, int type, unsigned char *buf, int size, const char **errpp); char *str_nexttok(char *buf, const char *delim, char **next); -char *str_frq(double f, int n); +const char *str_ccfrq(double f, int n); int str_levenshtein(const char *str1, const char *str2, int swap, int subst, int add, int del); size_t str_weighted_damerau_levenshtein(const char *str1, const char *str2); diff --git a/src/strutil.c b/src/strutil.c index f05f9461..58bf49e0 100644 --- a/src/strutil.c +++ b/src/strutil.c @@ -255,6 +255,33 @@ char *str_sprintf(const char *fmt, ...) { return p; } +// Return a string in closed-circuit space with the sprintf() result +const char *str_ccprintf(const char *fmt, ...) { + int size = 0, avail = sizeof cx->avr_space - AVR_SAFETY_MARGIN; + va_list ap; + + // Compute size + va_start(ap, fmt); + size = vsnprintf(NULL, size, fmt, ap); + va_end(ap); + + if(size < 0) + return ""; + + size++; // For terminating '\0' + if(size > avail) + size = avail; + char *p = avr_cc_buffer(size); + + va_start(ap, fmt); + size = vsnprintf(p, size, fmt, ap); + va_end(ap); + + if(size < 0) + *p = 0; + + return p; +} // Reads a potentially long line and returns it in a mmt_malloc'd buffer char *str_fgets(FILE *fp, const char **errpp) { @@ -877,7 +904,6 @@ void str_freedata(Str2data *sd) { */ unsigned long long int str_int(const char *str, int type, const char **errpp) { - char *tofree; const char *err = NULL; Str2data *sd = NULL; unsigned long long int ret = 0ULL; @@ -919,20 +945,17 @@ unsigned long long int str_int(const char *str, int type, const char **errpp) { if(signd == STR_SIGNED) { // Strictly signed if(sd->ll < smin[lds] || sd->ll > smax[lds]) { - err = cache_string(tofree=str_sprintf("out of int%d range", 1<<(3+lds))); - mmt_free(tofree); + err = cache_string(str_ccprintf("out of int%d range", 1<<(3+lds))); goto finished; } } else if(signd == STR_UNSIGNED) { // Strictly unsigned are out of range if u and -u are if(sd->ull > umax[lds] && ~sd->ull+1 > umax[lds]) { - err = cache_string(tofree=str_sprintf("out of uint%d range", 1<<(3+lds))); - mmt_free(tofree); + err = cache_string(str_ccprintf("out of uint%d range", 1<<(3+lds))); goto finished; } } else { // Neither strictly signed or unsigned if((sd->ll < smin[lds] || sd->ll > smax[lds]) && sd->ull > umax[lds] && ~sd->ull+1 > umax[lds]) { - err = cache_string(tofree=str_sprintf("out of int%d and uint%d range", 1<<(3+lds), 1<<(3+lds))); - mmt_free(tofree); + err = cache_string(str_ccprintf("out of int%d and uint%d range", 1<<(3+lds), 1<<(3+lds))); goto finished; } } @@ -1028,14 +1051,14 @@ char *str_nexttok(char *buf, const char *delim, char **next) { return (char *) q; } -// Return mmt_malloc'd string for frequency with n significant digits and xHz unit -char *str_frq(double f, int n) { +// Return string for frequency with n significant digits and xHz unit in closed-circuit space +const char *str_ccfrq(double f, int n) { struct { double fq; const char *pre; } prefix[] = {{1e9, "G"}, {1e6, "M"}, {1e3, "k"},}; for(size_t i = 0; i < sizeof prefix/sizeof*prefix; i++) if(f >= prefix[i].fq) - return str_sprintf("%.*g %sHz", n, f/prefix[i].fq, prefix[i].pre); - return str_sprintf("%.*g Hz", n, f); + return str_ccprintf("%.*g %sHz", n, f/prefix[i].fq, prefix[i].pre); + return str_ccprintf("%.*g Hz", n, f); } /* diff --git a/src/term.c b/src/term.c index d39d7850..54852be0 100644 --- a/src/term.c +++ b/src/term.c @@ -965,15 +965,13 @@ typedef struct { // Context parameters to be passed to functions // Cache the contents of the fuse and lock bits memories that a particular Configitem is involved in static int getfusel(const PROGRAMMER *pgm, const AVRPART *p, Fusel_t *fl, const Cfg_t *cci, const char **errpp) { const char *err = NULL; - char *tofree; int islock; islock = str_starts(cci->memstr, "lock"); if((islock && cci->t->memoffset != 0) || (!islock && (cci->t->memoffset < 0 || cci->t->memoffset >= (int) (sizeof fl->fuses/sizeof*fl->fuses)))) { - err = cache_string(tofree = str_sprintf("%s's %s has invalid memoffset %d", p->desc, cci->memstr, cci->t->memoffset)); - mmt_free(tofree); + err = cache_string(str_ccprintf("%s's %s has invalid memoffset %d", p->desc, cci->memstr, cci->t->memoffset)); goto back; } @@ -991,22 +989,19 @@ static int getfusel(const PROGRAMMER *pgm, const AVRPART *p, Fusel_t *fl, const const AVRMEM *mem = avr_locate_mem(p, cci->memstr); if(!mem) { - err = cache_string(tofree = str_sprintf("memory %s not defined for part %s", cci->memstr, p->desc)); - mmt_free(tofree); + err = cache_string(str_ccprintf("memory %s not defined for part %s", cci->memstr, p->desc)); goto back; } if((islock && mem->size != 4 && mem->size != 1) || (!islock && mem->size != 2 && mem->size != 1)) { - err = cache_string(tofree = str_sprintf("%s's %s memory has unexpected size %d", p->desc, mem->desc, mem->size)); - mmt_free(tofree); + err = cache_string(str_ccprintf("%s's %s memory has unexpected size %d", p->desc, mem->desc, mem->size)); goto back; } fl_t m = {.i = 0}; for(int i=0; isize; i++) if(led_read_byte(pgm, p, mem, i, m.b+i) < 0) { - err = cache_string(tofree = str_sprintf("cannot read %s's %s memory", p->desc, mem->desc)); - mmt_free(tofree); + err = cache_string(str_ccprintf("cannot read %s's %s memory", p->desc, mem->desc)); goto back; }