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);
52 void util_memory_d(void *ptrn, unsigned int line, const char *file) {
54 void *data = (void*)((uintptr_t)ptrn-sizeof(struct memblock_t));
55 struct memblock_t *info = (struct memblock_t*)data;
57 util_debug("MEM", "released: % 8u (bytes) address 0x%08X @ %s:%u\n", info->byte, data, file, line);
67 util_debug("MEM", "Memory information:\n\
68 Total allocations: %llu\n\
69 Total deallocations: %llu\n\
70 Total allocated: %llu (bytes)\n\
71 Total deallocated: %llu (bytes)\n\
72 Leaks found: lost %llu (bytes) in %d allocations\n",
81 * Some string utility functions, because strdup uses malloc, and we want
82 * to track all memory (without replacing malloc).
84 char *util_strdup(const char *s) {
91 if ((len = strlen(s)) && (ptr = mem_a(len+1))) {
99 * Remove quotes from a string, escapes from \ in string
100 * as well. This function shouldn't be used to create a
101 * char array that is later freed (it uses pointer arith)
103 char *util_strrq(char *s) {
107 while ((chr = *src++) != '\0') {
110 if ((chr = *src++) == '\0')
113 } else if (chr != '"')
121 * Remove newline from a string (if it exists). This is
122 * done pointer wise instead of strlen(), and an array
125 char *util_strrnl(char *src) {
126 if (!src) return NULL;
128 while (*cpy && *cpy != '\n')
136 * Removes any whitespace prefixed on a string by moving
137 * skipping past it, and stroing the skip distance, so
138 * the string can later be freed (if it was allocated)
140 char *util_strsws(char *skip, char **move) {
145 while (*skip == ' ' || *skip == '\t')
151 void util_debug(const char *area, const char *ms, ...) {
157 fprintf (stdout, "DEBUG: ");
159 fprintf(stdout, "%s", area);
160 fputs ("] ", stdout);
161 vfprintf(stdout, ms, va);
166 * Endianess swapping, all data must be stored little-endian. This
167 * reorders by stride and length, much nicer than other functions for
168 * certian-sized types like short or int.
170 void util_endianswap(void *m, int s, int l) {
174 /* ignore if we're already LE */
179 for(; i < s << 1; i++) {
180 unsigned char *p = (unsigned char *)m+w*s;
181 unsigned char t = p[i];
189 * This is an implementation of CRC32 & CRC16. The polynomials have been
190 * offline computed for faster generation at the cost of larger code size.
192 * CRC32 Polynomial: 0xEDB88320
193 * CRC16 Polynomial: 0x00001021
195 static const uint32_t util_crc32_table[] = {
196 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
197 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
198 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
199 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
200 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
201 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
202 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
203 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
204 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
205 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
206 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
207 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
208 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
209 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
210 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
211 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
212 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
213 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
214 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
215 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
216 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
217 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
218 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
219 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
220 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
221 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
222 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
223 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
224 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
225 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
226 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
227 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
228 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
229 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
230 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
231 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
232 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
233 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
234 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
235 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
236 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
237 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
238 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
240 static const uint16_t util_crc16_table[] = {
241 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5,
242 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B,
243 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210,
244 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
245 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C,
246 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401,
247 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B,
248 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
249 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6,
250 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738,
251 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5,
252 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
253 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969,
254 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96,
255 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC,
256 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
257 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03,
258 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD,
259 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6,
260 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
261 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A,
262 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB,
263 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1,
264 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
265 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C,
266 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2,
267 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB,
268 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
269 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447,
270 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8,
271 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2,
272 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
273 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9,
274 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827,
275 0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C,
276 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
277 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0,
278 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D,
279 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
280 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
281 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA,
282 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74,
283 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
287 * Implements a CRC function for X worth bits using (uint[X]_t)
288 * as type. and util_crc[X]_table.
291 uint##X##_t util_crc##X(const char *k, int len, const short clamp) { \
292 register uint##X##_t h= (uint##X##_t)0xFFFFFFFF; \
293 for (; len; --len, ++k) \
294 h = util_crc##X##_table[(h^((unsigned char)*k))&0xFF]^(h>>8); \
302 * Implements libc getline for systems that don't have it, which is
303 * assmed all. This works the same as getline().
305 int util_getline(char **lineptr, size_t *n, FILE *stream) {
310 if (!lineptr || !n || !stream)
313 if (!(*lineptr = mem_a((*n=64))))
321 int c = getc(stream);
324 char *tmp = mem_a((*n+=(*n>16)?*n:64));
328 chr = *n + *lineptr - pos;
329 strcpy(tmp,*lineptr);
330 if (!(*lineptr = tmp)) {
334 pos = *n - chr + *lineptr;
352 return (ret = pos - *lineptr);