Commit 17bb6250 authored by Peter Eisentraut's avatar Peter Eisentraut

Move strtoint() to common

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: default avatarMichael Paquier <michael@paquier.xyz>
parent 6cf86f43
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <ctype.h> #include <ctype.h>
#include "common/string.h"
#include "nodes/pg_list.h" #include "nodes/pg_list.h"
#include "nodes/readfuncs.h" #include "nodes/readfuncs.h"
#include "nodes/value.h" #include "nodes/value.h"
...@@ -215,18 +216,15 @@ nodeTokenType(char *token, int length) ...@@ -215,18 +216,15 @@ nodeTokenType(char *token, int length)
{ {
/* /*
* Yes. Figure out whether it is integral or float; this requires * 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. * both a syntax check and a range check. strtoint() can do both for us.
* We know the token will end at a character that strtol will stop at, * We know the token will end at a character that strtoint will stop at,
* so we do not need to modify the string. * so we do not need to modify the string.
*/ */
long val;
char *endptr; char *endptr;
errno = 0; errno = 0;
val = strtol(token, &endptr, 10); (void) strtoint(token, &endptr, 10);
if (endptr != token + length || errno == ERANGE || if (endptr != token + length || errno == ERANGE)
/* check for overflow of int */
val != (int) val)
return T_Float; return T_Float;
return T_Integer; return T_Integer;
} }
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #include <unistd.h>
#include "common/string.h"
#include "parser/gramparse.h" #include "parser/gramparse.h"
#include "parser/parser.h" /* only needed for GUC variables */ #include "parser/parser.h" /* only needed for GUC variables */
#include "parser/scansup.h" #include "parser/scansup.h"
...@@ -1211,14 +1212,12 @@ litbufdup(core_yyscan_t yyscanner) ...@@ -1211,14 +1212,12 @@ litbufdup(core_yyscan_t yyscanner)
static int static int
process_integer_literal(const char *token, YYSTYPE *lval) process_integer_literal(const char *token, YYSTYPE *lval)
{ {
long val; int val;
char *endptr; char *endptr;
errno = 0; errno = 0;
val = strtol(token, &endptr, 10); val = strtoint(token, &endptr, 10);
if (*endptr != '\0' || errno == ERANGE || if (*endptr != '\0' || errno == ERANGE)
/* check for overflow of int */
val != (int) val)
{ {
/* integer too large, treat it as a float */ /* integer too large, treat it as a float */
lval->str = pstrdup(token); lval->str = pstrdup(token);
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "access/htup_details.h" #include "access/htup_details.h"
#include "access/xact.h" #include "access/xact.h"
#include "catalog/pg_type.h" #include "catalog/pg_type.h"
#include "common/string.h"
#include "funcapi.h" #include "funcapi.h"
#include "miscadmin.h" #include "miscadmin.h"
#include "nodes/nodeFuncs.h" #include "nodes/nodeFuncs.h"
...@@ -251,23 +252,6 @@ static const datetkn *deltacache[MAXDATEFIELDS] = {NULL}; ...@@ -251,23 +252,6 @@ static const datetkn *deltacache[MAXDATEFIELDS] = {NULL};
static const datetkn *abbrevcache[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. * Calendar time to Julian date conversions.
* Julian date is commonly used in astronomical applications, * Julian date is commonly used in astronomical applications,
......
...@@ -41,3 +41,18 @@ pg_str_endswith(const char *str, const char *end) ...@@ -41,3 +41,18 @@ pg_str_endswith(const char *str, const char *end)
str += slen - elen; str += slen - elen;
return strcmp(str, end) == 0; 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;
}
...@@ -11,5 +11,6 @@ ...@@ -11,5 +11,6 @@
#define COMMON_STRING_H #define COMMON_STRING_H
extern bool pg_str_endswith(const char *str, const char *end); 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 */ #endif /* COMMON_STRING_H */
...@@ -4,4 +4,5 @@ ...@@ -4,4 +4,5 @@
/pgstrcasecmp.c /pgstrcasecmp.c
/rint.c /rint.c
/snprintf.c /snprintf.c
/string.c
/strnlen.c /strnlen.c
...@@ -32,6 +32,7 @@ SHLIB_EXPORTS = exports.txt ...@@ -32,6 +32,7 @@ SHLIB_EXPORTS = exports.txt
OBJS= numeric.o datetime.o common.o dt_common.o timestamp.o interval.o \ OBJS= numeric.o datetime.o common.o dt_common.o timestamp.o interval.o \
pgstrcasecmp.o \ pgstrcasecmp.o \
$(filter rint.o snprintf.o strnlen.o, $(LIBOBJS)) \ $(filter rint.o snprintf.o strnlen.o, $(LIBOBJS)) \
string.o \
$(WIN32RES) $(WIN32RES)
all: all-lib all: all-lib
...@@ -47,6 +48,9 @@ include $(top_srcdir)/src/Makefile.shlib ...@@ -47,6 +48,9 @@ include $(top_srcdir)/src/Makefile.shlib
pgstrcasecmp.c rint.c snprintf.c strnlen.c: % : $(top_srcdir)/src/port/% pgstrcasecmp.c rint.c snprintf.c strnlen.c: % : $(top_srcdir)/src/port/%
rm -f $@ && $(LN_S) $< . rm -f $@ && $(LN_S) $< .
string.c: % : $(top_srcdir)/src/common/%
rm -f $@ && $(LN_S) $< .
install: all installdirs install-lib install: all installdirs install-lib
installdirs: installdirs-lib installdirs: installdirs-lib
...@@ -54,6 +58,6 @@ installdirs: installdirs-lib ...@@ -54,6 +58,6 @@ installdirs: installdirs-lib
uninstall: uninstall-lib uninstall: uninstall-lib
clean distclean: clean-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 maintainer-clean: distclean maintainer-clean-lib
...@@ -9,25 +9,13 @@ ...@@ -9,25 +9,13 @@
#error -ffast-math is known to break this code #error -ffast-math is known to break this code
#endif #endif
#include "common/string.h"
#include "extern.h" #include "extern.h"
#include "dt.h" #include "dt.h"
#include "pgtypes_error.h" #include "pgtypes_error.h"
#include "pgtypes_interval.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 /* copy&pasted from .../src/backend/utils/adt/datetime.c
* and changesd struct pg_tm to struct tm * and changesd struct pg_tm to struct tm
*/ */
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include "common/string.h"
#include "extern.h" #include "extern.h"
#include "preproc.h" #include "preproc.h"
} }
...@@ -727,14 +729,12 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+ ...@@ -727,14 +729,12 @@ cppline {space}*#([^i][A-Za-z]*|{if}|{ifdef}|{ifndef}|{import})((\/\*[^*/]*\*+
return PARAM; return PARAM;
} }
<C,SQL>{integer} { <C,SQL>{integer} {
long val; int val;
char* endptr; char* endptr;
errno = 0; errno = 0;
val = strtol((char *)yytext, &endptr,10); val = strtoint(yytext, &endptr, 10);
if (*endptr != '\0' || errno == ERANGE || if (*endptr != '\0' || errno == ERANGE)
/* check for overflow of int */
val != (int) val)
{ {
errno = 0; errno = 0;
base_yylval.str = mm_strdup(yytext); base_yylval.str = mm_strdup(yytext);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment