1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/genericopenlibs/cstdlib/LSTDLIB/STRTOL.C Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,264 @@
1.4 +/*
1.5 +FUNCTION
1.6 + <<strtol>>---string to long
1.7 + <<strtoul>>---string to unsigned long
1.8 +
1.9 +INDEX
1.10 + strtol
1.11 +INDEX
1.12 + _strtol_r
1.13 +
1.14 +ANSI_SYNOPSIS
1.15 + #include <stdlib.h>
1.16 + long strtol(const char *<[s]>, char **<[ptr]>,int <[base]>);
1.17 + unsigned long strtoul(const char *<[s]>, char **<[ptr]>,
1.18 + int <[base]>);
1.19 +
1.20 +DESCRIPTION
1.21 +The function <<strtol>> converts the string <<*<[s]>>> to
1.22 +a <<long>>. First, it breaks down the string into three parts:
1.23 +leading whitespace, which is ignored; a subject string consisting
1.24 +of characters resembling an integer in the radix specified by <[base]>;
1.25 +and a trailing portion consisting of zero or more unparseable characters,
1.26 +and always including the terminating null character. Then, it attempts
1.27 +to convert the subject string into a <<long>> and returns the
1.28 +result.
1.29 +
1.30 +If the value of <[base]> is 0, the subject string is expected to look
1.31 +like a normal C integer constant: an optional sign, a possible `<<0x>>'
1.32 +indicating a hexadecimal base, and a number. If <[base]> is between
1.33 +2 and 36, the expected form of the subject is a sequence of letters
1.34 +and digits representing an integer in the radix specified by <[base]>,
1.35 +with an optional plus or minus sign. The letters <<a>>--<<z>> (or,
1.36 +equivalently, <<A>>--<<Z>>) are used to signify values from 10 to 35;
1.37 +only letters whose ascribed values are less than <[base]> are
1.38 +permitted. If <[base]> is 16, a leading <<0x>> is permitted.
1.39 +
1.40 +The subject sequence is the longest initial sequence of the input
1.41 +string that has the expected form, starting with the first
1.42 +non-whitespace character. If the string is empty or consists entirely
1.43 +of whitespace, or if the first non-whitespace character is not a
1.44 +permissible letter or digit, the subject string is empty.
1.45 +
1.46 +If the subject string is acceptable, and the value of <[base]> is zero,
1.47 +<<strtol>> attempts to determine the radix from the input string. A
1.48 +string with a leading <<0x>> is treated as a hexadecimal value; a string with
1.49 +a leading 0 and no <<x>> is treated as octal; all other strings are
1.50 +treated as decimal. If <[base]> is between 2 and 36, it is used as the
1.51 +conversion radix, as described above. If the subject string begins with
1.52 +a minus sign, the value is negated. Finally, a pointer to the first
1.53 +character past the converted subject string is stored in <[ptr]>, if
1.54 +<[ptr]> is not <<NULL>>.
1.55 +
1.56 +If the subject string is empty (or not in acceptable form), no conversion
1.57 +is performed and the value of <[s]> is stored in <[ptr]> (if <[ptr]> is
1.58 +not <<NULL>>).
1.59 +
1.60 +The alternate function <<_strtol_r>> is a reentrant version. The
1.61 +extra argument <[reent]> is a pointer to a reentrancy structure.
1.62 +
1.63 +The function <<strtoul>> is similar but does not permit an optional sign
1.64 +and returns an <<unsigned long>>.
1.65 +
1.66 +RETURNS
1.67 +<<strtol>> returns the converted value, if any. If no conversion was
1.68 +made, 0 is returned.
1.69 +
1.70 +<<strtol>> returns <<LONG_MAX>> or <<LONG_MIN>> if the magnitude of
1.71 +the converted value is too large, and sets <<errno>> to <<ERANGE>>.
1.72 +
1.73 +<<strtoul>> returns <<ULONG_MAX>> if the magnitude of the converted
1.74 +value is too large, and sets <<errno>> to <<ERANGE>>.
1.75 +
1.76 +PORTABILITY
1.77 +<<strtol>> and <<strtoul>> are both ANSI.
1.78 +
1.79 +No supporting OS subroutines are required.
1.80 + */
1.81 +
1.82 +/*-
1.83 + * Copyright (c) 1990 The Regents of the University of California.
1.84 + * All rights reserved.
1.85 + *
1.86 + * Redistribution and use in source and binary forms, with or without
1.87 + * modification, are permitted provided that the following conditions
1.88 + * are met:
1.89 + * 1. Redistributions of source code must retain the above copyright
1.90 + * notice, this list of conditions and the following disclaimer.
1.91 + * 2. Redistributions in binary form must reproduce the above copyright
1.92 + * notice, this list of conditions and the following disclaimer in the
1.93 + * documentation and/or other materials provided with the distribution.
1.94 + * 3. All advertising materials mentioning features or use of this software
1.95 + * must display the following acknowledgement:
1.96 + * This product includes software developed by the University of
1.97 + * California, Berkeley and its contributors.
1.98 + * 4. Neither the name of the University nor the names of its contributors
1.99 + * may be used to endorse or promote products derived from this software
1.100 + * without specific prior written permission.
1.101 + *
1.102 + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
1.103 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.104 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.105 + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
1.106 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.107 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.108 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.109 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.110 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.111 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.112 + * SUCH DAMAGE.
1.113 + */
1.114 +
1.115 +
1.116 +#include <_ansi.h>
1.117 +#include <limits.h>
1.118 +#include <ctype.h>
1.119 +#include <errno.h>
1.120 +#include <stdlib.h>
1.121 +#include <reent.h>
1.122 +
1.123 +/*
1.124 + * Convert a string to a long integer.
1.125 + *
1.126 + * Ignores `locale' stuff. Assumes that the upper and lower case
1.127 + * alphabets and digits are each contiguous.
1.128 + */
1.129 +static unsigned long _do_strtoX (const char *nptr, char **endptr, int base, int issigned)
1.130 +{
1.131 + register const char *s = nptr;
1.132 + register unsigned long acc;
1.133 + register int c;
1.134 + register unsigned long cutoff;
1.135 + register int neg = 0, any, cutlim;
1.136 + register const unsigned long long_min = (unsigned long)LONG_MIN;
1.137 +
1.138 + /*
1.139 + * Skip white space and pick up leading +/- sign if any.
1.140 + * If base is 0, allow 0x for hex and 0 for octal, else
1.141 + * assume decimal; if base is already 16, allow 0x.
1.142 + */
1.143 + do {
1.144 + c = *s++;
1.145 + } while (isspace(c));
1.146 +
1.147 + if ((c == '-')||(c == '+')) {
1.148 + issigned = 1;
1.149 + }
1.150 +
1.151 + if (issigned) {
1.152 + if (c == '-') {
1.153 + neg = 1;
1.154 + c = *s++;
1.155 + } else if (c == '+')
1.156 + c = *s++;
1.157 + }
1.158 + if ((base == 0 || base == 16) &&
1.159 + c == '0' && (*s == 'x' || *s == 'X')) {
1.160 + c = s[1];
1.161 + s += 2;
1.162 + base = 16;
1.163 + }
1.164 + if (base == 0)
1.165 + base = c == '0' ? 8 : 10;
1.166 +
1.167 + /*
1.168 + * Compute the cutoff value between legal numbers and illegal
1.169 + * numbers. That is the largest legal value, divided by the
1.170 + * base. An input number that is greater than this value, if
1.171 + * followed by a legal input character, is too big. One that
1.172 + * is equal to this value may be valid or not; the limit
1.173 + * between valid and invalid numbers is then based on the last
1.174 + * digit. For instance, if the range for longs is
1.175 + * [-2147483648..2147483647] and the input base is 10,
1.176 + * cutoff will be set to 214748364 and cutlim to either
1.177 + * 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
1.178 + * a value > 214748364, or equal but the next digit is > 7 (or 8),
1.179 + * the number is too big, and we will return a range error.
1.180 + *
1.181 + * Set any if any `digits' consumed; make it negative to indicate
1.182 + * overflow.
1.183 + */
1.184 + if (issigned)
1.185 + cutoff = neg ? long_min : LONG_MAX;
1.186 + else
1.187 + cutoff = ULONG_MAX;
1.188 + cutlim = cutoff % (unsigned long)base;
1.189 + cutoff = cutoff / (unsigned long)base;
1.190 + for (acc = 0, any = 0;; c = *s++) {
1.191 + if (isdigit(c))
1.192 + c -= '0';
1.193 + else if (isalpha(c))
1.194 + c -= isupper(c) ? 'A' - 10 : 'a' - 10;
1.195 + else
1.196 + break;
1.197 + if (c >= base)
1.198 + break;
1.199 + if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
1.200 + any = -1;
1.201 + else {
1.202 + any = 1;
1.203 + acc *= base;
1.204 + acc += c;
1.205 + }
1.206 + }
1.207 + if (any < 0) {
1.208 + if (issigned)
1.209 + acc = neg ? LONG_MIN : LONG_MAX;
1.210 + else
1.211 + acc = ULONG_MAX;
1.212 + errno = ERANGE;
1.213 + } else if (neg)
1.214 + acc = (unsigned long)(-(long)acc);
1.215 + if (endptr != 0)
1.216 + *endptr = (char *) (any ? s - 1 : nptr);
1.217 + return (acc);
1.218 +}
1.219 +
1.220 +/**
1.221 +Convert string to unsigned long integer.
1.222 +Parses string interpreting its content as an integer value
1.223 +until a character that can not be interpreted is found,
1.224 +and returns an unsigned long value.
1.225 +@return The converted unsigned long value from the input string.
1.226 +If an error occurs or no conversion can be made 0 is returned.
1.227 +@param s String representing an integer number.
1.228 +@param ptr Address of a pointer.
1.229 +This is filled by the function with the address where scan has ended.
1.230 +Serves to determine where there is the first non-numerical character in the string.
1.231 +@param base Numeral radix in which the number to be interpreted.
1.232 +Must be 0 or be between 2 and 36. If it is 0 the radix of the string is determined
1.233 +by the initial characters of the string:
1.234 +*/
1.235 +EXPORT_C unsigned long strtoul (const char *s, char **ptr, int base)
1.236 + {
1.237 + return _do_strtoX (s, ptr, base, 0);
1.238 + }
1.239 +
1.240 +/**
1.241 +Convert string to long integer.
1.242 +@return The converted long int value from the input string.
1.243 +If an error occurs or no conversion can be made 0 is returned.
1.244 +@param s String representing an integer number.
1.245 +@param ptr Address of a pointer.
1.246 +This is filled by the function with the address where scan has ended.
1.247 +@param base Numeral radix in which the number to be interpreted.
1.248 +Must be 0 or be between 2 and 36. If it is 0 the radix of the string
1.249 +is determined by the initial characters of the string
1.250 +*/
1.251 +EXPORT_C long strtol (const char *s, char **ptr, int base)
1.252 + {
1.253 + return (long)_do_strtoX (s, ptr, base, 1);
1.254 + }
1.255 +
1.256 +/**
1.257 +Convert string to integer.
1.258 +Parses string interpreting its content as a number and returns an int value.
1.259 +@return The converted integer value of the input string.
1.260 +On overflow the result is undefined.
1.261 +If an error occurs 0 is returned.
1.262 +@param s String representing an integer number.
1.263 +*/
1.264 +EXPORT_C int atoi (const char *s)
1.265 + {
1.266 + return (int) _do_strtoX (s, NULL, 10, 1);
1.267 + }