From 7bf56e6bfcd7b204b3507dc9acaaaa3dce2cbcdb Mon Sep 17 00:00:00 2001 From: Martin Schröder Date: Wed, 11 Jul 2007 21:13:59 +0000 Subject: Imported pdftex 1.40.4 git-svn-id: svn://tug.org/texlive/trunk@4561 c570f23f-e606-0410-a88d-b1316a301751 --- Build/source/libs/xpdf/goo/FixedPoint.cc | 29 +- Build/source/libs/xpdf/goo/FixedPoint.h | 5 + Build/source/libs/xpdf/goo/GString.cc | 449 +++++++++++++++++++++++++++++-- Build/source/libs/xpdf/goo/GString.h | 39 +++ Build/source/libs/xpdf/goo/Makefile.in | 7 +- Build/source/libs/xpdf/goo/depend.mk | 2 +- Build/source/libs/xpdf/goo/gfile.cc | 58 ++-- Build/source/libs/xpdf/goo/gfile.h | 5 - Build/source/libs/xpdf/goo/gmem.c | 239 ---------------- Build/source/libs/xpdf/goo/gmem.cc | 264 ++++++++++++++++++ Build/source/libs/xpdf/goo/gmem.h | 25 +- 11 files changed, 826 insertions(+), 296 deletions(-) delete mode 100644 Build/source/libs/xpdf/goo/gmem.c create mode 100644 Build/source/libs/xpdf/goo/gmem.cc (limited to 'Build/source/libs/xpdf/goo') 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 #include +#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 #include #include -#include "gtypes.h" +#include +#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 +#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: + // {:[][.]} + // where: + // - 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 + // - is the field width -- negative to reverse the alignment; + // starting with a leading zero to zero-fill (for integers) + // - is the number of digits to the right of the decimal + // point (for floating point numbers) + // - 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 -#ifndef WIN32 +#ifdef WIN32 +# include +#else # if defined(MACOS) # include # 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 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 . 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.c deleted file mode 100644 index b97535adf04..00000000000 --- a/Build/source/libs/xpdf/goo/gmem.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * gmem.c - * - * Memory routines with out-of-memory checking. - * - * Copyright 1996-2003 Glyph & Cog, LLC - */ - -#include -#include -#include -#include -#include -#include -#include "gmem.h" - -#ifdef DEBUG_MEM - -typedef struct _GMemHdr { - int size; - int index; - struct _GMemHdr *next; -} GMemHdr; - -#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7) -#define gMemTrlSize (sizeof(long)) - -#if gmemTrlSize==8 -#define gMemDeadVal 0xdeadbeefdeadbeefUL -#else -#define gMemDeadVal 0xdeadbeefUL -#endif - -/* round data size so trailer will be aligned */ -#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 int gMemIndex = 0; -static int gMemAlloc = 0; -static int gMemInUse = 0; - -#endif /* DEBUG_MEM */ - -void *gmalloc(int size) { -#ifdef DEBUG_MEM - int size1; - char *mem; - GMemHdr *hdr; - void *data; - int lst; - unsigned long *trl, *p; - - if (size <= 0) - return NULL; - size1 = gMemDataSize(size); - if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) { - fprintf(stderr, "Out of memory\n"); - exit(1); - } - hdr = (GMemHdr *)mem; - data = (void *)(mem + gMemHdrSize); - trl = (unsigned long *)(mem + gMemHdrSize + size1); - hdr->size = size; - hdr->index = gMemIndex++; - lst = ((int)hdr >> gMemListShift) & gMemListMask; - hdr->next = gMemList[lst]; - gMemList[lst] = hdr; - ++gMemAlloc; - gMemInUse += size; - for (p = (unsigned long *)data; p <= trl; ++p) - *p = gMemDeadVal; - return data; -#else - void *p; - - if (size <= 0) - return NULL; - if (!(p = malloc(size))) { - fprintf(stderr, "Out of memory\n"); - exit(1); - } - return p; -#endif -} - -void *grealloc(void *p, int size) { -#ifdef DEBUG_MEM - GMemHdr *hdr; - void *q; - int oldSize; - - if (size <= 0) { - if (p) - gfree(p); - return NULL; - } - if (p) { - hdr = (GMemHdr *)((char *)p - gMemHdrSize); - oldSize = hdr->size; - q = gmalloc(size); - memcpy(q, p, size < oldSize ? size : oldSize); - gfree(p); - } else { - q = gmalloc(size); - } - return q; -#else - void *q; - - if (size <= 0) { - if (p) - free(p); - return NULL; - } - if (p) - q = realloc(p, size); - else - q = malloc(size); - if (!q) { - fprintf(stderr, "Out of memory\n"); - exit(1); - } - return q; -#endif -} - -void *gmallocn(int nObjs, int objSize) { - int n; - - if (nObjs == 0) { - return NULL; - } - n = nObjs * objSize; - if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) { - fprintf(stderr, "Bogus memory allocation size\n"); - exit(1); - } - return gmalloc(n); -} - -void *greallocn(void *p, int nObjs, int objSize) { - int n; - - if (nObjs == 0) { - if (p) { - gfree(p); - } - return NULL; - } - n = nObjs * objSize; - if (objSize <= 0 || nObjs < 0 || nObjs >= INT_MAX / objSize) { - fprintf(stderr, "Bogus memory allocation size\n"); - exit(1); - } - return grealloc(p, n); -} - -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; - --gMemAlloc; - gMemInUse -= hdr->size; - size = gMemDataSize(hdr->size); - trl = (unsigned long *)((char *)hdr + gMemHdrSize + size); - if (*trl != gMemDeadVal) { - fprintf(stderr, "Overwrite past end of block %d at address %p\n", - hdr->index, p); - } - 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) - 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); - } - } else { - fprintf(f, "No memory blocks left allocated\n"); - } -} -#endif - -char *copyString(char *s) { - char *s1; - - s1 = (char *)gmalloc(strlen(s) + 1); - strcpy(s1, s); - return s1; -} diff --git a/Build/source/libs/xpdf/goo/gmem.cc b/Build/source/libs/xpdf/goo/gmem.cc new file mode 100644 index 00000000000..6b13b38d0f0 --- /dev/null +++ b/Build/source/libs/xpdf/goo/gmem.cc @@ -0,0 +1,264 @@ +/* + * gmem.c + * + * Memory routines with out-of-memory checking. + * + * Copyright 1996-2003 Glyph & Cog, LLC + */ + +#include +#include +#include +#include +#include +#include +#include "gmem.h" + +#ifdef DEBUG_MEM + +typedef struct _GMemHdr { + unsigned int magic; + int size; + int index; + 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 +#define gMemDeadVal 0xdeadbeefUL +#endif + +/* round data size so trailer will be aligned */ +#define gMemDataSize(size) \ + ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize) + +static GMemHdr *gMemHead = NULL; +static GMemHdr *gMemTail = NULL; + +static int gMemIndex = 0; +static int gMemAlloc = 0; +static int gMemInUse = 0; + +#endif /* DEBUG_MEM */ + +void *gmalloc(int size) GMEM_EXCEP { +#ifdef DEBUG_MEM + int size1; + char *mem; + GMemHdr *hdr; + void *data; + unsigned long *trl, *p; + + 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++; + 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) { + *p = gMemDeadVal; + } + return data; +#else + void *p; + + 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) GMEM_EXCEP { +#ifdef DEBUG_MEM + GMemHdr *hdr; + void *q; + int oldSize; + + if (size <= 0) { + if (p) { + gfree(p); + } + return NULL; + } + if (p) { + hdr = (GMemHdr *)((char *)p - gMemHdrSize); + oldSize = hdr->size; + q = gmalloc(size); + memcpy(q, p, size < oldSize ? size : oldSize); + gfree(p); + } else { + q = gmalloc(size); + } + return q; +#else + void *q; + + if (size <= 0) { + if (p) { + free(p); + } + return NULL; + } + if (p) { + q = realloc(p, size); + } 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) GMEM_EXCEP { + int n; + + if (nObjs == 0) { + return NULL; + } + 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) GMEM_EXCEP { + int n; + + if (nObjs == 0) { + if (p) { + gfree(p); + } + return NULL; + } + 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); +} + +void gfree(void *p) { +#ifdef DEBUG_MEM + int size; + GMemHdr *hdr; + unsigned long *trl, *clr; + + if (p) { + hdr = (GMemHdr *)((char *)p - gMemHdrSize); + 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); + trl = (unsigned long *)((char *)hdr + gMemHdrSize + size); + if (*trl != gMemDeadVal) { + fprintf(stderr, "Overwrite past end of block %d at address %p\n", + hdr->index, p); + } + 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) { + free(p); + } +#endif +} + +#ifdef DEBUG_MEM +void gMemReport(FILE *f) { + GMemHdr *p; + + 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 (p = gMemHead; p; p = p->next) { + fprintf(f, "%8d %8d\n", p->index, p->size); + } + } else { + fprintf(f, "No memory blocks left allocated\n"); + } +} +#endif + +char *copyString(char *s) { + char *s1; + + s1 = (char *)gmalloc(strlen(s) + 1); + strcpy(s1, s); + return s1; +} 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 +#include + +#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

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. -- cgit v1.2.3