[poppler] 3 commits - CMakeLists.txt fofi/FoFiType1C.cc goo/gstrtod.cc goo/gstrtod.h goo/Makefile.am poppler/Annot.cc poppler/Function.cc poppler/PDFDoc.cc utils/parseargs.c

Albert Astals Cid aacid at kemper.freedesktop.org
Sun Aug 16 15:17:10 PDT 2009


 CMakeLists.txt      |    2 
 fofi/FoFiType1C.cc  |    3 -
 goo/Makefile.am     |    6 +-
 goo/gstrtod.cc      |  147 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 goo/gstrtod.h       |   43 +++++++++++++++
 poppler/Annot.cc    |    5 +
 poppler/Function.cc |    3 -
 poppler/PDFDoc.cc   |    7 --
 utils/parseargs.c   |    4 +
 9 files changed, 208 insertions(+), 12 deletions(-)

New commits:
commit 25ff4be0b4521cc3d2de386cdeb589beb245d435
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Aug 17 00:15:10 2009 +0200

    No need to change the locale since we use gatof that does the right thing

diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index 6ae71ff..57a3ed8 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -323,11 +323,7 @@ void PDFDoc::checkHeader() {
     error(-1, "May not be a PDF file (continuing anyway)");
     return;
   }
-  {
-    char *theLocale = setlocale(LC_NUMERIC, "C");
-    pdfVersion = gatof(p);
-    setlocale(LC_NUMERIC, theLocale);
-  }
+  pdfVersion = gatof(p);
   // We don't do the version check. Don't add it back in.
 }
 
commit a6f698b4edc42c0414dd4690e1e037088321db2c
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Aug 17 00:14:35 2009 +0200

    Use gatof instead of atof

diff --git a/fofi/FoFiType1C.cc b/fofi/FoFiType1C.cc
index 6930c12..8921dfb 100644
--- a/fofi/FoFiType1C.cc
+++ b/fofi/FoFiType1C.cc
@@ -16,6 +16,7 @@
 #include <string.h>
 #include <math.h>
 #include "goo/gmem.h"
+#include "goo/gstrtod.h"
 #include "goo/GooString.h"
 #include "FoFiEncodings.h"
 #include "FoFiType1C.h"
@@ -2464,7 +2465,7 @@ int FoFiType1C::getOp(int pos, GBool charstring, GBool *ok) {
       }
     } while (i < 64);
     buf[i] = '\0';
-    op.num = atof(buf);
+    op.num = gatof(buf);
     op.isFP = gTrue;
 
   } else if (b0 >= 32 && b0 <= 246) {
diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index 99c3731..5832f67 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -39,6 +39,7 @@
 #include <math.h>
 #include <assert.h>
 #include "goo/gmem.h"
+#include "goo/gstrtod.h"
 #include "GooList.h"
 #include "Error.h"
 #include "Object.h"
@@ -2511,7 +2512,7 @@ void AnnotWidget::drawText(GooString *text, GooString *da, GfxFontDict *fontDict
       error(-1, "Invalid font name in 'Tf' operator in field's DA string");
     }
     tok = (GooString *)daToks->get(tfPos + 1);
-    fontSize = atof(tok->getCString());
+    fontSize = gatof(tok->getCString());
   } else {
     error(-1, "Missing 'Tf' operator in field's DA string");
   }
@@ -2870,7 +2871,7 @@ void AnnotWidget::drawListBox(GooString **text, GBool *selection,
       error(-1, "Invalid font name in 'Tf' operator in field's DA string");
     }
     tok = (GooString *)daToks->get(tfPos + 1);
-    fontSize = atof(tok->getCString());
+    fontSize = gatof(tok->getCString());
   } else {
     error(-1, "Missing 'Tf' operator in field's DA string");
   }
diff --git a/poppler/Function.cc b/poppler/Function.cc
index 431dc5d..73a6b5f 100644
--- a/poppler/Function.cc
+++ b/poppler/Function.cc
@@ -32,6 +32,7 @@
 #include <ctype.h>
 #include <math.h>
 #include "goo/gmem.h"
+#include "goo/gstrtod.h"
 #include "Object.h"
 #include "Dict.h"
 #include "Stream.h"
@@ -1236,7 +1237,7 @@ GBool PostScriptFunction::parseCode(Stream *str, int *codePtr) {
       resizeCode(*codePtr);
       if (isReal) {
 	code[*codePtr].type = psReal;
-          code[*codePtr].real = atof(tok->getCString());
+          code[*codePtr].real = gatof(tok->getCString());
       } else {
 	code[*codePtr].type = psInt;
 	code[*codePtr].intg = atoi(tok->getCString());
diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index d0d7e22..6ae71ff 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -41,6 +41,7 @@
 #ifdef WIN32
 #  include <windows.h>
 #endif
+#include "goo/gstrtod.h"
 #include "goo/GooString.h"
 #include "poppler-config.h"
 #include "GlobalParams.h"
@@ -324,7 +325,7 @@ void PDFDoc::checkHeader() {
   }
   {
     char *theLocale = setlocale(LC_NUMERIC, "C");
-    pdfVersion = atof(p);
+    pdfVersion = gatof(p);
     setlocale(LC_NUMERIC, theLocale);
   }
   // We don't do the version check. Don't add it back in.
diff --git a/utils/parseargs.c b/utils/parseargs.c
index 6363241..973af1c 100644
--- a/utils/parseargs.c
+++ b/utils/parseargs.c
@@ -29,6 +29,8 @@
 #include <ctype.h>
 #include "parseargs.h"
 
+#include "goo/gstrtod.h"
+
 static const ArgDesc *findArg(const ArgDesc *args, char *arg);
 static GBool grabArg(const ArgDesc *arg, int i, int *argc, char *argv[]);
 
@@ -133,7 +135,7 @@ static GBool grabArg(const ArgDesc *arg, int i, int *argc, char *argv[]) {
     break;
   case argFP:
     if (i + 1 < *argc && isFP(argv[i+1])) {
-      *(double *)arg->val = atof(argv[i+1]);
+      *(double *)arg->val = gatof(argv[i+1]);
       n = 2;
     } else {
       ok = gFalse;
commit 807b121cae45832d2e5832bad19c31e77420bfec
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Aug 17 00:10:30 2009 +0200

    Add a custom strtod that comes from libspectre
    
    Works over C locale integers without changing locale settings

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0b60c81..6854308 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -144,6 +144,7 @@ set(poppler_SRCS
   goo/gmem.cc
   goo/FixedPoint.cc
   goo/PNGWriter.cc
+  goo/gstrtod.cc
   fofi/FoFiBase.cc
   fofi/FoFiEncodings.cc
   fofi/FoFiTrueType.cc
@@ -349,6 +350,7 @@ if(ENABLE_XPDF_HEADERS)
     goo/gmem.h
     goo/gfile.h
     goo/FixedPoint.h
+    goo/gstrtod.h
     DESTINATION include/poppler/goo)
   install(FILES
     fofi/FoFiBase.h
diff --git a/goo/Makefile.am b/goo/Makefile.am
index 478e401..f10fd15 100644
--- a/goo/Makefile.am
+++ b/goo/Makefile.am
@@ -14,7 +14,8 @@ poppler_goo_include_HEADERS =			\
 	gmem.h					\
 	gfile.h					\
 	FixedPoint.h				\
-	PNGWriter.h
+	PNGWriter.h				\
+	gstrtod.h
 
 endif
 
@@ -30,4 +31,5 @@ libgoo_la_SOURCES =				\
 	GooString.cc				\
 	gmem.cc					\
 	FixedPoint.cc				\
-	PNGWriter.cc
+	PNGWriter.cc				\
+	gstrtod.cc
diff --git a/goo/gstrtod.cc b/goo/gstrtod.cc
new file mode 100644
index 0000000..e6c3a00
--- /dev/null
+++ b/goo/gstrtod.cc
@@ -0,0 +1,147 @@
+/* This file is part of Libspectre.
+ * 
+ * Copyright (C) 2007 Albert Astals Cid <aacid at kde.org>
+ * Copyright (C) 2007 Carlos Garcia Campos <carlosgc at gnome.org>
+ *
+ * Libspectre is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * Libspectre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/* This function comes from spectre-utils from libspectre */
+
+#include "gstrtod.h"
+
+#include <clocale>
+#include <cerrno>
+#include <cstdlib>
+#include <cstring>
+
+#define ascii_isspace(c) \
+  (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v')
+#define ascii_isdigit(c) \
+  (c >= '0' && c <= '9')
+  
+double gatof(const char *nptr)
+{
+  return gstrtod(nptr, NULL);
+}
+
+double gstrtod(const char *nptr, char **endptr)
+{
+  char *fail_pos;
+  double val;
+  struct lconv *locale_data;
+  const char *decimal_point;
+  int decimal_point_len;
+  const char *p, *decimal_point_pos;
+  const char *end = NULL; /* Silence gcc */
+  int strtod_errno;
+
+  fail_pos = NULL;
+
+  locale_data = localeconv ();
+  decimal_point = locale_data->decimal_point;
+  decimal_point_len = strlen (decimal_point);
+
+  decimal_point_pos = NULL;
+  end = NULL;
+
+  if (decimal_point[0] != '.' || decimal_point[1] != 0) {
+    p = nptr;
+    /* Skip leading space */
+    while (ascii_isspace (*p))
+      p++;
+    
+    /* Skip leading optional sign */
+    if (*p == '+' || *p == '-')
+      p++;
+    
+    if (ascii_isdigit (*p) || *p == '.') {
+      while (ascii_isdigit (*p))
+        p++;
+      
+      if (*p == '.')
+        decimal_point_pos = p++;
+
+      while (ascii_isdigit (*p))
+        p++;
+
+      if (*p == 'e' || *p == 'E')
+        p++;
+      if (*p == '+' || *p == '-')
+        p++;
+      while (ascii_isdigit (*p))
+        p++;
+
+      end = p;
+    }
+    /* For the other cases, we need not convert the decimal point */
+  }
+
+  if (decimal_point_pos) {
+    char *copy, *c;
+    
+    /* We need to convert the '.' to the locale specific decimal point */
+    copy = (char *) malloc (end - nptr + 1 + decimal_point_len);
+    
+    c = copy;
+    memcpy (c, nptr, decimal_point_pos - nptr);
+    c += decimal_point_pos - nptr;
+    memcpy (c, decimal_point, decimal_point_len);
+    c += decimal_point_len;
+    memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
+    c += end - (decimal_point_pos + 1);
+    *c = 0;
+
+    errno = 0;
+    val = strtod (copy, &fail_pos);
+    strtod_errno = errno;
+
+    if (fail_pos) {
+      if (fail_pos - copy > decimal_point_pos - nptr)
+        fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
+      else
+        fail_pos = (char *)nptr + (fail_pos - copy);
+    }
+
+    free (copy);
+  } else if (end) {
+    char *copy;
+    
+    copy = (char *) malloc (end - (char *)nptr + 1);
+    memcpy (copy, nptr, end - nptr);
+    *(copy + (end - (char *)nptr)) = 0;
+    
+    errno = 0;
+    val = strtod (copy, &fail_pos);
+    strtod_errno = errno;
+
+    if (fail_pos) {
+      fail_pos = (char *)nptr + (fail_pos - copy);
+    }
+
+    free (copy);
+  } else {
+    errno = 0;
+    val = strtod (nptr, &fail_pos);
+    strtod_errno = errno;
+  }
+
+  if (endptr)
+    *endptr = fail_pos;
+
+  errno = strtod_errno;
+
+  return val;
+}
diff --git a/goo/gstrtod.h b/goo/gstrtod.h
new file mode 100644
index 0000000..e8abdad
--- /dev/null
+++ b/goo/gstrtod.h
@@ -0,0 +1,43 @@
+/* This file is part of Libspectre.
+ * 
+ * Copyright (C) 2007 Albert Astals Cid <aacid at kde.org>
+ * Copyright (C) 2007 Carlos Garcia Campos <carlosgc at gnome.org>
+ *
+ * Libspectre is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * Libspectre is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+/* This function comes from spectre-utils from libspectre */
+
+#ifndef GSTRTOD_H
+#define GSTRTOD_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* This function behaves like the standard atof()/(strtod() function
+ * does in the C locale. It does this without actually changing
+ * the current locale, since that would not be thread-safe.
+ * A limitation of the implementation is that this function
+ * will still accept localized versions of infinities and NANs.
+ */
+double gatof(const char *nptr);
+double gstrtod(const char *nptr, char **endptr);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif


More information about the poppler mailing list