libutil

C Utility Library
git clone http://git.omkov.net/libutil
Log | Tree | Refs | README | LICENCE | Download

libutil/src/strtou.c (138 lines, 3.7 KiB) -rw-r--r-- file download

483949f Jamozed 2022-03-06 01:25:30
0
// util/strtou.c
98e5939 Jamozed 2021-11-27 17:53:46
1
// String conversion source file from libutil
99202e8 Jamozed 2021-02-21 23:23:02
2
// Copyright (C) 2021, Jakob Wakeling
7f427d9 Jamozed 2022-03-06 12:55:13
3
// MIT Licence
99202e8 Jamozed 2021-02-21 23:23:02
4
1aa1d3f Jamozed 2022-02-04 19:57:13
5
#include "util.h"
1aa1d3f Jamozed 2022-02-04 19:57:13
6
99202e8 Jamozed 2021-02-21 23:23:02
7
#include <ctype.h>
99202e8 Jamozed 2021-02-21 23:23:02
8
#include <errno.h>
99202e8 Jamozed 2021-02-21 23:23:02
9
99202e8 Jamozed 2021-02-21 23:23:02
10
/* Convert a string to an unsigned 8-bit integer */
1aa1d3f Jamozed 2022-02-04 19:57:13
11
u8 strtou8(const char *nptr, char **endptr, register int base) {
1aa1d3f Jamozed 2022-02-04 19:57:13
12
	register const char *s = nptr; register u8 i = 0, c;
99202e8 Jamozed 2021-02-21 23:23:02
13
	
99202e8 Jamozed 2021-02-21 23:23:02
14
	for (; isspace(*s); ++s);
99202e8 Jamozed 2021-02-21 23:23:02
15
	
99202e8 Jamozed 2021-02-21 23:23:02
16
	if (*s == '+') { ++s; } else if (*s == '-') { errno = EINVAL; goto end; }
99202e8 Jamozed 2021-02-21 23:23:02
17
	
99202e8 Jamozed 2021-02-21 23:23:02
18
	if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
99202e8 Jamozed 2021-02-21 23:23:02
19
		s += 2; base = 16;
99202e8 Jamozed 2021-02-21 23:23:02
20
	}
99202e8 Jamozed 2021-02-21 23:23:02
21
	else if (base == 0) { base = s[0] == '0' ? 8 : 10; }
99202e8 Jamozed 2021-02-21 23:23:02
22
	else if (base < 2 || base > 36) { errno = EINVAL; goto end; }
99202e8 Jamozed 2021-02-21 23:23:02
23
	
99202e8 Jamozed 2021-02-21 23:23:02
24
	for (;; ++s) {
99202e8 Jamozed 2021-02-21 23:23:02
25
		if (*s >= '0' && *s <= '9') { c = *s - '0'; }
99202e8 Jamozed 2021-02-21 23:23:02
26
		else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); }
99202e8 Jamozed 2021-02-21 23:23:02
27
		else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); }
99202e8 Jamozed 2021-02-21 23:23:02
28
		else { break; }
99202e8 Jamozed 2021-02-21 23:23:02
29
		
99202e8 Jamozed 2021-02-21 23:23:02
30
		if (c >= base) { break; }
1aa1d3f Jamozed 2022-02-04 19:57:13
31
		if (i > (U8_MAX - c) / base) {
1aa1d3f Jamozed 2022-02-04 19:57:13
32
			errno = ERANGE; i = U8_MAX; goto end;
99202e8 Jamozed 2021-02-21 23:23:02
33
		}
99202e8 Jamozed 2021-02-21 23:23:02
34
		
99202e8 Jamozed 2021-02-21 23:23:02
35
		i = i * base + c;
99202e8 Jamozed 2021-02-21 23:23:02
36
	}
99202e8 Jamozed 2021-02-21 23:23:02
37
	
99202e8 Jamozed 2021-02-21 23:23:02
38
end:;
99202e8 Jamozed 2021-02-21 23:23:02
39
	if (endptr) { *endptr = (char *)s; } return i;
99202e8 Jamozed 2021-02-21 23:23:02
40
}
99202e8 Jamozed 2021-02-21 23:23:02
41
99202e8 Jamozed 2021-02-21 23:23:02
42
/* Convert a string to an unsigned 16-bit integer */
1aa1d3f Jamozed 2022-02-04 19:57:13
43
u16 strtou16(const char *nptr, char **endptr, register int base) {
1aa1d3f Jamozed 2022-02-04 19:57:13
44
	register const char *s = nptr; register u16 i = 0, c;
99202e8 Jamozed 2021-02-21 23:23:02
45
	
99202e8 Jamozed 2021-02-21 23:23:02
46
	for (; isspace(*s); ++s);
99202e8 Jamozed 2021-02-21 23:23:02
47
	
99202e8 Jamozed 2021-02-21 23:23:02
48
	if (*s == '+') { ++s; } else if (*s == '-') { errno = EINVAL; goto end; }
99202e8 Jamozed 2021-02-21 23:23:02
49
	
99202e8 Jamozed 2021-02-21 23:23:02
50
	if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
99202e8 Jamozed 2021-02-21 23:23:02
51
		s += 2; base = 16;
99202e8 Jamozed 2021-02-21 23:23:02
52
	}
99202e8 Jamozed 2021-02-21 23:23:02
53
	else if (base == 0) { base = s[0] == '0' ? 8 : 10; }
99202e8 Jamozed 2021-02-21 23:23:02
54
	else if (base < 2 || base > 36) { errno = EINVAL; goto end; }
99202e8 Jamozed 2021-02-21 23:23:02
55
	
99202e8 Jamozed 2021-02-21 23:23:02
56
	for (;; ++s) {
99202e8 Jamozed 2021-02-21 23:23:02
57
		if (*s >= '0' && *s <= '9') { c = *s - '0'; }
99202e8 Jamozed 2021-02-21 23:23:02
58
		else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); }
99202e8 Jamozed 2021-02-21 23:23:02
59
		else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); }
99202e8 Jamozed 2021-02-21 23:23:02
60
		else { break; }
99202e8 Jamozed 2021-02-21 23:23:02
61
		
99202e8 Jamozed 2021-02-21 23:23:02
62
		if (c >= base) { break; }
1aa1d3f Jamozed 2022-02-04 19:57:13
63
		if (i > (U16_MAX - c) / base) {
1aa1d3f Jamozed 2022-02-04 19:57:13
64
			errno = ERANGE; i = U16_MAX; goto end;
99202e8 Jamozed 2021-02-21 23:23:02
65
		}
99202e8 Jamozed 2021-02-21 23:23:02
66
		
99202e8 Jamozed 2021-02-21 23:23:02
67
		i = i * base + c;
99202e8 Jamozed 2021-02-21 23:23:02
68
	}
99202e8 Jamozed 2021-02-21 23:23:02
69
	
99202e8 Jamozed 2021-02-21 23:23:02
70
end:;
99202e8 Jamozed 2021-02-21 23:23:02
71
	if (endptr) { *endptr = (char *)s; } return i;
99202e8 Jamozed 2021-02-21 23:23:02
72
}
99202e8 Jamozed 2021-02-21 23:23:02
73
99202e8 Jamozed 2021-02-21 23:23:02
74
/* Convert a string to an unsigned 32-bit integer */
1aa1d3f Jamozed 2022-02-04 19:57:13
75
u32 strtou32(const char *nptr, char **endptr, register int base) {
1aa1d3f Jamozed 2022-02-04 19:57:13
76
	register const char *s = nptr; register u32 i = 0, c;
99202e8 Jamozed 2021-02-21 23:23:02
77
	
99202e8 Jamozed 2021-02-21 23:23:02
78
	for (; isspace(*s); ++s);
99202e8 Jamozed 2021-02-21 23:23:02
79
	
99202e8 Jamozed 2021-02-21 23:23:02
80
	if (*s == '+') { ++s; } else if (*s == '-') { errno = EINVAL; goto end; }
99202e8 Jamozed 2021-02-21 23:23:02
81
	
99202e8 Jamozed 2021-02-21 23:23:02
82
	if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
99202e8 Jamozed 2021-02-21 23:23:02
83
		s += 2; base = 16;
99202e8 Jamozed 2021-02-21 23:23:02
84
	}
99202e8 Jamozed 2021-02-21 23:23:02
85
	else if (base == 0) { base = s[0] == '0' ? 8 : 10; }
99202e8 Jamozed 2021-02-21 23:23:02
86
	else if (base < 2 || base > 36) { errno = EINVAL; goto end; }
99202e8 Jamozed 2021-02-21 23:23:02
87
	
99202e8 Jamozed 2021-02-21 23:23:02
88
	for (;; ++s) {
99202e8 Jamozed 2021-02-21 23:23:02
89
		if (*s >= '0' && *s <= '9') { c = *s - '0'; }
99202e8 Jamozed 2021-02-21 23:23:02
90
		else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); }
99202e8 Jamozed 2021-02-21 23:23:02
91
		else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); }
99202e8 Jamozed 2021-02-21 23:23:02
92
		else { break; }
99202e8 Jamozed 2021-02-21 23:23:02
93
		
99202e8 Jamozed 2021-02-21 23:23:02
94
		if (c >= base) { break; }
1aa1d3f Jamozed 2022-02-04 19:57:13
95
		if (i > (U32_MAX - c) / base) {
1aa1d3f Jamozed 2022-02-04 19:57:13
96
			errno = ERANGE; i = U32_MAX; goto end;
99202e8 Jamozed 2021-02-21 23:23:02
97
		}
99202e8 Jamozed 2021-02-21 23:23:02
98
		
99202e8 Jamozed 2021-02-21 23:23:02
99
		i = i * base + c;
99202e8 Jamozed 2021-02-21 23:23:02
100
	}
99202e8 Jamozed 2021-02-21 23:23:02
101
	
99202e8 Jamozed 2021-02-21 23:23:02
102
end:;
99202e8 Jamozed 2021-02-21 23:23:02
103
	if (endptr) { *endptr = (char *)s; } return i;
99202e8 Jamozed 2021-02-21 23:23:02
104
}
99202e8 Jamozed 2021-02-21 23:23:02
105
99202e8 Jamozed 2021-02-21 23:23:02
106
/* Convert a string to an unsigned 64-bit integer */
1aa1d3f Jamozed 2022-02-04 19:57:13
107
u64 strtou64(const char *nptr, char **endptr, register int base) {
1aa1d3f Jamozed 2022-02-04 19:57:13
108
	register const char *s = nptr; register u64 i = 0, c;
99202e8 Jamozed 2021-02-21 23:23:02
109
	
99202e8 Jamozed 2021-02-21 23:23:02
110
	for (; isspace(*s); ++s);
99202e8 Jamozed 2021-02-21 23:23:02
111
	
99202e8 Jamozed 2021-02-21 23:23:02
112
	if (*s == '+') { ++s; } else if (*s == '-') { errno = EINVAL; goto end; }
99202e8 Jamozed 2021-02-21 23:23:02
113
	
99202e8 Jamozed 2021-02-21 23:23:02
114
	if ((!base || base == 16) && s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
99202e8 Jamozed 2021-02-21 23:23:02
115
		s += 2; base = 16;
99202e8 Jamozed 2021-02-21 23:23:02
116
	}
99202e8 Jamozed 2021-02-21 23:23:02
117
	else if (base == 0) { base = s[0] == '0' ? 8 : 10; }
99202e8 Jamozed 2021-02-21 23:23:02
118
	else if (base < 2 || base > 36) { errno = EINVAL; goto end; }
99202e8 Jamozed 2021-02-21 23:23:02
119
	
99202e8 Jamozed 2021-02-21 23:23:02
120
	for (;; ++s) {
99202e8 Jamozed 2021-02-21 23:23:02
121
		if (*s >= '0' && *s <= '9') { c = *s - '0'; }
99202e8 Jamozed 2021-02-21 23:23:02
122
		else if (*s >= 'A' && *s <= 'Z') { c = *s - ('A' - 10); }
99202e8 Jamozed 2021-02-21 23:23:02
123
		else if (*s >= 'a' && *s <= 'z') { c = *s - ('a' - 10); }
99202e8 Jamozed 2021-02-21 23:23:02
124
		else { break; }
99202e8 Jamozed 2021-02-21 23:23:02
125
		
99202e8 Jamozed 2021-02-21 23:23:02
126
		if (c >= base) { break; }
1aa1d3f Jamozed 2022-02-04 19:57:13
127
		if (i > (U64_MAX - c) / base) {
1aa1d3f Jamozed 2022-02-04 19:57:13
128
			errno = ERANGE; i = U64_MAX; goto end;
99202e8 Jamozed 2021-02-21 23:23:02
129
		}
99202e8 Jamozed 2021-02-21 23:23:02
130
		
99202e8 Jamozed 2021-02-21 23:23:02
131
		i = i * base + c;
99202e8 Jamozed 2021-02-21 23:23:02
132
	}
99202e8 Jamozed 2021-02-21 23:23:02
133
	
99202e8 Jamozed 2021-02-21 23:23:02
134
end:;
99202e8 Jamozed 2021-02-21 23:23:02
135
	if (endptr) { *endptr = (char *)s; } return i;
99202e8 Jamozed 2021-02-21 23:23:02
136
}
137