]> git.sur5r.net Git - openocd/blobdiff - src/helper/log.c
- using ERROR_COMMAND_SYNTAX_ERROR to print syntax in a couple of places
[openocd] / src / helper / log.c
index db0bc0bd6f889bd154babff3678bce6bf56d5ac7..8567c037a3f9536ebfe0bf2dcf28ccf5bc9b7897 100644 (file)
-/***************************************************************************
- *   Copyright (C) 2005 by Dominic Rath                                    *
- *   Dominic.Rath@gmx.de                                                   *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program is distributed in the hope that it will be useful,       *
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
- *   GNU General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
- ***************************************************************************/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "log.h"
-#include "configuration.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdarg.h>
-
-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:  ",
-       "Warning:",
-       "Info:   ",
-       "Debug:  ",
-};
-
-void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)
-{
-       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:%d %s(): %s\n", log_strings[level], file, line, function, buffer);
-       fflush(log_output);
-       
-       va_end(args);
-
-       if (callback)
-{
-       va_start(args, format);
-
-               callback(privData, file, line, function, format, args);
-
-       va_end(args);
-}
-
-}
-
-/* change the current debug level on the fly
- * 0: only ERRORS
- * 1: + WARNINGS
- * 2: + INFORMATIONAL MSGS
- * 3: + DEBUG MSGS
- */
-int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       if (argc == 0)
-               command_print(cmd_ctx, "debug_level: %i", debug_level);
-
-       if (argc > 0)
-               debug_level = strtoul(args[0], NULL, 0);
-
-       if (debug_level < 0)
-               debug_level = 0;
-
-       if (debug_level > 3)
-               debug_level = 3;
-
-       return ERROR_OK;
-}
-
-int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
-       if (argc == 1)
-       {
-               FILE* file = fopen(args[0], "w");
-               
-               if (file)
-               {
-                       log_output = file;
-               }
-       }
-
-       return ERROR_OK;
-}
-
-int log_register_commands(struct command_context_s *cmd_ctx)
-{
-       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;
-}
-
-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;
-       
-       if (log_output == NULL)
-       {
-               log_output = stderr;
-       }
-       
-       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)<size))
-           {
-               return string;
-           }
-           // there was just enough or not enough space, allocate more.
-           first=0;
-       }
-}
+/***************************************************************************\r
+ *   Copyright (C) 2005 by Dominic Rath                                    *\r
+ *   Dominic.Rath@gmx.de                                                   *\r
+ *                                                                         *\r
+ *   This program is free software; you can redistribute it and/or modify  *\r
+ *   it under the terms of the GNU General Public License as published by  *\r
+ *   the Free Software Foundation; either version 2 of the License, or     *\r
+ *   (at your option) any later version.                                   *\r
+ *                                                                         *\r
+ *   This program is distributed in the hope that it will be useful,       *\r
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
+ *   GNU General Public License for more details.                          *\r
+ *                                                                         *\r
+ *   You should have received a copy of the GNU General Public License     *\r
+ *   along with this program; if not, write to the                         *\r
+ *   Free Software Foundation, Inc.,                                       *\r
+ *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
+ ***************************************************************************/\r
+#ifdef HAVE_CONFIG_H\r
+#include "config.h"\r
+#endif\r
+\r
+#include "log.h"\r
+#include "configuration.h"\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+#include <stdarg.h>\r
+#include <time.h>\r
+\r
+int debug_level = -1;\r
+\r
+static FILE* log_output;\r
+\r
+static void *privData;\r
+static logCallback callback;\r
+static time_t start;\r
+\r
+void log_setCallback(logCallback c, void *p)\r
+{\r
+       callback = c;\r
+       privData = p;\r
+}\r
+\r
+static char *log_strings[5] = \r
+{\r
+       "User:   ",\r
+       "Error:  ",\r
+       "Warning:",\r
+       "Info:   ",\r
+       "Debug:  "\r
+};\r
+\r
+void log_printf(enum log_levels level, const char *file, int line, const char *function, const char *format, ...)\r
+{\r
+       static int count = 0;\r
+       count++;\r
+       va_list args;\r
+       char buffer[512];\r
+\r
+       if (level > debug_level)\r
+               return;\r
+\r
+       va_start(args, format);\r
+       vsnprintf(buffer, 512, format, args);\r
+\r
+       char *f = strrchr(file, '/');\r
+       if (f != NULL)\r
+               file = f + 1;\r
+\r
+       if (debug_level >= LOG_DEBUG)\r
+       {\r
+               /* print with count and time information */\r
+               time_t t=time(NULL)-start;\r
+               fprintf(log_output, "%s %d %ld %s:%d %s(): %s\n", log_strings[level+1], count, t, file, line, function, buffer);\r
+       }\r
+       else\r
+       {\r
+               /* do not print count and time */\r
+               fprintf(log_output, "%s %s:%d %s(): %s\n", log_strings[level+1], file, line, function, buffer);\r
+       }\r
+\r
+       fflush(log_output);\r
+       \r
+       va_end(args);\r
+\r
+       /* Never forward LOG_DEBUG, too verbose and they can be found in the log if need be */\r
+       if (callback && (level <= LOG_INFO))\r
+       {\r
+               va_start(args, format);\r
+               callback(privData, file, line, function, format, args);\r
+               va_end(args);\r
+       }\r
+}\r
+\r
+/* change the current debug level on the fly\r
+ * 0: only ERRORS\r
+ * 1: + WARNINGS\r
+ * 2: + INFORMATIONAL MSGS\r
+ * 3: + DEBUG MSGS\r
+ */\r
+int handle_debug_level_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       if (argc == 0)\r
+               command_print(cmd_ctx, "debug_level: %i", debug_level);\r
+\r
+       if (argc > 0)\r
+               debug_level = strtoul(args[0], NULL, 0);\r
+\r
+       if (debug_level < 0)\r
+               debug_level = 0;\r
+\r
+       if (debug_level > 3)\r
+               debug_level = 3;\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int handle_log_output_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)\r
+{\r
+       if (argc == 1)\r
+       {\r
+               FILE* file = fopen(args[0], "w");\r
+               \r
+               if (file)\r
+               {\r
+                       log_output = file;\r
+               }\r
+       }\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int log_register_commands(struct command_context_s *cmd_ctx)\r
+{\r
+       start = time(NULL);\r
+       register_command(cmd_ctx, NULL, "log_output", handle_log_output_command,\r
+               COMMAND_ANY, "redirect logging to <file> (default: stderr)");\r
+       register_command(cmd_ctx, NULL, "debug_level", handle_debug_level_command,\r
+               COMMAND_ANY, "adjust debug level <0-3>");\r
+\r
+       return ERROR_OK;\r
+}\r
+\r
+int log_init(struct command_context_s *cmd_ctx)\r
+{\r
+       /* set defaults for daemon configuration, if not set by cmdline or cfgfile */\r
+       if (debug_level == -1)\r
+               debug_level = LOG_INFO;\r
+       \r
+       if (log_output == NULL)\r
+       {\r
+               log_output = stderr;\r
+       }\r
+       \r
+       return ERROR_OK;\r
+}\r
+       \r
+int set_log_output(struct command_context_s *cmd_ctx, FILE *output)\r
+{\r
+       log_output = output;\r
+       return ERROR_OK;\r
+}\r
+\r
+/* return allocated string w/printf() result */\r
+char *allocPrintf(const char *fmt, va_list ap)\r
+{\r
+       char *string = NULL;\r
+       \r
+       /* start by 0 to exercise all the code paths. Need minimum 2 bytes to\r
+        * fit 1 char and 0 terminator. */\r
+       int size = 0;\r
+       int first = 1;\r
+       for (;;)\r
+       {\r
+               if ((string == NULL) || (!first))\r
+               {\r
+                       size = size * 2 + 2;\r
+                       char *t = string;\r
+                       string = realloc(string, size);\r
+                       if (string == NULL)\r
+                       {\r
+                               if (t != NULL)\r
+                                       free(t);\r
+                               return NULL;\r
+                       }\r
+               }\r
+       \r
+           int ret;\r
+           ret = vsnprintf(string, size, fmt, ap);\r
+           /* NB! The result of the vsnprintf() might be an *EMPTY* string! */\r
+           if ((ret >= 0) && ((ret + 1) < size))\r
+           {\r
+               return string;\r
+           }\r
+           /* there was just enough or not enough space, allocate more. */\r
+           first = 0;\r
+       }\r
+}\r