X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=util.c;h=ceed4491aa96c59d24a11b29be567d673b6f3a71;hb=9d89a059aa6d2a03d3a08de4db295e08e45458d9;hp=8a0758e8d2efa888cb89921df0ded32040ff27af;hpb=56edc3db9c8d372227198d462f541f8d68e46649;p=xonotic%2Fgmqcc.git diff --git a/util.c b/util.c index 8a0758e..ceed449 100644 --- a/util.c +++ b/util.c @@ -1,39 +1,7 @@ -/* - * Copyright (C) 2012, 2013, 2014 - * Dale Weiler - * Wolfgang Bumiller - * - * Permission is hereby granted, free of charge, to any person obtaining a copy of - * this software and associated documentation files (the "Software"), to deal in - * the Software without restriction, including without limitation the rights to - * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies - * of the Software, and to permit persons to whom the Software is furnished to do - * so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -#define GMQCC_PLATFORM_HEADER #include +#include #include "gmqcc.h" -#include "platform.h" -/* - * Initially this was handled with a table in the gmqcc.h header, but - * much to my surprise the contents of the table was duplicated for - * each translation unit, causing all these strings to be duplicated - * for every .c file it was included into. This method culls back on - * it. This is a 'utility' function because the executor also depends - * on this for disassembled byte-code. - */ const char *util_instr_str[VINSTR_END] = { "DONE", "MUL_F", "MUL_V", "MUL_FV", "MUL_VF", "DIV_F", "ADD_F", "ADD_V", @@ -58,7 +26,7 @@ const char *util_instr_str[VINSTR_END] = { * only required if big endian .. otherwise no need to swap * data. */ -#if PLATFORM_BYTE_ORDER == GMQCC_BYTE_ORDER_BIG +#if PLATFORM_BYTE_ORDER == GMQCC_BYTE_ORDER_BIG || PLATFORM_BYTE_ORDER == -1 static GMQCC_INLINE void util_swap16(uint16_t *d, size_t l) { while (l--) { d[l] = (d[l] << 8) | (d[l] >> 8); @@ -77,22 +45,12 @@ const char *util_instr_str[VINSTR_END] = { * so let's go the safe way */ static GMQCC_INLINE void util_swap64(uint32_t *d, size_t l) { - /* while (l--) { uint64_t v; v = ((d[l] << 8) & 0xFF00FF00FF00FF00) | ((d[l] >> 8) & 0x00FF00FF00FF00FF); v = ((v << 16) & 0xFFFF0000FFFF0000) | ((v >> 16) & 0x0000FFFF0000FFFF); d[l] = (v << 32) | (v >> 32); } - */ - size_t i; - l *= 2; - for (i = 0; i < l; i += 2) { - uint32_t v1 = d[i]; - d[i] = d[i+1]; - d[i+1] = v1; - util_swap32(d+i, 2); - } } #endif @@ -519,7 +477,7 @@ static const uint16_t util_crc16_table[8][256] = {{ /* Non - Reflected */ uint16_t util_crc16(uint16_t current, const char *GMQCC_RESTRICT k, size_t len) { - register uint16_t h = current; + uint16_t h = current; /* don't load twice */ const uint8_t *GMQCC_RESTRICT data = (const uint8_t *GMQCC_RESTRICT)k; @@ -584,64 +542,144 @@ size_t util_optimizationtostr(const char *in, char *out, size_t outsz) { return util_strtransform(in, out, outsz, "_ ", 'a'-'A'); } +static int util_vasprintf(char **dat, const char *fmt, va_list args) { + int ret; + int len; + char *tmp = NULL; + char buf[128]; + va_list cpy; + + va_copy(cpy, args); + len = vsnprintf(buf, sizeof(buf), fmt, cpy); + va_end (cpy); + + if (len < 0) + return len; + + if (len < (int)sizeof(buf)) { + *dat = util_strdup(buf); + return len; + } + + tmp = (char*)mem_a(len + 1); + if ((ret = vsnprintf(tmp, len + 1, fmt, args)) != len) { + mem_d(tmp); + *dat = NULL; + return -1; + } + + *dat = tmp; + return len; +} + int util_snprintf(char *str, size_t size, const char *fmt, ...) { va_list arg; - int ret; - + int ret; va_start(arg, fmt); - ret = platform_vsnprintf(str, size, fmt, arg); + ret = vsnprintf(str, size, fmt, arg); va_end(arg); - return ret; } int util_asprintf(char **ret, const char *fmt, ...) { va_list args; - int read; - + int read; va_start(args, fmt); - read = platform_vasprintf(ret, fmt, args); - va_end (args); - + read = util_vasprintf(ret, fmt, args); + va_end(args); return read; } int util_sscanf(const char *str, const char *format, ...) { va_list args; - int read; - + int read; va_start(args, format); - read = platform_vsscanf(str, format, args); + read = vsscanf(str, format, args); va_end(args); - return read; } char *util_strncpy(char *dest, const char *src, size_t n) { - return platform_strncpy(dest, src, n); + return strncpy(dest, src, n); } + char *util_strncat(char *dest, const char *src, size_t n) { - return platform_strncat(dest, src, n); + return strncat(dest, src, n); } + char *util_strcat(char *dest, const char *src) { - return platform_strcat(dest, src); + return strcat(dest, src); } + const char *util_strerror(int err) { - return platform_strerror(err); + return strerror(err); } const struct tm *util_localtime(const time_t *timer) { - return platform_localtime(timer); + return localtime(timer); } + const char *util_ctime(const time_t *timer) { - return platform_ctime(timer); + return ctime(timer); +} + +int util_getline(char **lineptr, size_t *n, FILE *stream) { + int chr; + int ret; + char *pos; + + if (!lineptr || !n || !stream) + return -1; + if (!*lineptr) { + if (!(*lineptr = (char*)mem_a((*n=64)))) + return -1; + } + + chr = *n; + pos = *lineptr; + + for (;;) { + int c = getc(stream); + + if (chr < 2) { + *n += (*n > 16) ? *n : 64; + chr = *n + *lineptr - pos; + if (!(*lineptr = (char*)mem_r(*lineptr,*n))) + return -1; + pos = *n - chr + *lineptr; + } + + if (ferror(stream)) + return -1; + if (c == EOF) { + if (pos == *lineptr) + return -1; + else + break; + } + + *pos++ = c; + chr--; + if (c == '\n') + break; + } + *pos = '\0'; + return (ret = pos - *lineptr); } -bool util_isatty(fs_file_t *file) { - if (file == (fs_file_t*)stdout) return !!platform_isatty(STDOUT_FILENO); - if (file == (fs_file_t*)stderr) return !!platform_isatty(STDERR_FILENO); +#ifndef _WIN32 +#include +bool util_isatty(FILE *file) { + if (file == stdout) return !!isatty(STDOUT_FILENO); + if (file == stderr) return !!isatty(STDERR_FILENO); + return false; +} +#else +bool util_isatty(FILE *file) { return false; } +#endif + /* * A small noncryptographic PRNG based on: * http://burtleburtle.net/bob/rand/smallprng.html @@ -679,3 +717,16 @@ void util_seed(uint32_t value) { (void)util_rand(); } +size_t hash(const char *string) { + size_t hash = 0; + for(; *string; ++string) { + hash += *string; + hash += (hash << 10); + hash ^= (hash >> 6); + } + hash += hash << 3; + hash ^= hash >> 11; + hash += hash << 15; + return hash; +} +