Pavel Chromy

- multiple log listeners
- added OUTPUT() to replace printf
- fix formatting

git-svn-id: svn://svn.berlios.de/openocd/trunk@346 b42882b7-edfa-0310-969c-e2dbd0fdcd60
This commit is contained in:
oharboe 2008-02-25 17:32:53 +00:00
parent 375c5f85d2
commit 7f1944a478
7 changed files with 3684 additions and 3635 deletions

View File

@ -374,7 +374,7 @@ int find_and_run_command(command_context_t *context, command_t *commands, char *
return ERROR_OK;
}
static int command_run_line_inner(command_context_t *context, char *line)
int command_run_line(command_context_t *context, char *line)
{
int nwords;
char *words[128] = {0};
@ -414,17 +414,6 @@ static int command_run_line_inner(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;
@ -467,7 +456,7 @@ int command_run_file(command_context_t *context, FILE *file, enum command_mode m
break;
/* run line */
if ((retval = command_run_line_inner(context, cmd)) == ERROR_COMMAND_CLOSE_CONNECTION)
if ((retval = command_run_line(context, cmd)) == ERROR_COMMAND_CLOSE_CONNECTION)
break;
}

View File

@ -33,17 +33,10 @@
int debug_level = -1;
static FILE* log_output;
static log_callback_t *log_callbacks = NULL;
static void *privData;
static logCallback callback;
static time_t start;
void log_setCallback(logCallback c, void *p)
{
callback = c;
privData = p;
}
static char *log_strings[5] =
{
"User: ",
@ -59,12 +52,22 @@ void log_printf(enum log_levels level, const char *file, int line, const char *f
count++;
va_list args;
char buffer[512];
log_callback_t *cb;
if (level > debug_level)
return;
va_start(args, format);
vsnprintf(buffer, 512, format, args);
va_end(args);
if (level == LOG_OUTPUT)
{
/* do not prepend any headers, just print out what we were given and return */
fputs(buffer, log_output);
fflush(log_output);
return;
}
char *f = strrchr(file, '/');
if (f != NULL)
@ -84,15 +87,16 @@ void log_printf(enum log_levels level, const char *file, int line, const char *f
fflush(log_output);
va_end(args);
/* Never forward LOG_DEBUG, too verbose and they can be found in the log if need be */
if (callback && (level <= LOG_INFO))
if (level <= LOG_INFO)
{
for (cb = log_callbacks; cb; cb = cb->next)
{
va_start(args, format);
callback(privData, file, line, function, format, args);
cb->fn(cb->priv, file, line, function, format, args);
va_end(args);
}
}
}
/* change the current debug level on the fly
@ -164,8 +168,51 @@ int set_log_output(struct command_context_s *cmd_ctx, FILE *output)
return ERROR_OK;
}
/* add/remove log callback handler */
int log_add_callback(log_callback_fn fn, void *priv)
{
log_callback_t *cb;
/* prevent the same callback to be registered more than once, just for sure */
for (cb = log_callbacks; cb; cb = cb->next)
{
if (cb->fn == fn && cb->priv == priv)
return ERROR_INVALID_ARGUMENTS;
}
/* alloc memory, it is safe just to return in case of an error, no need for the caller to check this */
if ((cb = malloc(sizeof(log_callback_t))) == NULL)
return ERROR_BUF_TOO_SMALL;
/* add item to the beginning of the linked list */
cb->fn = fn;
cb->priv = priv;
cb->next = log_callbacks;
log_callbacks = cb;
return ERROR_OK;
}
int log_remove_callback(log_callback_fn fn, void *priv)
{
log_callback_t *cb, **p;
for (p = &log_callbacks; cb = *p; p = &(*p)->next)
{
if (cb->fn == fn && cb->priv == priv)
{
*p = cb->next;
free(cb);
return ERROR_OK;
}
}
/* no such item */
return ERROR_INVALID_ARGUMENTS;
}
/* return allocated string w/printf() result */
char *allocPrintf(const char *fmt, va_list ap)
char *alloc_printf(const char *fmt, va_list ap)
{
char *string = NULL;

View File

@ -36,6 +36,7 @@
*/
enum log_levels
{
LOG_OUTPUT = -2,
LOG_USER = -1,
LOG_ERROR = 0,
LOG_WARNING = 1,
@ -50,10 +51,20 @@ extern int log_register_commands(struct command_context_s *cmd_ctx);
extern int log_init(struct command_context_s *cmd_ctx);
extern int set_log_output(struct command_context_s *cmd_ctx, FILE *output);
typedef void (*logCallback)(void *priv, const char *file, int line,
typedef void (*log_callback_fn)(void *priv, const char *file, int line,
const char *function, const char *format, va_list args);
extern void log_setCallback(logCallback callback, void *priv);
typedef struct log_callback_s
{
log_callback_fn fn;
void *priv;
struct log_callback_s *next;
} log_callback_t;
extern int log_add_callback(log_callback_fn fn, void *priv);
extern int log_remove_callback(log_callback_fn fn, void *priv);
char *alloc_printf(const char *fmt, va_list ap);
extern int debug_level;
@ -85,6 +96,11 @@ extern int debug_level;
log_printf (LOG_USER, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
#define OUTPUT(expr ...) \
do { \
log_printf (LOG_OUTPUT, __FILE__, __LINE__, __FUNCTION__, expr); \
} while(0)
/* general failures
* error codes < 100
@ -94,6 +110,4 @@ extern int debug_level;
#define ERROR_NO_CONFIG_FILE (-2)
#define ERROR_BUF_TOO_SMALL (-3)
char *allocPrintf(const char *fmt, va_list ap);
#endif /* LOG_H */

View File

@ -113,13 +113,13 @@ int parse_cmdline_args(struct command_context_s *cmd_ctx, int argc, char *argv[]
if (help_flag)
{
printf("Open On-Chip Debugger\n(c) 2005 by Dominic Rath\n\n");
printf("--help | -h\tdisplay this help\n");
printf("--file | -f\tuse configuration file <name>\n");
printf("--search | -s\tdir to search for config files and scripts.\n");
printf("--debug | -d\tset debug level <0-3>\n");
printf("--log_output | -l\tredirect log output to file <name>\n");
printf("--command | -c\trun <command>\n");
OUTPUT("Open On-Chip Debugger\n(c) 2005 by Dominic Rath\n\n");
OUTPUT("--help | -h\tdisplay this help\n");
OUTPUT("--file | -f\tuse configuration file <name>\n");
OUTPUT("--search | -s\tdir to search for config files and scripts.\n");
OUTPUT("--debug | -d\tset debug level <0-3>\n");
OUTPUT("--log_output | -l\tredirect log output to file <name>\n");
OUTPUT("--command | -c\trun <command>\n");
exit(-1);
}

View File

@ -303,7 +303,7 @@ int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
else if (reply == '-')
{
/* Stop sending output packets for now */
log_setCallback(NULL, NULL);
log_remove_callback(gdb_log_callback, connection);
WARNING("negative reply, retrying");
}
else if (reply == 0x3)
@ -316,7 +316,7 @@ int gdb_put_packet_inner(connection_t *connection, char *buffer, int len)
else if (reply == '-')
{
/* Stop sending output packets for now */
log_setCallback(NULL, NULL);
log_remove_callback(gdb_log_callback, connection);
WARNING("negative reply, retrying");
}
else
@ -579,7 +579,7 @@ int gdb_target_callback_event_handler(struct target_s *target, enum target_event
if (gdb_connection->frontend_state == TARGET_RUNNING)
{
/* stop forwarding log packets! */
log_setCallback(NULL, NULL);
log_remove_callback(gdb_log_callback, connection);
if (gdb_connection->ctrl_c)
{
@ -678,7 +678,7 @@ int gdb_connection_closed(connection_t *connection)
}
target_unregister_event_callback(gdb_target_callback_event_handler, connection);
log_setCallback(NULL, NULL);
log_remove_callback(gdb_log_callback, connection);
return ERROR_OK;
}
@ -1459,7 +1459,7 @@ int gdb_query_packet(connection_t *connection, target_t *target, char *packet, i
cmd[(packet_size - 6)/2] = 0x0;
/* We want to print all debug output to GDB connection */
log_setCallback(gdb_log_callback, connection);
log_add_callback(gdb_log_callback, connection);
target_call_timer_callbacks();
command_run_line(cmd_ctx, cmd);
free(cmd);
@ -1808,7 +1808,7 @@ static void gdb_log_callback(void *priv, const char *file, int line,
return;
}
char *t = allocPrintf(format, args);
char *t = alloc_printf(format, args);
if (t == NULL)
return;
@ -1886,7 +1886,7 @@ int gdb_input_inner(connection_t *connection)
* forward log output until the target is halted */
gdb_connection_t *gdb_con = connection->priv;
gdb_con->frontend_state = TARGET_RUNNING;
log_setCallback(gdb_log_callback, connection);
log_add_callback(gdb_log_callback, connection);
gdb_step_continue_packet(connection, target, packet, packet_size);
}
break;

View File

@ -92,7 +92,7 @@ void telnet_log_callback(void *priv, const char *file, int line,
const char *function, const char *format, va_list args)
{
connection_t *connection = priv;
char *t = allocPrintf(format, args);
char *t = alloc_printf(format, args);
char *t2;
if (t == NULL)
return;
@ -108,7 +108,6 @@ void telnet_log_callback(void *priv, const char *file, int line,
t2=endline+1;
} while (endline);
free(t);
}
@ -292,18 +291,18 @@ int telnet_input(connection_t *connection)
continue;
}
log_setCallback(telnet_log_callback, connection);
log_add_callback(telnet_log_callback, connection);
t_con->suppress_prompt = 1;
if ((retval = command_run_line(command_context, t_con->line)) != ERROR_OK)
{
retval = command_run_line(command_context, t_con->line);
log_remove_callback(telnet_log_callback, connection);
t_con->suppress_prompt = 0;
if (retval == ERROR_COMMAND_CLOSE_CONNECTION)
{
return ERROR_SERVER_REMOTE_CLOSED;
}
}
t_con->suppress_prompt = 0;
/* Save only non-blank lines in the history */
if (t_con->line_size > 0)