util  Diff

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]

To Artifact [70661568bf]:


27
28
29
30
31
32
33



34
35
36
37
38
39
40
..
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76

77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143

144
145
146
147
148
149
150
151
...
158
159
160
161
162
163
164
165
166
167
168
/* this is an expression that will be evaluated to
 * determine whether to compress ascii to a 7-bit
 * representation or to store it in 8-bit space.
 *  1 = 7-bit (compressed)
 *  0 = 8-bit (uncompressed) */
#	define _IAIA_EXP_ASCFORM (0)
#endif




enum /* constants */ {
	base7bit = 128,

	/* ascii address space */
	numspace        = (0x39 - 0x30) + 1, /* 10 */
	alphaspace      = (0x5a - 0x41) + 1, /* 26 */
................................................................................
		iaia_e_overflow,
	} iaia_error_type;
	typedef unsigned long long iaia_word_type;
#endif

/* -- string to integer converters -- */


iaia_error_type _IAIA_FN_ASCTOI(const char* s, iaia_word_type* ret) {
	iaia_word_type val = 0;

	for (;*s!=null;++s) {
		uint8_t v = *s;
		if (v > base7bit) return iaia_e_domain;

		if (_IAIA_EXP_ASCFORM)
			val *= base7bit;
			else val <<= 8;

		val += v;
	}

	*ret = val;
	return ok;
}


iaia_error_type _IAIA_FN_ATOI(iaia_word_type base, const char* s, iaia_word_type* ret) {
	/* s must be a null-terminated ASCII numeral string */
	if (base > maxbase) return iaia_e_base;

	/* override the default base if it's a basèd literal */
	if (s[0] == '@' || base == 0) return _IAIA_FN_ASCTOI(s + (s[0]=='@'),ret);
	else if (s[0] == '0' && s[1] == 'x') base = 16, s += 2;
	else if (s[0] == '0' && s[1] == 'd') base = 10, s += 2;
	else if (s[0] == '0' && s[1] == 'b') base =  2, s += 2;
	else if (s[0] == '0' && s[1] == 't') base =  3, s += 2;
	else if (s[0] == '0')                base =  8, s += 1;

	bool insens = (base <= imaxbase);
	iaia_word_type val = 0;

	for (;*s!=null;++s) {
		uint8_t v = *s;
		if(v >= 0x30 && v <= 0x39) v -= 0x30; else {
			if(v >= 0x61 && v <= 0x7a) {
				if (insens) v -= 0x20; else {
					v = numspace + alphaspace + (v - 0x61);
					goto checkval;
				}
................................................................................
}


/* -- integer to string converters -- */

/* needed for efficiency's sake, but really sucky -
 * this table needs to be kept in sync with the
 * itoa algorithm by hand. unfortunately, given C's
 * abject lack of metaprogramming, we have to do this
 * by hand. */
const char iaia_ref_table[] = /* numerals[10] */ "0123456789"
	/* bigalpha[26] */ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	/* smallalpha[26] */ "abcdefghijklmnopqrstuvwxyz";
_Static_assert (sizeof iaia_ref_table - 1 == maxbase, "tables out of sync");


iaia_error_type _IAIA_FN_ITOASC(iaia_word_type val, const char* buf_start, char* buf_end, char** newbuf) {
	char* ptr = buf_end;

	*ptr-- = 0;
	while(val > 0) {
		if (ptr < buf_start) return iaia_e_overflow;
		iaia_word_type rem = val % 128;
		if (_IAIA_EXP_ASCFORM)
			val /= base7bit;
			else val >>= 8;
		*ptr-- = (char)rem;
	}

	if (newbuf != null) *newbuf = ptr + 1;
	return ok;
}


iaia_error_type _IAIA_FN_ITOA(iaia_word_type base, iaia_word_type val, const char* buf_start,
		char* buf_end, char** newbuf, bool lowercase) {

	char* ptr = buf_end;

	if (base > maxbase) return iaia_e_base;
	if (base == 0) return _IAIA_FN_ITOASC(val, buf_start, buf_end, newbuf);

................................................................................
		char out = iaia_ref_table[rem];
		if (lowercase && base <= imaxbase)
			if (out >= 'A' && out <= 'Z')
				out += ('a' - 'A');
		*ptr-- = out;
	}

	if (newbuf != null) *newbuf = ptr + 1;
	return iaia_e_ok;
}








>
>
>







 







>
|


|











|


>
|
|













|







 







|







>
|












|
|


>
|







 







|



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
..
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
...
165
166
167
168
169
170
171
172
173
174
175
/* this is an expression that will be evaluated to
 * determine whether to compress ascii to a 7-bit
 * representation or to store it in 8-bit space.
 *  1 = 7-bit (compressed)
 *  0 = 8-bit (uncompressed) */
#	define _IAIA_EXP_ASCFORM (0)
#endif
#ifndef NULL
#	define NULL ((void*)0)
#endif

enum /* constants */ {
	base7bit = 128,

	/* ascii address space */
	numspace        = (0x39 - 0x30) + 1, /* 10 */
	alphaspace      = (0x5a - 0x41) + 1, /* 26 */
................................................................................
		iaia_e_overflow,
	} iaia_error_type;
	typedef unsigned long long iaia_word_type;
#endif

/* -- string to integer converters -- */

iaia_error_type
_IAIA_FN_ASCTOI(const char* s, iaia_word_type* ret) {
	iaia_word_type val = 0;

	for (;*s!=0;++s) {
		uint8_t v = *s;
		if (v > base7bit) return iaia_e_domain;

		if (_IAIA_EXP_ASCFORM)
			val *= base7bit;
			else val <<= 8;

		val += v;
	}

	*ret = val;
	return iaia_e_ok;
}

iaia_error_type
_IAIA_FN_ATOI(iaia_word_type base, const char* s, iaia_word_type* ret) {
	/* s must be a NUL-terminated ASCII numeral string */
	if (base > maxbase) return iaia_e_base;

	/* override the default base if it's a basèd literal */
	if (s[0] == '@' || base == 0) return _IAIA_FN_ASCTOI(s + (s[0]=='@'),ret);
	else if (s[0] == '0' && s[1] == 'x') base = 16, s += 2;
	else if (s[0] == '0' && s[1] == 'd') base = 10, s += 2;
	else if (s[0] == '0' && s[1] == 'b') base =  2, s += 2;
	else if (s[0] == '0' && s[1] == 't') base =  3, s += 2;
	else if (s[0] == '0')                base =  8, s += 1;

	bool insens = (base <= imaxbase);
	iaia_word_type val = 0;

	for (;*s!=0;++s) {
		uint8_t v = *s;
		if(v >= 0x30 && v <= 0x39) v -= 0x30; else {
			if(v >= 0x61 && v <= 0x7a) {
				if (insens) v -= 0x20; else {
					v = numspace + alphaspace + (v - 0x61);
					goto checkval;
				}
................................................................................
}


/* -- integer to string converters -- */

/* needed for efficiency's sake, but really sucky -
 * this table needs to be kept in sync with the
 * itoa algorithm manually. unfortunately, given C's
 * abject lack of metaprogramming, we have to do this
 * by hand. */
const char iaia_ref_table[] = /* numerals[10] */ "0123456789"
	/* bigalpha[26] */ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	/* smallalpha[26] */ "abcdefghijklmnopqrstuvwxyz";
_Static_assert (sizeof iaia_ref_table - 1 == maxbase, "tables out of sync");

iaia_error_type
_IAIA_FN_ITOASC(iaia_word_type val, const char* buf_start, char* buf_end, char** newbuf) {
	char* ptr = buf_end;

	*ptr-- = 0;
	while(val > 0) {
		if (ptr < buf_start) return iaia_e_overflow;
		iaia_word_type rem = val % 128;
		if (_IAIA_EXP_ASCFORM)
			val /= base7bit;
			else val >>= 8;
		*ptr-- = (char)rem;
	}

	if (newbuf != NULL) *newbuf = ptr + 1;
	return iaia_e_ok;
}

iaia_error_type
_IAIA_FN_ITOA(iaia_word_type base, iaia_word_type val, const char* buf_start,
		char* buf_end, char** newbuf, bool lowercase) {

	char* ptr = buf_end;

	if (base > maxbase) return iaia_e_base;
	if (base == 0) return _IAIA_FN_ITOASC(val, buf_start, buf_end, newbuf);

................................................................................
		char out = iaia_ref_table[rem];
		if (lowercase && base <= imaxbase)
			if (out >= 'A' && out <= 'Z')
				out += ('a' - 'A');
		*ptr-- = out;
	}

	if (newbuf != NULL) *newbuf = ptr + 1;
	return iaia_e_ok;
}