#include <stdarg.h>
#include <assert.h>
#include <apr_pools.h>
#include <apr_strings.h>
#include "svn_types.h"
#include "svn_string.h"
#ifndef SVN_DBG__PROTOTYPES
#define SVN_DBG__PROTOTYPES
#endif
#include "private/svn_debug.h"
#define DBG_FLAG "DBG: "
static const char *debug_file = NULL;
static long debug_line = 0;
static FILE * volatile debug_output = NULL;
static svn_boolean_t
quiet_mode(void)
{
return getenv("SVN_DBG_QUIET") != NULL;
}
void
svn_dbg__preamble(const char *file, long line, FILE *output)
{
debug_output = output;
if (output != NULL && !quiet_mode())
{
const char *slash = strrchr(file, '/');
if (slash == NULL)
slash = strrchr(file, '\\');
if (slash)
debug_file = slash + 1;
else
debug_file = file;
}
debug_line = line;
}
static void
debug_vprintf(const char *fmt, va_list ap)
{
FILE *output = debug_output;
char prefix[80], buffer[4096];
char *s = buffer;
int n;
if (output == NULL || quiet_mode())
return;
n = apr_snprintf(prefix, sizeof(prefix), DBG_FLAG "%s:%4ld: ",
debug_file, debug_line);
assert(n < sizeof(prefix) - 1);
n = apr_vsnprintf(buffer, sizeof(buffer), fmt, ap);
assert(n < sizeof(buffer) - 1);
do
{
char *newline = strchr(s, '\n');
if (newline)
*newline = '\0';
fputs(prefix, output);
fputs(s, output);
fputc('\n', output);
if (! newline)
break;
s = newline + 1;
}
while (*s);
}
void
svn_dbg__printf(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
debug_vprintf(fmt, ap);
va_end(ap);
}
void
svn_dbg__print_props(apr_hash_t *props,
const char *header_fmt,
...)
{
#ifdef SVN_DEBUG
apr_hash_index_t *hi;
va_list ap;
va_start(ap, header_fmt);
debug_vprintf(header_fmt, ap);
va_end(ap);
if (props == NULL)
{
svn_dbg__printf(" (null)\n");
return;
}
for (hi = apr_hash_first(apr_hash_pool_get(props), props); hi;
hi = apr_hash_next(hi))
{
const char *name = apr_hash_this_key(hi);
svn_string_t *val = apr_hash_this_val(hi);
svn_dbg__printf(" '%s' -> '%s'\n", name, val->data);
}
#endif
}