*
* Debugging functions for the Common UNIX Printing System (CUPS).
*
- * Copyright 2008 by Apple Inc.
+ * Copyright 2008-2009 by Apple Inc.
*
* These coded instructions, statements, and computer programs are the
* property of Apple Inc. and are protected by Federal copyright
#include "globals.h"
#include "debug.h"
-#include <sys/time.h>
+#ifdef WIN32
+# include <io.h>
+#else
+# include <sys/time.h>
+# include <unistd.h>
+#endif /* WIN32 */
#include <fcntl.h>
-#include <unistd.h>
+#ifndef WIN32
+# include <regex.h>
+#endif /* WIN32 */
/*
int _cups_debug_fd = -1;
/* Debug log file descriptor */
+int _cups_debug_level = 1;
+ /* Log level (0 to 9) */
#ifdef DEBUG
* Local globals...
*/
+# ifndef WIN32
+static regex_t *debug_filter = NULL;
+ /* Filter expression for messages */
+# endif /* !WIN32 */
static int debug_init = 0; /* Did we initialize debugging? */
# ifdef HAVE_PTHREAD_H
static pthread_mutex_t debug_mutex = PTHREAD_MUTEX_INITIALIZER;
* 'debug_vsnprintf()' - Format a string into a fixed size buffer.
*/
-int /* O - Number of bytes formatted */
+static int /* O - Number of bytes formatted */
debug_vsnprintf(char *buffer, /* O - Output buffer */
size_t bufsize, /* O - Size of output buffer */
const char *format, /* I - printf-style format string */
struct timeval curtime; /* Current time */
char buffer[2048]; /* Output buffer */
size_t bytes; /* Number of bytes in buffer */
- const char *cups_debug_log;/* CUPS_DEBUG_LOG environment variable */
-
+ int level; /* Log level in message */
+ const char *cups_debug_filter,
+ /* CUPS_DEBUG_FILTER environment variable */
+ *cups_debug_level,
+ /* CUPS_DEBUG_LEVEL environment variable */
+ *cups_debug_log;/* CUPS_DEBUG_LOG environment variable */
+
/*
* See if we need to do any logging...
if (!debug_init)
{
- debug_init = 1;
-
if ((cups_debug_log = getenv("CUPS_DEBUG_LOG")) == NULL)
_cups_debug_fd = -1;
else if (!strcmp(cups_debug_log, "-"))
else
{
snprintf(buffer, sizeof(buffer), cups_debug_log, getpid());
- _cups_debug_fd = open(buffer, O_WRONLY | O_APPEND | O_CREAT, 0644);
+
+ if (buffer[0] == '+')
+ _cups_debug_fd = open(buffer + 1, O_WRONLY | O_APPEND | O_CREAT, 0644);
+ else
+ _cups_debug_fd = open(buffer, O_WRONLY | O_TRUNC | O_CREAT, 0644);
+ }
+
+ if ((cups_debug_level = getenv("CUPS_DEBUG_LEVEL")) != NULL)
+ _cups_debug_level = atoi(cups_debug_level);
+
+ if ((cups_debug_filter = getenv("CUPS_DEBUG_FILTER")) != NULL)
+ {
+ if ((debug_filter = (regex_t *)calloc(1, sizeof(regex_t))) == NULL)
+ fputs("Unable to allocate memory for CUPS_DEBUG_FILTER - results not "
+ "filtered!\n", stderr);
+ else if (regcomp(debug_filter, cups_debug_filter, REG_EXTENDED))
+ {
+ fputs("Bad regular expression in CUPS_DEBUG_FILTER - results not "
+ "filtered!\n", stderr);
+ free(debug_filter);
+ debug_filter = NULL;
+ }
}
+
+ debug_init = 1;
}
pthread_mutex_unlock(&debug_mutex);
if (_cups_debug_fd < 0)
return;
+ /*
+ * Filter as needed...
+ */
+
+ if (isdigit(format[0]))
+ level = *format++ - '0';
+ else
+ level = 0;
+
+ if (level > _cups_debug_level)
+ return;
+
+ if (debug_filter)
+ {
+ int result; /* Filter result */
+
+ pthread_mutex_lock(&debug_mutex);
+ result = regexec(debug_filter, format, 0, NULL, 0);
+ pthread_mutex_unlock(&debug_mutex);
+
+ if (result)
+ return;
+ }
+
/*
* Format the message...
*/
void
_cups_debug_puts(const char *s) /* I - String to output */
{
- _cups_debug_printf("%s\n", s);
+ char format[4]; /* C%s */
+
+ format[0] = *s++;
+ format[1] = '%';
+ format[2] = 's';
+ format[3] = '\0';
+
+ _cups_debug_printf(format, s);
}