portable xprintf implementation
This commit is contained in:
parent
e4248584b6
commit
32d6760d4f
|
@ -561,25 +561,76 @@ xfprintf(xFILE *stream, const char *fmt, ...)
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
xfile_printint(xFILE *stream, long x, int base)
|
||||||
|
{
|
||||||
|
static char digits[] = "0123456789abcdef";
|
||||||
|
char buf[20];
|
||||||
|
int i, neg;
|
||||||
|
|
||||||
|
neg = 0;
|
||||||
|
if (x < 0) {
|
||||||
|
neg = 1;
|
||||||
|
x = -x;
|
||||||
|
}
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
buf[i++] = digits[x % base];
|
||||||
|
} while ((x /= base) != 0);
|
||||||
|
|
||||||
|
if (neg) {
|
||||||
|
buf[i++] = '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
while (i-- > 0) {
|
||||||
|
xputc(buf[i], stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PIC_INLINE int
|
PIC_INLINE int
|
||||||
xvfprintf(xFILE *stream, const char *fmt, va_list ap)
|
xvfprintf(xFILE *stream, const char *fmt, va_list ap)
|
||||||
{
|
{
|
||||||
va_list ap2;
|
const char *p;
|
||||||
|
char *sval;
|
||||||
|
int ival;
|
||||||
|
double dval;
|
||||||
|
void *vp;
|
||||||
|
long seekr = xftell(stream);
|
||||||
|
|
||||||
va_copy(ap2, ap);
|
for (p = fmt; *p; p++) {
|
||||||
{
|
if (*p != '%') {
|
||||||
char buf[vsnprintf(NULL, 0, fmt, ap2)];
|
xputc(*p, stream);
|
||||||
|
continue;
|
||||||
vsnprintf(buf, sizeof buf + 1, fmt, ap);
|
|
||||||
|
|
||||||
if (xfwrite(buf, sizeof buf, 1, stream) < 1) {
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
switch (*++p) {
|
||||||
va_end(ap2);
|
case 'd':
|
||||||
return (int)(sizeof buf);
|
case 'i':
|
||||||
|
ival = va_arg(ap, int);
|
||||||
|
xfile_printint(stream, ival, 10);
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
dval = va_arg(ap, double);
|
||||||
|
xfile_printint(stream, dval, 10);
|
||||||
|
xputc('.', stream);
|
||||||
|
xfile_printint(stream, fabs((dval - (int)dval) * 1e4), 10);
|
||||||
|
break;
|
||||||
|
case 's':
|
||||||
|
sval = va_arg(ap, char*);
|
||||||
|
xfputs(sval, stream);
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
vp = va_arg(ap, void*);
|
||||||
|
xfputs("0x", stream);
|
||||||
|
xfile_printint(stream, dval, 16);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
xputc(*(p-1), stream);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return xftell(stream) - seekr;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue