| Index: debug.c
|
| diff --git a/debug.c b/debug.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fc51ef699d0b22d9e29c41a24318faf1cdc9ecab
|
| --- /dev/null
|
| +++ b/debug.c
|
| @@ -0,0 +1,303 @@
|
| +/****************************************************************************
|
| + | (C) Copyright 2008 Novell, Inc. All Rights Reserved.
|
| + |
|
| + | GPLv2: This program is free software; you can redistribute it
|
| + | and/or modify it under the terms of version 2 of the GNU General
|
| + | Public License as published by the Free Software Foundation.
|
| + |
|
| + | This program is distributed in the hope that it will be useful,
|
| + | but WITHOUT ANY WARRANTY; without even the implied warranty of
|
| + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
| + | GNU General Public License for more details.
|
| + +-------------------------------------------------------------------------*/
|
| +
|
| +#include <stdlib.h>
|
| +#include <stdio.h>
|
| +#include <stdarg.h>
|
| +#include <ctype.h>
|
| +#include <debug.h>
|
| +#include <string.h>
|
| +
|
| +#ifdef __WINDOWS__
|
| + #define strncasecmp _strnicmp
|
| + #define strcasecmp _stricmp
|
| + #define snprintf sprintf_s
|
| +#endif
|
| +
|
| +#include <style.h>
|
| +
|
| +int DebugIsOn = 1;
|
| +int AssertIsOn = 1;
|
| +int FnDebugIsOn = 1;
|
| +
|
| +static FILE **stdbug = &stdout;
|
| +
|
| +int debugon (void)
|
| +{
|
| + return DebugIsOn = 1;
|
| +}
|
| +
|
| +int debugoff (void)
|
| +{
|
| + return DebugIsOn = 0;
|
| +}
|
| +
|
| +int fdebugon (void)
|
| +{
|
| + return FnDebugIsOn = 1;
|
| +}
|
| +
|
| +int fdebugoff (void)
|
| +{
|
| + return FnDebugIsOn = 0;
|
| +}
|
| +
|
| +void debugstderr (void)
|
| +{
|
| + stdbug = &stderr;
|
| +}
|
| +
|
| +void debugstdout (void)
|
| +{
|
| + stdbug = &stdout;
|
| +}
|
| +
|
| +bool debug_is_on (void)
|
| +{
|
| + return DebugIsOn;
|
| +}
|
| +
|
| +bool debug_is_off (void)
|
| +{
|
| + return !DebugIsOn;
|
| +}
|
| +
|
| +int debugenv (void)
|
| +{
|
| + char *c;
|
| +
|
| + c = getenv("DEBUG");
|
| + if (c) {
|
| + if (strcasecmp(c, "on") == 0) {
|
| + fprintf(*stdbug, "Debug is on\n");
|
| + DebugIsOn = 1;
|
| + debugon();
|
| + fdebugon();
|
| + } else if (strcasecmp(c, "off") == 0) {
|
| + debugoff();
|
| + fdebugoff();
|
| + }
|
| + }
|
| + return DebugIsOn;
|
| +}
|
| +
|
| +bool prf (const char *fn)
|
| +{
|
| + if (FnDebugIsOn) {
|
| + fprintf(*stdbug, "%s\n", fn);
|
| + fflush(*stdbug);
|
| + }
|
| + return TRUE;
|
| +}
|
| +
|
| +int prbug (const char *format, ...)
|
| +{
|
| + va_list args;
|
| + int rc;
|
| +
|
| + va_start(args, format);
|
| + rc = vfprintf(*stdbug, format, args);
|
| + va_end(args);
|
| +
|
| + return rc;
|
| +}
|
| +
|
| +int flushbug (void)
|
| +{
|
| + return fflush(*stdbug);
|
| +}
|
| +
|
| +bool print (const char *fn, unsigned line, const char *format, ...)
|
| +{
|
| + va_list args;
|
| + char buf[80];
|
| + char *b = buf;
|
| + int r = sizeof(buf);
|
| + int n;
|
| +
|
| + if (!DebugIsOn) return TRUE;
|
| +
|
| + if (line) {
|
| + n = snprintf(b, r, "%s<%u>", fn, line);
|
| + } else {
|
| + n = snprintf(b, r, "%s", fn);
|
| + }
|
| + b += n;
|
| + r -= n;
|
| +
|
| + va_start(args, format);
|
| + vsnprintf(b, r, format, args);
|
| + va_end(args);
|
| +
|
| + fprintf(*stdbug, "%s\n", buf);
|
| + fflush(*stdbug);
|
| +
|
| + return TRUE;
|
| +}
|
| +
|
| +bool pr (const char *fn, unsigned line, const char *label)
|
| +{
|
| + if (label) return print(fn, line, "%s", label);
|
| + else return print(fn, line, "");
|
| +}
|
| +
|
| +bool prd (const char *fn, unsigned line, const char *label, s64 x)
|
| +{
|
| + return print(fn, line, "%s=%lld", label, x);
|
| +}
|
| +
|
| +bool prp (const char *fn, unsigned line, const char *label, void *x)
|
| +{
|
| + return print(fn, line, "%s=%p", label, x);
|
| +}
|
| +
|
| +bool prs (const char *fn, unsigned line, const char *label, const char *s)
|
| +{
|
| + return print(fn, line, "%s=%s", label, s);
|
| +}
|
| +
|
| +bool pru (const char *fn, unsigned line, const char *label, u64 x)
|
| +{
|
| + return print(fn, line, "%s=%llu", label, x);
|
| +}
|
| +
|
| +bool prx (const char *fn, unsigned line, const char *label, u64 x)
|
| +{
|
| + return print(fn, line, "%s=%llx", label, x);
|
| +}
|
| +
|
| +bool prg (const char *fn, unsigned line, const char *label, double x)
|
| +{
|
| + return print(fn, line, "%s=%g", label, x);
|
| +}
|
| +
|
| +static void pr_n_u8 (const void *mem, unint n)
|
| +{
|
| + const u8 *u = mem;
|
| + unint i;
|
| +
|
| + prbug(" ");
|
| + for (i = 4; i > n; i--) prbug(" ");
|
| +
|
| + while (i-- > 0) prbug("%.2x", u[i]);
|
| +}
|
| +
|
| +bool prmem (
|
| + const char *label,
|
| + const void *mem,
|
| + unsigned int n)
|
| +{
|
| + enum { NLONGS = 4,
|
| + NCHARS = NLONGS * sizeof(u32) };
|
| +
|
| + const u32 *p = mem;
|
| + const char *c = mem;
|
| + unsigned i, j;
|
| + unsigned q, r;
|
| +
|
| + if (!DebugIsOn) return TRUE;
|
| +
|
| + prbug("%s:\n", label);
|
| +
|
| + q = n / NCHARS;
|
| + r = n % NCHARS;
|
| + for (i = 0; i < q; i++) {
|
| + prbug("%p:", p);
|
| + for (j = 0; j < NLONGS; j++) {
|
| + prbug(" %8x", *p++);
|
| + }
|
| + prbug(" | ");
|
| + for (j = 0; j < NCHARS; j++, c++) {
|
| + prbug("%c", isprint(*c) ? *c : '.');
|
| + }
|
| + prbug("\n");
|
| + }
|
| + flushbug();
|
| + if (!r) return TRUE;
|
| + prbug("%8p:", p);
|
| + for (j = 0; j < r / sizeof(u32); j++) {
|
| + prbug(" %8x", *p++);
|
| + }
|
| + i = r % sizeof(u32);
|
| + if (i) {
|
| + ++j;
|
| + pr_n_u8(p, i);
|
| + }
|
| + for (; j < NLONGS; j++) {
|
| + prbug(" ");
|
| + }
|
| + prbug(" | ");
|
| + for (j = 0; j < r; j++, c++) {
|
| + prbug("%c", isprint(*c) ? *c : '.');
|
| + }
|
| + prbug("\n");
|
| + flushbug();
|
| + return TRUE;
|
| +}
|
| +
|
| +bool prbytes (
|
| + const char *label,
|
| + const void *mem,
|
| + unsigned int n)
|
| +{
|
| + enum { CHARS_PER_LINE = 16 };
|
| + const u8 *p = mem;
|
| + const char *c = mem;
|
| + unsigned i, j;
|
| + unsigned q, r;
|
| +
|
| + if (!DebugIsOn) return TRUE;
|
| +
|
| + prbug("%s:\n", label);
|
| +
|
| + q = n / CHARS_PER_LINE;
|
| + r = n % CHARS_PER_LINE;
|
| + for (i = 0; i < q; i++) {
|
| + prbug("%p:", p);
|
| + for (j = 0; j < CHARS_PER_LINE; j++) {
|
| + prbug(" %.2x", *p++);
|
| + }
|
| + prbug(" | ");
|
| + for (j = 0; j < CHARS_PER_LINE; j++, c++) {
|
| + prbug("%c", isprint(*c) ? *c : '.');
|
| + }
|
| + prbug("\n");
|
| + }
|
| + if (r) {
|
| + prbug("%8p:", p);
|
| + for (j = 0; j < r; j++) {
|
| + prbug(" %.2x", *p++);
|
| + }
|
| + for (; j < CHARS_PER_LINE; j++) {
|
| + prbug(" ");
|
| + }
|
| + prbug(" | ");
|
| + for (j = 0; j < r; j++, c++) {
|
| + prbug("%c", isprint(*c) ? *c : '.');
|
| + }
|
| + prbug("\n");
|
| + }
|
| + flushbug();
|
| + return TRUE;
|
| +}
|
| +
|
| +int assertError (const char *what)
|
| +{
|
| + if (AssertIsOn) {
|
| + prbug("ASSERT FAILED: %s\n", what);
|
| + flushbug();
|
| + exit(2);
|
| + }
|
| + return 0;
|
| +}
|
| +
|
|
|