summaryrefslogtreecommitdiff
path: root/source/fitz/printf.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2017-03-15 17:27:43 +0100
committerTor Andersson <tor.andersson@artifex.com>2017-03-22 12:07:26 +0100
commitc1b2500028a9461f1835f8879b2ad34260e2726c (patch)
tree1f0e97f2141f56bf83543446238b20a7aad59143 /source/fitz/printf.c
parente013fd7d0f5ae8f5c994aad4d02f5169946f1a26 (diff)
downloadmupdf-c1b2500028a9461f1835f8879b2ad34260e2726c.tar.xz
Extend our printf formatting to take width and precision.
Diffstat (limited to 'source/fitz/printf.c')
-rw-r--r--source/fitz/printf.c267
1 files changed, 172 insertions, 95 deletions
diff --git a/source/fitz/printf.c b/source/fitz/printf.c
index d0f95327..ab87e2e9 100644
--- a/source/fitz/printf.c
+++ b/source/fitz/printf.c
@@ -60,7 +60,23 @@ static void fmtfloat(struct fmtbuf *out, float f)
}
}
-static void fmtuint(struct fmtbuf *out, unsigned int a, int z, int base)
+static void fmtfloat_e(struct fmtbuf *out, double f, int w, int p)
+{
+ char buf[100], *s = buf;
+ snprintf(buf, sizeof buf, "%*.*e", w, p, f);
+ while (*s)
+ fmtputc(out, *s++);
+}
+
+static void fmtfloat_f(struct fmtbuf *out, double f, int w, int p)
+{
+ char buf[100], *s = buf;
+ snprintf(buf, sizeof buf, "%*.*f", w, p, f);
+ while (*s)
+ fmtputc(out, *s++);
+}
+
+static void fmtuint32(struct fmtbuf *out, unsigned int a, int s, int z, int w, int base)
{
char buf[40];
int i;
@@ -70,13 +86,15 @@ static void fmtuint(struct fmtbuf *out, unsigned int a, int z, int base)
buf[i++] = fz_hex_digits[a % base];
a /= base;
}
- while (i < z)
- buf[i++] = '0';
+ while (i < w)
+ buf[i++] = z;
+ if (s)
+ fmtputc(out, '+');
while (i > 0)
fmtputc(out, buf[--i]);
}
-static void fmtuint64(struct fmtbuf *out, uint64_t a, int z, int base)
+static void fmtuint64(struct fmtbuf *out, uint64_t a, int s, int z, int w, int base)
{
char buf[80];
int i;
@@ -86,13 +104,15 @@ static void fmtuint64(struct fmtbuf *out, uint64_t a, int z, int base)
buf[i++] = fz_hex_digits[a % base];
a /= base;
}
- while (i < z)
- buf[i++] = '0';
+ while (i < w)
+ buf[i++] = z;
+ if (s)
+ fmtputc(out, '+');
while (i > 0)
fmtputc(out, buf[--i]);
}
-static void fmtint(struct fmtbuf *out, int value, int z, int base)
+static void fmtint32(struct fmtbuf *out, int value, int s, int z, int w, int base)
{
unsigned int a;
@@ -103,12 +123,12 @@ static void fmtint(struct fmtbuf *out, int value, int z, int base)
}
else
a = value;
- fmtuint(out, a, z, base);
+ fmtuint32(out, a, s, z, w, base);
}
-static void fmtint64(struct fmtbuf *out, int64_t value, int z, int base)
+static void fmtint64(struct fmtbuf *out, int64_t value, int s, int z, int w, int base)
{
- unsigned int a;
+ uint64_t a;
if (value < 0)
{
@@ -117,7 +137,7 @@ static void fmtint64(struct fmtbuf *out, int64_t value, int z, int base)
}
else
a = value;
- fmtuint64(out, a, z, base);
+ fmtuint64(out, a, s, z, w, base);
}
static void fmtquote(struct fmtbuf *out, const char *s, int sq, int eq)
@@ -153,14 +173,11 @@ void
fz_format_string(fz_context *ctx, void *user, void (*emit)(fz_context *ctx, void *user, int c), const char *fmt, va_list args)
{
struct fmtbuf out;
- int c, i, n, z;
- fz_matrix *m;
- fz_rect *r;
- fz_point *p;
+ int c, s, z, p, w;
+ int32_t i32;
int64_t i64;
- double f;
- char *s;
- size_t length;
+ const char *str;
+ size_t bits;
out.ctx = ctx;
out.user = user;
@@ -174,45 +191,90 @@ fz_format_string(fz_context *ctx, void *user, void (*emit)(fz_context *ctx, void
if (c == 0)
break;
- z = 1;
- if (c == '0' && fmt[0] && fmt[1]) {
- z = *fmt++ - '0';
+ /* sign */
+ s = 0;
+ if (c == '+') {
+ s = 1;
c = *fmt++;
- while (c >= '0' && c <= '9' && fmt[0])
- {
- z = z*10 + c - '0';
+ if (c == 0)
+ break;
+ }
+
+ /* TODO: '-' to left justify */
+
+ /* leading zero */
+ z = ' ';
+ if (c == '0') {
+ z = '0';
+ c = *fmt++;
+ if (c == 0)
+ break;
+ }
+
+ /* width */
+ w = 0;
+ if (c == '*') {
+ c = *fmt++;
+ w = va_arg(args, int);
+ } else {
+ while (c >= '0' && c <= '9') {
+ w = w * 10 + c - '0';
c = *fmt++;
}
}
+ if (c == 0)
+ break;
- /* Check for lengths */
- length = 0;
- switch (c) {
- case 'l':
+ /* precision */
+ p = 6;
+ if (c == '.') {
c = *fmt++;
- if (c == 'l')
- length = 64;
- else
- {
- length = sizeof(long) * 8;
- fmt--;
+ if (c == 0)
+ break;
+ if (c == '*') {
+ c = *fmt++;
+ p = va_arg(args, int);
+ } else {
+ if (c >= '0' && c <= '9')
+ p = 0;
+ while (c >= '0' && c <= '9') {
+ p = p * 10 + c - '0';
+ c = *fmt++;
+ }
}
+ }
+ if (c == 0)
break;
- case 't':
- length = sizeof(ptrdiff_t) * 8;
- break;
- case 'z':
- length = sizeof(size_t) * 8;
- break;
- case 'Z':
- length = sizeof(fz_off_t) * 8;
- break;
+
+ /* lengths */
+ bits = 0;
+ if (c == 'l') {
+ c = *fmt++;
+ bits = sizeof(long) * 8;
+ if (c == 'l') {
+ c = *fmt++;
+ bits = 64;
+ }
+ if (c == 0)
+ break;
+ }
+ if (c == 't') {
+ c = *fmt++;
+ bits = sizeof(ptrdiff_t) * 8;
+ if (c == 0)
+ break;
+ }
+ if (c == 'z') {
+ c = *fmt++;
+ bits = sizeof(size_t) * 8;
+ if (c == 0)
+ break;
}
- if (length != 0)
- {
+ if (c == 'Z') {
c = *fmt++;
+ bits = sizeof(fz_off_t) * 8;
if (c == 0)
- break; /* Can't warn :( */
+ break;
}
switch (c) {
@@ -223,34 +285,42 @@ fz_format_string(fz_context *ctx, void *user, void (*emit)(fz_context *ctx, void
case '%':
fmtputc(&out, '%');
break;
- case 'M': /* fz_matrix * */
- m = va_arg(args, fz_matrix*);
- fmtfloat(&out, m->a); fmtputc(&out, ' ');
- fmtfloat(&out, m->b); fmtputc(&out, ' ');
- fmtfloat(&out, m->c); fmtputc(&out, ' ');
- fmtfloat(&out, m->d); fmtputc(&out, ' ');
- fmtfloat(&out, m->e); fmtputc(&out, ' ');
- fmtfloat(&out, m->f);
+
+ case 'M':
+ {
+ fz_matrix *matrix = va_arg(args, fz_matrix*);
+ fmtfloat(&out, matrix->a); fmtputc(&out, ' ');
+ fmtfloat(&out, matrix->b); fmtputc(&out, ' ');
+ fmtfloat(&out, matrix->c); fmtputc(&out, ' ');
+ fmtfloat(&out, matrix->d); fmtputc(&out, ' ');
+ fmtfloat(&out, matrix->e); fmtputc(&out, ' ');
+ fmtfloat(&out, matrix->f);
+ }
break;
- 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);
+ case 'R':
+ {
+ fz_rect *rect = va_arg(args, fz_rect*);
+ fmtfloat(&out, rect->x0); fmtputc(&out, ' ');
+ fmtfloat(&out, rect->y0); fmtputc(&out, ' ');
+ fmtfloat(&out, rect->x1); fmtputc(&out, ' ');
+ fmtfloat(&out, rect->y1);
+ }
break;
- case 'P': /* fz_point * */
- p = va_arg(args, fz_point*);
- fmtfloat(&out, p->x); fmtputc(&out, ' ');
- fmtfloat(&out, p->y);
+ case 'P':
+ {
+ fz_point *point = va_arg(args, fz_point*);
+ fmtfloat(&out, point->x); fmtputc(&out, ' ');
+ fmtfloat(&out, point->y);
+ }
break;
+
case 'C': /* unicode char */
c = va_arg(args, int);
if (c < 128)
fmtputc(&out, c);
else {
char buf[10];
- n = fz_runetochar(buf, c);
+ int i, n = fz_runetochar(buf, c);
for (i=0; i < n; ++i)
fmtputc(&out, buf[i]);
}
@@ -259,73 +329,80 @@ fz_format_string(fz_context *ctx, void *user, void (*emit)(fz_context *ctx, void
c = va_arg(args, int);
fmtputc(&out, c);
break;
+
+ case 'e':
+ fmtfloat_e(&out, va_arg(args, double), w, p);
+ break;
case 'f':
+ fmtfloat_f(&out, va_arg(args, double), w, p);
+ break;
case 'g':
- f = va_arg(args, double);
- fmtfloat(&out, f);
+ fmtfloat(&out, va_arg(args, double));
break;
+
case 'p':
- length = 8 * sizeof(void *);
- z = 2 * sizeof(void *);
+ bits = 8 * sizeof(void *);
+ w = 2 * sizeof(void *);
fmtputc(&out, '0');
fmtputc(&out, 'x');
/* fallthrough */
case 'x':
- if (length == 64)
+ if (bits == 64)
{
i64 = va_arg(args, int64_t);
- fmtuint64(&out, i64, z, 16);
+ fmtuint64(&out, i64, s, z, w, 16);
}
else
{
- i = va_arg(args, int);
- fmtuint(&out, i, z, 16);
+ i32 = va_arg(args, int);
+ fmtuint32(&out, i32, s, z, w, 16);
}
break;
case 'd':
- if (length == 64)
+ if (bits == 64)
{
i64 = va_arg(args, int64_t);
- fmtint64(&out, i64, z, 10);
+ fmtint64(&out, i64, s, z, w, 10);
}
else
{
- i = va_arg(args, int);
- fmtint(&out, i, z, 10);
+ i32 = va_arg(args, int);
+ fmtint32(&out, i32, s, z, w, 10);
}
break;
case 'u':
- if (length == 64)
+ if (bits == 64)
{
i64 = va_arg(args, int64_t);
- fmtuint64(&out, i64, z, 10);
+ fmtuint64(&out, i64, s, z, w, 10);
}
else
{
- i = va_arg(args, int);
- fmtuint(&out, i, z, 10);
+ i32 = va_arg(args, int);
+ fmtuint32(&out, i32, s, z, w, 10);
}
break;
case 'o':
- i = va_arg(args, int);
- fmtint(&out, i, z, 8);
+ i32 = va_arg(args, int);
+ fmtint32(&out, i32, s, z, w, 8);
break;
+
case 's':
- s = va_arg(args, char*);
- if (!s)
- s = "(null)";
- while ((c = *s++) != 0)
+ str = va_arg(args, const char*);
+ if (!str)
+ str = "(null)";
+ while ((c = *str++) != 0)
fmtputc(&out, c);
break;
- case 'q':
- s = va_arg(args, char*);
- if (!s) s = "";
- fmtquote(&out, s, '"', '"');
+ case 'q': /* quoted string */
+ str = va_arg(args, const char*);
+ if (!str) str = "";
+ fmtquote(&out, str, '"', '"');
break;
- case '(':
- s = va_arg(args, char*);
- if (!s) s = "";
- fmtquote(&out, s, '(', ')');
+ case '(': /* pdf string */
+ str = va_arg(args, const char*);
+ if (!str) str = "";
+ fmtquote(&out, str, '(', ')');
break;
}
}