~ubuntu-branches/ubuntu/gutsy/diffutils/gutsy

« back to all changes in this revision

Viewing changes to lib/strtol.c

  • Committer: Bazaar Package Importer
  • Author(s): Santiago Vila
  • Date: 2005-02-15 22:45:18 UTC
  • Revision ID: james.westby@ubuntu.com-20050215224518-dw9ti3me00twpcmt
Tags: upstream-2.8.1
ImportĀ upstreamĀ versionĀ 2.8.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Convert string representation of a number into an integer value.
 
2
   Copyright (C) 1991, 92, 94, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
 
3
   NOTE: The canonical source of this file is maintained with the GNU C
 
4
   Library.  Bugs can be reported to bug-glibc@gnu.org.
 
5
 
 
6
   This program is free software; you can redistribute it and/or modify it
 
7
   under the terms of the GNU General Public License as published by the
 
8
   Free Software Foundation; either version 2, or (at your option) any
 
9
   later version.
 
10
 
 
11
   This program is distributed in the hope that it will be useful,
 
12
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
   GNU General Public License for more details.
 
15
 
 
16
   You should have received a copy of the GNU General Public License
 
17
   along with this program; if not, write to the Free Software Foundation,
 
18
   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
19
 
 
20
#if HAVE_CONFIG_H
 
21
# include <config.h>
 
22
#endif
 
23
 
 
24
#ifdef _LIBC
 
25
# define USE_NUMBER_GROUPING
 
26
# define STDC_HEADERS
 
27
# define HAVE_LIMITS_H
 
28
#endif
 
29
 
 
30
#include <ctype.h>
 
31
#include <errno.h>
 
32
#ifndef errno
 
33
extern int errno;
 
34
#endif
 
35
#ifndef __set_errno
 
36
# define __set_errno(Val) errno = (Val)
 
37
#endif
 
38
 
 
39
#ifdef HAVE_LIMITS_H
 
40
# include <limits.h>
 
41
#endif
 
42
 
 
43
#ifdef STDC_HEADERS
 
44
# include <stddef.h>
 
45
# include <stdlib.h>
 
46
# include <string.h>
 
47
#else
 
48
# ifndef NULL
 
49
#  define NULL 0
 
50
# endif
 
51
#endif
 
52
 
 
53
#ifdef USE_NUMBER_GROUPING
 
54
# include "../locale/localeinfo.h"
 
55
#endif
 
56
 
 
57
/* Nonzero if we are defining `strtoul' or `strtoull', operating on
 
58
   unsigned integers.  */
 
59
#ifndef UNSIGNED
 
60
# define UNSIGNED 0
 
61
# define INT LONG int
 
62
#else
 
63
# define INT unsigned LONG int
 
64
#endif
 
65
 
 
66
/* Determine the name.  */
 
67
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
 
68
# if UNSIGNED
 
69
#  ifdef USE_WIDE_CHAR
 
70
#   ifdef QUAD
 
71
#    define strtol __wcstoull_l
 
72
#   else
 
73
#    define strtol __wcstoul_l
 
74
#   endif
 
75
#  else
 
76
#   ifdef QUAD
 
77
#    define strtol __strtoull_l
 
78
#   else
 
79
#    define strtol __strtoul_l
 
80
#   endif
 
81
#  endif
 
82
# else
 
83
#  ifdef USE_WIDE_CHAR
 
84
#   ifdef QUAD
 
85
#    define strtol __wcstoll_l
 
86
#   else
 
87
#    define strtol __wcstol_l
 
88
#   endif
 
89
#  else
 
90
#   ifdef QUAD
 
91
#    define strtol __strtoll_l
 
92
#   else
 
93
#    define strtol __strtol_l
 
94
#   endif
 
95
#  endif
 
96
# endif
 
97
#else
 
98
# if UNSIGNED
 
99
#  ifdef USE_WIDE_CHAR
 
100
#   ifdef QUAD
 
101
#    define strtol wcstoull
 
102
#   else
 
103
#    define strtol wcstoul
 
104
#   endif
 
105
#  else
 
106
#   ifdef QUAD
 
107
#    define strtol strtoull
 
108
#   else
 
109
#    define strtol strtoul
 
110
#   endif
 
111
#  endif
 
112
# else
 
113
#  ifdef USE_WIDE_CHAR
 
114
#   ifdef QUAD
 
115
#    define strtol wcstoll
 
116
#   else
 
117
#    define strtol wcstol
 
118
#   endif
 
119
#  else
 
120
#   ifdef QUAD
 
121
#    define strtol strtoll
 
122
#   endif
 
123
#  endif
 
124
# endif
 
125
#endif
 
126
 
 
127
/* If QUAD is defined, we are defining `strtoll' or `strtoull',
 
128
   operating on `long long int's.  */
 
129
#ifdef QUAD
 
130
# define LONG long long
 
131
# define STRTOL_LONG_MIN LONG_LONG_MIN
 
132
# define STRTOL_LONG_MAX LONG_LONG_MAX
 
133
# define STRTOL_ULONG_MAX ULONG_LONG_MAX
 
134
 
 
135
/* The extra casts work around common compiler bugs,
 
136
   e.g. Cray C 5.0.3.0 when t == time_t.  */
 
137
# ifndef TYPE_SIGNED
 
138
#  define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
 
139
# endif
 
140
# ifndef TYPE_MINIMUM
 
141
#  define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \
 
142
                                ? ~ (t) 0 << (sizeof (t) * CHAR_BIT - 1) \
 
143
                                : (t) 0))
 
144
# endif
 
145
# ifndef TYPE_MAXIMUM
 
146
#  define TYPE_MAXIMUM(t) ((t) (~ (t) 0 - TYPE_MINIMUM (t)))
 
147
# endif
 
148
 
 
149
# ifndef ULONG_LONG_MAX
 
150
#  define ULONG_LONG_MAX TYPE_MAXIMUM (unsigned long long)
 
151
# endif
 
152
# ifndef LONG_LONG_MAX
 
153
#  define LONG_LONG_MAX TYPE_MAXIMUM (long long int)
 
154
# endif
 
155
# ifndef LONG_LONG_MIN
 
156
#  define LONG_LONG_MIN TYPE_MINIMUM (long long int)
 
157
# endif
 
158
 
 
159
# if __GNUC__ == 2 && __GNUC_MINOR__ < 7
 
160
   /* Work around gcc bug with using this constant.  */
 
161
   static const unsigned long long int maxquad = ULONG_LONG_MAX;
 
162
#  undef STRTOL_ULONG_MAX
 
163
#  define STRTOL_ULONG_MAX maxquad
 
164
# endif
 
165
#else
 
166
# define LONG long
 
167
 
 
168
# ifndef ULONG_MAX
 
169
#  define ULONG_MAX ((unsigned long) ~(unsigned long) 0)
 
170
# endif
 
171
# ifndef LONG_MAX
 
172
#  define LONG_MAX ((long int) (ULONG_MAX >> 1))
 
173
# endif
 
174
# define STRTOL_LONG_MIN LONG_MIN
 
175
# define STRTOL_LONG_MAX LONG_MAX
 
176
# define STRTOL_ULONG_MAX ULONG_MAX
 
177
#endif
 
178
 
 
179
 
 
180
/* We use this code also for the extended locale handling where the
 
181
   function gets as an additional argument the locale which has to be
 
182
   used.  To access the values we have to redefine the _NL_CURRENT
 
183
   macro.  */
 
184
#ifdef USE_IN_EXTENDED_LOCALE_MODEL
 
185
# undef _NL_CURRENT
 
186
# define _NL_CURRENT(category, item) \
 
187
  (current->values[_NL_ITEM_INDEX (item)].string)
 
188
# define LOCALE_PARAM , loc
 
189
# define LOCALE_PARAM_DECL __locale_t loc;
 
190
#else
 
191
# define LOCALE_PARAM
 
192
# define LOCALE_PARAM_DECL
 
193
#endif
 
194
 
 
195
#if defined _LIBC || defined HAVE_WCHAR_H
 
196
# include <wchar.h>
 
197
#endif
 
198
 
 
199
#ifdef USE_WIDE_CHAR
 
200
# include <wctype.h>
 
201
# define L_(Ch) L##Ch
 
202
# define UCHAR_TYPE wint_t
 
203
# define STRING_TYPE wchar_t
 
204
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
 
205
#  define ISSPACE(Ch) __iswspace_l ((Ch), loc)
 
206
#  define ISALPHA(Ch) __iswalpha_l ((Ch), loc)
 
207
#  define TOUPPER(Ch) __towupper_l ((Ch), loc)
 
208
# else
 
209
#  define ISSPACE(Ch) iswspace (Ch)
 
210
#  define ISALPHA(Ch) iswalpha (Ch)
 
211
#  define TOUPPER(Ch) towupper (Ch)
 
212
# endif
 
213
#else
 
214
# if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
 
215
#  define IN_CTYPE_DOMAIN(c) 1
 
216
# else
 
217
#  define IN_CTYPE_DOMAIN(c) isascii(c)
 
218
# endif
 
219
# define L_(Ch) Ch
 
220
# define UCHAR_TYPE unsigned char
 
221
# define STRING_TYPE char
 
222
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
 
223
#  define ISSPACE(Ch) __isspace_l ((Ch), loc)
 
224
#  define ISALPHA(Ch) __isalpha_l ((Ch), loc)
 
225
#  define TOUPPER(Ch) __toupper_l ((Ch), loc)
 
226
# else
 
227
#  define ISSPACE(Ch) (IN_CTYPE_DOMAIN (Ch) && isspace (Ch))
 
228
#  define ISALPHA(Ch) (IN_CTYPE_DOMAIN (Ch) && isalpha (Ch))
 
229
#  define TOUPPER(Ch) (IN_CTYPE_DOMAIN (Ch) ? toupper (Ch) : (Ch))
 
230
# endif
 
231
#endif
 
232
 
 
233
/* For compilers which are ansi but don't define __STDC__, like SGI
 
234
   Irix-4.0.5 cc, also check whether PROTOTYPES is defined. */
 
235
#if defined (__STDC__) || defined (PROTOTYPES)
 
236
# define INTERNAL(X) INTERNAL1(X)
 
237
# define INTERNAL1(X) __##X##_internal
 
238
# define WEAKNAME(X) WEAKNAME1(X)
 
239
#else
 
240
# define INTERNAL(X) __/**/X/**/_internal
 
241
#endif
 
242
 
 
243
#ifdef USE_NUMBER_GROUPING
 
244
/* This file defines a function to check for correct grouping.  */
 
245
# include "grouping.h"
 
246
#endif
 
247
 
 
248
 
 
249
 
 
250
/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
 
251
   If BASE is 0 the base is determined by the presence of a leading
 
252
   zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
 
253
   If BASE is < 2 or > 36, it is reset to 10.
 
254
   If ENDPTR is not NULL, a pointer to the character after the last
 
255
   one converted is stored in *ENDPTR.  */
 
256
 
 
257
INT
 
258
INTERNAL (strtol) (nptr, endptr, base, group LOCALE_PARAM)
 
259
     const STRING_TYPE *nptr;
 
260
     STRING_TYPE **endptr;
 
261
     int base;
 
262
     int group;
 
263
     LOCALE_PARAM_DECL
 
264
{
 
265
  int negative;
 
266
  register unsigned LONG int cutoff;
 
267
  register unsigned int cutlim;
 
268
  register unsigned LONG int i;
 
269
  register const STRING_TYPE *s;
 
270
  register UCHAR_TYPE c;
 
271
  const STRING_TYPE *save, *end;
 
272
  int overflow;
 
273
 
 
274
#ifdef USE_NUMBER_GROUPING
 
275
# ifdef USE_IN_EXTENDED_LOCALE_MODEL
 
276
  struct locale_data *current = loc->__locales[LC_NUMERIC];
 
277
# endif
 
278
  /* The thousands character of the current locale.  */
 
279
  wchar_t thousands = L'\0';
 
280
  /* The numeric grouping specification of the current locale,
 
281
     in the format described in <locale.h>.  */
 
282
  const char *grouping;
 
283
 
 
284
  if (group)
 
285
    {
 
286
      grouping = _NL_CURRENT (LC_NUMERIC, GROUPING);
 
287
      if (*grouping <= 0 || *grouping == CHAR_MAX)
 
288
        grouping = NULL;
 
289
      else
 
290
        {
 
291
          /* Figure out the thousands separator character.  */
 
292
# if defined _LIBC || defined _HAVE_BTOWC
 
293
          thousands = __btowc (*_NL_CURRENT (LC_NUMERIC, THOUSANDS_SEP));
 
294
          if (thousands == WEOF)
 
295
            thousands = L'\0';
 
296
# endif
 
297
          if (thousands == L'\0')
 
298
            grouping = NULL;
 
299
        }
 
300
    }
 
301
  else
 
302
    grouping = NULL;
 
303
#endif
 
304
 
 
305
  if (base < 0 || base == 1 || base > 36)
 
306
    {
 
307
      __set_errno (EINVAL);
 
308
      return 0;
 
309
    }
 
310
 
 
311
  save = s = nptr;
 
312
 
 
313
  /* Skip white space.  */
 
314
  while (ISSPACE (*s))
 
315
    ++s;
 
316
  if (*s == L_('\0'))
 
317
    goto noconv;
 
318
 
 
319
  /* Check for a sign.  */
 
320
  if (*s == L_('-'))
 
321
    {
 
322
      negative = 1;
 
323
      ++s;
 
324
    }
 
325
  else if (*s == L_('+'))
 
326
    {
 
327
      negative = 0;
 
328
      ++s;
 
329
    }
 
330
  else
 
331
    negative = 0;
 
332
 
 
333
  /* Recognize number prefix and if BASE is zero, figure it out ourselves.  */
 
334
  if (*s == L_('0'))
 
335
    {
 
336
      if ((base == 0 || base == 16) && TOUPPER (s[1]) == L_('X'))
 
337
        {
 
338
          s += 2;
 
339
          base = 16;
 
340
        }
 
341
      else if (base == 0)
 
342
        base = 8;
 
343
    }
 
344
  else if (base == 0)
 
345
    base = 10;
 
346
 
 
347
  /* Save the pointer so we can check later if anything happened.  */
 
348
  save = s;
 
349
 
 
350
#ifdef USE_NUMBER_GROUPING
 
351
  if (group)
 
352
    {
 
353
      /* Find the end of the digit string and check its grouping.  */
 
354
      end = s;
 
355
      for (c = *end; c != L_('\0'); c = *++end)
 
356
        if ((wchar_t) c != thousands
 
357
            && ((wchar_t) c < L_('0') || (wchar_t) c > L_('9'))
 
358
            && (!ISALPHA (c) || (int) (TOUPPER (c) - L_('A') + 10) >= base))
 
359
          break;
 
360
      if (*s == thousands)
 
361
        end = s;
 
362
      else
 
363
        end = correctly_grouped_prefix (s, end, thousands, grouping);
 
364
    }
 
365
  else
 
366
#endif
 
367
    end = NULL;
 
368
 
 
369
  cutoff = STRTOL_ULONG_MAX / (unsigned LONG int) base;
 
370
  cutlim = STRTOL_ULONG_MAX % (unsigned LONG int) base;
 
371
 
 
372
  overflow = 0;
 
373
  i = 0;
 
374
  for (c = *s; c != L_('\0'); c = *++s)
 
375
    {
 
376
      if (s == end)
 
377
        break;
 
378
      if (c >= L_('0') && c <= L_('9'))
 
379
        c -= L_('0');
 
380
      else if (ISALPHA (c))
 
381
        c = TOUPPER (c) - L_('A') + 10;
 
382
      else
 
383
        break;
 
384
      if ((int) c >= base)
 
385
        break;
 
386
      /* Check for overflow.  */
 
387
      if (i > cutoff || (i == cutoff && c > cutlim))
 
388
        overflow = 1;
 
389
      else
 
390
        {
 
391
          i *= (unsigned LONG int) base;
 
392
          i += c;
 
393
        }
 
394
    }
 
395
 
 
396
  /* Check if anything actually happened.  */
 
397
  if (s == save)
 
398
    goto noconv;
 
399
 
 
400
  /* Store in ENDPTR the address of one character
 
401
     past the last character we converted.  */
 
402
  if (endptr != NULL)
 
403
    *endptr = (STRING_TYPE *) s;
 
404
 
 
405
#if !UNSIGNED
 
406
  /* Check for a value that is within the range of
 
407
     `unsigned LONG int', but outside the range of `LONG int'.  */
 
408
  if (overflow == 0
 
409
      && i > (negative
 
410
              ? -((unsigned LONG int) (STRTOL_LONG_MIN + 1)) + 1
 
411
              : (unsigned LONG int) STRTOL_LONG_MAX))
 
412
    overflow = 1;
 
413
#endif
 
414
 
 
415
  if (overflow)
 
416
    {
 
417
      __set_errno (ERANGE);
 
418
#if UNSIGNED
 
419
      return STRTOL_ULONG_MAX;
 
420
#else
 
421
      return negative ? STRTOL_LONG_MIN : STRTOL_LONG_MAX;
 
422
#endif
 
423
    }
 
424
 
 
425
  /* Return the result of the appropriate sign.  */
 
426
  return negative ? -i : i;
 
427
 
 
428
noconv:
 
429
  /* We must handle a special case here: the base is 0 or 16 and the
 
430
     first two characters are '0' and 'x', but the rest are no
 
431
     hexadecimal digits.  This is no error case.  We return 0 and
 
432
     ENDPTR points to the `x`.  */
 
433
  if (endptr != NULL)
 
434
    {
 
435
      if (save - nptr >= 2 && TOUPPER (save[-1]) == L_('X')
 
436
          && save[-2] == L_('0'))
 
437
        *endptr = (STRING_TYPE *) &save[-1];
 
438
      else
 
439
        /*  There was no number to convert.  */
 
440
        *endptr = (STRING_TYPE *) nptr;
 
441
    }
 
442
 
 
443
  return 0L;
 
444
}
 
445
 
 
446
/* External user entry point.  */
 
447
 
 
448
#if _LIBC - 0 == 0
 
449
# undef PARAMS
 
450
# if defined (__STDC__) && __STDC__
 
451
#  define PARAMS(Args) Args
 
452
# else
 
453
#  define PARAMS(Args) ()
 
454
# endif
 
455
 
 
456
/* Prototype.  */
 
457
INT strtol PARAMS ((const STRING_TYPE *nptr, STRING_TYPE **endptr, int base));
 
458
#endif
 
459
 
 
460
 
 
461
INT
 
462
#ifdef weak_function
 
463
weak_function
 
464
#endif
 
465
strtol (nptr, endptr, base LOCALE_PARAM)
 
466
     const STRING_TYPE *nptr;
 
467
     STRING_TYPE **endptr;
 
468
     int base;
 
469
     LOCALE_PARAM_DECL
 
470
{
 
471
  return INTERNAL (strtol) (nptr, endptr, base, 0 LOCALE_PARAM);
 
472
}