1 //===========================================================================
5 // String to long long int conversion function
7 //===========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 // eCos is free software; you can redistribute it and/or modify it under
14 // the terms of the GNU General Public License as published by the Free
15 // Software Foundation; either version 2 or (at your option) any later version.
17 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
19 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
22 // You should have received a copy of the GNU General Public License along
23 // with eCos; if not, write to the Free Software Foundation, Inc.,
24 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 // As a special exception, if other files instantiate templates or use macros
27 // or inline functions from this file, or you compile this file and link it
28 // with other works to produce a work based on this file, this file does not
29 // by itself cause the resulting work to be covered by the GNU General Public
30 // License. However the source code for this file must still be made available
31 // in accordance with section (3) of the GNU General Public License.
33 // This exception does not invalidate any other reasons why a work based on
34 // this file might be covered by the GNU General Public License.
35 // -------------------------------------------
36 //####ECOSGPLCOPYRIGHTEND####
37 //===========================================================================
38 //#####DESCRIPTIONBEGIN####
40 // Author(s): jlarmour
41 // Contributors: Fredrik Hederstierna, converted file from long to long long.
42 // Date: 2000-04-30, 2004-02-19
47 //####DESCRIPTIONEND####
49 //===========================================================================
51 // This code is based on original code with the following copyright:
54 * Copyright (c) 1990 The Regents of the University of California.
55 * All rights reserved.
57 * Redistribution and use in source and binary forms, with or without
58 * modification, are permitted provided that the following conditions
60 * 1. Redistributions of source code must retain the above copyright
61 * notice, this list of conditions and the following disclaimer.
62 * 2. Redistributions in binary form must reproduce the above copyright
63 * notice, this list of conditions and the following disclaimer in the
64 * documentation and/or other materials provided with the distribution.
65 * 3. Neither the name of the University nor the names of its contributors
66 * may be used to endorse or promote products derived from this software
67 * without specific prior written permission.
69 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
70 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
71 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
72 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
73 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
74 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
75 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
76 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
77 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
78 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
85 #include <pkgconf/libc_stdlib.h> // Configuration header
89 #include <cyg/infra/cyg_type.h> // Common type definitions and support
90 #include <cyg/infra/cyg_trac.h> // Tracing support
91 #include <cyg/infra/cyg_ass.h> // Assertion support
92 #include <limits.h> // Definition of LONG_LONG_MIN and LONG_LONG_MAX
93 #include <ctype.h> // Definition of many ctype functions
94 #include <errno.h> // Error code definitions
95 #include <stdlib.h> // Header for all stdlib functions
102 // Convert a string to a long long integer.
104 // Ignores `locale' stuff. Assumes that the upper and lower case
105 // alphabets and digits are each contiguous.
109 strtoll( const char *nptr, char **endptr, int base )
111 const char *s = nptr;
112 unsigned long long acc;
114 unsigned long long cutoff;
115 int neg = 0, any, cutlim;
117 CYG_REPORT_FUNCNAMETYPE( "strtoll", "returning long long %lld" );
118 CYG_REPORT_FUNCARG3( "nptr=%08x, endptr=%08x, base=%d",
119 nptr, endptr, base );
120 CYG_CHECK_DATA_PTR( nptr, "nptr is not a valid pointer!" );
123 CYG_CHECK_DATA_PTR( endptr, "endptr is not a valid pointer!" );
126 // Skip white space and pick up leading +/- sign if any.
127 // If base is 0, allow 0x for hex and 0 for octal, else
128 // assume decimal; if base is already 16, allow 0x.
133 } while (isspace(c));
139 if ((base == 0 || base == 16) &&
140 c == '0' && (*s == 'x' || *s == 'X')) {
146 base = c == '0' ? 8 : 10;
149 // Compute the cutoff value between legal numbers and illegal
150 // numbers. That is the largest legal value, divided by the
151 // base. An input number that is greater than this value, if
152 // followed by a legal input character, is too big. One that
153 // is equal to this value may be valid or not; the limit
154 // between valid and invalid numbers is then based on the last
155 // digit. For instance, if the range for long longs is
156 // [-2147483648..2147483647] and the input base is 10,
157 // cutoff will be set to 214748364 and cutlim to either
158 // 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
159 // a value > 214748364, or equal but the next digit is > 7 (or 8),
160 // the number is too big, and we will return a range error.
162 // Set any if any `digits' consumed; make it negative to indicate
166 cutoff = neg ? -(unsigned long long)LONG_LONG_MIN : LONG_LONG_MAX;
167 cutlim = cutoff % (unsigned long long)base;
168 cutoff /= (unsigned long long)base;
169 for (acc = 0, any = 0;; c = *s++) {
173 c -= isupper(c) ? 'A' - 10 : 'a' - 10;
178 if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
187 acc = neg ? LONG_LONG_MIN : LONG_LONG_MAX;
192 *endptr = (char *) (any ? s - 1 : nptr);
194 CYG_REPORT_RETVAL ( acc );