From fd8704d982d8a8630d8f0a584d9116ab766ae43c Mon Sep 17 00:00:00 2001 From: Joerg Wunsch Date: Sun, 10 Mar 2024 22:55:50 +0100 Subject: [PATCH] Implement avrdude_message2() from main.c This is eventually to be replaced by a Python callback. Right now, use what main.c is using. --- src/libavrdude.i | 106 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 3 deletions(-) diff --git a/src/libavrdude.i b/src/libavrdude.i index 1985ba7a..58622d12 100644 --- a/src/libavrdude.i +++ b/src/libavrdude.i @@ -25,9 +25,109 @@ int avrdude_message(int msglvl, const char *format, ...) return rc; } -int avrdude_message2(FILE *fp, int lno, const char *file, const char *func, int msgmode, int msglvl, const char *format, ...) { - printf("avrdude_message2() called\n"); - return 0; + +// This is the version from main.c +// Should be handled by something overridable from Python +int avrdude_message2(FILE *fp, int lno, const char *file, + const char *func, int msgmode, int msglvl, + const char *format, ...) +{ + int rc = 0; + va_list ap; + + static struct { // Memorise whether last print ended at beginning of line + FILE *fp; + int bol; // Are we at the beginning of a line for this fp stream? + } bols[5+1]; // Cater for up to 5 different FILE pointers plus one catch-all + + size_t bi = 0; // bi is index to bols[] array + for(bi=0; bi < sizeof bols/sizeof*bols -1; bi++) { // Note the -1, so bi is valid after loop + if(!bols[bi].fp) { // First free space + bols[bi].fp = fp; // Insert fp in first free space + bols[bi].bol = 1; // Assume beginning of line on first use + } + if(bols[bi].fp == fp) + break; + } + + if(msglvl <= MSG_ERROR) // Serious error? Free progress bars (if any) + report_progress(1, -1, NULL); + + if(msgmode & MSG2_FLUSH) { + fflush(stdout); + fflush(stderr); + } + + // Reduce effective verbosity level by number of -q above one when printing to stderr + if ((quell_progress < 2 || fp != stderr? verbose: verbose+1-quell_progress) >= msglvl) { + if(msgmode & MSG2_PROGNAME) { + if(!bols[bi].bol) + fprintf(fp, "\n"); + fprintf(fp, "%s", progname); + if(verbose >= MSG_NOTICE && (msgmode & MSG2_FUNCTION)) + fprintf(fp, " %s()", func); + if(verbose >= MSG_DEBUG && (msgmode & MSG2_FILELINE)) { + const char *pr = strrchr(file, '/'); // Only print basename +#if defined (WIN32) + if(!pr) + pr = strrchr(file, '\\'); +#endif + pr = pr? pr+1: file; + fprintf(fp, " [%s:%d]", pr, lno); + } + if(msgmode & MSG2_TYPE) + fprintf(fp, " level %d", msglvl); + fprintf(fp, ": "); + bols[bi].bol = 0; + } else if(msgmode & MSG2_INDENT1) { + fprintf(fp, "%*s", (int) strlen(progname)+1, ""); + bols[bi].bol = 0; + } else if(msgmode & MSG2_INDENT2) { + fprintf(fp, "%*s", (int) strlen(progname)+2, ""); + bols[bi].bol = 0; + } + + // Vertical tab at start of format string is a conditional new line + if(*format == '\v') { + format++; + if(!bols[bi].bol) { + fprintf(fp, "\n"); + bols[bi].bol = 1; + } + } + + // Figure out whether this print will leave us at beginning of line + + // Determine required size first + va_start(ap, format); + rc = vsnprintf(NULL, 0, format, ap); + va_end(ap); + + if(rc < 0) // Some errror? + return 0; + + rc++; // Accommodate terminating nul + char *p = cfg_malloc(__func__, rc); + va_start(ap, format); + rc = vsnprintf(p, rc, format, ap); + va_end(ap); + + if(rc < 0) { + free(p); + return 0; + } + + if(*p) { + fprintf(fp, "%s", p); // Finally: print! + bols[bi].bol = p[strlen(p)-1] == '\n'; + } + free(p); + } + + if(msgmode & MSG2_FLUSH) + fflush(fp); + + return rc; } PROGRAMMER *cast_programmer(LNODEID p) {