5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 * this software and associated documentation files (the "Software"), to deal in
7 * the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is furnished to do
10 * so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 unsigned long long mem_ab = 0;
28 unsigned long long mem_db = 0;
29 unsigned long long mem_at = 0;
30 unsigned long long mem_dt = 0;
38 void *util_memory_a(unsigned int byte, unsigned int line, const char *file) {
39 struct memblock_t *info = malloc(sizeof(struct memblock_t) + byte);
40 void *data =(void*)((uintptr_t)info+sizeof(struct memblock_t));
41 if (!data) return NULL;
46 util_debug("MEM", "allocation: % 8u (bytes) address 0x%08X @ %s:%u\n", byte, data, file, line);
53 void util_memory_d(void *ptrn, unsigned int line, const char *file) {
55 void *data = (void*)((uintptr_t)ptrn-sizeof(struct memblock_t));
56 struct memblock_t *info = (struct memblock_t*)data;
58 util_debug("MEM", "released: % 8u (bytes) address 0x%08X @ %s:%u\n", info->byte, data, file, line);
69 util_debug("MEM", "Memory information:\n\
70 Total allocations: %llu\n\
71 Total deallocations: %llu\n\
72 Total allocated: %llu (bytes)\n\
73 Total deallocated: %llu (bytes)\n\
74 Leaks found: lost %llu (bytes) in %d allocations\n",
83 * Some string utility functions, because strdup uses malloc, and we want
84 * to track all memory (without replacing malloc).
86 char *util_strdup(const char *s) {
93 if ((len = strlen(s)) && (ptr = mem_a(len+1))) {
101 * Remove quotes from a string, escapes from \ in string
102 * as well. This function shouldn't be used to create a
103 * char array that is later freed (it uses pointer arith)
105 char *util_strrq(const char *s) {
106 char *dst = (char*)s;
107 char *src = (char*)s;
109 while ((chr = *src++) != '\0') {
112 if ((chr = *src++) == '\0')
115 } else if (chr != '"')
123 * Chops a substring from an existing string by creating a
124 * copy of it and null terminating it at the required position.
126 char *util_strchp(const char *s, const char *e) {
134 return util_strdup(s);
138 * Remove newline from a string (if it exists). This is
139 * done pointer wise instead of strlen(), and an array
142 char *util_strrnl(const char *src) {
143 if (!src) return NULL;
144 char *cpy = (char*)src;
145 while (*cpy && *cpy != '\n')
153 * Removes any whitespace prefixed on a string by moving
154 * skipping past it, and stroing the skip distance, so
155 * the string can later be freed (if it was allocated)
157 char *util_strsws(const char *skip) {
162 while (*skip == ' ' || *skip == '\t')
164 return util_strdup(skip-size);
168 * Returns true if string is all uppercase, otherwise
171 bool util_strupper(const char *str) {
181 * Returns true if string is all digits, otherwise
184 bool util_strdigit(const char *str) {
193 void util_debug(const char *area, const char *ms, ...) {
199 fprintf (stdout, "DEBUG: ");
201 fprintf(stdout, "%s", area);
202 fputs ("] ", stdout);
203 vfprintf(stdout, ms, va);
208 * Endianess swapping, all data must be stored little-endian. This
209 * reorders by stride and length, much nicer than other functions for
210 * certian-sized types like short or int.
212 void util_endianswap(void *m, int s, int l) {
216 /* ignore if we're already LE */
221 for(; i < s << 1; i++) {
222 unsigned char *p = (unsigned char *)m+w*s;
223 unsigned char t = p[i];
231 * This is an implementation of CRC32 & CRC16. The polynomials have been
232 * offline computed for faster generation at the cost of larger code size.
234 * CRC32 Polynomial: 0xEDB88320
235 * CRC16 Polynomial: 0x00001021
237 static const uint32_t util_crc32_table[] = {
238 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
239 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
240 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
241 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
242 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
243 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
244 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
245 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
246 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
247 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
248 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
249 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
250 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
251 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
252 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
253 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
254 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
255 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
256 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
257 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
258 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
259 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
260 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
261 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
262 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
263 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
264 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
265 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
266 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
267 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
268 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
269 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
270 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
271 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
272 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
273 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
274 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
275 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
276 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
277 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
278 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
279 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
280 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
282 static const uint16_t util_crc16_table[] = {
283 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5,
284 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B,
285 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210,
286 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
287 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C,
288 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401,
289 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B,
290 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
291 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6,
292 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738,
293 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5,
294 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
295 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969,
296 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96,
297 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC,
298 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
299 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03,
300 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD,
301 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6,
302 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
303 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A,
304 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB,
305 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1,
306 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
307 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C,
308 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2,
309 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB,
310 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
311 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447,
312 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8,
313 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2,
314 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
315 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9,
316 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827,
317 0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C,
318 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
319 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0,
320 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D,
321 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
322 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
323 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA,
324 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74,
325 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
329 * Implements a CRC function for X worth bits using (uint[X]_t)
330 * as type. and util_crc[X]_table.
333 uint##X##_t util_crc##X(const char *k, int len, const short clamp) { \
334 register uint##X##_t h= (uint##X##_t)0xFFFFFFFF; \
335 for (; len; --len, ++k) \
336 h = util_crc##X##_table[(h^((unsigned char)*k))&0xFF]^(h>>8); \
344 * Implements libc getline for systems that don't have it, which is
345 * assmed all. This works the same as getline().
347 int util_getline(char **lineptr, size_t *n, FILE *stream) {
352 if (!lineptr || !n || !stream)
355 if (!(*lineptr = mem_a((*n=64))))
363 int c = getc(stream);
366 char *tmp = mem_a((*n+=(*n>16)?*n:64));
370 chr = *n + *lineptr - pos;
371 strcpy(tmp,*lineptr);
372 if (!(*lineptr = tmp)) {
376 pos = *n - chr + *lineptr;
394 return (ret = pos - *lineptr);