#include <stdio.h>
#include <stdarg.h>

int trace(char * s, ...)
{
	static const char DEC[] = "0123456789\0";
	static const char HEX[] = "0123456789abcdef\0";
	
	va_list ap;
	char * ptr;
	int i;
	int j;
	int k;
	char buf[16];
	int len = strlen(s);

	va_start(ap, s);
	for (i = 0; i < len; i++)
	{
		if (s[i] == '%' && i < len-1)
		{
			i++;
			switch (s[i])
			{
				case '%': /* % */
					putchar('%');
					break;
				case 's': /* string */
					ptr = va_arg(ap, char *);
					if (!ptr) break;
					while (*ptr) putchar(*ptr++);
					break;
				case 'd': /* decimal, pos. and neg. */
					j = va_arg(ap, int);
					if (j < 0) putchar('-');
					for (k = 15; k && j; --k)
					{
						buf[k] = DEC[j % 10];
						j /= 10;
					}
					for (; k < 15; putchar(buf[++k]));
					break;
				case 'c': /* character */
					putchar(va_arg(ap, char));
					break;
				case 'x': /* hexadecimal */
					j = va_arg(ap, int);
					for (k = 15; k && j; --k)
					{
						buf[k] = DEC[j % 16];
						j /= 16;
					}
					for (; k < 15; putchar(buf[++k]));
					break;
				default: /* UNKNOWN */
					putchar(s[i]);
					break;
			}
		}
		else putchar(s[i]);
	}
	va_end(ap);	
	return 0;
}

int main(int argc, char ** argv)
{
	trace("hello world [%s] %d %c 0x%x %%\n", "hallo", 10, '@', 85);
	return 0;
}
