]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/language/c/libc/stdlib/v2_0/src/strtoull.cxx
TX51 pre-release
[karo-tx-redboot.git] / packages / language / c / libc / stdlib / v2_0 / src / strtoull.cxx
1 //===========================================================================
2 //
3 //      strtoull.cxx
4 //
5 //      String to unsigned long long int conversion function
6 //
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.
12 //
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.
16 //
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
20 // for more details.
21 //
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.
25 //
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.
32 //
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####
39 //
40 // Author(s):    jlarmour
41 // Contributors: Fredrik Hederstierna, converted file from long to long long.
42 // Date:         2000-04-30, 2004-02-19
43 // Purpose:     
44 // Description: 
45 // Usage:       
46 //
47 //####DESCRIPTIONEND####
48 //
49 //===========================================================================
50 //
51 // This code is based on original code with the following copyright:
52 //
53 /*
54  * Copyright (c) 1990 Regents of the University of California.
55  * All rights reserved.
56  *
57  * Redistribution and use in source and binary forms, with or without
58  * modification, are permitted provided that the following conditions
59  * are met:
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.
68  *
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
79  * SUCH DAMAGE.
80  */
81
82
83 // CONFIGURATION
84
85 #include <pkgconf/libc_stdlib.h>   // Configuration header
86
87 // INCLUDES
88
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 ULONG_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
96                                     // (like this one)
97
98
99 // FUNCTIONS
100
101 //
102 // Convert a string to an unsigned long long integer.
103 //
104 // Ignores `locale' stuff.  Assumes that the upper and lower case
105 // alphabets and digits are each contiguous.
106 //
107
108 unsigned long long
109 strtoull( const char *nptr, char **endptr, int base )
110 {
111     const char *s = nptr;
112     unsigned long long acc;
113     int c;
114     unsigned long long cutoff;
115     int neg = 0, any, cutlim;
116     
117     CYG_REPORT_FUNCNAMETYPE( "strtoull", "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!" );
121
122     if (endptr != NULL)
123         CYG_CHECK_DATA_PTR( endptr, "endptr is not a valid pointer!" );
124     //
125     // See strtoll for comments as to the logic used.
126     //
127     do {
128         c = *s++;
129     } while (isspace(c));
130     if (c == '-') {
131         neg = 1;
132         c = *s++;
133     } else if (c == '+')
134         c = *s++;
135     if ((base == 0 || base == 16) &&
136         c == '0' && (*s == 'x' || *s == 'X')) {
137         c = s[1];
138         s += 2;
139         base = 16;
140     }
141     if (base == 0)
142         base = c == '0' ? 8 : 10;
143     cutoff = (unsigned long long)ULONG_LONG_MAX / (unsigned long long)base;
144     cutlim = (unsigned long long)ULONG_LONG_MAX % (unsigned long long)base;
145     for (acc = 0, any = 0;; c = *s++) {
146         if (isdigit(c))
147             c -= '0';
148         else if (isalpha(c))
149             c -= isupper(c) ? 'A' - 10 : 'a' - 10;
150         else
151             break;
152         if (c >= base)
153             break;
154         if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
155             any = -1;
156         else {
157             any = 1;
158             acc *= base;
159             acc += c;
160         }
161     }
162     if (any < 0) {
163         acc = ULONG_LONG_MAX;
164         errno = ERANGE;
165     } else if (neg)
166         acc = -acc;
167     if (endptr != 0)
168         *endptr = (char *) (any ? s - 1 : nptr);
169     
170     CYG_REPORT_RETVAL( acc );
171
172     return acc;
173 } // strtoull()
174
175 // EOF strtoull.cxx