Buffer debug output to reduce the number of write() calls and allow to

output information that was logged before the library was initialised.
This commit is contained in:
Sam Hocevar
2009-12-20 12:24:50 +00:00
committed by sam
parent 2f05014c09
commit c4bcc65505
+58 -31
View File
@@ -24,6 +24,7 @@
# include <inttypes.h>
#endif
#include <stdio.h>
#include <string.h>
#if defined HAVE_UNISTD_H
# include <unistd.h>
#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;
}