diff options
Diffstat (limited to 'source/fitz')
-rw-r--r-- | source/fitz/printf.c | 136 |
1 files changed, 118 insertions, 18 deletions
diff --git a/source/fitz/printf.c b/source/fitz/printf.c index 3d0ed19b..f63da293 100644 --- a/source/fitz/printf.c +++ b/source/fitz/printf.c @@ -1,5 +1,11 @@ #include "mupdf/fitz.h" +/* This definition will be made elsewhere soon, but putting it here + * temporarily means the commits can be sensibly ordered. */ +typedef int fz_off_t; + +static const char *fz_hex_digits = "0123456789abcdef"; + struct fmtbuf { char *p; @@ -54,24 +60,30 @@ static void fmtfloat(struct fmtbuf *out, float f) } } -static void fmtint(struct fmtbuf *out, int value, int z, int base) +static void fmtuint(struct fmtbuf *out, unsigned int a, int z, int base) { - static const char *digits = "0123456789abcdef"; char buf[40]; - unsigned int a; int i; - if (value < 0) - { - fmtputc(out, '-'); - a = -value; + i = 0; + while (a) { + buf[i++] = fz_hex_digits[a % base]; + a /= base; } - else - a = value; + while (i < z) + buf[i++] = '0'; + while (i > 0) + fmtputc(out, buf[--i]); +} + +static void fmtuint64(struct fmtbuf *out, uint64_t a, int z, int base) +{ + char buf[80]; + int i; i = 0; while (a) { - buf[i++] = digits[a % base]; + buf[i++] = fz_hex_digits[a % base]; a /= base; } while (i < z) @@ -80,6 +92,34 @@ static void fmtint(struct fmtbuf *out, int value, int z, int base) fmtputc(out, buf[--i]); } +static void fmtint(struct fmtbuf *out, int value, int z, int base) +{ + unsigned int a; + + if (value < 0) + { + fmtputc(out, '-'); + a = -value; + } + else + a = value; + fmtuint(out, a, z, base); +} + +static void fmtint64(struct fmtbuf *out, int64_t value, int z, int base) +{ + unsigned int a; + + if (value < 0) + { + fmtputc(out, '-'); + a = -value; + } + else + a = value; + fmtuint64(out, a, z, base); +} + static void fmtquote(struct fmtbuf *out, const char *s, int sq, int eq) { int c; @@ -117,8 +157,10 @@ fz_vsnprintf(char *buffer, int space, const char *fmt, va_list args) fz_rect *r; fz_point *p; int c, i, n, z; + int64_t i64; double f; char *s; + int length; out.p = buffer; out.s = space; @@ -134,6 +176,36 @@ fz_vsnprintf(char *buffer, int space, const char *fmt, va_list args) if (c == '0' && fmt[0] && fmt[1]) { z = *fmt++ - '0'; c = *fmt++; + if (c >= '0' && 'c' <= '9' && fmt[0]) + { + z = z*10 + c - '0'; + c = *fmt++; + } + } + /* Check for lengths */ + length = 0; + switch (c) { + case 'l': + c = *fmt++; + if (c == 'l') + length = 64; + else + fmt--; + break; + case 'z': + if (sizeof(size_t) >= 8) + length = 64; + break; + case 'Z': + if (sizeof(fz_off_t) >= 8) + length = 64; + break; + } + if (length != 0) + { + c = *fmt++; + if (c == 0) + break; /* Can't warn :( */ } switch (c) { default: @@ -143,7 +215,7 @@ fz_vsnprintf(char *buffer, int space, const char *fmt, va_list args) case '%': fmtputc(&out, '%'); break; - case 'M': + case 'M': /* fz_matrix * */ m = va_arg(args, fz_matrix*); fmtfloat(&out, m->a); fmtputc(&out, ' '); fmtfloat(&out, m->b); fmtputc(&out, ' '); @@ -152,19 +224,19 @@ fz_vsnprintf(char *buffer, int space, const char *fmt, va_list args) fmtfloat(&out, m->e); fmtputc(&out, ' '); fmtfloat(&out, m->f); break; - case 'R': + case 'R': /* fz_rect * */ r = va_arg(args, fz_rect*); fmtfloat(&out, r->x0); fmtputc(&out, ' '); fmtfloat(&out, r->y0); fmtputc(&out, ' '); fmtfloat(&out, r->x1); fmtputc(&out, ' '); fmtfloat(&out, r->y1); break; - case 'P': + case 'P': /* fz_point * */ p = va_arg(args, fz_point*); fmtfloat(&out, p->x); fmtputc(&out, ' '); fmtfloat(&out, p->y); break; - case 'C': + case 'C': /* unicode char */ c = va_arg(args, int); if (c < 128) fmtputc(&out, c); @@ -185,12 +257,40 @@ fz_vsnprintf(char *buffer, int space, const char *fmt, va_list args) fmtfloat(&out, f); break; case 'x': - i = va_arg(args, int); - fmtint(&out, i, z, 16); + if (length == 64) + { + i64 = va_arg(args, int64_t); + fmtuint64(&out, i64, z, 16); + } + else + { + i = va_arg(args, int); + fmtuint(&out, i, z, 16); + } break; case 'd': - i = va_arg(args, int); - fmtint(&out, i, z, 10); + if (length == 64) + { + i64 = va_arg(args, int64_t); + fmtint64(&out, i64, z, 10); + } + else + { + i = va_arg(args, int); + fmtint(&out, i, z, 10); + } + break; + case 'u': + if (length == 64) + { + i64 = va_arg(args, int64_t); + fmtuint64(&out, i64, z, 10); + } + else + { + i = va_arg(args, int); + fmtuint(&out, i, z, 10); + } break; case 'o': i = va_arg(args, int); |