OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [libiberty/] [strtol.c] - Diff between revs 154 and 816

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 154 Rev 816
/*-
/*-
 * Copyright (c) 1990 The Regents of the University of California.
 * Copyright (c) 1990 The Regents of the University of California.
 * All rights reserved.
 * All rights reserved.
 *
 *
 * Redistribution and use in source and binary forms, with or without
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * modification, are permitted provided that the following conditions
 * are met:
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *    documentation and/or other materials provided with the distribution.
 * 3. [rescinded 22 July 1999]
 * 3. [rescinded 22 July 1999]
 * 4. Neither the name of the University nor the names of its contributors
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *    without specific prior written permission.
 *
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 * SUCH DAMAGE.
 */
 */
 
 
/*
/*
 
 
@deftypefn Supplemental {long int} strtol (const char *@var{string}, char **@var{endptr}, int @var{base})
@deftypefn Supplemental {long int} strtol (const char *@var{string}, char **@var{endptr}, int @var{base})
@deftypefnx Supplemental {unsigned long int} strtoul (const char *@var{string}, char **@var{endptr}, int @var{base})
@deftypefnx Supplemental {unsigned long int} strtoul (const char *@var{string}, char **@var{endptr}, int @var{base})
 
 
The @code{strtol} function converts the string in @var{string} to a
The @code{strtol} function converts the string in @var{string} to a
long integer value according to the given @var{base}, which must be
long integer value according to the given @var{base}, which must be
between 2 and 36 inclusive, or be the special value 0.  If @var{base}
between 2 and 36 inclusive, or be the special value 0.  If @var{base}
is 0, @code{strtol} will look for the prefixes @code{0} and @code{0x}
is 0, @code{strtol} will look for the prefixes @code{0} and @code{0x}
to indicate bases 8 and 16, respectively, else default to base 10.
to indicate bases 8 and 16, respectively, else default to base 10.
When the base is 16 (either explicitly or implicitly), a prefix of
When the base is 16 (either explicitly or implicitly), a prefix of
@code{0x} is allowed.  The handling of @var{endptr} is as that of
@code{0x} is allowed.  The handling of @var{endptr} is as that of
@code{strtod} above.  The @code{strtoul} function is the same, except
@code{strtod} above.  The @code{strtoul} function is the same, except
that the converted value is unsigned.
that the converted value is unsigned.
 
 
@end deftypefn
@end deftypefn
 
 
*/
*/
 
 
#ifdef HAVE_CONFIG_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#include "config.h"
#endif
#endif
#ifdef HAVE_LIMITS_H
#ifdef HAVE_LIMITS_H
#include <limits.h>
#include <limits.h>
#endif
#endif
#ifdef HAVE_SYS_PARAM_H
#ifdef HAVE_SYS_PARAM_H
#include <sys/param.h>
#include <sys/param.h>
#endif
#endif
#include <errno.h>
#include <errno.h>
#ifdef NEED_DECLARATION_ERRNO
#ifdef NEED_DECLARATION_ERRNO
extern int errno;
extern int errno;
#endif
#endif
#include "safe-ctype.h"
#include "safe-ctype.h"
 
 
/* FIXME: It'd be nice to configure around these, but the include files are too
/* FIXME: It'd be nice to configure around these, but the include files are too
   painful.  These macros should at least be more portable than hardwired hex
   painful.  These macros should at least be more portable than hardwired hex
   constants. */
   constants. */
 
 
#ifndef ULONG_MAX
#ifndef ULONG_MAX
#define ULONG_MAX       ((unsigned long)(~0L))          /* 0xFFFFFFFF */
#define ULONG_MAX       ((unsigned long)(~0L))          /* 0xFFFFFFFF */
#endif
#endif
 
 
#ifndef LONG_MAX
#ifndef LONG_MAX
#define LONG_MAX        ((long)(ULONG_MAX >> 1))        /* 0x7FFFFFFF */
#define LONG_MAX        ((long)(ULONG_MAX >> 1))        /* 0x7FFFFFFF */
#endif
#endif
 
 
#ifndef LONG_MIN
#ifndef LONG_MIN
#define LONG_MIN        ((long)(~LONG_MAX))             /* 0x80000000 */
#define LONG_MIN        ((long)(~LONG_MAX))             /* 0x80000000 */
#endif
#endif
 
 
/*
/*
 * Convert a string to a long integer.
 * Convert a string to a long integer.
 *
 *
 * Ignores `locale' stuff.  Assumes that the upper and lower case
 * Ignores `locale' stuff.  Assumes that the upper and lower case
 * alphabets and digits are each contiguous.
 * alphabets and digits are each contiguous.
 */
 */
long
long
strtol(const char *nptr, char **endptr, register int base)
strtol(const char *nptr, char **endptr, register int base)
{
{
        register const char *s = nptr;
        register const char *s = nptr;
        register unsigned long acc;
        register unsigned long acc;
        register int c;
        register int c;
        register unsigned long cutoff;
        register unsigned long cutoff;
        register int neg = 0, any, cutlim;
        register int neg = 0, any, cutlim;
 
 
        /*
        /*
         * Skip white space and pick up leading +/- sign if any.
         * Skip white space and pick up leading +/- sign if any.
         * If base is 0, allow 0x for hex and 0 for octal, else
         * If base is 0, allow 0x for hex and 0 for octal, else
         * assume decimal; if base is already 16, allow 0x.
         * assume decimal; if base is already 16, allow 0x.
         */
         */
        do {
        do {
                c = *s++;
                c = *s++;
        } while (ISSPACE(c));
        } while (ISSPACE(c));
        if (c == '-') {
        if (c == '-') {
                neg = 1;
                neg = 1;
                c = *s++;
                c = *s++;
        } else if (c == '+')
        } else if (c == '+')
                c = *s++;
                c = *s++;
        if ((base == 0 || base == 16) &&
        if ((base == 0 || base == 16) &&
            c == '0' && (*s == 'x' || *s == 'X')) {
            c == '0' && (*s == 'x' || *s == 'X')) {
                c = s[1];
                c = s[1];
                s += 2;
                s += 2;
                base = 16;
                base = 16;
        }
        }
        if (base == 0)
        if (base == 0)
                base = c == '0' ? 8 : 10;
                base = c == '0' ? 8 : 10;
 
 
        /*
        /*
         * Compute the cutoff value between legal numbers and illegal
         * Compute the cutoff value between legal numbers and illegal
         * numbers.  That is the largest legal value, divided by the
         * numbers.  That is the largest legal value, divided by the
         * base.  An input number that is greater than this value, if
         * base.  An input number that is greater than this value, if
         * followed by a legal input character, is too big.  One that
         * followed by a legal input character, is too big.  One that
         * is equal to this value may be valid or not; the limit
         * is equal to this value may be valid or not; the limit
         * between valid and invalid numbers is then based on the last
         * between valid and invalid numbers is then based on the last
         * digit.  For instance, if the range for longs is
         * digit.  For instance, if the range for longs is
         * [-2147483648..2147483647] and the input base is 10,
         * [-2147483648..2147483647] and the input base is 10,
         * cutoff will be set to 214748364 and cutlim to either
         * cutoff will be set to 214748364 and cutlim to either
         * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
         * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
         * a value > 214748364, or equal but the next digit is > 7 (or 8),
         * a value > 214748364, or equal but the next digit is > 7 (or 8),
         * the number is too big, and we will return a range error.
         * the number is too big, and we will return a range error.
         *
         *
         * Set any if any `digits' consumed; make it negative to indicate
         * Set any if any `digits' consumed; make it negative to indicate
         * overflow.
         * overflow.
         */
         */
        cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
        cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
        cutlim = cutoff % (unsigned long)base;
        cutlim = cutoff % (unsigned long)base;
        cutoff /= (unsigned long)base;
        cutoff /= (unsigned long)base;
        for (acc = 0, any = 0;; c = *s++) {
        for (acc = 0, any = 0;; c = *s++) {
                if (ISDIGIT(c))
                if (ISDIGIT(c))
                        c -= '0';
                        c -= '0';
                else if (ISALPHA(c))
                else if (ISALPHA(c))
                        c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
                        c -= ISUPPER(c) ? 'A' - 10 : 'a' - 10;
                else
                else
                        break;
                        break;
                if (c >= base)
                if (c >= base)
                        break;
                        break;
                if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
                if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
                        any = -1;
                        any = -1;
                else {
                else {
                        any = 1;
                        any = 1;
                        acc *= base;
                        acc *= base;
                        acc += c;
                        acc += c;
                }
                }
        }
        }
        if (any < 0) {
        if (any < 0) {
                acc = neg ? LONG_MIN : LONG_MAX;
                acc = neg ? LONG_MIN : LONG_MAX;
                errno = ERANGE;
                errno = ERANGE;
        } else if (neg)
        } else if (neg)
                acc = -acc;
                acc = -acc;
        if (endptr != 0)
        if (endptr != 0)
                *endptr = (char *) (any ? s - 1 : nptr);
                *endptr = (char *) (any ? s - 1 : nptr);
        return (acc);
        return (acc);
}
}
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.