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

Subversion Repositories openrisc

[/] [openrisc/] [tags/] [gnu-src/] [newlib-1.18.0/] [newlib-1.18.0-or32-1.0rc2/] [newlib/] [libc/] [stdlib/] [strtol.c] - Diff between revs 207 and 520

Only display areas with differences | Details | Blame | View Log

Rev 207 Rev 520
/*
/*
FUNCTION
FUNCTION
   <<strtol>>---string to long
   <<strtol>>---string to long
 
 
INDEX
INDEX
        strtol
        strtol
INDEX
INDEX
        _strtol_r
        _strtol_r
 
 
ANSI_SYNOPSIS
ANSI_SYNOPSIS
        #include <stdlib.h>
        #include <stdlib.h>
        long strtol(const char *<[s]>, char **<[ptr]>,int <[base]>);
        long strtol(const char *<[s]>, char **<[ptr]>,int <[base]>);
 
 
        long _strtol_r(void *<[reent]>,
        long _strtol_r(void *<[reent]>,
                       const char *<[s]>, char **<[ptr]>,int <[base]>);
                       const char *<[s]>, char **<[ptr]>,int <[base]>);
 
 
TRAD_SYNOPSIS
TRAD_SYNOPSIS
        #include <stdlib.h>
        #include <stdlib.h>
        long strtol (<[s]>, <[ptr]>, <[base]>)
        long strtol (<[s]>, <[ptr]>, <[base]>)
        char *<[s]>;
        char *<[s]>;
        char **<[ptr]>;
        char **<[ptr]>;
        int <[base]>;
        int <[base]>;
 
 
        long _strtol_r (<[reent]>, <[s]>, <[ptr]>, <[base]>)
        long _strtol_r (<[reent]>, <[s]>, <[ptr]>, <[base]>)
        char *<[reent]>;
        char *<[reent]>;
        char *<[s]>;
        char *<[s]>;
        char **<[ptr]>;
        char **<[ptr]>;
        int <[base]>;
        int <[base]>;
 
 
DESCRIPTION
DESCRIPTION
The function <<strtol>> converts the string <<*<[s]>>> to
The function <<strtol>> converts the string <<*<[s]>>> to
a <<long>>. First, it breaks down the string into three parts:
a <<long>>. First, it breaks down the string into three parts:
leading whitespace, which is ignored; a subject string consisting
leading whitespace, which is ignored; a subject string consisting
of characters resembling an integer in the radix specified by <[base]>;
of characters resembling an integer in the radix specified by <[base]>;
and a trailing portion consisting of zero or more unparseable characters,
and a trailing portion consisting of zero or more unparseable characters,
and always including the terminating null character. Then, it attempts
and always including the terminating null character. Then, it attempts
to convert the subject string into a <<long>> and returns the
to convert the subject string into a <<long>> and returns the
result.
result.
 
 
If the value of <[base]> is 0, the subject string is expected to look
If the value of <[base]> is 0, the subject string is expected to look
like a normal C integer constant: an optional sign, a possible `<<0x>>'
like a normal C integer constant: an optional sign, a possible `<<0x>>'
indicating a hexadecimal base, and a number. If <[base]> is between
indicating a hexadecimal base, and a number. If <[base]> is between
2 and 36, the expected form of the subject is a sequence of letters
2 and 36, the expected form of the subject is a sequence of letters
and digits representing an integer in the radix specified by <[base]>,
and digits representing an integer in the radix specified by <[base]>,
with an optional plus or minus sign. The letters <<a>>--<<z>> (or,
with an optional plus or minus sign. The letters <<a>>--<<z>> (or,
equivalently, <<A>>--<<Z>>) are used to signify values from 10 to 35;
equivalently, <<A>>--<<Z>>) are used to signify values from 10 to 35;
only letters whose ascribed values are less than <[base]> are
only letters whose ascribed values are less than <[base]> are
permitted. If <[base]> is 16, a leading <<0x>> is permitted.
permitted. If <[base]> is 16, a leading <<0x>> is permitted.
 
 
The subject sequence is the longest initial sequence of the input
The subject sequence is the longest initial sequence of the input
string that has the expected form, starting with the first
string that has the expected form, starting with the first
non-whitespace character.  If the string is empty or consists entirely
non-whitespace character.  If the string is empty or consists entirely
of whitespace, or if the first non-whitespace character is not a
of whitespace, or if the first non-whitespace character is not a
permissible letter or digit, the subject string is empty.
permissible letter or digit, the subject string is empty.
 
 
If the subject string is acceptable, and the value of <[base]> is zero,
If the subject string is acceptable, and the value of <[base]> is zero,
<<strtol>> attempts to determine the radix from the input string. A
<<strtol>> attempts to determine the radix from the input string. A
string with a leading <<0x>> is treated as a hexadecimal value; a string with
string with a leading <<0x>> is treated as a hexadecimal value; a string with
a leading 0 and no <<x>> is treated as octal; all other strings are
a leading 0 and no <<x>> is treated as octal; all other strings are
treated as decimal. If <[base]> is between 2 and 36, it is used as the
treated as decimal. If <[base]> is between 2 and 36, it is used as the
conversion radix, as described above. If the subject string begins with
conversion radix, as described above. If the subject string begins with
a minus sign, the value is negated. Finally, a pointer to the first
a minus sign, the value is negated. Finally, a pointer to the first
character past the converted subject string is stored in <[ptr]>, if
character past the converted subject string is stored in <[ptr]>, if
<[ptr]> is not <<NULL>>.
<[ptr]> is not <<NULL>>.
 
 
If the subject string is empty (or not in acceptable form), no conversion
If the subject string is empty (or not in acceptable form), no conversion
is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is
is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is
not <<NULL>>).
not <<NULL>>).
 
 
The alternate function <<_strtol_r>> is a reentrant version.  The
The alternate function <<_strtol_r>> is a reentrant version.  The
extra argument <[reent]> is a pointer to a reentrancy structure.
extra argument <[reent]> is a pointer to a reentrancy structure.
 
 
RETURNS
RETURNS
<<strtol>> returns the converted value, if any. If no conversion was
<<strtol>> returns the converted value, if any. If no conversion was
made, 0 is returned.
made, 0 is returned.
 
 
<<strtol>> returns <<LONG_MAX>> or <<LONG_MIN>> if the magnitude of
<<strtol>> returns <<LONG_MAX>> or <<LONG_MIN>> if the magnitude of
the converted value is too large, and sets <<errno>> to <<ERANGE>>.
the converted value is too large, and sets <<errno>> to <<ERANGE>>.
 
 
PORTABILITY
PORTABILITY
<<strtol>> is ANSI.
<<strtol>> is ANSI.
 
 
No supporting OS subroutines are required.
No supporting OS subroutines are required.
*/
*/
 
 
/*-
/*-
 * 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. All advertising materials mentioning features or use of this software
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *    must display the following acknowledgement:
 *      This product includes software developed by the University of
 *      This product includes software developed by the University of
 *      California, Berkeley and its contributors.
 *      California, Berkeley and its contributors.
 * 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.
 */
 */
 
 
 
 
#include <_ansi.h>
#include <_ansi.h>
#include <limits.h>
#include <limits.h>
#include <ctype.h>
#include <ctype.h>
#include <errno.h>
#include <errno.h>
#include <stdlib.h>
#include <stdlib.h>
#include <reent.h>
#include <reent.h>
 
 
/*
/*
 * 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
_DEFUN (_strtol_r, (rptr, nptr, endptr, base),
_DEFUN (_strtol_r, (rptr, nptr, endptr, base),
        struct _reent *rptr _AND
        struct _reent *rptr _AND
        _CONST char *nptr _AND
        _CONST char *nptr _AND
        char **endptr _AND
        char **endptr _AND
        int base)
        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;
                rptr->_errno = ERANGE;
                rptr->_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);
}
}
 
 
#ifndef _REENT_ONLY
#ifndef _REENT_ONLY
 
 
long
long
_DEFUN (strtol, (s, ptr, base),
_DEFUN (strtol, (s, ptr, base),
        _CONST char *s _AND
        _CONST char *s _AND
        char **ptr _AND
        char **ptr _AND
        int base)
        int base)
{
{
        return _strtol_r (_REENT, s, ptr, base);
        return _strtol_r (_REENT, s, ptr, base);
}
}
 
 
#endif
#endif
 
 

powered by: WebSVN 2.1.0

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