#include <stddef.h>
#include <stdio.h>
-inline unsigned int nextpow10 (unsigned int x) {
+inline unsigned int nextpow (unsigned int x, int base) {
unsigned int n = 0;
while (x) {
n++;
- x = x / 10;
+ x = x / base;
}
return (n == 0) ? 1 : n;
}
char *s;
int d = 0;
unsigned int u;
- void *p;
char c = *fmt++;
/* copy standard char */
*str++ = c;
} else {
int t = 0;
- size_t i;
+ char w = '0';
+ size_t i, sz = 0;
+ void *p = NULL;
+
+ /* stamp */
+ if ((*fmt == ' ') || (*fmt == '0')) {
+ w = *fmt++;
+ }
+
+ /* size */
+ if ((*fmt >= '1') && (*fmt <= '9')) {
+ sz = *fmt++ - '0';
+ }
/* process format char */
switch (*fmt++) {
/* fall through */
case 'u': /* unsigned int */
u = (t) ? (unsigned int)d : va_arg (ap, unsigned int);
- for (i = nextpow10 (u), s = str; i > 0; i--, s++) {
+ for (i = nextpow (u, 10), s = str; i > 0; i--, s++) {
str[i - 1] = '0' + (u % 10);
u /= 10;
}
str = s;
break;
case 'p': /* pointer */
- p = va_arg (ap, void *);
*str++ = '0';
*str++ = 'x';
- for (i = sizeof (void *) * 2; i > 0; i--) {
+ w = '0';
+ sz = sizeof (void *) * 2;
+ p = va_arg (ap, void *);
+ /* fall through */
+ case 'x': /* integer hexa */
+ if (!p) {
+ u = va_arg (ap, unsigned int);
+ p = (void *)u;
+ if (sz == 0) {
+ sz = nextpow (u, 16);
+ }
+ }
+ for (i = sz, t = 1; i > 0; i--) {
char x = (char)(((uintptr_t)p >> (i * 4 - 4)) & 0xf);
- *str++ = (x > 9) ? 'a' + x - 10 : '0' + x;
+ if ((t == 1) && (x == 0)) {
+ *str++ = w;
+ } else {
+ *str++ = (x > 9) ? 'a' + x - 10 : '0' + x;
+ t = 0;
+ }
}
break;
case 's': /* string */
return 0;
}
-/* vim: set ts=4 sw=4 et */
+/* vim: set ts=4 sw=4 et: */