1
/*-------------------------------------------------------------------------
4
* utility functions for I/O of built-in numeric types.
6
* Portions Copyright (c) 1996-2011, PostgreSQL Global Development Group
7
* Portions Copyright (c) 1994, Regents of the University of California
11
* src/backend/utils/adt/numutils.c
13
*-------------------------------------------------------------------------
21
#include "utils/builtins.h"
24
* pg_atoi: convert string to integer
26
* allows any number of leading or trailing whitespace characters.
28
* 'size' is the sizeof() the desired integral result (1, 2, or 4 bytes).
30
* c, if not 0, is a terminator character that may appear after the
31
* integer (plus whitespace). If 0, the string must end after the integer.
33
* Unlike plain atoi(), this will throw ereport() upon bad input format or
37
pg_atoi(char *s, int size, int c)
43
* Some versions of strtol treat the empty string as an error, but some
44
* seem not to. Make an explicit test to be sure we catch it.
47
elog(ERROR, "NULL pointer");
50
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
51
errmsg("invalid input syntax for integer: \"%s\"",
55
l = strtol(s, &badp, 10);
57
/* We made no progress parsing the string, so bail out */
60
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
61
errmsg("invalid input syntax for integer: \"%s\"",
68
#if defined(HAVE_LONG_INT_64)
69
/* won't get ERANGE on these with 64-bit longs... */
70
|| l < INT_MIN || l > INT_MAX
74
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
75
errmsg("value \"%s\" is out of range for type integer", s)));
78
if (errno == ERANGE || l < SHRT_MIN || l > SHRT_MAX)
80
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
81
errmsg("value \"%s\" is out of range for type smallint", s)));
84
if (errno == ERANGE || l < SCHAR_MIN || l > SCHAR_MAX)
86
(errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
87
errmsg("value \"%s\" is out of range for 8-bit integer", s)));
90
elog(ERROR, "unsupported result size: %d", size);
94
* Skip any trailing whitespace; if anything but whitespace remains before
95
* the terminating character, bail out
97
while (*badp && *badp != c && isspace((unsigned char) *badp))
100
if (*badp && *badp != c)
102
(errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
103
errmsg("invalid input syntax for integer: \"%s\"",
110
* pg_itoa: converts a signed 16-bit integer to its string representation
112
* Caller must ensure that 'a' points to enough memory to hold the result
113
* (at least 7 bytes, counting a leading sign and trailing NUL).
115
* It doesn't seem worth implementing this separately.
118
pg_itoa(int16 i, char *a)
120
pg_ltoa((int32) i, a);
124
* pg_ltoa: converts a signed 32-bit integer to its string representation
126
* Caller must ensure that 'a' points to enough memory to hold the result
127
* (at least 12 bytes, counting a leading sign and trailing NUL).
130
pg_ltoa(int32 value, char *a)
136
* Avoid problems with the most negative integer not being representable
137
* as a positive integer.
139
if (value == (-2147483647 - 1))
141
memcpy(a, "-2147483648", 12);
150
/* Compute the result string backwards. */
154
int32 oldval = value;
157
remainder = oldval - value * 10;
158
*a++ = '0' + remainder;
159
} while (value != 0);
164
/* Add trailing NUL byte, and back up 'a' to the last character. */
167
/* Reverse string. */
178
* pg_lltoa: convert a signed 64-bit integer to its string representation
180
* Caller must ensure that 'a' points to enough memory to hold the result
181
* (at least MAXINT8LEN+1 bytes, counting a leading sign and trailing NUL).
184
pg_lltoa(int64 value, char *a)
190
* Avoid problems with the most negative integer not being representable
191
* as a positive integer.
193
if (value == (-INT64CONST(0x7FFFFFFFFFFFFFFF) - 1))
195
memcpy(a, "-9223372036854775808", 21);
204
/* Compute the result string backwards. */
208
int64 oldval = value;
211
remainder = oldval - value * 10;
212
*a++ = '0' + remainder;
213
} while (value != 0);
218
/* Add trailing NUL byte, and back up 'a' to the last character. */
221
/* Reverse string. */