From 2a0317e6f40a4f2d5d20ccdaae82100f0ad4340a Mon Sep 17 00:00:00 2001 From: mifi Date: Wed, 13 Feb 2008 19:02:17 +0000 Subject: - added patch to Improving progress/error output for telnet & GDB monitor (thanks to Øyvind for the patch) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://svn.berlios.de/openocd/trunk@293 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/helper/command.c | 17 +++++++++++--- src/helper/log.c | 64 +++++++++++++++++++++++++++++++++++++++++++--------- src/helper/log.h | 30 ++++++++---------------- 3 files changed, 77 insertions(+), 34 deletions(-) (limited to 'src/helper') diff --git a/src/helper/command.c b/src/helper/command.c index afd86672..9f756d41 100644 --- a/src/helper/command.c +++ b/src/helper/command.c @@ -268,7 +268,7 @@ void command_print(command_context_t *context, char *format, ...) /* process format string */ /* TODO: possible bug. va_list is undefined after the first call to vsnprintf */ while (!buffer || (n = vsnprintf(buffer, size, format, ap)) >= size) - { + { /* increase buffer until it fits the whole string */ if (!(p = realloc(buffer, size += 4096))) { @@ -359,7 +359,7 @@ int find_and_run_command(command_context_t *context, command_t *commands, char * return ERROR_OK; } -int command_run_line(command_context_t *context, char *line) +static int command_run_line_inner(command_context_t *context, char *line) { int nwords; char *words[128] = {0}; @@ -399,6 +399,17 @@ int command_run_line(command_context_t *context, char *line) return retval; } +int command_run_line(command_context_t *context, char *line) +{ + int retval=command_run_line_inner(context, line); + // we don't want any dangling callbacks! + // + // Capturing output from logging is *very* loosly modeled on C/C++ exceptions. + // the capture must be set up at function entry and + // stops when the function call returns + log_setCallback(NULL, NULL); + return retval; +} int command_run_file(command_context_t *context, FILE *file, enum command_mode mode) { int retval = ERROR_OK; @@ -441,7 +452,7 @@ int command_run_file(command_context_t *context, FILE *file, enum command_mode m break; /* run line */ - if ((retval = command_run_line(context, cmd)) == ERROR_COMMAND_CLOSE_CONNECTION) + if ((retval = command_run_line_inner(context, cmd)) == ERROR_COMMAND_CLOSE_CONNECTION) break; } diff --git a/src/helper/log.c b/src/helper/log.c index 74407078..db0bc0bd 100644 --- a/src/helper/log.c +++ b/src/helper/log.c @@ -33,6 +33,16 @@ int debug_level = -1; static FILE* log_output; + +static void *privData; +static logCallback callback; + +void log_setCallback(logCallback c, void *p) +{ + callback=c; + privData=p; +} + static char *log_strings[4] = { "Error: ", @@ -56,25 +66,18 @@ void log_printf(enum log_levels level, const char *file, int line, const char *f fflush(log_output); va_end(args); -} -void short_log_printf(enum log_levels level, const char *format, ...) + if (callback) { - va_list args; - char buffer[512]; - - if (level > debug_level) - return; - va_start(args, format); - vsnprintf(buffer, 512, format, args); - fprintf(log_output, "%s %s\n", log_strings[level], buffer); - fflush(log_output); + callback(privData, file, line, function, format, args); va_end(args); } +} + /* change the current debug level on the fly * 0: only ERRORS * 1: + WARNINGS @@ -136,3 +139,42 @@ int log_init(struct command_context_s *cmd_ctx) return ERROR_OK; } + +int set_log_output(struct command_context_s *cmd_ctx, FILE *output) +{ + log_output=output; + return ERROR_OK; +} + +/* return allocated string w/printf() result */ +char *allocPrintf(const char *fmt, va_list ap) +{ + char *string=NULL; + int size=0; // start by 0 to exercise all the code paths. Need minimum 2 bytes to fit 1 char and 0 terminator. + int first=1; + for (;;) + { + if ((string==NULL)||(!first)) + { + size=size*2+2; + char *t=string; + string=realloc(string, size); + if (string==NULL) + { + if (t!=NULL) + free(t); + return NULL; + } + } + + int ret; + ret = vsnprintf(string, size, fmt, ap); + // NB! The result of the vsnprintf() might be an *EMPTY* string! + if ((ret>=0)&&((ret+1)