Move strtoint() to common
authorPeter Eisentraut <peter_e@gmx.net>
Tue, 13 Mar 2018 14:21:09 +0000 (10:21 -0400)
committerPeter Eisentraut <peter_e@gmx.net>
Tue, 13 Mar 2018 14:21:09 +0000 (10:21 -0400)
Several places used similar code to convert a string to an int, so take
the function that we already had and make it globally available.

Reviewed-by: Michael Paquier <michael@paquier.xyz>
src/backend/nodes/read.c
src/backend/parser/scan.l
src/backend/utils/adt/datetime.c
src/common/string.c
src/include/common/string.h
src/interfaces/ecpg/pgtypeslib/.gitignore
src/interfaces/ecpg/pgtypeslib/Makefile
src/interfaces/ecpg/pgtypeslib/interval.c
src/interfaces/ecpg/preproc/pgc.l

index 6e9fa45e37e37ff91c000e48d844d629b2b69f18..d3c742693bbe9c91854f45434e4c1749d4244479 100644 (file)
@@ -21,6 +21,7 @@
 
 #include <ctype.h>
 
+#include "common/string.h"
 #include "nodes/pg_list.h"
 #include "nodes/readfuncs.h"
 #include "nodes/value.h"
@@ -215,18 +216,15 @@ nodeTokenType(char *token, int length)
    {
        /*
         * Yes.  Figure out whether it is integral or float; this requires
-        * both a syntax check and a range check. strtol() can do both for us.
-        * We know the token will end at a character that strtol will stop at,
+        * both a syntax check and a range check. strtoint() can do both for us.
+        * We know the token will end at a character that strtoint will stop at,
         * so we do not need to modify the string.
         */
-       long        val;
        char       *endptr;
 
        errno = 0;
-       val = strtol(token, &endptr, 10);
-       if (endptr != token + length || errno == ERANGE ||
-           /* check for overflow of int */
-           val != (int) val)
+       (void) strtoint(token, &endptr, 10);
+       if (endptr != token + length || errno == ERANGE)
            return T_Float;
        return T_Integer;
    }
index 97d4dee6282859dc7f5f26069dae66e32e7b3b56..0cd782827ac8cfb9d73b72ce465585b5b33edf71 100644 (file)
@@ -34,6 +34,7 @@
 #include <ctype.h>
 #include <unistd.h>
 
+#include "common/string.h"
 #include "parser/gramparse.h"
 #include "parser/parser.h"     /* only needed for GUC variables */
 #include "parser/scansup.h"
@@ -1211,14 +1212,12 @@ litbufdup(core_yyscan_t yyscanner)
 static int
 process_integer_literal(const char *token, YYSTYPE *lval)
 {
-   long        val;
+   int         val;
    char       *endptr;
 
    errno = 0;
-   val = strtol(token, &endptr, 10);
-   if (*endptr != '\0' || errno == ERANGE ||
-       /* check for overflow of int */
-       val != (int) val)
+   val = strtoint(token, &endptr, 10);
+   if (*endptr != '\0' || errno == ERANGE)
    {
        /* integer too large, treat it as a float */
        lval->str = pstrdup(token);
index 8375b93c39777979a9d437ef53afdcd71e756e34..3f0f65c2956542dae5ea9b3f8a175a1b9619ce20 100644 (file)
@@ -22,6 +22,7 @@
 #include "access/htup_details.h"
 #include "access/xact.h"
 #include "catalog/pg_type.h"
+#include "common/string.h"
 #include "funcapi.h"
 #include "miscadmin.h"
 #include "nodes/nodeFuncs.h"
@@ -251,23 +252,6 @@ static const datetkn *deltacache[MAXDATEFIELDS] = {NULL};
 static const datetkn *abbrevcache[MAXDATEFIELDS] = {NULL};
 
 
-/*
- * strtoint --- just like strtol, but returns int not long
- */
-static int
-strtoint(const char *nptr, char **endptr, int base)
-{
-   long        val;
-
-   val = strtol(nptr, endptr, base);
-#ifdef HAVE_LONG_INT_64
-   if (val != (long) ((int32) val))
-       errno = ERANGE;
-#endif
-   return (int) val;
-}
-
-
 /*
  * Calendar time to Julian date conversions.
  * Julian date is commonly used in astronomical applications,
index 0e3557076a12d8b1dacc9bbd6d5b60bfbd3c6637..a45e9b8858034312e6f0878665a98a2e2e01a350 100644 (file)
@@ -41,3 +41,18 @@ pg_str_endswith(const char *str, const char *end)
    str += slen - elen;
    return strcmp(str, end) == 0;
 }
+
+
+/*
+ * strtoint --- just like strtol, but returns int not long
+ */
+int
+strtoint(const char *restrict str, char **restrict endptr, int base)
+{
+   long        val;
+
+   val = strtol(str, endptr, base);
+   if (val != (int) val)
+       errno = ERANGE;
+   return (int) val;
+}
index 06934b99144661fe07733111b8b49b1975b276b7..23e2e01f0e7a2ab49067a0d0024b4d8db7cbb3ab 100644 (file)
@@ -11,5 +11,6 @@
 #define COMMON_STRING_H
 
 extern bool pg_str_endswith(const char *str, const char *end);
+extern int strtoint(const char *restrict str, char **restrict endptr, int base);
 
 #endif                         /* COMMON_STRING_H */
index df46a79972d1460798d7fa057b081dcf461b6baa..d5f0fae445af3cc0122c17f04041d3fefa4d5bd4 100644 (file)
@@ -4,4 +4,5 @@
 /pgstrcasecmp.c
 /rint.c
 /snprintf.c
+/string.c
 /strnlen.c
index 01206568f1ccac7b95fdb0eef87cb270d1601b88..0945f3d5bcd67618a86db6e18156aaff662d493c 100644 (file)
@@ -32,6 +32,7 @@ SHLIB_EXPORTS = exports.txt
 OBJS= numeric.o datetime.o common.o dt_common.o timestamp.o interval.o \
    pgstrcasecmp.o \
    $(filter rint.o snprintf.o strnlen.o, $(LIBOBJS)) \
+   string.o \
    $(WIN32RES)
 
 all: all-lib
@@ -47,6 +48,9 @@ include $(top_srcdir)/src/Makefile.shlib
 pgstrcasecmp.c rint.c snprintf.c strnlen.c: % : $(top_srcdir)/src/port/%
    rm -f $@ && $(LN_S) $< .
 
+string.c: % : $(top_srcdir)/src/common/%
+   rm -f $@ && $(LN_S) $< .
+
 install: all installdirs install-lib
 
 installdirs: installdirs-lib
@@ -54,6 +58,6 @@ installdirs: installdirs-lib
 uninstall: uninstall-lib
 
 clean distclean: clean-lib
-   rm -f $(OBJS) pgstrcasecmp.c rint.c snprintf.c strnlen.c
+   rm -f $(OBJS) pgstrcasecmp.c rint.c snprintf.c strnlen.c string.c
 
 maintainer-clean: distclean maintainer-clean-lib
index 24a2f36d4db5941a20f9eb8721925e4b97ea2a63..6146a3c7b6c25a52790bd2fd18d45f2e768e2c7e 100644 (file)
@@ -9,25 +9,13 @@
 #error -ffast-math is known to break this code
 #endif
 
+#include "common/string.h"
+
 #include "extern.h"
 #include "dt.h"
 #include "pgtypes_error.h"
 #include "pgtypes_interval.h"
 
-/* copy&pasted from .../src/backend/utils/adt/datetime.c */
-static int
-strtoint(const char *nptr, char **endptr, int base)
-{
-   long        val;
-
-   val = strtol(nptr, endptr, base);
-#ifdef HAVE_LONG_INT_64
-   if (val != (long) ((int32) val))
-       errno = ERANGE;
-#endif
-   return (int) val;
-}
-
 /* copy&pasted from .../src/backend/utils/adt/datetime.c
  * and changesd struct pg_tm to struct tm
  */
index ba1798c77eb252cbe3c82581b92a12107609fdcb..405dee73b039dc7fea0316ff1479bbbd65af36c3 100644 (file)
@@ -21,6 +21,8 @@
 #include <ctype.h>
 #include <limits.h>
 
+#include "common/string.h"
+
 #include "extern.h"
 #include "preproc.h"
 }
@@ -727,14 +729,12 @@ cppline           {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
                        return PARAM;
                    }
 <C,SQL>{integer}   {
-                       long val;
+                       int val;
                        char* endptr;
 
                        errno = 0;
-                       val = strtol((char *)yytext, &endptr,10);
-                       if (*endptr != '\0' || errno == ERANGE ||
-                           /* check for overflow of int */
-                           val != (int) val)
+                       val = strtoint(yytext, &endptr, 10);
+                       if (*endptr != '\0' || errno == ERANGE)
                        {
                            errno = 0;
                            base_yylval.str = mm_strdup(yytext);