log4c.c

Go to the documentation of this file.
00001 /* 
00002  * Copyright (c) 2001, Bit Farm, Inc. All rights reserved.
00003  *
00004  * Redistribution and use in source and binary forms, with or without
00005  * modification, are permitted provided that the following conditions
00006  * are met:
00007  * 1. Redistributions of source code must retain the above copyright
00008  *    notice, this list of conditions and the following disclaimer.
00009  * 2. Redistributions in binary form must reproduce the above copyright
00010  *    notice, this list of conditions and the following disclaimer in the
00011  *    documentation and/or other materials provided with the distribution.
00012  * 3. The name of the author may not be used to endorse or promote products
00013  *    derived from this software without specific prior written permission.
00014  * 
00015  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00016  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00017  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00018  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00019  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00020  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00021  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00022  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00023  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00024  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00025  */
00026 
00027 /* Modified slightly for Race into Space project. */
00028 
00029 /**
00030  * Logging for C - implementation.
00031  *
00032  * See log4c.h for documentation.
00033  */
00034 #include "logging.h"
00035 #include "log4c.h"
00036 #include "macros.h"
00037 #include <errno.h>
00038 #include <stdarg.h>
00039 #include <stdlib.h>
00040 #include <limits.h>
00041 #include <string.h>
00042 #include <assert.h>
00043 
00044 struct LogCategory _LOGV(LOG_ROOT_CAT) = {
00045     0, 0, 0,
00046     STRINGIFY(LOG_ROOT_CAT), LP_UNINITIALIZED, 0,
00047     NULL, 0
00048 };
00049 
00050 #if 0
00051 static const char* s_controlString = NULL;
00052 
00053 static const char* applyControlString(struct LogCategory* cat) {
00054 
00055     const char* cp = s_controlString;
00056     
00057     if (cp == NULL) return NULL;
00058 
00059     while (*cp != 0) {
00060         const char *name, *dot, *eq;;
00061         cp += strspn(cp, " ");
00062         name = cp;
00063         cp += strcspn(cp, ".= ");
00064         dot = cp;
00065         cp += strcspn(cp, "= ");
00066         eq = cp;
00067         cp += strcspn(cp, " ");
00068         if (*dot != '.' || *eq != '=') {
00069 
00070             return "Invalid control string";
00071         }
00072         else if (0 == strncmp(name, cat->name, dot - name)) {
00073             if (0 == strncmp(dot + 1, "thresh", eq - dot - 1)) {
00074                 char *end = NULL;
00075                 unsigned long val = 0;
00076                 errno = 0;
00077                 val = strtoul(eq + 1, &end, 10);
00078                 if (end == eq + 1)
00079                     return "No digits after 'thresh'";
00080                 else if (end != NULL)
00081                     return "Bad value for 'thresh'";
00082                 else if (val > INT_MAX)
00083                     val = INT_MAX;
00084                 log_setThreshold(cat, (int)val);
00085             }
00086         }
00087     }
00088     return "";
00089 } // applyControlString
00090 #endif
00091 
00092 void _log_logEvent(struct LogCategory* category, struct LogEvent* ev, ...)
00093 {
00094     struct LogCategory* cat = category;
00095     while(1) {
00096         struct LogAppender* appender = cat->appender;
00097         if (appender != NULL) {
00098             va_start(ev->ap, ev);
00099             appender->doAppend(appender, ev);
00100             va_end(ev->ap);
00101         }
00102         if (!cat->willLogToParent)
00103             break;
00104 
00105         cat = cat->parent;
00106     } 
00107 } // _log_logEvent
00108 
00109 static const char * initCategory(struct LogCategory* category) {
00110     if (category == &_LOGV(LOG_ROOT_CAT)) {
00111         if (category->thresholdPriority == LP_UNINITIALIZED)
00112             category->thresholdPriority = LP_WARNING;
00113         if (!category->appender)
00114             category->appender = log_defaultLogAppender;
00115     } else {
00116         log_setParent(category, category->parent);
00117     }
00118     return ""; /* applyControlString(category); */
00119 }
00120 
00121 /**
00122  * This gets called the first time a category is referenced and performs the
00123  * initialization. 
00124  * Also resets threshold to inherited!
00125  */
00126 int _log_initCat(int priority, struct LogCategory* category) {
00127     
00128     initCategory(category);
00129         
00130     return priority >= category->thresholdPriority;
00131 } // _log_initCat
00132 
00133 void log_setParent(struct LogCategory* cat, struct LogCategory* parent) {
00134 
00135     assert(parent != NULL);
00136 
00137     // unlink from current parent
00138     if (cat->thresholdPriority != LP_UNINITIALIZED) {
00139         struct LogCategory** cpp = &parent->firstChild;
00140         while(*cpp != cat && *cpp != NULL) {
00141             cpp = &(*cpp)->nextSibling;
00142         }
00143         assert(*cpp == cat);
00144         *cpp = cat->nextSibling;
00145     }
00146 
00147     // Set new parent
00148     cat->parent = parent;
00149     cat->nextSibling = parent->firstChild;
00150     parent->firstChild = cat;
00151 
00152     // Make sure parent is initialized
00153     initCategory(parent);
00154     
00155     // Reset priority
00156     if (cat->isThreshInherited)
00157         cat->thresholdPriority = parent->thresholdPriority;
00158     
00159 } // log_setParent
00160 
00161 static void setInheritedThresholds(struct LogCategory* cat)
00162 {
00163     struct LogCategory* child = cat->firstChild;
00164     for( ; child != NULL; child = child->nextSibling)
00165     {
00166         if (child->isThreshInherited) {
00167             child->thresholdPriority = cat->thresholdPriority;
00168             setInheritedThresholds(child);
00169         }
00170     }
00171 }
00172 
00173 void log_setThreshold(struct LogCategory* cat, int thresholdPriority) {
00174     cat->thresholdPriority = thresholdPriority;
00175     cat->isThreshInherited = 0;
00176     setInheritedThresholds(cat);
00177 }
00178 
00179 #if 0
00180 const char* log_setControlString(const char* cs) {
00181     if (s_controlString == NULL) {
00182         s_controlString = cs;
00183         return initCategory(&_LOGV(LOG_ROOT_CAT));
00184     } else {
00185         return "log_setControlString should not be invoked twice.";
00186     }
00187 }
00188 #endif
00189 
00190 void log_setAppender(struct LogCategory* cat, struct LogAppender* app) {
00191     cat->appender = app;
00192 }

Generated on Fri Sep 28 00:35:45 2007 for raceintospace by  doxygen 1.5.3