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