Differences From
Artifact [1d0d9f385e]:
- File
clib/iaia.c
— part of check-in
[6a14de1811]
at
2019-07-20 23:37:03
on branch trunk
— udpate xpriv to use sysv shmem by default; give iaia an option to generate its own types, and allow selecting between 7-bit and 8-bit encodings for ascii (defaulting to 8-bit); update mkpw to work with new iaia; update ord to add flag controlling byte length (7 or 8) for iaia's ascii mode
(user:
lexi,
size: 4370)
[annotate]
[blame]
[check-ins using]
27 27 /* this is an expression that will be evaluated to
28 28 * determine whether to compress ascii to a 7-bit
29 29 * representation or to store it in 8-bit space.
30 30 * 1 = 7-bit (compressed)
31 31 * 0 = 8-bit (uncompressed) */
32 32 # define _IAIA_EXP_ASCFORM (0)
33 33 #endif
34 +#ifndef NULL
35 +# define NULL ((void*)0)
36 +#endif
34 37
35 38 enum /* constants */ {
36 39 base7bit = 128,
37 40
38 41 /* ascii address space */
39 42 numspace = (0x39 - 0x30) + 1, /* 10 */
40 43 alphaspace = (0x5a - 0x41) + 1, /* 26 */
................................................................................
52 55 iaia_e_overflow,
53 56 } iaia_error_type;
54 57 typedef unsigned long long iaia_word_type;
55 58 #endif
56 59
57 60 /* -- string to integer converters -- */
58 61
59 -iaia_error_type _IAIA_FN_ASCTOI(const char* s, iaia_word_type* ret) {
62 +iaia_error_type
63 +_IAIA_FN_ASCTOI(const char* s, iaia_word_type* ret) {
60 64 iaia_word_type val = 0;
61 65
62 - for (;*s!=null;++s) {
66 + for (;*s!=0;++s) {
63 67 uint8_t v = *s;
64 68 if (v > base7bit) return iaia_e_domain;
65 69
66 70 if (_IAIA_EXP_ASCFORM)
67 71 val *= base7bit;
68 72 else val <<= 8;
69 73
70 74 val += v;
71 75 }
72 76
73 77 *ret = val;
74 - return ok;
78 + return iaia_e_ok;
75 79 }
76 80
77 -iaia_error_type _IAIA_FN_ATOI(iaia_word_type base, const char* s, iaia_word_type* ret) {
78 - /* s must be a null-terminated ASCII numeral string */
81 +iaia_error_type
82 +_IAIA_FN_ATOI(iaia_word_type base, const char* s, iaia_word_type* ret) {
83 + /* s must be a NUL-terminated ASCII numeral string */
79 84 if (base > maxbase) return iaia_e_base;
80 85
81 86 /* override the default base if it's a basèd literal */
82 87 if (s[0] == '@' || base == 0) return _IAIA_FN_ASCTOI(s + (s[0]=='@'),ret);
83 88 else if (s[0] == '0' && s[1] == 'x') base = 16, s += 2;
84 89 else if (s[0] == '0' && s[1] == 'd') base = 10, s += 2;
85 90 else if (s[0] == '0' && s[1] == 'b') base = 2, s += 2;
86 91 else if (s[0] == '0' && s[1] == 't') base = 3, s += 2;
87 92 else if (s[0] == '0') base = 8, s += 1;
88 93
89 94 bool insens = (base <= imaxbase);
90 95 iaia_word_type val = 0;
91 96
92 - for (;*s!=null;++s) {
97 + for (;*s!=0;++s) {
93 98 uint8_t v = *s;
94 99 if(v >= 0x30 && v <= 0x39) v -= 0x30; else {
95 100 if(v >= 0x61 && v <= 0x7a) {
96 101 if (insens) v -= 0x20; else {
97 102 v = numspace + alphaspace + (v - 0x61);
98 103 goto checkval;
99 104 }
................................................................................
112 117 }
113 118
114 119
115 120 /* -- integer to string converters -- */
116 121
117 122 /* needed for efficiency's sake, but really sucky -
118 123 * this table needs to be kept in sync with the
119 - * itoa algorithm by hand. unfortunately, given C's
124 + * itoa algorithm manually. unfortunately, given C's
120 125 * abject lack of metaprogramming, we have to do this
121 126 * by hand. */
122 127 const char iaia_ref_table[] = /* numerals[10] */ "0123456789"
123 128 /* bigalpha[26] */ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
124 129 /* smallalpha[26] */ "abcdefghijklmnopqrstuvwxyz";
125 130 _Static_assert (sizeof iaia_ref_table - 1 == maxbase, "tables out of sync");
126 131
127 -iaia_error_type _IAIA_FN_ITOASC(iaia_word_type val, const char* buf_start, char* buf_end, char** newbuf) {
132 +iaia_error_type
133 +_IAIA_FN_ITOASC(iaia_word_type val, const char* buf_start, char* buf_end, char** newbuf) {
128 134 char* ptr = buf_end;
129 135
130 136 *ptr-- = 0;
131 137 while(val > 0) {
132 138 if (ptr < buf_start) return iaia_e_overflow;
133 139 iaia_word_type rem = val % 128;
134 140 if (_IAIA_EXP_ASCFORM)
135 141 val /= base7bit;
136 142 else val >>= 8;
137 143 *ptr-- = (char)rem;
138 144 }
139 145
140 - if (newbuf != null) *newbuf = ptr + 1;
141 - return ok;
146 + if (newbuf != NULL) *newbuf = ptr + 1;
147 + return iaia_e_ok;
142 148 }
143 149
144 -iaia_error_type _IAIA_FN_ITOA(iaia_word_type base, iaia_word_type val, const char* buf_start,
150 +iaia_error_type
151 +_IAIA_FN_ITOA(iaia_word_type base, iaia_word_type val, const char* buf_start,
145 152 char* buf_end, char** newbuf, bool lowercase) {
146 153
147 154 char* ptr = buf_end;
148 155
149 156 if (base > maxbase) return iaia_e_base;
150 157 if (base == 0) return _IAIA_FN_ITOASC(val, buf_start, buf_end, newbuf);
151 158
................................................................................
158 165 char out = iaia_ref_table[rem];
159 166 if (lowercase && base <= imaxbase)
160 167 if (out >= 'A' && out <= 'Z')
161 168 out += ('a' - 'A');
162 169 *ptr-- = out;
163 170 }
164 171
165 - if (newbuf != null) *newbuf = ptr + 1;
172 + if (newbuf != NULL) *newbuf = ptr + 1;
166 173 return iaia_e_ok;
167 174 }
168 175