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
36 struct memblock_t *next;
37 struct memblock_t *prev;
40 static struct memblock_t *mem_start = NULL;
42 void *util_memory_a(unsigned int byte, unsigned int line, const char *file) {
43 struct memblock_t *info = malloc(sizeof(struct memblock_t) + byte);
44 void *data = (void*)(info+1);
45 if (!info) return NULL;
50 info->next = mem_start;
52 mem_start->prev = info;
55 util_debug("MEM", "allocation: % 8u (bytes) address 0x%08X @ %s:%u\n", byte, data, file, line);
62 void util_memory_d(void *ptrn, unsigned int line, const char *file) {
63 struct memblock_t *info = NULL;
66 info = ((struct memblock_t*)ptrn - 1);
68 util_debug("MEM", "released: % 8u (bytes) address 0x%08X @ %s:%u\n", info->byte, ptrn, file, line);
73 info->prev->next = info->next;
75 info->next->prev = info->prev;
76 if (info == mem_start)
77 mem_start = info->next;
82 void *util_memory_r(void *ptrn, unsigned int byte, unsigned int line, const char *file) {
83 struct memblock_t *oldinfo = NULL;
85 struct memblock_t *newinfo;
88 return util_memory_a(byte, line, file);
90 util_memory_d(ptrn, line, file);
94 oldinfo = ((struct memblock_t*)ptrn - 1);
95 newinfo = malloc(sizeof(struct memblock_t) + byte);
97 util_debug("MEM", "reallocation: % 8u -> %u (bytes) address 0x%08X -> 0x%08X @ %s:%u\n", oldinfo->byte, byte, ptrn, (void*)(newinfo+1), file, line);
101 util_memory_d(oldinfo+1, line, file);
104 newinfo->line = line;
105 newinfo->byte = byte;
106 newinfo->file = file;
107 newinfo->next = oldinfo->next;
108 newinfo->prev = oldinfo->prev;
109 if (mem_start == oldinfo)
113 memcpy(newinfo+1, oldinfo+1, oldinfo->byte);
116 mem_db += newinfo->byte;
117 mem_db -= oldinfo->byte;
124 void util_meminfo() {
125 struct memblock_t *info;
130 for (info = mem_start; info; info = info->next) {
131 util_debug("MEM", "lost: % 8u (bytes) at %s:%u\n",
137 util_debug("MEM", "Memory information:\n\
138 Total allocations: %llu\n\
139 Total deallocations: %llu\n\
140 Total allocated: %llu (bytes)\n\
141 Total deallocated: %llu (bytes)\n\
142 Leaks found: lost %llu (bytes) in %d allocations\n",
151 * Some string utility functions, because strdup uses malloc, and we want
152 * to track all memory (without replacing malloc).
154 char *util_strdup(const char *s) {
161 if ((len = strlen(s)) && (ptr = mem_a(len+1))) {
169 * Remove quotes from a string, escapes from \ in string
170 * as well. This function shouldn't be used to create a
171 * char array that is later freed (it uses pointer arith)
173 char *util_strrq(const char *s) {
174 char *dst = (char*)s;
175 char *src = (char*)s;
177 while ((chr = *src++) != '\0') {
180 if ((chr = *src++) == '\0')
183 } else if (chr != '"')
191 * Chops a substring from an existing string by creating a
192 * copy of it and null terminating it at the required position.
194 char *util_strchp(const char *s, const char *e) {
195 const char *c = NULL;
203 return util_strdup(s);
207 * Returns true if string is all uppercase, otherwise
210 bool util_strupper(const char *str) {
220 * Returns true if string is all digits, otherwise
223 bool util_strdigit(const char *str) {
232 bool util_strncmpexact(const char *src, const char *ned, size_t len) {
233 return (!strncmp(src, ned, len) && !src[len]);
236 void util_debug(const char *area, const char *ms, ...) {
241 if (!strcmp(area, "MEM") && !opts_memchk)
245 fprintf (stdout, "DEBUG: ");
247 fprintf(stdout, "%s", area);
248 fputs ("] ", stdout);
249 vfprintf(stdout, ms, va);
254 * Endianess swapping, all data must be stored little-endian. This
255 * reorders by stride and length, much nicer than other functions for
256 * certian-sized types like short or int.
258 void util_endianswap(void *m, int s, int l) {
262 /* ignore if we're already LE */
267 for(; i < s << 1; i++) {
268 unsigned char *p = (unsigned char *)m+w*s;
269 unsigned char t = p[i];
277 * CRC algorithms vary in the width of the polynomial, the value of said polynomial,
278 * the initial value used for the register, weather the bits of each byte are reflected
279 * before being processed, weather the algorithm itself feeds input bytes through the
280 * register or XORs them with a byte from one end and then straight into the table, as
281 * well as (but not limited to the idea of reflected versions) where the final register
282 * value becomes reversed, and finally weather the value itself is used to XOR the final
283 * register value. AS such you can already imagine how painfully annoying CRCs are,
284 * of course we stand to target Quake, which expects it's certian set of rules for proper
285 * calculation of a CRC.
287 * In most traditional CRC algorithms on uses a reflected table driven method where a value
288 * or register is reflected if it's bits are swapped around it's center. For example:
289 * take the bits 0101 is the 4-bit reflection of 1010, and respectfully 0011 would be the
290 * reflection of 1100. Quakle however expects a NON-Reflected CRC on the output, but still
291 * requires a final XOR on the values (0xFFFF and 0x0000) this is a standard CCITT CRC-16
292 * which I respectfully as a programmer don't agree with.
294 * So now you know what we target, and why we target it, despite how unsettling it may seem
295 * but those are what Quake seems to request.
299 * This is an implementation of CRC32 & CRC16. The polynomials have been
300 * offline computed for faster generation at the cost of larger code size.
302 * CRC32 Polynomial: 0xEDB88320
303 * CRC16 Polynomial: 0x00001021
305 static const uint32_t util_crc32_table[] = {
306 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
307 0xE963A535, 0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
308 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
309 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
310 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
311 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
312 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, 0x35B5A8FA, 0x42B2986C,
313 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
314 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
315 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
316 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106,
317 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
318 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
319 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
320 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950,
321 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
322 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
323 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
324 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA,
325 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
326 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
327 0xB7BD5C3B, 0xC0BA6CAD, 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
328 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84,
329 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
330 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
331 0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
332 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8, 0xA1D1937E,
333 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
334 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
335 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
336 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, 0xC5BA3BBE, 0xB2BD0B28,
337 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
338 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
339 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
340 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242,
341 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
342 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
343 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
344 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC,
345 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
346 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
347 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
348 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
350 static const uint16_t util_crc16_table[] = {
351 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5,
352 0x60C6, 0x70E7, 0x8108, 0x9129, 0xA14A, 0xB16B,
353 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF, 0x1231, 0x0210,
354 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
355 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C,
356 0xF3FF, 0xE3DE, 0x2462, 0x3443, 0x0420, 0x1401,
357 0x64E6, 0x74C7, 0x44A4, 0x5485, 0xA56A, 0xB54B,
358 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
359 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6,
360 0x5695, 0x46B4, 0xB75B, 0xA77A, 0x9719, 0x8738,
361 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC, 0x48C4, 0x58E5,
362 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
363 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969,
364 0xA90A, 0xB92B, 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96,
365 0x1A71, 0x0A50, 0x3A33, 0x2A12, 0xDBFD, 0xCBDC,
366 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
367 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03,
368 0x0C60, 0x1C41, 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD,
369 0xAD2A, 0xBD0B, 0x8D68, 0x9D49, 0x7E97, 0x6EB6,
370 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
371 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A,
372 0x9F59, 0x8F78, 0x9188, 0x81A9, 0xB1CA, 0xA1EB,
373 0xD10C, 0xC12D, 0xF14E, 0xE16F, 0x1080, 0x00A1,
374 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
375 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C,
376 0xE37F, 0xF35E, 0x02B1, 0x1290, 0x22F3, 0x32D2,
377 0x4235, 0x5214, 0x6277, 0x7256, 0xB5EA, 0xA5CB,
378 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
379 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447,
380 0x5424, 0x4405, 0xA7DB, 0xB7FA, 0x8799, 0x97B8,
381 0xE75F, 0xF77E, 0xC71D, 0xD73C, 0x26D3, 0x36F2,
382 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
383 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9,
384 0xB98A, 0xA9AB, 0x5844, 0x4865, 0x7806, 0x6827,
385 0x18C0, 0x08E1, 0x3882, 0x28A3, 0xCB7D, 0xDB5C,
386 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
387 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0,
388 0x2AB3, 0x3A92, 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D,
389 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9, 0x7C26, 0x6C07,
390 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
391 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA,
392 0x8FD9, 0x9FF8, 0x6E17, 0x7E36, 0x4E55, 0x5E74,
393 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
397 * Implements a CRC function for X worth bits using (uint[X]_t)
398 * as type. and util_crc[X]_table.
400 * Quake expects a non-reflective CRC.
403 uint##X##_t util_crc##X(uint##X##_t current, const char *k, size_t len) { \
404 register uint##X##_t h= current; \
405 for (; len; --len, ++k) \
406 h = util_crc##X##_table[(h>>8)^((unsigned char)*k)]^(h<<8); \
414 uint##X##_t util_crc##X(const char *k, int len, const short clamp) { \
415 register uint##X##_t h= (uint##X##_t)0xFFFFFFFF; \
416 for (; len; --len, ++k) \
417 h = util_crc##X##_table[(h^((unsigned char)*k))&0xFF]^(h>>8); \
424 * Implements libc getline for systems that don't have it, which is
425 * assmed all. This works the same as getline().
427 int util_getline(char **lineptr, size_t *n, FILE *stream) {
432 if (!lineptr || !n || !stream)
435 if (!(*lineptr = (char*)mem_a((*n=64))))
443 int c = getc(stream);
446 char *tmp = (char*)mem_a((*n+=(*n>16)?*n:64));
450 memcpy(tmp, *lineptr, pos - *lineptr);
451 chr = *n + *lineptr - pos;
452 if (!(*lineptr = tmp)) {
456 pos = *n - chr + *lineptr;
474 return (ret = pos - *lineptr);
477 size_t util_strtocmd(const char *in, char *out, size_t outsz) {
479 for (; *in && sz < outsz; ++in, ++out, ++sz) {
482 else if (isalpha(*in) && !isupper(*in))
483 *out = *in + 'A' - 'a';
491 size_t util_strtononcmd(const char *in, char *out, size_t outsz) {
493 for (; *in && sz < outsz; ++in, ++out, ++sz) {
496 else if (isalpha(*in) && isupper(*in))
497 *out = *in + 'a' - 'A';
505 FILE *util_fopen(const char *filename, const char *mode)
509 if (fopen_s(&out, filename, mode) != 0)
513 return fopen(filename, mode);