diff options
author | Martin Schröder <martin@oneiros.de> | 2007-07-11 21:13:59 +0000 |
---|---|---|
committer | Martin Schröder <martin@oneiros.de> | 2007-07-11 21:13:59 +0000 |
commit | 7bf56e6bfcd7b204b3507dc9acaaaa3dce2cbcdb (patch) | |
tree | 5f8b4be4a21dc917441e4d2a1ec3e6fe25fd0192 /Build/source/libs/xpdf/goo | |
parent | c0da09fd6e4a542610245624c185a66f5ec814b2 (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.cc | 29 | ||||
-rw-r--r-- | Build/source/libs/xpdf/goo/FixedPoint.h | 5 | ||||
-rw-r--r-- | Build/source/libs/xpdf/goo/GString.cc | 449 | ||||
-rw-r--r-- | Build/source/libs/xpdf/goo/GString.h | 39 | ||||
-rw-r--r-- | Build/source/libs/xpdf/goo/Makefile.in | 7 | ||||
-rw-r--r-- | Build/source/libs/xpdf/goo/depend.mk | 2 | ||||
-rw-r--r-- | Build/source/libs/xpdf/goo/gfile.cc | 58 | ||||
-rw-r--r-- | Build/source/libs/xpdf/goo/gfile.h | 5 | ||||
-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.h | 25 |
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. |