log_callback_t -> struct log_callback
[openocd.git] / src / helper / log.c
index 9bfe4d11c56f81c7c0fb9cc9bbf6c4aa59cb9cbb..1724beccbb61de7b40acbba74e7a01fa17d4028c 100644 (file)
@@ -45,7 +45,7 @@
 int debug_level = -1;
 
 static FILE* log_output;
-static log_callback_t *log_callbacks = NULL;
+static struct log_callback *log_callbacks = NULL;
 
 static long long last_time;
 static long long current_time;
@@ -64,6 +64,95 @@ static char *log_strings[5] =
 
 static int count = 0;
 
+
+static struct store_log_forward * log_head = NULL;
+static int log_forward_count = 0;
+
+struct store_log_forward
+{
+       struct store_log_forward * next;
+       const char * file;
+       int line;
+       const char * function;
+       const char * string;
+};
+
+/* either forward the log to the listeners or store it for possible forwarding later */
+static void log_forward(const char *file, int line, const char *function, const char *string)
+{
+       if (log_forward_count==0)
+       {
+               struct log_callback *cb, *next;
+               cb = log_callbacks;
+               /* DANGER!!!! the log callback can remove itself!!!! */
+               while (cb)
+               {
+                       next = cb->next;
+                       cb->fn(cb->priv, file, line, function, string);
+                       cb = next;
+               }
+       } else
+       {
+               struct store_log_forward *log = malloc(sizeof (struct store_log_forward));
+               log->file = strdup(file);
+               log->line = line;
+               log->function = strdup(function);
+               log->string = strdup(string);
+               log->next = NULL;
+               if (log_head==NULL)
+                       log_head = log;
+               else
+               {
+                       /* append to tail */
+                       struct store_log_forward * t;
+                       t = log_head;
+                       while (t->next!=NULL)
+                       {
+                               t = t->next;
+                       }
+                       t->next = log;
+               }
+       }
+}
+
+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
@@ -131,18 +220,11 @@ static void log_puts(enum log_levels level, const char *file, int line, const ch
        /* Never forward LOG_LVL_DEBUG, too verbose and they can be found in the log if need be */
        if (level <= LOG_LVL_INFO)
        {
-               log_callback_t *cb, *next;
-               cb = log_callbacks;
-               /* DANGER!!!! the log callback can remove itself!!!! */
-               while (cb)
-               {
-                       next = cb->next;
-                       cb->fn(cb->priv, file, line, function, string);
-                       cb = next;
-               }
+               log_forward(file, line, function, string);
        }
 }
 
+
 void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
 {
        char *string;
@@ -192,14 +274,12 @@ void log_printf_lf(enum log_levels level, const char *file, int line, const char
  * 2: + INFORMATIONAL MSGS
  * 3: + DEBUG MSGS
  */
-int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+COMMAND_HANDLER(handle_debug_level_command)
 {
        if (argc == 1)
        {
                unsigned new_level;
-               int retval = parse_uint(args[0], &new_level);
-               if (ERROR_OK != retval)
-                       return retval;
+               COMMAND_PARSE_NUMBER(uint, args[0], new_level);
                debug_level = MIN(new_level, LOG_LVL_DEBUG);
        }
        else if (argc > 1)
@@ -222,7 +302,7 @@ int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, cha
        return ERROR_OK;
 }
 
-int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
+COMMAND_HANDLER(handle_log_output_command)
 {
        if (argc == 1)
        {
@@ -273,7 +353,7 @@ int set_log_output(struct command_context_s *cmd_ctx, FILE *output)
 /* add/remove log callback handler */
 int log_add_callback(log_callback_fn fn, void *priv)
 {
-       log_callback_t *cb;
+       struct log_callback *cb;
 
        /* prevent the same callback to be registered more than once, just for sure */
        for (cb = log_callbacks; cb; cb = cb->next)
@@ -283,7 +363,7 @@ int log_add_callback(log_callback_fn fn, void *priv)
        }
 
        /* 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)
+       if ((cb = malloc(sizeof(struct log_callback))) == NULL)
                return ERROR_BUF_TOO_SMALL;
 
        /* add item to the beginning of the linked list */
@@ -297,7 +377,7 @@ int log_add_callback(log_callback_fn fn, void *priv)
 
 int log_remove_callback(log_callback_fn fn, void *priv)
 {
-       log_callback_t *cb, **p;
+       struct log_callback *cb, **p;
 
        for (p = &log_callbacks; (cb = *p); p = &(*p)->next)
        {

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)