Provide and use str_ccprintf() for temporary strings in closed-circuit space

This commit is contained in:
Stefan Rueger
2024-05-10 18:38:28 +01:00
parent 500ab6a460
commit befcc6cf3d
4 changed files with 50 additions and 30 deletions

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);
}
/*

View File

@@ -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; i<mem->size; 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;
}