poldek: poldek/Cellar/log4c/README (NEW), poldek/Cellar/log4c/Make...
mis
mis at pld-linux.org
Thu Jan 24 00:08:42 CET 2008
Author: mis Date: Wed Jan 23 23:08:42 2008 GMT
Module: poldek Tag: HEAD
---- Log message:
- lightweight log4 lib, to use some day
---- Files affected:
poldek/poldek/Cellar/log4c:
README (NONE -> 1.1) (NEW), Makefile.am (NONE -> 1.1) (NEW), defaultAppender.c (NONE -> 1.1) (NEW), log4c.c (NONE -> 1.1) (NEW), log4c.h (NONE -> 1.1) (NEW)
---- Diffs:
================================================================
Index: poldek/poldek/Cellar/log4c/README
diff -u /dev/null poldek/poldek/Cellar/log4c/README:1.1
--- /dev/null Thu Jan 24 00:08:42 2008
+++ poldek/poldek/Cellar/log4c/README Thu Jan 24 00:08:37 2008
@@ -0,0 +1,13 @@
+/** @mainpage
+This is a sort of poor C programmer's Log4J. It lacks many features. But, in
+true C-hacker spirit, it is even more efficient. This is critical, since I plan
+to use it in some real-time, embedded software.
+
+All the documentation is in log4c.h.
+
+Take a look at test_log4c.c for a short usage example.
+
+The Sovereign
+Bit Farm, Inc.
+mgm at bitfarminc.com
+*/
================================================================
Index: poldek/poldek/Cellar/log4c/Makefile.am
diff -u /dev/null poldek/poldek/Cellar/log4c/Makefile.am:1.1
--- /dev/null Thu Jan 24 00:08:42 2008
+++ poldek/poldek/Cellar/log4c/Makefile.am Thu Jan 24 00:08:37 2008
@@ -0,0 +1,19 @@
+# $Id$
+
+AM_CFLAGS = @AM_CFLAGS@
+
+LIBS =
+noinst_LTLIBRARIES = liblog4c.la
+libsigint_la_SOURCES = log4c.c log4c.h defaultAppender.c
+
+dist-hook:
+ rm -rf $(distdir)/.deps
+
+clean-local:
+ -rm -f core *.o *.bak *~ *% *\# TAGS gmon.out \#* *\#
+
+
+MAINTAINERCLEANFILES = mkinstalldirs install-sh missing *.tar.gz *.spec \
+ config.h.in configure Makefile.in config.h \
+ config.sub config.guess aclocal.m4 \
+ libtool ltconfig ltmain.sh stamp-h* depcomp *.1
================================================================
Index: poldek/poldek/Cellar/log4c/defaultAppender.c
diff -u /dev/null poldek/poldek/Cellar/log4c/defaultAppender.c:1.1
--- /dev/null Thu Jan 24 00:08:42 2008
+++ poldek/poldek/Cellar/log4c/defaultAppender.c Thu Jan 24 00:08:37 2008
@@ -0,0 +1,78 @@
+// $Id$
+// Copyright (c) 2001, Bit Farm, Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. The name of the author may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "log4c.h"
+#include <stdio.h>
+
+/**
+ * The root category's default logging function.
+ */
+
+static char *priorityNames[] = {
+ "Zero Priority",
+ "TRACE",
+ "DEBUG",
+ "INFO",
+ "NOTICE",
+ "WARNING",
+ "ERROR",
+ "CRITICAL ERROR",
+ "ALERT",
+ "EMERGENCY",
+};
+
+static void doAppend(struct LogAppender* this, struct LogEvent* ev);
+
+static struct DefaultLogAppender {
+ struct LogAppender appender;
+ FILE *file;
+} defaultLogAppender = { { doAppend }, NULL } ;
+
+struct LogAppender* log_defaultLogAppender = &defaultLogAppender.appender;
+
+static void doAppend(struct LogAppender* this0, struct LogEvent* ev) {
+
+ // TODO: define a format field in struct for timestamp, etc.
+ char *pn;
+ char buf[20];
+ struct DefaultLogAppender* this = (struct DefaultLogAppender*)this0;
+
+ if (this->file == NULL) this->file = stderr;
+
+ if (ev->priority < 0) {
+ pn = "Negative Priority NOT ALLOWED!!";
+ }
+ else if (ev->priority < sizeof(priorityNames)) {
+ pn = priorityNames[ev->priority];
+ } else {
+ sprintf(buf, "%s+%d",
+ priorityNames[sizeof(priorityNames)-1],
+ ev->priority - sizeof(priorityNames) + 1);
+ }
+ fprintf(stderr, "%-7s ", pn);
+ fprintf(stderr, "%s:%d: ", ev->fileName, ev->lineNum);
+ vfprintf(stderr, ev->fmt, ev->ap);
+ fprintf(stderr, "\n");
+}
================================================================
Index: poldek/poldek/Cellar/log4c/log4c.c
diff -u /dev/null poldek/poldek/Cellar/log4c/log4c.c:1.1
--- /dev/null Thu Jan 24 00:08:42 2008
+++ poldek/poldek/Cellar/log4c/log4c.c Thu Jan 24 00:08:37 2008
@@ -0,0 +1,175 @@
+// $Id$
+// Copyright (c) 2001, Bit Farm, Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. The name of the author may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/**
+ * Logging for C - implementation.
+ *
+ * See log4c.h for documentation.
+ */
+#include "log4c.h"
+#include <stdarg.h>
+#include <assert.h>
+
+#ifndef NULL
+ #define NULL 0L
+#endif
+
+#define TRUE 1
+#define FALSE 0
+
+struct LogCategory _LOGV(LOG_ROOT_CAT) = {
+ 0, 0, 0,
+ "root", LP_UNINITIALIZED, 0,
+ NULL, 0
+};
+
+static const char* s_controlString = NULL;
+
+static const char* applyControlString(struct LogCategory* cat) {
+
+ const char* cp = s_controlString;
+
+ if (cp == NULL) return;
+
+ while (*cp != 0) {
+ const char *name, *dot, *eq;;
+ cp += strspn(cp, " ");
+ name = cp;
+ cp += strcspn(cp, ".= ");
+ dot = cp;
+ cp += strcspn(cp, "= ");
+ eq = cp;
+ cp += strcspn(cp, " ");
+ if (*dot != '.' || *eq != '=') {
+
+ return "Invalid control string";
+ }
+ else if (0 == strncmp(name, cat->name, dot - name)) {
+ if (0 == strncmp(dot + 1, "thresh", eq - dot - 1)) {
+ log_setThreshold(cat, atoi(eq + 1));
+ }
+ }
+ }
+ return "";
+} // applyControlString
+
+void _log_logEvent(struct LogCategory* category, struct LogEvent* ev, ...)
+{
+ struct LogCategory* cat = category;
+ va_start(ev->ap, ev);
+ while(1) {
+ struct LogAppender* appender = cat->appender;
+ if (appender != NULL) {
+ appender->doAppend(appender, ev);
+ }
+ if (!cat->willLogToParent)
+ break;
+
+ cat = cat->parent;
+ }
+ va_end(ev->ap);
+} // _log_logEvent
+
+static const char * initCategory(struct LogCategory* category) {
+ if (category == &_LOGV(LOG_ROOT_CAT)) {
+ category->thresholdPriority = LP_WARNING;
+ category->appender = log_defaultLogAppender;
+ } else {
+ log_setParent(category, category->parent);
+ }
+ return applyControlString(category);
+}
+
+/**
+ * This gets called the first time a category is referenced and performs the
+ * initialization.
+ * Also resets threshold to inherited!
+ */
+int _log_initCat(int priority, struct LogCategory* category) {
+
+ initCategory(category);
+
+ return priority >= category->thresholdPriority;
+} // _log_initCat
+
+void log_setParent(struct LogCategory* cat, struct LogCategory* parent) {
+
+ assert(parent != NULL);
+
+ // unlink from current parent
+ if (cat->thresholdPriority != LP_UNINITIALIZED) {
+ struct LogCategory** cpp = &parent->firstChild;
+ while(*cpp != cat && *cpp != NULL) {
+ cpp = &(*cpp)->nextSibling;
+ }
+ assert(*cpp == cat);
+ *cpp = cat->nextSibling;
+ }
+
+ // Set new parent
+ cat->parent = parent;
+ cat->nextSibling = parent->firstChild;
+ parent->firstChild = cat;
+
+ // Make sure parent is initialized
+ if (parent->thresholdPriority == LP_UNINITIALIZED) {
+ initCategory(parent);
+ }
+
+ // Reset priority
+ cat->thresholdPriority = parent->thresholdPriority;
+ cat->isThreshInherited = TRUE;
+
+} // log_setParent
+
+static void setInheritedThresholds(struct LogCategory* cat)
+{
+ struct LogCategory* child = cat->firstChild;
+ for( ; child != NULL; child = child->nextSibling)
+ {
+ if (child->isThreshInherited) {
+ child->thresholdPriority = cat->thresholdPriority;
+ setInheritedThresholds(child);
+ }
+ }
+}
+
+void log_setThreshold(struct LogCategory* cat, int thresholdPriority) {
+ cat->thresholdPriority = thresholdPriority;
+ cat->isThreshInherited = FALSE;
+ setInheritedThresholds(cat);
+}
+
+const char* log_setControlString(const char* cs) {
+ if (s_controlString == NULL) {
+ s_controlString = cs;
+ return initCategory(&_LOGV(LOG_ROOT_CAT));
+ } else {
+ return "log_setControlString should not be invoked twice.";
+ }
+}
+
+void log_setAppender(struct LogCategory* cat, struct LogAppender* app) {
+ cat->appender = app;
+}
================================================================
Index: poldek/poldek/Cellar/log4c/log4c.h
diff -u /dev/null poldek/poldek/Cellar/log4c/log4c.h:1.1
--- /dev/null Thu Jan 24 00:08:42 2008
+++ poldek/poldek/Cellar/log4c/log4c.h Thu Jan 24 00:08:37 2008
@@ -0,0 +1,569 @@
+// $Id$
+// Copyright (c) 2001, Bit Farm, Inc. All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+// 3. The name of the author may not be used to endorse or promote products
+// derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/**
+ * @file log4c.h
+ * An easy-to-use, fast and flexible message logging architecture.
+ *
+ * This is loosely based on the Apache project's Log4J, Log4CC,
+ * etc. project. Because C is not object oriented, a lot had to change.
+ *
+ * The following documentation is a hacked version of the Log4J docs.
+ *
+ * OVERVIEW
+ *
+ * Log4C has 3 main concepts: category, priority and appender.
+ * These three concepts work together to enable developers to log messages
+ * according to message type and priority, and to control at runtime how these
+ * messages are formatted and where they are reported.
+ *
+ * CATEGORY HIERARCHY
+ *
+ * The first and foremost advantage of any logging API over plain printf()
+ * resides in its ability to disable certain log statements while allowing
+ * others to print unhindered. This capability assumes that the logging space,
+ * that is, the space of all possible logging statements, is categorized
+ * according to some developer-chosen criteria.
+ *
+ * This observation led to choosing category as the central concept of the
+ * system. Every category is declared by providing a name and an optional
+ * parent. If no parent is explicitly named, the root category, LOG_ROOT_CAT is
+ * the category's parent.
+ *
+ * A category is created by a macro call at the top level of a file.
+ * A category can be created with any one of the following macros:
+ *
+ * - LOG_NEW_CATEGORY(MyCat);
+ * - LOG_NEW_SUBCATEGORY(MyCat, ParentCat);
+ * - LOG_NEW_DEFAULT_CATEGORY(MyCat);
+ * - LOG_NEW_DEFAULT_SUBCATEGORY(MyCat, ParentCat);
+ *
+ * The parent cat can be defined in the same file or in another file, but each
+ * category may have only one definition.
+ *
+ * Typically, there will be a Category for each module and sub-module, so you
+ * can independently control logging for each module.
+ *
+ * PRIORITY
+ *
+ * A category may be assigned a threshold priorty. The set of priorites are
+ * defined by symbolic constants: LP_TRACE, LP_DEBUG, LP_INFO,
+ * LP_NOTICE, LP_WARNING , LP_ERROR, LP_CRITICAL, LP_ALERT, and LP_EMERGENCY.
+ * The priorities are simply non-negative integers. [It is possible to use your
+ * own set by supplying a custom appender.]
+ *
+ * If a given category is not assigned a threshold priority, then it inherits
+ * one from its closest ancestor with an assigned threshold.
+ *
+ * To ensure that all categories can eventually inherit a threshold, the root
+ * category always has an assigned threshold priority.
+ *
+ * Logging requests are made by invoking a logging macro on a category.
+ * All of the macros have a printf-style format string followed by arguments.
+ * Because most C compilers do not support vararg macros, there is a version of
+ * the macro for any number of arguments from 0 to 6. The macro name ends with
+ * the total number of arguments.
+ *
+ * Here is an example of the most basic type of macro:
+ *
+ * <code>
+ * CLOG5(MyCat, LP_WARN, "Values are: %d and '%s'", 5, "oops");
+ * </code>
+ *
+ * This is a logging request with priority WARN.
+ *
+ * A logging request is said to be enabled if its priority is higher than or
+ * equal to the threshold priority of its category. Otherwise, the request is
+ * said to be disabled. A category without an assigned priority will inherit
+ * one from the hierarchy.
+ *
+ * It is possible to use any non-negative integer as a priority. If, as in the
+ * example, one of the standard priorites is used, then there is a convenience
+ * macro that is typically used instead. For example, the above example is
+ * equivalent to the shorter:
+ *
+ * <code>
+ * CWARN4(MyCat, "Values are: %d and '%s'", 5, "oops");
+ * </code>
+ *
+ * DEFAULT CATEGORY
+ *
+ * If LOG_NEW_DEFAULT_SUBCATEGORY(MyCat, Parent) or
+ * LOG_NEW_DEFAULT_CATEGORY(MyCat) is used to create the category, then the
+ * even shorter form can be used:
+ *
+ * <code>
+ * WARN3("Values are: %d and '%s'", 5, "oops");
+ * </code>
+ *
+ * Only one default category can be created per file, though multiple
+ * non-defaults can be created and used.
+ *
+ * EXAMPLE
+ *
+ * Here is a more complete example:
+ *
+ * @code
+ * #include "log4c.h"
+ *
+ * // create a category and a default subcategory
+ * LOG_NEW_CATEGORY(VSS);
+ * LOG_NEW_DEFAULT_SUBCATEGORY(SA, VSS);
+ *
+ * main() {
+ * // Now set the parent's priority.
+ * // (the string would typcially be a runtime option)
+ * log_setControlString("SA.thresh=3");
+ *
+ * // alternatively: log_setThreshold(&SA, LP_INFO);
+ *
+ * // This request is enabled, because WARNING >= INFO.
+ * CWARN2(VSS, "Low fuel level.");
+ *
+ * // This request is disabled, because DEBUG < INFO.
+ * CDEBUG2(VSS, "Starting search for nearest gas station.");
+ *
+ * // The default category SA inherits its priority from VSS. Thus,
+ * // the following request is enabled because INFO >= INFO.
+ * INFO1("Located nearest gas station.");
+ *
+ * // This request is disabled, because DEBUG < INFO.
+ * DEBUG1("Exiting gas station search");
+ * }
+ * @endcode
+ *
+ * CONFIGURATION
+ *
+ * Configuration is typically done during program initialization by invoking
+ * the log_setControlString() method. The control string passed to it typically
+ * comes from the command line. Look at the doucmentation for that function for
+ * the format of the control string.
+ *
+ * PERFORMANCE
+ *
+ * Clever design insures efficiency. Except for the first invocation, a
+ * disabled logging request requires an a single comparison of a static
+ * variable to a constant.
+ *
+ * There is also compile time constant, LOG_STATIC_THRESHOLD, which causes all
+ * logging requests with a lower priority to be optimized to 0 cost by the
+ * compiler. By setting it to LP_INFINITE, all logging requests are statically
+ * disabled and cost nothing. Released executables might typically be compiled
+ * with "-DLOG_STATIC_THRESHOLD=LP_INFO"
+ *
+ * APPENDERS
+ *
+ * Each category has an optional appender. An appender is a pointer to a
+ * structure whcih starts with a pointer to a doAppend() function. DoAppend()
+ * prints a message to a log.
+ *
+ * WHen a category is passed a message by one of the logging macros, the
+ * category performs the following actions:
+ *
+ * 1. if the category has an appender, the message is passed to the appender's
+ * doAppend() function,
+ *
+ * 2. if 'willLogToParent' is true for the category, the message is passed to
+ * the category's parent.
+ *
+ * By default, all categories except root have no appender and
+ * 'willLogToParent' is true. This situation causes all messages to be logged
+ * by the root category's appender.
+ *
+ * Typically, you would only change the root category's appender when you
+ * wanted, say, a different output format. Copying defaultLogAppender.c would
+ * be a good start.
+ *
+ * The default appender function currently prints to stderr.
+ *
+ * MISC
+ *
+ * Do not use any of the macros that start with '_'.
+ *
+ * The current set of macros force each file to use categories declared in that
+ * file. This is intentional. Make the category a child of the file's module
+ * category.
+ *
+ * Log4J has a 'rolling file appender' which you can select with a run-time
+ * option & specify the max file size. This would be a nice default for
+ * non-kernel applications.
+ *
+ * CAVEATS
+ *
+ * Category names are global variables.
+ */
+#ifndef _LOG4C_H_
+#define _LOG4C_H_
+
+#include <stdarg.h>
+
+/**
+ * @name Priority Values
+ *
+ * These are the same names (except TRACE is new) as used by Unix syslog(), but
+ * the numerical values are different.
+ *@{
+ */
+
+#define LP_NONE 0
+#define LP_TRACE 1
+#define LP_DEBUG 2
+#define LP_INFO 3
+#define LP_NOTICE 4
+#define LP_WARNING 5
+#define LP_ERROR 6
+#define LP_CRITICAL 7
+#define LP_ALERT 8
+#define LP_EMERGENCY 9
+
+#define LP_UNINITIALIZED -1 ///< for internal use only
+
+#ifndef LOG_STATIC_THRESHOLD
+/**
+ * All logging with priority < LOG_STATIC_THRESHOLD is disabled at compile
+ * time, i.e., compiled out.
+ */
+ #define LOG_STATIC_THRESHOLD LP_NONE
+#endif
+
+/*@}*/
+
+/** Transforms a category name to a global variable name. */
+#define _LOGV(cat) _LOG_CONCAT(_log_c, cat)
+#define _LOG_CONCAT(x,y) x ## y
+
+/** The root of the category hierarchy. */
+#define LOG_ROOT_CAT LogRoot
+
+/** Defines a new subcategory of the parent. */
+#define LOG_NEW_SUBCATEGORY(catName, parent) \
+ extern struct LogCategory _LOGV(parent); \
+ struct LogCategory _LOGV(catName) = { \
+ &_LOGV(parent), 0, 0, \
+ #catName, LP_UNINITIALIZED, 1, \
+ 0, 1 \
+ };
+
+/**
+ * Creates a new subcategory of the root category.
+ */
+#define LOG_NEW_CATEGORY(catName) LOG_NEW_SUBCATEGORY(catName, LOG_ROOT_CAT)
+
+/**
+ * Creates a new subcategory of the root category.
+ */
+
+#define _LOG_DEFAULT_CATEGORY(cname) \
+ static struct LogCategory* _log_defaultCategory = &_LOGV(cname);
+
+/**
+ * Creates a new subcategory of the root category and makes it the default
+ * (used by macros that don't explicitly specify a category).
<<Diff was trimmed, longer than 597 lines>>
More information about the pld-cvs-commit
mailing list