Update NOTES.opensolaris with scheduling details
[kopensolaris-gnu/glibc.git] / stdlib / strtol.c
index cac133e..e90c51c 100644 (file)
-/* Copyright (C) 1991, 1992, 1994 Free Software Foundation, Inc.
+/* Convert string representation of a number into an integer value.
+   Copyright (C) 1991,92,94,95,96,97,98,99,2000,2001,2002,2003,2004,2007
+       Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB.  If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA.  */
-
-#include <ctype.h>
-#include <limits.h>
-#include <stddef.h>
 #include <stdlib.h>
+#include <wchar.h>
+#include <locale/localeinfo.h>
 
-
-#ifndef        UNSIGNED
-#define        UNSIGNED        0
+#ifndef UNSIGNED
+# define UNSIGNED 0
+# define INT LONG int
+#else
+# define INT unsigned LONG int
 #endif
 
-/* Convert NPTR to an `unsigned long int' or `long int' in base BASE.
-   If BASE is 0 the base is determined by the presence of a leading
-   zero, indicating octal or a leading "0x" or "0X", indicating hexadecimal.
-   If BASE is < 2 or > 36, it is reset to 10.
-   If ENDPTR is not NULL, a pointer to the character after the last
-   one converted is stored in *ENDPTR.  */
-#if    UNSIGNED
-unsigned long int
-#define        strtol  strtoul
+#if UNSIGNED
+# ifdef USE_WIDE_CHAR
+#  ifdef QUAD
+#   define strtol wcstoull
+#   define __strtol_l __wcstoull_l
+#  else
+#   define strtol wcstoul
+#   define __strtol_l __wcstoul_l
+#  endif
+# else
+#  ifdef QUAD
+#   define strtol strtoull
+#   define __strtol_l __strtoull_l
+#  else
+#   define strtol strtoul
+#   define __strtol_l __strtoul_l
+#  endif
+# endif
 #else
-long int
+# ifdef USE_WIDE_CHAR
+#  ifdef QUAD
+#   define strtol wcstoll
+#   define __strtol_l __wcstoll_l
+#  else
+#   define strtol wcstol
+#   define __strtol_l __wcstol_l
+#  endif
+# else
+#  ifdef QUAD
+#   define strtol strtoll
+#   define __strtol_l __strtoll_l
+#  endif
+# endif
 #endif
-strtol (nptr, endptr, base)
-     const char *nptr;
-     char **endptr;
-     int base;
-{
-  int negative;
-  register unsigned long int cutoff;
-  register unsigned int cutlim;
-  register unsigned long int i;
-  register const char *s;
-  register unsigned char c;
-  const char *save;
-  int overflow;
-
-  if (base < 0 || base == 1 || base > 36)
-    base = 10;
-
-  s = nptr;
-
-  /* Skip white space.  */
-  while (isspace (*s))
-    ++s;
-  if (*s == '\0')
-    goto noconv;
-
-  /* Check for a sign.  */
-  if (*s == '-')
-    {
-      negative = 1;
-      ++s;
-    }
-  else if (*s == '+')
-    {
-      negative = 0;
-      ++s;
-    }
-  else
-    negative = 0;
-
-  if (base == 16 && s[0] == '0' && toupper (s[1]) == 'X')
-    s += 2;
-
-  /* If BASE is zero, figure it out ourselves.  */
-  if (base == 0)
-    if (*s == '0')
-      {
-       if (toupper (s[1]) == 'X')
-         {
-           s += 2;
-           base = 16;
-         }
-       else
-         base = 8;
-      }
-    else
-      base = 10;
-
-  /* Save the pointer so we can check later if anything happened.  */
-  save = s;
-
-  cutoff = ULONG_MAX / (unsigned long int) base;
-  cutlim = ULONG_MAX % (unsigned long int) base;
-
-  overflow = 0;
-  i = 0;
-  for (c = *s; c != '\0'; c = *++s)
-    {
-      if (isdigit (c))
-       c -= '0';
-      else if (isalpha (c))
-       c = toupper (c) - 'A' + 10;
-      else
-       break;
-      if (c >= base)
-       break;
-      /* Check for overflow.  */
-      if (i > cutoff || (i == cutoff && c > cutlim))
-       overflow = 1;
-      else
-       {
-         i *= (unsigned long int) base;
-         i += c;
-       }
-    }
-
-  /* Check if anything actually happened.  */
-  if (s == save)
-    goto noconv;
-
-  /* Store in ENDPTR the address of one character
-     past the last character we converted.  */
-  if (endptr != NULL)
-    *endptr = (char *) s;
-
-#if    !UNSIGNED
-  /* Check for a value that is within the range of
-     `unsigned long int', but outside the range of `long int'.  */
-  if (i > (negative ?
-          -(unsigned long int) LONG_MIN : (unsigned long int) LONG_MAX))
-    overflow = 1;
+
+
+/* If QUAD is defined, we are defining `strtoll' or `strtoull',
+   operating on `long long int's.  */
+#ifdef QUAD
+# define LONG long long
+#else
+# define LONG long
 #endif
 
-  if (overflow)
-    {
-      errno = ERANGE;
-#if    UNSIGNED
-      return ULONG_MAX;
+
+#ifdef USE_WIDE_CHAR
+# define STRING_TYPE wchar_t
 #else
-      return negative ? LONG_MIN : LONG_MAX;
+# define STRING_TYPE char
 #endif
-    }
 
-  /* Return the result of the appropriate sign.  */
-  return (negative ? -i : i);
 
-noconv:
-  /* There was no number to convert.  */
-  if (endptr != NULL)
-    *endptr = (char *) nptr;
-  return 0L;
+#define INTERNAL(X) INTERNAL1(X)
+#define INTERNAL1(X) __##X##_internal
+
+
+extern INT INTERNAL (__strtol_l) (const STRING_TYPE *, STRING_TYPE **, int,
+                                 int, __locale_t);
+
+
+INT
+INTERNAL (strtol) (nptr, endptr, base, group)
+     const STRING_TYPE *nptr;
+     STRING_TYPE **endptr;
+     int base;
+     int group;
+{
+  return INTERNAL (__strtol_l) (nptr, endptr, base, group, _NL_CURRENT_LOCALE);
+}
+libc_hidden_def (INTERNAL (strtol))
+
+
+INT
+strtol (nptr, endptr, base)
+     const STRING_TYPE *nptr;
+     STRING_TYPE **endptr;
+     int base;
+{
+  return INTERNAL (__strtol_l) (nptr, endptr, base, 0, _NL_CURRENT_LOCALE);
 }
+libc_hidden_def (strtol)