From c4bcc655052a1161eb39226cc3c10a7c9601d24a Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Sun, 20 Dec 2009 12:24:50 +0000 Subject: [PATCH] Buffer debug output to reduce the number of write() calls and allow to output information that was logged before the library was initialised. --- src/libzzuf/debug.c | 89 +++++++++++++++++++++++++++++---------------- 1 file changed, 58 insertions(+), 31 deletions(-) diff --git a/src/libzzuf/debug.c b/src/libzzuf/debug.c index 42115f1..da4db8d 100644 --- a/src/libzzuf/debug.c +++ b/src/libzzuf/debug.c @@ -24,6 +24,7 @@ # include #endif #include +#include #if defined HAVE_UNISTD_H # include #endif @@ -42,20 +43,24 @@ static void mydebug(char const *format, va_list args); * Helper macro to write an integer value to a given file descriptor, * either in base 10 or in hexadecimal. */ -#define WRITE_INT(fd, i, base) \ +#define WRITE_INT(i, base) \ do \ { \ char buf[128], *b = buf + 127; \ if(i <= 0) \ - write(fd, (i = -i) ? "-" : "0", 1); /* XXX: hack here */ \ + append((i = -i) ? "-" : "0", 1); /* XXX: hack here */ \ while(i) \ { \ *b-- = hex2char[i % base]; \ i /= base; \ } \ - write(fd, b + 1, (int)(buf + 127 - b)); \ + append(b + 1, (int)(buf + 127 - b)); \ } while(0) +/* Temporary buffer for deferred output */ +char debugbuffer[BUFSIZ]; +size_t debugcount = 1; + void _zz_debug(char const *format, ...) { va_list args; @@ -85,23 +90,36 @@ void _zz_debug2(char const *format, ...) * - vfprintf(stderr, format, args); * - fprintf(stderr, "\n"); */ +static inline void append(void const *data, size_t count) +{ + if (debugcount + count <= sizeof(debugbuffer)) + { + memcpy(debugbuffer + debugcount, data, count); + debugcount += count; + } +} + static void mydebug(char const *format, va_list args) { static char const *hex2char = "0123456789abcdef"; char const *f; int saved_errno; - if(_zz_debugfd < 0) - return; - saved_errno = errno; - write(_zz_debugfd, "** zzuf debug ** ", 17); + /* If there is spare data and the debug fd is open, we send the data */ + if (debugcount && _zz_debugfd >= 0) + { + write(_zz_debugfd, debugbuffer, debugcount); + debugcount = 0; + } + + append("** zzuf debug ** ", 17); for(f = format; *f; f++) { if(*f != '%') { - write(_zz_debugfd, f, 1); + append(f, 1); continue; } @@ -113,47 +131,47 @@ static void mydebug(char const *format, va_list args) { char i = (char)(unsigned char)va_arg(args, int); if(i >= 0x20 && i < 0x7f) - write(_zz_debugfd, &i, 1); + append(&i, 1); else if(i == '\n') - write(_zz_debugfd, "\\n", 2); + append("\\n", 2); else if(i == '\t') - write(_zz_debugfd, "\\t", 2); + append("\\t", 2); else if(i == '\r') - write(_zz_debugfd, "\\r", 2); + append("\\r", 2); else { - write(_zz_debugfd, "\\x", 2); - write(_zz_debugfd, hex2char + ((i & 0xf0) >> 4), 1); - write(_zz_debugfd, hex2char + (i & 0x0f), 1); + append("\\x", 2); + append(hex2char + ((i & 0xf0) >> 4), 1); + append(hex2char + (i & 0x0f), 1); } } else if(*f == 'i' || *f == 'd') { int i = va_arg(args, int); - WRITE_INT(_zz_debugfd, i, 10); + WRITE_INT(i, 10); } else if(*f == 'x') { int i = va_arg(args, int); - WRITE_INT(_zz_debugfd, i, 16); + WRITE_INT(i, 16); } else if(f[0] == 'l' && (f[1] == 'i' || f[1] == 'd')) { long int i = va_arg(args, long int); - WRITE_INT(_zz_debugfd, i, 10); + WRITE_INT(i, 10); f++; } else if(f[0] == 'l' && f[1] == 'l' && (f[2] == 'i' || f[1] == 'd')) { long long int i = va_arg(args, long long int); - WRITE_INT(_zz_debugfd, i, 10); + WRITE_INT(i, 10); f += 2; } else if(f[0] == 'g') { double g = va_arg(args, double), h = 0.0000001; int i = (int)g; - WRITE_INT(_zz_debugfd, i, 10); + WRITE_INT(i, 10); for(i = 0; i < 7; i++) { g = (g - (int)g) * 10; @@ -161,46 +179,55 @@ static void mydebug(char const *format, va_list args) if(g < h) break; if(i == 0) - write(_zz_debugfd, ".", 1); - write(_zz_debugfd, hex2char + (int)g, 1); + append(".", 1); + append(hex2char + (int)g, 1); } } else if(f[0] == 'p') { uintptr_t i = va_arg(args, uintptr_t); if(!i) - write(_zz_debugfd, "NULL", 5); + append("NULL", 5); else { - write(_zz_debugfd, "0x", 2); - WRITE_INT(_zz_debugfd, i, 16); + append("0x", 2); + WRITE_INT(i, 16); } } else if(f[0] == 's') { char *s = va_arg(args, char *); if(!s) - write(_zz_debugfd, "(nil)", 5); + append("(nil)", 5); else { int l = 0; while(s[l]) l++; - write(_zz_debugfd, s, l); + append(s, l); } } else if(f[0] == '0' && f[1] == '2' && f[2] == 'x') { int i = va_arg(args, int); - write(_zz_debugfd, hex2char + ((i & 0xf0) >> 4), 1); - write(_zz_debugfd, hex2char + (i & 0x0f), 1); + append(hex2char + ((i & 0xf0) >> 4), 1); + append(hex2char + (i & 0x0f), 1); f += 2; } else { - write(_zz_debugfd, f - 1, 2); + append(f - 1, 2); } } - write(_zz_debugfd, "\n", 1); + append("\n", 1); + + /* If the debug fd is open, we send the data */ + if (_zz_debugfd >= 0) + { + write(_zz_debugfd, debugbuffer, debugcount); + debugcount = 0; + } + errno = saved_errno; } +