ReactOS  0.4.14-dev-317-g96040ec
astoll.c
Go to the documentation of this file.
1 /* @(#)astoll.c 1.5 15/12/10 Copyright 1985, 2000-2015 J. Schilling */
2 /*
3  * astoll() converts a string to long long
4  *
5  * Leading tabs and spaces are ignored.
6  * Both return pointer to the first char that has not been used.
7  * Caller must check if this means a bad conversion.
8  *
9  * leading "+" is ignored
10  * leading "0" makes conversion octal (base 8)
11  * leading "0x" makes conversion hex (base 16)
12  *
13  * Llong is silently reverted to long if the compiler does not
14  * support long long.
15  *
16  * Copyright (c) 1985, 2000-2015 J. Schilling
17  */
18 /*
19  * The contents of this file are subject to the terms of the
20  * Common Development and Distribution License, Version 1.0 only
21  * (the "License"). You may not use this file except in compliance
22  * with the License.
23  *
24  * See the file CDDL.Schily.txt in this distribution for details.
25  * A copy of the CDDL is also available via the Internet at
26  * http://www.opensource.org/licenses/cddl1.txt
27  *
28  * When distributing Covered Code, include this CDDL HEADER in each
29  * file and include the License file CDDL.Schily.txt from this distribution.
30  */
31 
32 #include <schily/mconfig.h>
33 #include <schily/standard.h>
34 #include <schily/utypes.h>
35 #include <schily/schily.h>
36 #include <schily/errno.h>
37 
38 #define is_space(c) ((c) == ' ' || (c) == '\t')
39 #define is_digit(c) ((c) >= '0' && (c) <= '9')
40 #define is_hex(c) (\
41  ((c) >= 'a' && (c) <= 'f') || \
42  ((c) >= 'A' && (c) <= 'F'))
43 
44 #define is_lower(c) ((c) >= 'a' && (c) <= 'z')
45 #define is_upper(c) ((c) >= 'A' && (c) <= 'Z')
46 #define to_lower(c) (((c) >= 'A' && (c) <= 'Z') ? (c) - 'A'+'a' : (c))
47 
48 #if ('i' + 1) < 'j'
49 #define BASE_MAX ('i' - 'a' + 10 + 1) /* This is EBCDIC */
50 #else
51 #define BASE_MAX ('z' - 'a' + 10 + 1) /* This is ASCII */
52 #endif
53 
54 
55 char *
57  register const char *s;
58  Llong *l;
59 {
60  return (astollb(s, l, 0));
61 }
62 
63 char *
65  register const char *s;
66  Llong *l;
67  register int base;
68 {
69  int neg = 0;
70  register ULlong ret = (ULlong)0;
71  ULlong maxmult;
72  ULlong maxval;
73  register int digit;
74  register char c;
75 
76  if (base > BASE_MAX || base == 1 || base < 0) {
78  return ((char *)s);
79  }
80 
81  while (is_space(*s))
82  s++;
83 
84  if (*s == '+') {
85  s++;
86  } else if (*s == '-') {
87  s++;
88  neg++;
89  }
90 
91  if (base == 0) {
92  if (*s == '0') {
93  base = 8;
94  s++;
95  if (*s == 'x' || *s == 'X') {
96  s++;
97  base = 16;
98  }
99  } else {
100  base = 10;
101  }
102  }
103  if (neg) {
104  /*
105  * Portable way to compute the positive value of "min-Llong"
106  * as -TYPE_MINVAL(Llong) does not work.
107  */
108  maxval = ((ULlong)(-1 * (TYPE_MINVAL(Llong)+1))) + 1;
109  } else {
110  maxval = TYPE_MAXVAL(Llong);
111  }
112  maxmult = maxval / base;
113  for (; (c = *s) != 0; s++) {
114 
115  if (is_digit(c)) {
116  digit = c - '0';
117  } else if (is_lower(c)) {
118  digit = c - 'a' + 10;
119  } else if (is_upper(c)) {
120  digit = c - 'A' + 10;
121  } else {
122  break;
123  }
124 
125  if (digit < base) {
126  if (ret > maxmult)
127  goto overflow;
128  ret *= base;
129  if (maxval - ret < digit)
130  goto overflow;
131  ret += digit;
132  } else {
133  break;
134  }
135  }
136  if (neg) {
137  *l = (Llong)-1 * ret;
138  } else {
139  *l = (Llong)ret;
140  }
141  return ((char *)s);
142 overflow:
143  for (; (c = *s) != 0; s++) {
144 
145  if (is_digit(c)) {
146  digit = c - '0';
147  } else if (is_lower(c)) {
148  digit = c - 'a' + 10;
149  } else if (is_upper(c)) {
150  digit = c - 'A' + 10;
151  } else {
152  break;
153  }
154  if (digit >= base)
155  break;
156  }
157  if (neg) {
158  *l = TYPE_MINVAL(Llong);
159  } else {
160  *l = TYPE_MAXVAL(Llong);
161  }
162  seterrno(ERANGE);
163  return ((char *)s);
164 }
long Llong
Definition: stdint.h:152
Definition: arc.h:39
#define is_digit(c)
Definition: astoll.c:39
char * astoll(const char *s, Llong *l)
Definition: astoll.c:56
#define TYPE_MINVAL(t)
Definition: stdint.h:86
unsigned long ULlong
Definition: stdint.h:154
GLuint base
Definition: 3dtext.c:35
#define BASE_MAX
Definition: astoll.c:51
r l[0]
Definition: byte_order.h:167
EXPORT int seterrno(int err)
Definition: seterrno.c:34
const GLubyte * c
Definition: glext.h:8905
#define ERANGE
Definition: acclib.h:92
int ret
GLdouble s
Definition: gl.h:2039
#define is_upper(c)
Definition: astoll.c:45
char * astollb(const char *s, Llong *l, int base)
Definition: astoll.c:64
#define TYPE_MAXVAL(t)
Definition: stdint.h:89
#define is_space(c)
Definition: astoll.c:38
#define c
Definition: ke_i.h:80
#define is_lower(c)
Definition: astoll.c:44