]> mj.ucw.cz Git - libucw.git/blobdiff - ucw/log.c
XML: Brief documentation of LibUCW-XML
[libucw.git] / ucw / log.c
index df6eae0531ecdef5f5e3352acd49157ec418aa14..4a951e3277dc4bad99eae8a99feeaebece38a4c6 100644 (file)
--- a/ucw/log.c
+++ b/ucw/log.c
@@ -3,6 +3,7 @@
  *
  *     (c) 1997--2009 Martin Mares <mj@ucw.cz>
  *     (c) 2008 Tomas Gavenciak <gavento@ucw.cz>
+ *     (c) 2014 Tomas Valla <tom@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
@@ -33,7 +34,9 @@ static void NONRET do_die(void);
 static int default_log_handler(struct log_stream *ls UNUSED, struct log_msg *m)
 {
   // This is a completely bare version of the log-file module. Errors are ignored.
-  write(2, m->m, m->m_len);
+  if (write(2, m->m, m->m_len) < 0)
+    {
+    }
   return 0;
 }
 
@@ -66,7 +69,7 @@ int log_streams_after = 0;            /* The first never-used index in log_streams.ptr */
  */
 
 struct log_stream *
-log_stream_by_flags(uns flags)
+log_stream_by_flags(uint flags)
 {
   int n = LS_GET_STRNUM(flags);
   if (n < 0 || n >= log_streams_after || log_streams.ptr[n]->regnum == -1)
@@ -79,9 +82,9 @@ log_stream_by_flags(uns flags)
 char **log_type_names;
 
 char *
-log_type_name(uns flags)
+log_type_name(uint flags)
 {
-  uns type = LS_GET_TYPE(flags);
+  uint type = LS_GET_TYPE(flags);
 
   if (!log_type_names || !log_type_names[type])
     return "default";
@@ -92,7 +95,7 @@ log_type_name(uns flags)
 /*** Logging ***/
 
 void
-vmsg(uns cat, const char *fmt, va_list args)
+vmsg(uint cat, const char *fmt, va_list args)
 {
   struct timeval tv;
   struct tm tm;
@@ -102,7 +105,7 @@ vmsg(uns cat, const char *fmt, va_list args)
   char msgbuf[256];
   char *p;
   int len;
-  uns sighandler = cat & L_SIGHANDLER;
+  uint sighandler = cat & L_SIGHANDLER;
   struct log_stream *ls;
   struct log_msg m = { .flags = cat };
 
@@ -161,10 +164,11 @@ vmsg(uns cat, const char *fmt, va_list args)
     }
 
   /* Pass the message to the log_stream */
-  if (log_pass_msg(0, ls, &m))
+  log_pass_msg(ls, &m);
+  if (m.error)
     {
       /* Error (such as infinite loop) occurred */
-      log_pass_msg(0, &log_stream_default, &m);
+      log_pass_msg(&log_stream_default, &m);
     }
 
   if (m.raw_msg != msgbuf)
@@ -194,7 +198,7 @@ log_report_err(struct log_stream *ls, struct log_msg *m, int err)
       errno = err;
       snprintf(errbuf, sizeof(errbuf), "Error logging to %s: %m", name);
     }
-  log_pass_msg(0, &log_stream_default, &errm);
+  log_pass_msg(&log_stream_default, &errm);
 
   if (ls->stream_flags & LSFLAG_ERR_IS_FATAL)
     do_die();
@@ -203,32 +207,20 @@ log_report_err(struct log_stream *ls, struct log_msg *m, int err)
 /* Maximal depth of log_pass_msg recursion */
 #define LS_MAX_DEPTH 64
 
-int
-log_pass_msg(int depth, struct log_stream *ls, struct log_msg *m)
+void
+log_pass_filtered(struct log_stream *ls, struct log_msg *m)
 {
-  ASSERT(ls);
-
-  /* Check recursion depth */
-  if (depth > LS_MAX_DEPTH)
-    {
-      log_report_err(ls, m, EDEADLK);
-      return 1;
-    }
-
-  /* Filter by level, type and hook function */
-  if (!((1 << LS_GET_LEVEL(m->flags)) & ls->levels) ||
-      !((1 << LS_GET_TYPE(m->flags)) & ls->types) ||
-      ls->filter && ls->filter(ls, m))
-    return 0;
-
   /* Pass the message to substreams */
   CLIST_FOR_EACH(simp_node *, s, ls->substreams)
-    if (log_pass_msg(depth+1, s->p, m))
-      return 1;
+    {
+      log_pass_msg(s->p, m);
+      if (m->error)
+       return;
+    }
 
   /* Will pass to the handler of this stream... is there any? */
   if (!ls->handler)
-    return 0;
+    return;
 
   /* Will print a message type? */
   char *type = NULL;
@@ -316,13 +308,42 @@ log_pass_msg(int depth, struct log_stream *ls, struct log_msg *m)
 
   if (free_buf)
     xfree(free_buf);
-  return 0;
+}
+
+void
+log_pass_msg(struct log_stream *ls, struct log_msg *m)
+{
+  ASSERT(ls);
+
+  /* Check recursion depth */
+  if (m->depth > LS_MAX_DEPTH)
+    {
+      log_report_err(ls, m, EDEADLK);
+      m->error = 1;
+      return;
+    }
+
+  /* Filter by level and type */
+  if (!((1 << LS_GET_LEVEL(m->flags)) & ls->levels) ||
+      !((1 << LS_GET_TYPE(m->flags)) & ls->types))
+    return;
+
+  m->depth++;
+
+  if (ls->filter && ls->filter(ls, m))
+    {
+      // The filter might have called log_pass_filtered()
+    }
+  else
+    log_pass_filtered(ls, m);
+
+  m->depth--;
 }
 
 /*** Utility functions ***/
 
 void
-msg(unsigned int cat, const char *fmt, ...)
+msg(uint cat, const char *fmt, ...)
 {
   va_list args;
 
@@ -368,6 +389,16 @@ assert_failed(const char *assertion, const char *file, int line)
   abort();
 }
 
+void
+assert_failed_msg(const char *assertion, const char *file, int line, const char *fmt, ...)
+{
+  va_list args;
+  va_start(args, fmt);
+  vmsg(L_DEBUG, fmt, args);
+  msg(L_FATAL, "Assertion `%s' failed at %s:%d", assertion, file, line);
+  abort();
+}
+
 void
 assert_failed_noinfo(void)
 {