Embedded Artistry libc
C Standard Library Support for Bare-metal Systems
strtoull.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 1992, 1993
3  * The Regents of the University of California. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  * must display the following acknowledgement:
15  * This product includes software developed by the University of
16  * California, Berkeley and its contributors.
17  * 4. Neither the name of the University nor the names of its contributors
18  * may be used to endorse or promote products derived from this software
19  * without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include <ctype.h>
35 #include <limits.h>
36 #include <stdlib.h>
37 
38 /*
39  * Convert a string to an unsigned long long integer.
40  *
41  * Assumes that the upper and lower case
42  * alphabets and digits are each contiguous.
43  */
44 unsigned long long strtoull(const char* __restrict nptr, char** __restrict endptr, int base)
45 {
46  const char* s;
47  unsigned long long acc;
48  char c;
49  unsigned long long cutoff;
50  int neg, any, cutlim;
51 
52  /*
53  * See strtoq for comments as to the logic used.
54  */
55  s = nptr;
56  do
57  {
58  c = *s++;
59  } while(isspace((unsigned char)c));
60  if(c == '-')
61  {
62  neg = 1;
63  c = *s++;
64  }
65  else
66  {
67  neg = 0;
68  if(c == '+')
69  {
70  {
71  c = *s++;
72  }
73  }
74  }
75  if((base == 0 || base == 16) && c == '0' && (*s == 'x' || *s == 'X'))
76  {
77  c = s[1];
78  s += 2;
79  base = 16;
80  }
81  if(base == 0)
82  {
83  {
84  base = c == '0' ? 8 : 10;
85  }
86  }
87  acc = any = 0;
88  if(base < 2 || base > 36)
89  {
90  {
91  goto noconv;
92  }
93  }
94 
95  cutoff = ULLONG_MAX / (unsigned long long)base;
96  cutlim = (int)(ULLONG_MAX % (unsigned long long)base);
97  for(;; c = *s++)
98  {
99  if(c >= '0' && c <= '9')
100  {
101  {
102  c -= '0';
103  }
104  }
105  else if(c >= 'A' && c <= 'Z')
106  {
107  {
108  c -= 'A' - 10;
109  }
110  }
111  else if(c >= 'a' && c <= 'z')
112  {
113  {
114  c -= 'a' - 10;
115  }
116  }
117  else
118  {
119  {
120  break;
121  }
122  }
123  if(c >= base)
124  {
125  {
126  break;
127  }
128  }
129  if(any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
130  {
131  {
132  any = -1;
133  }
134  }
135  else
136  {
137  any = 1;
138  acc *= (unsigned long)base;
139  acc += (unsigned long)c;
140  }
141  }
142  if(any < 0)
143  {
144  acc = ULLONG_MAX;
145  // errno = ERANGE;
146  }
147  else if(!any)
148  {
149  noconv:
150  // PJ: nonstandard, but since no errno, acc = 0
151  acc = 0;
152  // errno = EINVAL;
153  }
154  else if(neg)
155  {
156  acc = -acc;
157  }
158  if(endptr != NULL)
159  {
160  *endptr = (char*)(uintptr_t)(any ? s - 1 : nptr);
161  }
162  return (acc);
163 }
unsigned long long strtoull(const char *__restrict nptr, char **__restrict endptr, int base)
Interprets an unsigned long long value in a byte string pointed to by str.
Definition: strtoull.c:44
#define NULL
Definition: stddef.h:15
int isspace(int ch)
Checks if the given character is a whitespace character.
Definition: isspace.c:5
#define ULLONG_MAX
Definition: limits.h:67