* Copyright (C) 2005 by Dominic Rath *
* Dominic.Rath@gmx.de *
* *
- * Copyright (C) 2007,2008 Øyvind Harboe *
+ * Copyright (C) 2007-2010 Øyvind Harboe *
* oyvind.harboe@zylin.com *
* *
* Copyright (C) 2008 by Spencer Oliver *
#include "time_support.h"
// @todo the inclusion of server.h here is a layering violation
-#include "server.h"
+#include <server/server.h>
#include <stdarg.h>
}
}
-void log_try(void)
-{
- log_forward_count++;
-}
-
-void log_catch(void)
-{
- assert(log_forward_count>0);
- log_forward_count--;
-}
-
-void log_rethrow(void)
-{
- log_catch();
- if (log_forward_count==0)
- {
- struct store_log_forward *log;
-
- log = log_head;
- while (log != NULL)
- {
- log_forward(log->file, log->line, log->function, log->string);
-
- struct store_log_forward *t=log;
- log = log->next;
-
- free((void *)t->file);
- free((void *)t->function);
- free((void *)t->string);
- free(t);
-
- }
-
- log_head = NULL;
- }
-}
-
-
/* The log_puts() serves to somewhat different goals:
*
* - logging
if (f != NULL)
file = f + 1;
- if (strchr(string, '\n') != NULL)
+ if (strlen(string) > 0)
{
if (debug_level >= LOG_LVL_DEBUG)
{
#endif
string);
}
- else if (server_use_pipes == 0)
+ else
{
/* if we are using gdb through pipes then we do not want any output
* to the pipe otherwise we get repeated strings */
- if (strcmp(string, "\n") != 0)
- {
- /* print human readable output - but skip empty lines */
- fprintf(log_output, "%s%s",
- (level > LOG_LVL_USER)?log_strings[level + 1]:"", string);
- }
+ fprintf(log_output, "%s%s",
+ (level > LOG_LVL_USER)?log_strings[level + 1]:"", string);
}
} else
{
- /* only entire lines are logged. Otherwise it's
- * single chars intended for the log callbacks. */
+ /* Empty strings are sent to log callbacks to keep e.g. gdbserver alive, here we do nothing. */
}
fflush(log_output);
va_end(ap);
}
-/* change the current debug level on the fly
- * 0: only ERRORS
- * 1: + WARNINGS
- * 2: + INFORMATIONAL MSGS
- * 3: + DEBUG MSGS
- */
COMMAND_HANDLER(handle_debug_level_command)
{
if (CMD_ARGC == 1)
{
- unsigned new_level;
- COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], new_level);
- debug_level = MIN(new_level, LOG_LVL_DEBUG);
- }
- else if (CMD_ARGC > 1)
- return ERROR_COMMAND_SYNTAX_ERROR;
-
- if (debug_level >= LOG_LVL_DEBUG && server_use_pipes == 1)
- {
- /* if we are enabling debug info then we need to write to a log file
- * otherwise the pipe will get full and cause issues with gdb */
- FILE* file = fopen("openocd.log", "w");
- if (file)
+ int new_level;
+ COMMAND_PARSE_NUMBER(int, CMD_ARGV[0], new_level);
+ if ((debug_level > LOG_LVL_DEBUG) || (new_level < LOG_LVL_SILENT))
{
- log_output = file;
- LOG_WARNING("enabling log output as we are using pipes");
+ LOG_ERROR("level must be between %d and %d", LOG_LVL_SILENT, LOG_LVL_DEBUG);
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
+ debug_level = new_level;
}
+ else if (CMD_ARGC > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
command_print(CMD_CTX, "debug_level: %i", debug_level);
return ERROR_OK;
}
+static struct command_registration log_command_handlers[] = {
+ {
+ .name = "log_output",
+ .handler = handle_log_output_command,
+ .mode = COMMAND_ANY,
+ .help = "redirect logging to a file (default: stderr)",
+ .usage = "file_name",
+ },
+ {
+ .name = "debug_level",
+ .handler = handle_debug_level_command,
+ .mode = COMMAND_ANY,
+ .help = "Sets the verbosity level of debugging output. "
+ "0 shows errors only; 1 adds warnings; "
+ "2 (default) adds other info; 3 adds debugging.",
+ .usage = "number",
+ },
+ COMMAND_REGISTRATION_DONE
+};
+
int log_register_commands(struct command_context *cmd_ctx)
{
- start = timeval_ms();
- register_command(cmd_ctx, NULL, "log_output", handle_log_output_command,
- COMMAND_ANY, "redirect logging to <file> (default: stderr)");
- register_command(cmd_ctx, NULL, "debug_level", handle_debug_level_command,
- COMMAND_ANY, "adjust debug level <0-3>");
-
- return ERROR_OK;
+ return register_commands(cmd_ctx, NULL, log_command_handlers);
}
-int log_init(struct command_context *cmd_ctx)
+void log_init(void)
{
- /* set defaults for daemon configuration, if not set by cmdline or cfgfile */
+ /* set defaults for daemon configuration,
+ * if not set by cmdline or cfgfile */
if (debug_level == -1)
debug_level = LOG_LVL_INFO;
- if (log_output == NULL)
+ char *debug_env = getenv("OPENOCD_DEBUG_LEVEL");
+ if (NULL != debug_env)
{
- log_output = stderr;
+ int value;
+ int retval = parse_int(debug_env, &value);
+ if (ERROR_OK == retval &&
+ debug_level >= LOG_LVL_SILENT &&
+ debug_level <= LOG_LVL_DEBUG)
+ {
+ debug_level = value;
+ }
}
- start = last_time = timeval_ms();
+ if (log_output == NULL)
+ log_output = stderr;
- return ERROR_OK;
+ start = last_time = timeval_ms();
}
int set_log_output(struct command_context *cmd_ctx, FILE *output)
for (cb = log_callbacks; cb; cb = cb->next)
{
if (cb->fn == fn && cb->priv == priv)
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
/* alloc memory, it is safe just to return in case of an error, no need for the caller to check this */
}
/* no such item */
- return ERROR_INVALID_ARGUMENTS;
+ return ERROR_COMMAND_SYNTAX_ERROR;
}
/* return allocated string w/printf() result */