cryptutils

Cryptographic Software Utilities
git clone http://git.omkov.net/cryptutils
Log | Tree | Refs | README | LICENCE | Download

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

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