libutil

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

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

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