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. */