summaryrefslogtreecommitdiff
path: root/source/fitz
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2015-03-20 18:59:27 +0000
committerRobin Watts <robin.watts@artifex.com>2015-03-24 19:50:02 +0000
commit25b979f243f0cd074dcfb91d0ecb7b3a2e07694b (patch)
tree51e2cc223ae227900ceb8c3822fbad8a611066e5 /source/fitz
parent33c49228d078cc963ac5e59e526c97d2fd50a01f (diff)
downloadmupdf-25b979f243f0cd074dcfb91d0ecb7b3a2e07694b.tar.xz
Update our printf to cope with various useful extensions.
Ensure that %010d works. Ensure that we can output 64 bit values (%ll{d,u,x}). Ensure that we can output size_t and fz_off_t (%z{d,u,x} and %Z{d,u,x}). fz_off_t isn't defined yet (it will be introduced by a commit that depends on this one), so for now, we put a stub definition in printf.c that we will remove later.
Diffstat (limited to 'source/fitz')
-rw-r--r--source/fitz/printf.c136
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);