~ubuntu-branches/ubuntu/hardy/postgresql-8.4/hardy-backports

« back to all changes in this revision

Viewing changes to src/backend/utils/adt/numutils.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2009-03-20 12:00:13 UTC
  • Revision ID: james.westby@ubuntu.com-20090320120013-hogj7egc5mjncc5g
Tags: upstream-8.4~0cvs20090328
ImportĀ upstreamĀ versionĀ 8.4~0cvs20090328

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-------------------------------------------------------------------------
 
2
 *
 
3
 * numutils.c
 
4
 *        utility functions for I/O of built-in numeric types.
 
5
 *
 
6
 *              integer:                                pg_atoi, pg_itoa, pg_ltoa
 
7
 *
 
8
 * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group
 
9
 * Portions Copyright (c) 1994, Regents of the University of California
 
10
 *
 
11
 *
 
12
 * IDENTIFICATION
 
13
 *        $PostgreSQL$
 
14
 *
 
15
 *-------------------------------------------------------------------------
 
16
 */
 
17
#include "postgres.h"
 
18
 
 
19
#include <math.h>
 
20
#include <limits.h>
 
21
#include <ctype.h>
 
22
 
 
23
#include "utils/builtins.h"
 
24
 
 
25
/*
 
26
 * pg_atoi: convert string to integer
 
27
 *
 
28
 * allows any number of leading or trailing whitespace characters.
 
29
 *
 
30
 * 'size' is the sizeof() the desired integral result (1, 2, or 4 bytes).
 
31
 *
 
32
 * c, if not 0, is a terminator character that may appear after the
 
33
 * integer (plus whitespace).  If 0, the string must end after the integer.
 
34
 *
 
35
 * Unlike plain atoi(), this will throw ereport() upon bad input format or
 
36
 * overflow.
 
37
 */
 
38
int32
 
39
pg_atoi(char *s, int size, int c)
 
40
{
 
41
        long            l;
 
42
        char       *badp;
 
43
 
 
44
        /*
 
45
         * Some versions of strtol treat the empty string as an error, but some
 
46
         * seem not to.  Make an explicit test to be sure we catch it.
 
47
         */
 
48
        if (s == NULL)
 
49
                elog(ERROR, "NULL pointer");
 
50
        if (*s == 0)
 
51
                ereport(ERROR,
 
52
                                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 
53
                                 errmsg("invalid input syntax for integer: \"%s\"",
 
54
                                                s)));
 
55
 
 
56
        errno = 0;
 
57
        l = strtol(s, &badp, 10);
 
58
 
 
59
        /* We made no progress parsing the string, so bail out */
 
60
        if (s == badp)
 
61
                ereport(ERROR,
 
62
                                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 
63
                                 errmsg("invalid input syntax for integer: \"%s\"",
 
64
                                                s)));
 
65
 
 
66
        switch (size)
 
67
        {
 
68
                case sizeof(int32):
 
69
                        if (errno == ERANGE
 
70
#if defined(HAVE_LONG_INT_64)
 
71
                        /* won't get ERANGE on these with 64-bit longs... */
 
72
                                || l < INT_MIN || l > INT_MAX
 
73
#endif
 
74
                                )
 
75
                                ereport(ERROR,
 
76
                                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 
77
                                errmsg("value \"%s\" is out of range for type integer", s)));
 
78
                        break;
 
79
                case sizeof(int16):
 
80
                        if (errno == ERANGE || l < SHRT_MIN || l > SHRT_MAX)
 
81
                                ereport(ERROR,
 
82
                                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 
83
                                errmsg("value \"%s\" is out of range for type smallint", s)));
 
84
                        break;
 
85
                case sizeof(int8):
 
86
                        if (errno == ERANGE || l < SCHAR_MIN || l > SCHAR_MAX)
 
87
                                ereport(ERROR,
 
88
                                                (errcode(ERRCODE_NUMERIC_VALUE_OUT_OF_RANGE),
 
89
                                errmsg("value \"%s\" is out of range for 8-bit integer", s)));
 
90
                        break;
 
91
                default:
 
92
                        elog(ERROR, "unsupported result size: %d", size);
 
93
        }
 
94
 
 
95
        /*
 
96
         * Skip any trailing whitespace; if anything but whitespace remains before
 
97
         * the terminating character, bail out
 
98
         */
 
99
        while (*badp && *badp != c && isspace((unsigned char) *badp))
 
100
                badp++;
 
101
 
 
102
        if (*badp && *badp != c)
 
103
                ereport(ERROR,
 
104
                                (errcode(ERRCODE_INVALID_TEXT_REPRESENTATION),
 
105
                                 errmsg("invalid input syntax for integer: \"%s\"",
 
106
                                                s)));
 
107
 
 
108
        return (int32) l;
 
109
}
 
110
 
 
111
/*
 
112
 *              pg_itoa                 - converts a short int to its string represention
 
113
 *
 
114
 *              Note:
 
115
 *                              previously based on ~ingres/source/gutil/atoi.c
 
116
 *                              now uses vendor's sprintf conversion
 
117
 */
 
118
void
 
119
pg_itoa(int16 i, char *a)
 
120
{
 
121
        sprintf(a, "%hd", (short) i);
 
122
}
 
123
 
 
124
/*
 
125
 *              pg_ltoa                 - converts a long int to its string represention
 
126
 *
 
127
 *              Note:
 
128
 *                              previously based on ~ingres/source/gutil/atoi.c
 
129
 *                              now uses vendor's sprintf conversion
 
130
 */
 
131
void
 
132
pg_ltoa(int32 l, char *a)
 
133
{
 
134
        sprintf(a, "%d", l);
 
135
}