X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=util.c;h=fa6e79772662e0d24765f6970632491690aa2fdf;hp=73c5335e08e49a3d87929a75351bdfd5d3315ad5;hb=1b5504fb9eae2f1eb2a0ef90afecf35387087bcb;hpb=b47e3ebccf562b26671247c2e99f4a0f6bc8e969;ds=sidebyside diff --git a/util.c b/util.c index 73c5335..fa6e797 100644 --- a/util.c +++ b/util.c @@ -262,7 +262,7 @@ void util_debug(const char *area, const char *ms, ...) { /* * only required if big endian .. otherwise no need to swap * data. - */ + */ #if PLATFORM_BYTE_ORDER == GMQCC_BYTE_ORDER_BIG static GMQCC_INLINE void util_swap16(uint16_t *d, size_t l) { while (l--) { @@ -402,7 +402,7 @@ static const uint16_t util_crc16_table[] = { /* Non - Reflected */ uint16_t util_crc16(uint16_t current, const char *k, size_t len) { register uint16_t h = current; - for (; len; --len, ++k) + for (; len; --len, ++k) h = util_crc16_table[(h>>8)^((unsigned char)*k)]^(h<<8); return h; } @@ -410,9 +410,9 @@ uint16_t util_crc16(uint16_t current, const char *k, size_t len) { #if 0 uint16_t util_crc16(const char *k, int len, const short clamp) { register uint16_t h= (uint16_t)0xFFFFFFFF; - for (; len; --len, ++k) + for (; len; --len, ++k) h = util_crc16_table[(h^((unsigned char)*k))&0xFF]^(h>>8); - return (~h)%clamp; + return (~h)%clamp; } #endif @@ -465,8 +465,7 @@ GMQCC_INLINE size_t util_hthash(hash_table_t *ht, const char *key) { const unsigned char *data = (const unsigned char*)key; while (size >= 4) { - alias = *(uint32_t*)data; - + alias = (data[0] | (data[1] << 8) | (data[2] << 16) | (data[3] << 24)); alias *= mix; alias ^= alias >> rot; alias *= mix; @@ -674,7 +673,7 @@ void util_htdel(hash_table_t *ht) { * Portable implementation of vasprintf/asprintf. Assumes vsnprintf * exists, otherwise compiler error. * - * TODO: fix for MSVC .... + * TODO: fix for MSVC .... */ int util_vasprintf(char **dat, const char *fmt, va_list args) { int ret; @@ -686,16 +685,15 @@ int util_vasprintf(char **dat, const char *fmt, va_list args) { * formatted string if it overflows. However there is a MSVC * intrinsic (which is documented wrong) called _vcsprintf which * will return the required amount to allocate. - */ + */ #ifdef _MSC_VER - char *str; if ((len = _vscprintf(fmt, args)) < 0) { *dat = NULL; return -1; } - tmp = mem_a(len + 1); - if ((ret = _vsnprintf(tmp, len+1, fmt, args)) != len) { + tmp = (char*)mem_a(len + 1); + if ((ret = _vsnprintf_s(tmp, len+1, len+1, fmt, args)) != len) { mem_d(tmp); *dat = NULL; return -1; @@ -742,6 +740,92 @@ int util_asprintf(char **ret, const char *fmt, ...) { return read; } +/* + * These are various re-implementations (wrapping the real ones) of + * string functions that MSVC consideres unsafe. We wrap these up and + * use the safe varations on MSVC. + */ +#ifdef _MSC_VER + static char **util_strerror_allocated() { + static char **data = NULL; + return data; + } + + static void util_strerror_cleanup(void) { + size_t i; + char **data = util_strerror_allocated(); + for (i = 0; i < vec_size(data); i++) + mem_d(data[i]); + vec_free(data); + } + + const char *util_strerror(int num) { + char *allocated = NULL; + static bool install = false; + static size_t tries = 0; + char **vector = util_strerror_allocated(); + + /* try installing cleanup handler */ + while (!install) { + if (tries == 32) + return "(unknown)"; + + install = !atexit(&util_strerror_cleanup); + tries ++; + } + + allocated = (char*)mem_a(4096); /* A page must be enough */ + strerror_s(allocated, 4096, num); + + vec_push(vector, allocated); + return (const char *)allocated; + } + + int util_snprintf(char *src, size_t bytes, const char *format, ...) { + int rt; + va_list va; + va_start(va, format); + + rt = vsprintf_s(src, bytes, format, va); + va_end (va); + + return rt; + } + + char *util_strcat(char *dest, const char *src) { + strcat_s(dest, strlen(src), src); + return dest; + } + + char *util_strncpy(char *dest, const char *src, size_t num) { + strncpy_s(dest, num, src, num); + return dest; + } +#else + const char *util_strerror(int num) { + return strerror(num); + } + + int util_snprintf(char *src, size_t bytes, const char *format, ...) { + int rt; + va_list va; + va_start(va, format); + rt = vsnprintf(src, bytes, format, va); + va_end (va); + + return rt; + } + + char *util_strcat(char *dest, const char *src) { + return strcat(dest, src); + } + + char *util_strncpy(char *dest, const char *src, size_t num) { + return strncpy(dest, src, num); + } + +#endif /*! _MSC_VER */ + /* * Implementation of the Mersenne twister PRNG (pseudo random numer * generator). Implementation of MT19937. Has a period of 2^19937-1 @@ -779,7 +863,7 @@ static GMQCC_INLINE void mt_generate() { * a branch that is executed every iteration from [0, MT_SIZE). * * Please see: http://www.quadibloc.com/crypto/co4814.htm for more - * information on how this clever trick works. + * information on how this clever trick works. */ static const uint32_t matrix[2] = { 0x00000000,