summaryrefslogtreecommitdiff
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
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.
-rw-r--r--include/mupdf/fitz/output.h5
-rw-r--r--source/fitz/printf.c136
-rw-r--r--source/pdf/pdf-write.c6
3 files changed, 125 insertions, 22 deletions
diff --git a/include/mupdf/fitz/output.h b/include/mupdf/fitz/output.h
index 5be32d44..6291d37e 100644
--- a/include/mupdf/fitz/output.h
+++ b/include/mupdf/fitz/output.h
@@ -87,13 +87,16 @@ int fz_vfprintf(fz_context *ctx, FILE *file, const char *fmt, va_list ap);
int fz_fprintf(fz_context *ctx, FILE *file, const char *fmt, ...);
/*
- fz_vsnprintf: Our customised vsnprintf routine. Takes %c, %d, %o, %s, %x, as usual.
+ fz_vsnprintf: Our customised vsnprintf routine. Takes %c, %d, %o, %s, %u, %x, as usual.
Modifiers are not supported except for zero-padding ints (e.g. %02d, %03o, %04x, etc).
%f and %g both output in "as short as possible hopefully lossless non-exponent" form,
see fz_ftoa for specifics.
%C outputs a utf8 encoded int.
%M outputs a fz_matrix*. %R outputs a fz_rect*. %P outputs a fz_point*.
%q and %( output escaped strings in C/PDF syntax.
+ %ll{d,u,x} indicates that the values are 64bit.
+ %z{d,u,x} indicates that the value is a size_t.
+ %Z{d,u,x} indicates that the value is a fz_off_t.
*/
int fz_vsnprintf(char *buffer, int space, const char *fmt, va_list args);
int fz_snprintf(char *buffer, int space, const char *fmt, ...);
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);
diff --git a/source/pdf/pdf-write.c b/source/pdf/pdf-write.c
index 5f815e03..358deb7e 100644
--- a/source/pdf/pdf-write.c
+++ b/source/pdf/pdf-write.c
@@ -1788,9 +1788,9 @@ static void writexrefsubsect(pdf_write_options *opts, int from, int to)
for (num = from; num < to; num++)
{
if (opts->use_list[num])
- fprintf(opts->out, "%010d %05d n \n", opts->ofs_list[num], opts->gen_list[num]);
+ fprintf(opts->out, "%010Zd %05d n \n", opts->ofs_list[num], opts->gen_list[num]);
else
- fprintf(opts->out, "%010d %05d f \n", opts->ofs_list[num], opts->gen_list[num]);
+ fprintf(opts->out, "%010Zd %05d f \n", opts->ofs_list[num], opts->gen_list[num]);
}
}
@@ -2011,7 +2011,7 @@ static void writexrefstream(fz_context *ctx, pdf_document *doc, pdf_write_option
pdf_update_stream(ctx, doc, dict, fzbuf, 0);
writeobject(ctx, doc, opts, num, 0, 0);
- fprintf(opts->out, "startxref\n%d\n%%%%EOF\n", startxref);
+ fprintf(opts->out, "startxref\n%Zd\n%%%%EOF\n", startxref);
}
fz_always(ctx)
{