summaryrefslogtreecommitdiff
path: root/Build/source/libs/xpdf/goo
diff options
context:
space:
mode:
authorMartin Schröder <martin@oneiros.de>2007-07-11 21:13:59 +0000
committerMartin Schröder <martin@oneiros.de>2007-07-11 21:13:59 +0000
commit7bf56e6bfcd7b204b3507dc9acaaaa3dce2cbcdb (patch)
tree5f8b4be4a21dc917441e4d2a1ec3e6fe25fd0192 /Build/source/libs/xpdf/goo
parentc0da09fd6e4a542610245624c185a66f5ec814b2 (diff)
Imported pdftex 1.40.4
git-svn-id: svn://tug.org/texlive/trunk@4561 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/libs/xpdf/goo')
-rw-r--r--Build/source/libs/xpdf/goo/FixedPoint.cc29
-rw-r--r--Build/source/libs/xpdf/goo/FixedPoint.h5
-rw-r--r--Build/source/libs/xpdf/goo/GString.cc449
-rw-r--r--Build/source/libs/xpdf/goo/GString.h39
-rw-r--r--Build/source/libs/xpdf/goo/Makefile.in7
-rw-r--r--Build/source/libs/xpdf/goo/depend.mk2
-rw-r--r--Build/source/libs/xpdf/goo/gfile.cc58
-rw-r--r--Build/source/libs/xpdf/goo/gfile.h5
-rw-r--r--Build/source/libs/xpdf/goo/gmem.cc (renamed from Build/source/libs/xpdf/goo/gmem.c)119
-rw-r--r--Build/source/libs/xpdf/goo/gmem.h25
10 files changed, 634 insertions, 104 deletions
diff --git a/Build/source/libs/xpdf/goo/FixedPoint.cc b/Build/source/libs/xpdf/goo/FixedPoint.cc
index f969959a66b..47c2834a34b 100644
--- a/Build/source/libs/xpdf/goo/FixedPoint.cc
+++ b/Build/source/libs/xpdf/goo/FixedPoint.cc
@@ -18,13 +18,15 @@
#include "FixedPoint.h"
+#define ln2 ((FixedPoint)0.69314718)
+
FixedPoint FixedPoint::sqrt(FixedPoint x) {
FixedPoint y0, y1, z;
if (x.val <= 0) {
y1.val = 0;
} else {
- y1.val = x.val >> 1;
+ y1.val = x.val == 1 ? 2 : x.val >> 1;
do {
y0.val = y1.val;
z = x / y0;
@@ -34,10 +36,9 @@ FixedPoint FixedPoint::sqrt(FixedPoint x) {
return y1;
}
-//~ this is not very accurate
FixedPoint FixedPoint::pow(FixedPoint x, FixedPoint y) {
FixedPoint t, t2, lnx0, lnx, z0, z;
- int d, i;
+ int d, n, i;
if (y.val <= 0) {
z.val = 0;
@@ -56,6 +57,8 @@ FixedPoint FixedPoint::pow(FixedPoint x, FixedPoint y) {
lnx.val <<= 1;
t = y * lnx;
// exp(y * ln(x))
+ n = floor(t / ln2);
+ t -= ln2 * n;
t2 = t;
d = 1;
i = 1;
@@ -67,6 +70,11 @@ FixedPoint FixedPoint::pow(FixedPoint x, FixedPoint y) {
++i;
d *= i;
} while (::abs(z.val - z0.val) > 2 && d < (1 << fixptShift));
+ if (n >= 0) {
+ z.val <<= n;
+ } else if (n < 0) {
+ z.val >>= -n;
+ }
}
return z;
}
@@ -92,4 +100,19 @@ int FixedPoint::div(int x, int y) {
#endif
}
+GBool FixedPoint::divCheck(FixedPoint x, FixedPoint y, FixedPoint *result) {
+#if 1 //~tmp
+ FixPtInt64 z;
+
+ z = ((FixPtInt64)x.val << fixptShift) / y.val;
+ if ((z == 0 && x != 0) ||
+ z >= ((FixPtInt64)1 << 31) || z < -((FixPtInt64)1 << 31)) {
+ return gFalse;
+ }
+ result->val = z;
+ return gTrue;
+#else
+#endif
+}
+
#endif // USE_FIXEDPOINT
diff --git a/Build/source/libs/xpdf/goo/FixedPoint.h b/Build/source/libs/xpdf/goo/FixedPoint.h
index 7e89018edb9..abcb212101d 100644
--- a/Build/source/libs/xpdf/goo/FixedPoint.h
+++ b/Build/source/libs/xpdf/goo/FixedPoint.h
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "gtypes.h"
#define fixptShift 16
#define fixptMaskL ((1 << fixptShift) - 1)
@@ -135,6 +136,10 @@ public:
static FixedPoint pow(FixedPoint x, FixedPoint y);
+ // Compute *result = x/y; return false if there is an underflow or
+ // overflow.
+ static GBool divCheck(FixedPoint x, FixedPoint y, FixedPoint *result);
+
private:
static FixedPoint make(int valA) { FixedPoint x; x.val = valA; return x; }
diff --git a/Build/source/libs/xpdf/goo/GString.cc b/Build/source/libs/xpdf/goo/GString.cc
index 049dcf38dc9..de280ad9842 100644
--- a/Build/source/libs/xpdf/goo/GString.cc
+++ b/Build/source/libs/xpdf/goo/GString.cc
@@ -18,14 +18,66 @@
#include <stddef.h>
#include <string.h>
#include <ctype.h>
-#include "gtypes.h"
+#include <math.h>
+#include "gmem.h"
#include "GString.h"
+//------------------------------------------------------------------------
+
+union GStringFormatArg {
+ int i;
+ Guint ui;
+ long l;
+ Gulong ul;
+ double f;
+ char c;
+ char *s;
+ GString *gs;
+};
+
+enum GStringFormatType {
+ fmtIntDecimal,
+ fmtIntHex,
+ fmtIntOctal,
+ fmtIntBinary,
+ fmtUIntDecimal,
+ fmtUIntHex,
+ fmtUIntOctal,
+ fmtUIntBinary,
+ fmtLongDecimal,
+ fmtLongHex,
+ fmtLongOctal,
+ fmtLongBinary,
+ fmtULongDecimal,
+ fmtULongHex,
+ fmtULongOctal,
+ fmtULongBinary,
+ fmtDouble,
+ fmtDoubleTrim,
+ fmtChar,
+ fmtString,
+ fmtGString,
+ fmtSpace
+};
+
+static char *formatStrings[] = {
+ "d", "x", "o", "b", "ud", "ux", "uo", "ub",
+ "ld", "lx", "lo", "lb", "uld", "ulx", "ulo", "ulb",
+ "f", "g",
+ "c",
+ "s",
+ "t",
+ "w",
+ NULL
+};
+
+//------------------------------------------------------------------------
+
static inline int size(int len) {
int delta;
-
- delta = len < 256 ? 7 : 255;
- return ((len + 1) + delta) & ~delta;
+ for (delta = 8; delta < len && delta < 0x100000; delta <<= 1) ;
+ // this is ((len + 1) + (delta - 1)) & ~(delta - 1)
+ return (len + delta) & ~(delta - 1);
}
inline void GString::resize(int length1) {
@@ -92,28 +144,30 @@ GString::GString(GString *str1, GString *str2) {
GString *GString::fromInt(int x) {
char buf[24]; // enough space for 64-bit ints plus a little extra
- GBool neg;
- Guint y;
- int i;
+ char *p;
+ int len;
- i = 24;
- if (x == 0) {
- buf[--i] = '0';
- } else {
- if ((neg = x < 0)) {
- y = (Guint)-x;
- } else {
- y = (Guint)x;
- }
- while (i > 0 && y > 0) {
- buf[--i] = '0' + y % 10;
- y /= 10;
- }
- if (neg && i > 0) {
- buf[--i] = '-';
- }
- }
- return new GString(buf + i, 24 - i);
+ formatInt(x, buf, sizeof(buf), gFalse, 0, 10, &p, &len);
+ return new GString(p, len);
+}
+
+GString *GString::format(char *fmt, ...) {
+ va_list argList;
+ GString *s;
+
+ s = new GString();
+ va_start(argList, fmt);
+ s->appendfv(fmt, argList);
+ va_end(argList);
+ return s;
+}
+
+GString *GString::formatv(char *fmt, va_list argList) {
+ GString *s;
+
+ s = new GString();
+ s->appendfv(fmt, argList);
+ return s;
}
GString::~GString() {
@@ -159,6 +213,351 @@ GString *GString::append(const char *str, int lengthA) {
return this;
}
+GString *GString::appendf(char *fmt, ...) {
+ va_list argList;
+
+ va_start(argList, fmt);
+ appendfv(fmt, argList);
+ va_end(argList);
+ return this;
+}
+
+GString *GString::appendfv(char *fmt, va_list argList) {
+ GStringFormatArg *args;
+ int argsLen, argsSize;
+ GStringFormatArg arg;
+ int idx, width, prec;
+ GBool reverseAlign, zeroFill;
+ GStringFormatType ft;
+ char buf[65];
+ int len, i;
+ char *p0, *p1, *str;
+
+ argsLen = 0;
+ argsSize = 8;
+ args = (GStringFormatArg *)gmallocn(argsSize, sizeof(GStringFormatArg));
+
+ p0 = fmt;
+ while (*p0) {
+ if (*p0 == '{') {
+ ++p0;
+ if (*p0 == '{') {
+ ++p0;
+ append('{');
+ } else {
+
+ // parse the format string
+ if (!(*p0 >= '0' && *p0 <= '9')) {
+ break;
+ }
+ idx = *p0 - '0';
+ for (++p0; *p0 >= '0' && *p0 <= '9'; ++p0) {
+ idx = 10 * idx + (*p0 - '0');
+ }
+ if (*p0 != ':') {
+ break;
+ }
+ ++p0;
+ if (*p0 == '-') {
+ reverseAlign = gTrue;
+ ++p0;
+ } else {
+ reverseAlign = gFalse;
+ }
+ width = 0;
+ zeroFill = *p0 == '0';
+ for (; *p0 >= '0' && *p0 <= '9'; ++p0) {
+ width = 10 * width + (*p0 - '0');
+ }
+ if (*p0 == '.') {
+ ++p0;
+ prec = 0;
+ for (; *p0 >= '0' && *p0 <= '9'; ++p0) {
+ prec = 10 * prec + (*p0 - '0');
+ }
+ } else {
+ prec = 0;
+ }
+ for (ft = (GStringFormatType)0;
+ formatStrings[ft];
+ ft = (GStringFormatType)(ft + 1)) {
+ if (!strncmp(p0, formatStrings[ft], strlen(formatStrings[ft]))) {
+ break;
+ }
+ }
+ if (!formatStrings[ft]) {
+ break;
+ }
+ p0 += strlen(formatStrings[ft]);
+ if (*p0 != '}') {
+ break;
+ }
+ ++p0;
+
+ // fetch the argument
+ if (idx > argsLen) {
+ break;
+ }
+ if (idx == argsLen) {
+ if (argsLen == argsSize) {
+ argsSize *= 2;
+ args = (GStringFormatArg *)greallocn(args, argsSize,
+ sizeof(GStringFormatArg));
+ }
+ switch (ft) {
+ case fmtIntDecimal:
+ case fmtIntHex:
+ case fmtIntOctal:
+ case fmtIntBinary:
+ case fmtSpace:
+ args[argsLen].i = va_arg(argList, int);
+ break;
+ case fmtUIntDecimal:
+ case fmtUIntHex:
+ case fmtUIntOctal:
+ case fmtUIntBinary:
+ args[argsLen].ui = va_arg(argList, Guint);
+ break;
+ case fmtLongDecimal:
+ case fmtLongHex:
+ case fmtLongOctal:
+ case fmtLongBinary:
+ args[argsLen].l = va_arg(argList, long);
+ break;
+ case fmtULongDecimal:
+ case fmtULongHex:
+ case fmtULongOctal:
+ case fmtULongBinary:
+ args[argsLen].ul = va_arg(argList, Gulong);
+ break;
+ case fmtDouble:
+ case fmtDoubleTrim:
+ args[argsLen].f = va_arg(argList, double);
+ break;
+ case fmtChar:
+ args[argsLen].c = (char)va_arg(argList, int);
+ break;
+ case fmtString:
+ args[argsLen].s = va_arg(argList, char *);
+ break;
+ case fmtGString:
+ args[argsLen].gs = va_arg(argList, GString *);
+ break;
+ }
+ ++argsLen;
+ }
+
+ // format the argument
+ arg = args[idx];
+ switch (ft) {
+ case fmtIntDecimal:
+ formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 10, &str, &len);
+ break;
+ case fmtIntHex:
+ formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 16, &str, &len);
+ break;
+ case fmtIntOctal:
+ formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
+ break;
+ case fmtIntBinary:
+ formatInt(arg.i, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
+ break;
+ case fmtUIntDecimal:
+ formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 10,
+ &str, &len);
+ break;
+ case fmtUIntHex:
+ formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 16,
+ &str, &len);
+ break;
+ case fmtUIntOctal:
+ formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
+ break;
+ case fmtUIntBinary:
+ formatUInt(arg.ui, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
+ break;
+ case fmtLongDecimal:
+ formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 10, &str, &len);
+ break;
+ case fmtLongHex:
+ formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 16, &str, &len);
+ break;
+ case fmtLongOctal:
+ formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
+ break;
+ case fmtLongBinary:
+ formatInt(arg.l, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
+ break;
+ case fmtULongDecimal:
+ formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 10,
+ &str, &len);
+ break;
+ case fmtULongHex:
+ formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 16,
+ &str, &len);
+ break;
+ case fmtULongOctal:
+ formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 8, &str, &len);
+ break;
+ case fmtULongBinary:
+ formatUInt(arg.ul, buf, sizeof(buf), zeroFill, width, 2, &str, &len);
+ break;
+ case fmtDouble:
+ formatDouble(arg.f, buf, sizeof(buf), prec, gFalse, &str, &len);
+ break;
+ case fmtDoubleTrim:
+ formatDouble(arg.f, buf, sizeof(buf), prec, gTrue, &str, &len);
+ break;
+ case fmtChar:
+ buf[0] = arg.c;
+ str = buf;
+ len = 1;
+ reverseAlign = !reverseAlign;
+ break;
+ case fmtString:
+ str = arg.s;
+ len = strlen(str);
+ reverseAlign = !reverseAlign;
+ break;
+ case fmtGString:
+ str = arg.gs->getCString();
+ len = arg.gs->getLength();
+ reverseAlign = !reverseAlign;
+ break;
+ case fmtSpace:
+ str = buf;
+ len = 0;
+ width = arg.i;
+ break;
+ }
+
+ // append the formatted arg, handling width and alignment
+ if (!reverseAlign && len < width) {
+ for (i = len; i < width; ++i) {
+ append(' ');
+ }
+ }
+ append(str, len);
+ if (reverseAlign && len < width) {
+ for (i = len; i < width; ++i) {
+ append(' ');
+ }
+ }
+ }
+
+ } else if (*p0 == '}') {
+ ++p0;
+ if (*p0 == '}') {
+ ++p0;
+ }
+ append('}');
+
+ } else {
+ for (p1 = p0 + 1; *p1 && *p1 != '{' && *p1 != '}'; ++p1) ;
+ append(p0, p1 - p0);
+ p0 = p1;
+ }
+ }
+
+ gfree(args);
+ return this;
+}
+
+void GString::formatInt(long x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ char **p, int *len) {
+ static char vals[17] = "0123456789abcdef";
+ GBool neg;
+ int start, i, j;
+
+ i = bufSize;
+ if ((neg = x < 0)) {
+ x = -x;
+ }
+ start = neg ? 1 : 0;
+ if (x == 0) {
+ buf[--i] = '0';
+ } else {
+ while (i > start && x) {
+ buf[--i] = vals[x % base];
+ x /= base;
+ }
+ }
+ if (zeroFill) {
+ for (j = bufSize - i; i > start && j < width - start; ++j) {
+ buf[--i] = '0';
+ }
+ }
+ if (neg) {
+ buf[--i] = '-';
+ }
+ *p = buf + i;
+ *len = bufSize - i;
+}
+
+void GString::formatUInt(Gulong x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ char **p, int *len) {
+ static char vals[17] = "0123456789abcdef";
+ int i, j;
+
+ i = bufSize;
+ if (x == 0) {
+ buf[--i] = '0';
+ } else {
+ while (i > 0 && x) {
+ buf[--i] = vals[x % base];
+ x /= base;
+ }
+ }
+ if (zeroFill) {
+ for (j = bufSize - i; i > 0 && j < width; ++j) {
+ buf[--i] = '0';
+ }
+ }
+ *p = buf + i;
+ *len = bufSize - i;
+}
+
+void GString::formatDouble(double x, char *buf, int bufSize, int prec,
+ GBool trim, char **p, int *len) {
+ GBool neg, started;
+ double x2;
+ int d, i, j;
+
+ if ((neg = x < 0)) {
+ x = -x;
+ }
+ x = floor(x * pow(10.0, prec) + 0.5);
+ i = bufSize;
+ started = !trim;
+ for (j = 0; j < prec && i > 1; ++j) {
+ x2 = floor(0.1 * (x + 0.5));
+ d = (int)floor(x - 10 * x2 + 0.5);
+ if (started || d != 0) {
+ buf[--i] = '0' + d;
+ started = gTrue;
+ }
+ x = x2;
+ }
+ if (i > 1 && started) {
+ buf[--i] = '.';
+ }
+ if (i > 1) {
+ do {
+ x2 = floor(0.1 * (x + 0.5));
+ d = (int)floor(x - 10 * x2 + 0.5);
+ buf[--i] = '0' + d;
+ x = x2;
+ } while (i > 1 && x);
+ }
+ if (neg) {
+ buf[--i] = '-';
+ }
+ *p = buf + i;
+ *len = bufSize - i;
+}
+
GString *GString::insert(int i, char c) {
int j;
diff --git a/Build/source/libs/xpdf/goo/GString.h b/Build/source/libs/xpdf/goo/GString.h
index f4ff7c6a9ee..dd22e2d8f6b 100644
--- a/Build/source/libs/xpdf/goo/GString.h
+++ b/Build/source/libs/xpdf/goo/GString.h
@@ -17,6 +17,9 @@
#pragma interface
#endif
+#include <stdarg.h>
+#include "gtypes.h"
+
class GString {
public:
@@ -43,6 +46,30 @@ public:
// Convert an integer to a string.
static GString *fromInt(int x);
+ // Create a formatted string. Similar to printf, but without the
+ // string overflow issues. Formatting elements consist of:
+ // {<arg>:[<width>][.<precision>]<type>}
+ // where:
+ // - <arg> is the argument number (arg 0 is the first argument
+ // following the format string) -- NB: args must be first used in
+ // order; they can be reused in any order
+ // - <width> is the field width -- negative to reverse the alignment;
+ // starting with a leading zero to zero-fill (for integers)
+ // - <precision> is the number of digits to the right of the decimal
+ // point (for floating point numbers)
+ // - <type> is one of:
+ // d, x, o, b -- int in decimal, hex, octal, binary
+ // ud, ux, uo, ub -- unsigned int
+ // ld, lx, lo, lb, uld, ulx, ulo, ulb -- long, unsigned long
+ // f, g -- double
+ // c -- char
+ // s -- string (char *)
+ // t -- GString *
+ // w -- blank space; arg determines width
+ // To get literal curly braces, use {{ or }}.
+ static GString *format(char *fmt, ...);
+ static GString *formatv(char *fmt, va_list argList);
+
// Destructor.
~GString();
@@ -67,6 +94,10 @@ public:
GString *append(const char *str);
GString *append(const char *str, int lengthA);
+ // Append a formatted string.
+ GString *appendf(char *fmt, ...);
+ GString *appendfv(char *fmt, va_list argList);
+
// Insert a character or string.
GString *insert(int i, char c);
GString *insert(int i, GString *str);
@@ -92,6 +123,14 @@ private:
char *s;
void resize(int length1);
+ static void formatInt(long x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ char **p, int *len);
+ static void formatUInt(Gulong x, char *buf, int bufSize,
+ GBool zeroFill, int width, int base,
+ char **p, int *len);
+ static void formatDouble(double x, char *buf, int bufSize, int prec,
+ GBool trim, char **p, int *len);
};
#endif
diff --git a/Build/source/libs/xpdf/goo/Makefile.in b/Build/source/libs/xpdf/goo/Makefile.in
index fe992f46ac5..4cebea29e0b 100644
--- a/Build/source/libs/xpdf/goo/Makefile.in
+++ b/Build/source/libs/xpdf/goo/Makefile.in
@@ -5,6 +5,7 @@
# Copyright 1996 Derek B. Noonburg
#
# Modified for pdftex by Martin Schröder 2005
+# $Id$
#
#========================================================================
@@ -43,17 +44,17 @@ CXX_SRC = \
$(srcdir)/GHash.cc \
$(srcdir)/GList.cc \
$(srcdir)/GString.cc \
+ $(srcdir)/gmem.cc \
$(srcdir)/gmempp.cc \
$(srcdir)/gfile.cc
C_SRC = \
- $(srcdir)/gmem.c \
$(srcdir)/parseargs.c
#------------------------------------------------------------------------
-GOO_CXX_OBJS = FixedPoint.o GHash.o GList.o GString.o gmempp.o gfile.o
-GOO_C_OBJS = gmem.o parseargs.o
+GOO_CXX_OBJS = FixedPoint.o GHash.o GList.o GString.o gmem.o gmempp.o gfile.o
+GOO_C_OBJS = parseargs.o
GOO_OBJS = $(GOO_CXX_OBJS) $(GOO_C_OBJS)
libGoo.a: $(GOO_OBJS)
diff --git a/Build/source/libs/xpdf/goo/depend.mk b/Build/source/libs/xpdf/goo/depend.mk
index c0dfb37f7b5..8aa02de24cb 100644
--- a/Build/source/libs/xpdf/goo/depend.mk
+++ b/Build/source/libs/xpdf/goo/depend.mk
@@ -23,7 +23,7 @@ GString.o: $(srcdir)/GString.cc ../aconf.h \
$(srcdirparent)/aconf2.h \
$(srcdir)/gtypes.h \
$(srcdir)/GString.h
-gmem.o: $(srcdir)/gmem.c ../aconf.h \
+gmem.o: $(srcdir)/gmem.cc ../aconf.h \
$(srcdirparent)/aconf2.h \
$(srcdir)/gmem.h
parseargs.o: $(srcdir)/parseargs.c \
diff --git a/Build/source/libs/xpdf/goo/gfile.cc b/Build/source/libs/xpdf/goo/gfile.cc
index caa96e7459b..740b3ea1ff6 100644
--- a/Build/source/libs/xpdf/goo/gfile.cc
+++ b/Build/source/libs/xpdf/goo/gfile.cc
@@ -10,7 +10,9 @@
#include <aconf.h>
-#ifndef WIN32
+#ifdef WIN32
+# include <time.h>
+#else
# if defined(MACOS)
# include <sys/stat.h>
# elif !defined(ACORN)
@@ -441,21 +443,45 @@ time_t getModTime(char *fileName) {
GBool openTempFile(GString **name, FILE **f, char *mode, char *ext) {
#if defined(WIN32)
//---------- Win32 ----------
- char *s;
-
- if (!(s = _tempnam(getenv("TEMP"), NULL))) {
- return gFalse;
- }
- *name = new GString(s);
- free(s);
- if (ext) {
- (*name)->append(ext);
+ char *tempDir;
+ GString *s, *s2;
+ char buf[32];
+ FILE *f2;
+ int t, i;
+
+ // this has the standard race condition problem, but I haven't found
+ // a better way to generate temp file names with extensions on
+ // Windows
+ if ((tempDir = getenv("TEMP"))) {
+ s = new GString(tempDir);
+ s->append('\\');
+ } else {
+ s = new GString();
}
- if (!(*f = fopen((*name)->getCString(), mode))) {
- delete (*name);
- return gFalse;
+ s->append("x");
+ t = (int)time(NULL);
+ for (i = 0; i < 1000; ++i) {
+ sprintf(buf, "%d", t + i);
+ s2 = s->copy()->append(buf);
+ if (ext) {
+ s2->append(ext);
+ }
+ if (!(f2 = fopen(s2->getCString(), "r"))) {
+ if (!(f2 = fopen(s2->getCString(), mode))) {
+ delete s2;
+ delete s;
+ return gFalse;
+ }
+ *name = s2;
+ *f = f2;
+ delete s;
+ return gTrue;
+ }
+ fclose(f2);
+ delete s2;
}
- return gTrue;
+ delete s;
+ return gFalse;
#elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS)
//---------- non-Unix ----------
char *s;
@@ -672,9 +698,9 @@ GDirEntry *GDir::getNextEntry() {
struct dirent *ent;
e = NULL;
if (dir) {
- ent = readdir(dir);
+ ent = (struct dirent *)readdir(dir);
if (ent && !strcmp(ent->d_name, ".")) {
- ent = readdir(dir);
+ ent = (struct dirent *)readdir(dir);
}
if (ent) {
e = new GDirEntry(path->getCString(), ent->d_name, doStat);
diff --git a/Build/source/libs/xpdf/goo/gfile.h b/Build/source/libs/xpdf/goo/gfile.h
index 8817e8b2381..82f1d7a98e3 100644
--- a/Build/source/libs/xpdf/goo/gfile.h
+++ b/Build/source/libs/xpdf/goo/gfile.h
@@ -46,9 +46,6 @@
# endif
# endif
#endif
-#if defined(__DJGPP__)
-typedef unsigned int time_t;
-#endif
#include "gtypes.h"
class GString;
@@ -86,9 +83,7 @@ extern time_t getModTime(char *fileName);
// should be done to the returned file pointer; the file may be
// reopened later for reading, but not for writing. The <mode> string
// should be "w" or "wb". Returns true on success.
-#ifndef PDF_PARSER_ONLY
extern GBool openTempFile(GString **name, FILE **f, char *mode, char *ext);
-#endif
// Execute <command>. Returns true on success.
extern GBool executeCommand(char *cmd);
diff --git a/Build/source/libs/xpdf/goo/gmem.c b/Build/source/libs/xpdf/goo/gmem.cc
index b97535adf04..6b13b38d0f0 100644
--- a/Build/source/libs/xpdf/goo/gmem.c
+++ b/Build/source/libs/xpdf/goo/gmem.cc
@@ -17,14 +17,17 @@
#ifdef DEBUG_MEM
typedef struct _GMemHdr {
+ unsigned int magic;
int size;
int index;
- struct _GMemHdr *next;
+ struct _GMemHdr *next, *prev;
} GMemHdr;
#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7)
#define gMemTrlSize (sizeof(long))
+#define gMemMagic 0xabcd9999
+
#if gmemTrlSize==8
#define gMemDeadVal 0xdeadbeefdeadbeefUL
#else
@@ -35,19 +38,8 @@ typedef struct _GMemHdr {
#define gMemDataSize(size) \
((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize)
-#define gMemNLists 64
-#define gMemListShift 4
-#define gMemListMask (gMemNLists - 1)
-static GMemHdr *gMemList[gMemNLists] = {
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
+static GMemHdr *gMemHead = NULL;
+static GMemHdr *gMemTail = NULL;
static int gMemIndex = 0;
static int gMemAlloc = 0;
@@ -55,57 +47,75 @@ static int gMemInUse = 0;
#endif /* DEBUG_MEM */
-void *gmalloc(int size) {
+void *gmalloc(int size) GMEM_EXCEP {
#ifdef DEBUG_MEM
int size1;
char *mem;
GMemHdr *hdr;
void *data;
- int lst;
unsigned long *trl, *p;
- if (size <= 0)
+ if (size <= 0) {
return NULL;
+ }
size1 = gMemDataSize(size);
if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) {
+#if USE_EXCEPTIONS
+ throw GMemException();
+#else
fprintf(stderr, "Out of memory\n");
exit(1);
+#endif
}
hdr = (GMemHdr *)mem;
data = (void *)(mem + gMemHdrSize);
trl = (unsigned long *)(mem + gMemHdrSize + size1);
+ hdr->magic = gMemMagic;
hdr->size = size;
hdr->index = gMemIndex++;
- lst = ((int)hdr >> gMemListShift) & gMemListMask;
- hdr->next = gMemList[lst];
- gMemList[lst] = hdr;
+ if (gMemTail) {
+ gMemTail->next = hdr;
+ hdr->prev = gMemTail;
+ gMemTail = hdr;
+ } else {
+ hdr->prev = NULL;
+ gMemHead = gMemTail = hdr;
+ }
+ hdr->next = NULL;
++gMemAlloc;
gMemInUse += size;
- for (p = (unsigned long *)data; p <= trl; ++p)
+ for (p = (unsigned long *)data; p <= trl; ++p) {
*p = gMemDeadVal;
+ }
return data;
#else
void *p;
- if (size <= 0)
+ if (size <= 0) {
return NULL;
+ }
if (!(p = malloc(size))) {
+#if USE_EXCEPTIONS
+ throw GMemException();
+#else
fprintf(stderr, "Out of memory\n");
exit(1);
+#endif
}
return p;
#endif
}
-void *grealloc(void *p, int size) {
+void *grealloc(void *p, int size) GMEM_EXCEP {
#ifdef DEBUG_MEM
GMemHdr *hdr;
void *q;
int oldSize;
if (size <= 0) {
- if (p)
+ if (p) {
gfree(p);
+ }
return NULL;
}
if (p) {
@@ -122,23 +132,29 @@ void *grealloc(void *p, int size) {
void *q;
if (size <= 0) {
- if (p)
+ if (p) {
free(p);
+ }
return NULL;
}
- if (p)
+ if (p) {
q = realloc(p, size);
- else
+ } else {
q = malloc(size);
+ }
if (!q) {
+#if USE_EXCEPTIONS
+ throw GMemException();
+#else
fprintf(stderr, "Out of memory\n");
exit(1);
+#endif
}
return q;
#endif
}
-void *gmallocn(int nObjs, int objSize) {
+void *gmallocn(int nObjs, int objSize) GMEM_EXCEP {
int n;
if (nObjs == 0) {
@@ -146,13 +162,17 @@ void *gmallocn(int nObjs, int objSize) {
}
n = nObjs * objSize;
if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
+#if USE_EXCEPTIONS
+ throw GMemException();
+#else
fprintf(stderr, "Bogus memory allocation size\n");
exit(1);
+#endif
}
return gmalloc(n);
}
-void *greallocn(void *p, int nObjs, int objSize) {
+void *greallocn(void *p, int nObjs, int objSize) GMEM_EXCEP {
int n;
if (nObjs == 0) {
@@ -163,8 +183,12 @@ void *greallocn(void *p, int nObjs, int objSize) {
}
n = nObjs * objSize;
if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) {
+#if USE_EXCEPTIONS
+ throw GMemException();
+#else
fprintf(stderr, "Bogus memory allocation size\n");
exit(1);
+#endif
}
return grealloc(p, n);
}
@@ -173,22 +197,23 @@ void gfree(void *p) {
#ifdef DEBUG_MEM
int size;
GMemHdr *hdr;
- GMemHdr *prevHdr, *q;
- int lst;
unsigned long *trl, *clr;
if (p) {
hdr = (GMemHdr *)((char *)p - gMemHdrSize);
- lst = ((int)hdr >> gMemListShift) & gMemListMask;
- for (prevHdr = NULL, q = gMemList[lst]; q; prevHdr = q, q = q->next) {
- if (q == hdr)
- break;
- }
- if (q) {
- if (prevHdr)
- prevHdr->next = hdr->next;
- else
- gMemList[lst] = hdr->next;
+ if (hdr->magic == gMemMagic &&
+ ((hdr->prev == NULL) == (hdr == gMemHead)) &&
+ ((hdr->next == NULL) == (hdr == gMemTail))) {
+ if (hdr->prev) {
+ hdr->prev->next = hdr->next;
+ } else {
+ gMemHead = hdr->next;
+ }
+ if (hdr->next) {
+ hdr->next->prev = hdr->prev;
+ } else {
+ gMemTail = hdr->prev;
+ }
--gMemAlloc;
gMemInUse -= hdr->size;
size = gMemDataSize(hdr->size);
@@ -197,32 +222,32 @@ void gfree(void *p) {
fprintf(stderr, "Overwrite past end of block %d at address %p\n",
hdr->index, p);
}
- for (clr = (unsigned long *)hdr; clr <= trl; ++clr)
+ for (clr = (unsigned long *)hdr; clr <= trl; ++clr) {
*clr = gMemDeadVal;
+ }
free(hdr);
} else {
fprintf(stderr, "Attempted to free bad address %p\n", p);
}
}
#else
- if (p)
+ if (p) {
free(p);
+ }
#endif
}
#ifdef DEBUG_MEM
void gMemReport(FILE *f) {
GMemHdr *p;
- int lst;
fprintf(f, "%d memory allocations in all\n", gMemIndex);
if (gMemAlloc > 0) {
fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc);
fprintf(f, " index size\n");
fprintf(f, "-------- --------\n");
- for (lst = 0; lst < gMemNLists; ++lst) {
- for (p = gMemList[lst]; p; p = p->next)
- fprintf(f, "%8d %8d\n", p->index, p->size);
+ for (p = gMemHead; p; p = p->next) {
+ fprintf(f, "%8d %8d\n", p->index, p->size);
}
} else {
fprintf(f, "No memory blocks left allocated\n");
diff --git a/Build/source/libs/xpdf/goo/gmem.h b/Build/source/libs/xpdf/goo/gmem.h
index e74d1822318..da34736f216 100644
--- a/Build/source/libs/xpdf/goo/gmem.h
+++ b/Build/source/libs/xpdf/goo/gmem.h
@@ -10,6 +10,23 @@
#define GMEM_H
#include <stdio.h>
+#include <aconf.h>
+
+#if USE_EXCEPTIONS
+
+class GMemException {
+public:
+ GMemException() {}
+ ~GMemException() {}
+};
+
+#define GMEM_EXCEP throw(GMemException)
+
+#else // USE_EXCEPTIONS
+
+#define GMEM_EXCEP
+
+#endif // USE_EXCEPTIONS
#ifdef __cplusplus
extern "C" {
@@ -19,13 +36,13 @@ extern "C" {
* Same as malloc, but prints error message and exits if malloc()
* returns NULL.
*/
-extern void *gmalloc(int size);
+extern void *gmalloc(int size) GMEM_EXCEP;
/*
* Same as realloc, but prints error message and exits if realloc()
* returns NULL. If <p> is NULL, calls malloc instead of realloc().
*/
-extern void *grealloc(void *p, int size);
+extern void *grealloc(void *p, int size) GMEM_EXCEP;
/*
* These are similar to gmalloc and grealloc, but take an object count
@@ -33,8 +50,8 @@ extern void *grealloc(void *p, int size);
* bytes, but there is an additional error check that the total size
* doesn't overflow an int.
*/
-extern void *gmallocn(int nObjs, int objSize);
-extern void *greallocn(void *p, int nObjs, int objSize);
+extern void *gmallocn(int nObjs, int objSize) GMEM_EXCEP;
+extern void *greallocn(void *p, int nObjs, int objSize) GMEM_EXCEP;
/*
* Same as free, but checks for and ignores NULL pointers.