From 9d15a167e74293f025deba7dc560e964afcaf20e Mon Sep 17 00:00:00 2001 From: Stefan Rueger Date: Fri, 10 May 2024 13:03:05 +0100 Subject: [PATCH] Provide avr_cc_buffer(n) for allocating n bytes in temporary buffer --- src/avr.c | 31 ++++++++++++++++++++++--------- src/libavrdude.h | 6 +++++- 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/avr.c b/src/avr.c index 039e488e..53a7b395 100644 --- a/src/avr.c +++ b/src/avr.c @@ -1442,6 +1442,26 @@ int avr_put_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int cycles) { } +// Return temporary string buffer with n bytes from a closed-circuit space +char *avr_cc_buffer(size_t n) { + if(n > sizeof cx->avr_space) { + pmsg_error("requested size %lu too big for cx->avr_space[%lu] (change source)\n", + (unsigned long) n, (unsigned long) sizeof cx->avr_space); + cx->avr_s = cx->avr_space; + n = sizeof cx->avr_space; + } else if(!cx->avr_s) + cx->avr_s = cx->avr_space; + + cx->avr_s += strlen(cx->avr_s) + 1; // Move behind string from last call + + // Rewind if too little space left + if((size_t) (cx->avr_s - cx->avr_space) > sizeof cx->avr_space - n) + cx->avr_s = cx->avr_space; + + memset(cx->avr_s, 0, n); + return cx->avr_s; +} + /* * Returns a string in closed-circuit space with a list of programming * modes encoded in pm; variant creates the list in subtly different ways: @@ -1451,13 +1471,7 @@ int avr_put_cycle_count(const PROGRAMMER *pgm, const AVRPART *p, int cycles) { * If pm is 0 (no programming modes) returns "0" */ static char *prog_modes_string(int pm, int variant) { - // Return string is overwritten after a few calls - if(!cx->avr_s) - cx->avr_s = cx->avr_space; - char *type = cx->avr_s + strlen(cx->avr_s) + 1; - // Overwrite space once only 128 bytes left - if((size_t) (type - cx->avr_space) > sizeof cx->avr_space - 128) - type = cx->avr_space; + char *type = avr_cc_buffer(256); // Longest returned string has 142 chars const char *spm = variant? "SPM": "bootloader"; const char *sep = variant == 2? " | PM_": ", "; @@ -1491,8 +1505,7 @@ static char *prog_modes_string(int pm, int variant) { if(pm & PM_aWire) strcat(strcat(type, sep), "aWire"); - cx->avr_s = type + (type[1] == 0? 0: skip); - return cx->avr_s; + return type + (type[1] == 0? 0: skip); } char *avr_prog_modes(int pm) { // PM_SPM prints bootloader diff --git a/src/libavrdude.h b/src/libavrdude.h index 6df3788f..9b25c496 100644 --- a/src/libavrdude.h +++ b/src/libavrdude.h @@ -1515,6 +1515,8 @@ int terminal_line(const PROGRAMMER *pgm, const AVRPART *p, const char *line); char *terminal_get_input(const char *prompt); void terminal_setup_update_progress(void); +char *avr_cc_buffer(size_t n); + #ifdef __cplusplus } #endif @@ -1530,11 +1532,13 @@ void terminal_setup_update_progress(void); */ typedef struct { + // Closed-circuit space for returning strings in a persistent buffer + char *avr_s, avr_space[8192]; + // Static variables from avr.c int avr_disableffopt; // Disables trailing 0xff flash optimisation uint64_t avr_epoch; // Epoch for avr_ustimestamp() int avr_epoch_init; // Whether above epoch is initialised - char avr_space[1024], *avr_s; // Closed-circuit space for avr+prog_modes() int avr_last_percent; // Last valid percentage for report_progress() double avr_start_time; // Start time in s of report_progress() activity