[poppler] poppler/goo: FixedPoint.cc, 1.1, 1.1.4.1 FixedPoint.h, 1.2, 1.2.4.1 GooString.cc, 1.4, 1.4.2.1 GooString.h, 1.4, 1.4.2.1 Makefile.am, 1.5, 1.5.4.1 gfile.cc, 1.3, 1.3.4.1 gmem.c, 1.7, NONE gmem.cc, NONE, 1.1.2.1 gmem.h, 1.4, 1.4.2.1

Albert Astals Cid aacid at kemper.freedesktop.org
Sat Mar 31 16:46:33 PDT 2007


Update of /cvs/poppler/poppler/goo
In directory kemper:/tmp/cvs-serv23633/goo

Modified Files:
      Tag: xpdf302merge
	FixedPoint.cc FixedPoint.h GooString.cc GooString.h 
	Makefile.am gfile.cc gmem.h 
Added Files:
      Tag: xpdf302merge
	gmem.cc 
Removed Files:
      Tag: xpdf302merge
	gmem.c 
Log Message:
merged goo dir from xpdf3.02, that was easy :D


Index: FixedPoint.cc
===================================================================
RCS file: /cvs/poppler/poppler/goo/FixedPoint.cc,v
retrieving revision 1.1
retrieving revision 1.1.4.1
diff -u -d -r1.1 -r1.1.4.1
--- FixedPoint.cc	16 Sep 2005 18:29:18 -0000	1.1
+++ FixedPoint.cc	31 Mar 2007 23:46:31 -0000	1.1.4.1
@@ -18,13 +18,17 @@
 
 #include "FixedPoint.h"
 
+#define ln2 ((FixedPoint)0.69314718)
+
+#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 +38,9 @@
   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 +59,8 @@
     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 +72,11 @@
       ++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 +102,19 @@
 #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

Index: FixedPoint.h
===================================================================
RCS file: /cvs/poppler/poppler/goo/FixedPoint.h,v
retrieving revision 1.2
retrieving revision 1.2.4.1
diff -u -d -r1.2 -r1.2.4.1
--- FixedPoint.h	6 Feb 2006 20:49:21 -0000	1.2
+++ FixedPoint.h	31 Mar 2007 23:46:31 -0000	1.2.4.1
@@ -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 @@
 
   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; }

Index: GooString.cc
===================================================================
RCS file: /cvs/poppler/poppler/goo/GooString.cc,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -u -d -r1.4 -r1.4.2.1
--- GooString.cc	28 Dec 2006 15:51:44 -0000	1.4
+++ GooString.cc	31 Mar 2007 23:46:31 -0000	1.4.2.1
@@ -19,9 +19,61 @@
 #include <string.h>
 #include <ctype.h>
 #include <assert.h>
-#include "gtypes.h"
+#include <math.h>
+#include "gmem.h"
 #include "GooString.h"
 
+//------------------------------------------------------------------------
+
+union GooStringFormatArg {
+  int i;
+  Guint ui;
+  long l;
+  Gulong ul;
+  double f;
+  char c;
+  char *s;
+  GooString *gs;
+};
+
+enum GooStringFormatType {
+  fmtIntDecimal,
+  fmtIntHex,
+  fmtIntOctal,
+  fmtIntBinary,
+  fmtUIntDecimal,
+  fmtUIntHex,
+  fmtUIntOctal,
+  fmtUIntBinary,
+  fmtLongDecimal,
+  fmtLongHex,
+  fmtLongOctal,
+  fmtLongBinary,
+  fmtULongDecimal,
+  fmtULongHex,
+  fmtULongOctal,
+  fmtULongBinary,
+  fmtDouble,
+  fmtDoubleTrim,
+  fmtChar,
+  fmtString,
+  fmtGooString,
+  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
+};
+
+//------------------------------------------------------------------------
+
 int inline GooString::roundedSize(int len) {
   int delta;
   if (len <= STR_STATIC_SIZE-1)
@@ -135,28 +187,29 @@
 
 GooString *GooString::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;
+  formatInt(x, buf, sizeof(buf), gFalse, 0, 10, &p, &len);
+  return new GooString(p, 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 GooString(buf + i, 24 - i);
+GooString *GooString::format(char *fmt, ...) {
+  va_list argList;
+  GooString *s;
+
+  s = new GooString();
+  va_start(argList, fmt);
+  s->appendfv(fmt, argList);
+  va_end(argList);
+  return s;
+}
+
+GooString *GooString::formatv(char *fmt, va_list argList) {
+  GooString *s;
+
+  s = new GooString();
+  s->appendfv(fmt, argList);
+  return s;
 }
 
 GooString::~GooString() {
@@ -186,6 +239,351 @@
   return this;
 }
 
+GooString *GooString::appendf(char *fmt, ...) {
+  va_list argList;
+
+  va_start(argList, fmt);
+  appendfv(fmt, argList);
+  va_end(argList);
+  return this;
+}
+
+GooString *GooString::appendfv(char *fmt, va_list argList) {
+  GooStringFormatArg *args;
+  int argsLen, argsSize;
+  GooStringFormatArg arg;
+  int idx, width, prec;
+  GBool reverseAlign, zeroFill;
+  GooStringFormatType ft;
+  char buf[65];
+  int len, i;
+  char *p0, *p1, *str;
+
+  argsLen = 0;
+  argsSize = 8;
+  args = (GooStringFormatArg *)gmallocn(argsSize, sizeof(GooStringFormatArg));
+
+  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 = (GooStringFormatType)0;
+	     formatStrings[ft];
+	     ft = (GooStringFormatType)(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 = (GooStringFormatArg *)greallocn(args, argsSize,
+						 sizeof(GooStringFormatArg));
+	  }
+	  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 fmtGooString:
+	    args[argsLen].gs = va_arg(argList, GooString *);
+	    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 fmtGooString:
+	  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 GooString::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 GooString::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 GooString::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, 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;
+}
+
 GooString *GooString::insert(int i, char c) {
   return insert(i, (const char*)&c, 1);
 }

Index: GooString.h
===================================================================
RCS file: /cvs/poppler/poppler/goo/GooString.h,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -u -d -r1.4 -r1.4.2.1
--- GooString.h	28 Dec 2006 15:51:44 -0000	1.4
+++ GooString.h	31 Mar 2007 23:46:31 -0000	1.4.2.1
@@ -8,13 +8,14 @@
 //
 //========================================================================
 
-#ifndef GSTRING_H
-#define GSTRING_H
+#ifndef GooString_H
+#define GooString_H
 
 #ifdef USE_GCC_PRAGMAS
 #pragma interface
 #endif
 
+#include <stdarg.h>
 #include <stdlib.h> // for NULL
 #include "gtypes.h"
 
@@ -50,6 +51,30 @@
   // Convert an integer to a string.
   static GooString *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 -- GooString *
+  //     w -- blank space; arg determines width
+  // To get literal curly braces, use {{ or }}.
+  static GooString *format(char *fmt, ...);
+  static GooString *formatv(char *fmt, va_list argList);
+
   // Destructor.
   ~GooString();
 
@@ -73,6 +98,10 @@
   GooString *append(GooString *str);
   GooString *append(const char *str, int lengthA=CALC_STRING_LEN);
 
+  // Append a formatted string.
+  GooString *appendf(char *fmt, ...);
+  GooString *appendfv(char *fmt, va_list argList);
+
   // Insert a character or string.
   GooString *insert(int i, char c);
   GooString *insert(int i, GooString *str);
@@ -110,6 +139,14 @@
   char *s;
 
   void resize(int newLength);
+  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

Index: Makefile.am
===================================================================
RCS file: /cvs/poppler/poppler/goo/Makefile.am,v
retrieving revision 1.5
retrieving revision 1.5.4.1
diff -u -d -r1.5 -r1.5.4.1
--- Makefile.am	6 Jan 2006 10:05:58 -0000	1.5
+++ Makefile.am	31 Mar 2007 23:46:31 -0000	1.5.4.1
@@ -25,5 +25,5 @@
 	GooList.cc				\
 	GooTimer.cc				\
 	GooString.cc				\
-	gmem.c					\
+	gmem.cc					\
 	FixedPoint.cc

Index: gfile.cc
===================================================================
RCS file: /cvs/poppler/poppler/goo/gfile.cc,v
retrieving revision 1.3
retrieving revision 1.3.4.1
diff -u -d -r1.3 -r1.3.4.1
--- gfile.cc	19 Sep 2006 04:39:08 -0000	1.3
+++ gfile.cc	31 Mar 2007 23:46:31 -0000	1.3.4.1
@@ -10,7 +10,9 @@
 
 #include <config.h>
 
-#ifndef WIN32
+#ifdef WIN32
+#  include <time.h>
+#else
 #  if defined(MACOS)
 #    include <sys/stat.h>
 #  elif !defined(ACORN)
@@ -440,21 +442,45 @@
 GBool openTempFile(GooString **name, FILE **f, char *mode, char *ext) {
 #if defined(WIN32)
   //---------- Win32 ----------
-  char *s;
+  char *tempDir;
+  GString *s, *s2;
+  char buf[32];
+  FILE *f2;
+  int t, i;
 
-  if (!(s = _tempnam(getenv("TEMP"), NULL))) {
-    return gFalse;
-  }
-  *name = new GooString(s);
-  free(s);
-  if (ext) {
-    (*name)->append(ext);
+  // 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;

--- gmem.c DELETED ---

--- NEW FILE: gmem.cc ---
/*
 * gmem.c
 *
 * Memory routines with out-of-memory checking.
 *
 * Copyright 1996-2003 Glyph & Cog, LLC
 */

#include <config.h>
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#include <limits.h>
#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(size_t 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, size_t 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;
}

Index: gmem.h
===================================================================
RCS file: /cvs/poppler/poppler/goo/gmem.h,v
retrieving revision 1.4
retrieving revision 1.4.2.1
diff -u -d -r1.4 -r1.4.2.1
--- gmem.h	28 Dec 2006 15:51:44 -0000	1.4
+++ gmem.h	31 Mar 2007 23:46:31 -0000	1.4.2.1
@@ -10,6 +10,23 @@
 #define GMEM_H
 
 #include <stdio.h>
+#include <config.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 @@
  * Same as malloc, but prints error message and exits if malloc()
  * returns NULL.
  */
-extern void *gmalloc(size_t size);
+extern void *gmalloc(size_t 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, size_t size);
+extern void *grealloc(void *p, size_t size) GMEM_EXCEP;
 
 /*
  * These are similar to gmalloc and grealloc, but take an object count
@@ -33,11 +50,11 @@
  * 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;
 
 /*
- * #ifdef DEBUG_MEM, adds debuging info. If not, same as free.
+ * Same as free, but checks for and ignores NULL pointers.
  */
 extern void gfree(void *p);
 



More information about the poppler mailing list