]> git.sur5r.net Git - openocd/blobdiff - src/helper/log.c
print out an error if srst_pulls_trst is not specified for
[openocd] / src / helper / log.c
index cdd7b7bfe512d2f82efd4860871fca1adebfa5bf..e9c1fa205d2a5aa5273a3b2fa445593aa6d5ee88 100644 (file)
 
 #include "log.h"
 #include "configuration.h"
+#include "time_support.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stdarg.h>
-#include <time.h>
+
+#define PRINT_MEM() 0
+#if PRINT_MEM()
+#include <malloc.h>
+#endif
 
 int debug_level = -1;
 
 static FILE* log_output;
 static log_callback_t *log_callbacks = NULL;
 
-static time_t start;
+static long long start;
 
 static char *log_strings[5] =
 {
@@ -60,9 +65,8 @@ static int count = 0;
  */
 static void log_puts(enum log_levels level, const char *file, int line, const char *function, const char *string)
 {
-       log_callback_t *cb;
-
-       if (level == LOG_OUTPUT)
+       char *f;
+       if (level == LOG_LVL_OUTPUT)
        {
                /* do not prepend any headers, just print out what we were given and return */
                fputs(string, log_output);
@@ -70,17 +74,29 @@ static void log_puts(enum log_levels level, const char *file, int line, const ch
                return;
        }
 
-       char *f = strrchr(file, '/');
+       f = strrchr(file, '/');
        if (f != NULL)
                file = f + 1;
 
        if (strchr(string, '\n')!=NULL)
        {
-               if (debug_level >= LOG_DEBUG)
+               if (debug_level >= LOG_LVL_DEBUG)
                {
                        /* print with count and time information */
-                       int t=(int)(time(NULL)-start);
-                       fprintf(log_output, "%s %d %d %s:%d %s(): %s", log_strings[level+1], count, t, file, line, function, string);
+                       int t=(int)(timeval_ms()-start);
+#if PRINT_MEM()        
+                       struct mallinfo info;
+                       info = mallinfo();
+#endif
+                       fprintf(log_output, "%s %d %d %s:%d %s()"
+#if PRINT_MEM()
+                                       " %d"
+#endif
+                                       ": %s", log_strings[level+1], count, t, file, line, function, 
+#if PRINT_MEM()
+                                       info.fordblks,
+#endif
+                                       string);
                }
                else
                {
@@ -95,13 +111,17 @@ static void log_puts(enum log_levels level, const char *file, int line, const ch
 
        fflush(log_output);
        
-       /* Never forward LOG_DEBUG, too verbose and they can be found in the log if need be */
-       if (level <= LOG_INFO)
+       /* 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;
-               for (cb = log_callbacks; cb; cb = cb->next)
+               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;
                }
        }
 }
@@ -109,15 +129,15 @@ static void log_puts(enum log_levels level, const char *file, int line, const ch
 void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
 {
        char *string;
+       va_list ap;
 
        count++;
        if (level > debug_level)
                return;
 
-       va_list ap;
        va_start(ap, format);
 
-       string = alloc_printf(format, ap);
+       string = alloc_vprintf(format, ap);
        if (string != NULL)
        {
                log_puts(level, file, line, function, string);
@@ -130,18 +150,18 @@ void log_printf(enum log_levels level, const char *file, int line, const char *f
 void log_printf_lf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
 {
        char *string;
+       va_list ap;
 
        count++;
        if (level > debug_level)
                return;
        
-       va_list ap;
        va_start(ap, format);
        
-       string = alloc_printf(format, ap);
+       string = alloc_vprintf(format, ap);
        if (string != NULL)
        {
-               strcat(string, "\n"); /* alloc_printf guaranteed the buffer to be at least one char longer */
+               strcat(string, "\n"); /* alloc_vprintf guaranteed the buffer to be at least one char longer */
                log_puts(level, file, line, function, string);
                free(string);
        }
@@ -189,7 +209,7 @@ int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char
 
 int log_register_commands(struct command_context_s *cmd_ctx)
 {
-       start = time(NULL);
+       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,
@@ -202,7 +222,7 @@ int log_init(struct command_context_s *cmd_ctx)
 {
        /* set defaults for daemon configuration, if not set by cmdline or cfgfile */
        if (debug_level == -1)
-               debug_level = LOG_INFO;
+               debug_level = LOG_LVL_INFO;
        
        if (log_output == NULL)
        {
@@ -262,36 +282,48 @@ int log_remove_callback(log_callback_fn fn, void *priv)
 }
 
 /* return allocated string w/printf() result */
-char *alloc_printf(const char *fmt, va_list ap)
+char *alloc_vprintf(const char *fmt, va_list ap)
 {
        /* no buffer at the beginning, force realloc to do the job */
        char *string = NULL;
        
-       /* start with minimal length to exercise all the code paths */
-       int size = 1;
+       /* start with buffer size suitable for typical messages */
+       int size = 128;
 
        for (;;)
        {
-               size *= 2; /* double the buffer size */
-
-                       char *t = string;
-                       string = realloc(string, size);
-                       if (string == NULL)
-                       {
-                               if (t != NULL)
-                                       free(t);
-                               return NULL;
-                       }
-       
+               char *t = string;
+               va_list ap_copy;
                int ret;
-               ret = vsnprintf(string, size, fmt, ap);
+               string = realloc(string, size);
+               if (string == NULL)
+               {
+                       if (t != NULL)
+                               free(t);
+                       return NULL;
+               }
+
+               va_copy(ap_copy, ap);
+
+               ret = vsnprintf(string, size, fmt, ap_copy);
                /* NB! The result of the vsnprintf() might be an *EMPTY* string! */
                if ((ret >= 0) && ((ret + 1) < size))
                        break;
 
                /* there was just enough or not enough space, allocate more in the next round */
+               size *= 2; /* double the buffer size */
        }
        
        /* the returned buffer is by principle guaranteed to be at least one character longer */
        return string;
 }
+
+char *alloc_printf(const char *format, ...)
+{
+       char *string;
+       va_list ap;
+       va_start(ap, format);
+       string = alloc_vprintf(format, ap);
+       va_end(ap);
+       return string;
+}