diff options
Diffstat (limited to 'subversion/libsvn_subr/debug.c')
-rw-r--r-- | subversion/libsvn_subr/debug.c | 155 |
1 files changed, 155 insertions, 0 deletions
diff --git a/subversion/libsvn_subr/debug.c b/subversion/libsvn_subr/debug.c new file mode 100644 index 0000000..be331ed --- /dev/null +++ b/subversion/libsvn_subr/debug.c @@ -0,0 +1,155 @@ +/* + * debug.c : small functions to help SVN developers + * + * ==================================================================== + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * ==================================================================== + */ + +/* These functions are only available to SVN developers and should never + be used in release code. One of the reasons to avoid this code in release + builds is that this code is not thread-safe. */ +#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: " + +/* This will be tweaked by the preamble code. */ +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()) + { + /* Quick and dirty basename() code. */ + const char *slash = strrchr(file, '/'); + + if (slash == NULL) + slash = strrchr(file, '\\'); + if (slash) + debug_file = slash + 1; + else + debug_file = file; + } + debug_line = line; +} + + +/* Print a formatted string using format FMT and argument-list AP, + * prefixing each line of output with a debug header. */ +static void +debug_vprintf(const char *fmt, va_list ap) +{ + FILE *output = debug_output; + char prefix[80], buffer[1000]; + 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); /* print another line, except after a final newline */ +} + + +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, + ...) +{ +/* We only build this code if SVN_DEBUG is defined. */ +#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 = svn__apr_hash_index_key(hi); + svn_string_t *val = svn__apr_hash_index_val(hi); + + svn_dbg__printf(" '%s' -> '%s'\n", name, val->data); + } +#endif /* SVN_DEBUG */ +} + |