diff --git a/stb.h b/stb.h index 5ca0859..241fb2e 100644 --- a/stb.h +++ b/stb.h @@ -417,14 +417,80 @@ typedef union #include #endif +////////////////////////////////////////////////////////////////////////////// +// +// C library function platform handling +// -STB_EXTERN void stb_wrapper_malloc(void *newp, int sz, char *file, int line); +#ifdef STB_DEFINE + +#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__) +static FILE * stb_p_fopen(const char *filename, const char *mode) +{ + FILE *f; + if (0 == fopen_s(&f, filename, mode)) + return f; + else + return NULL; +} +static FILE * stb_p_wfopen(const wchar_t *filename, const wchar_t *mode) +{ + FILE *f; + if (0 == _wfopen_s(&f, filename, mode)) + return f; + else + return NULL; +} +static char *stb_p_strcpy_s(char *a, size_t size, const char *b) +{ + strcpy_s(a,size,b); + return a; +} +static char *stb_p_strncpy_s(char *a, size_t size, const char *b, size_t count) +{ + strncpy_s(a,size,b,count); + return a; +} +#define stb_p_mktemp(s) (_mktemp_s(s, strlen(s)+1) == 0) +#define stb_p_sprintf sprintf_s +#define stb_p_size(x) ,(x) +#else +#define stb_p_fopen fopen +#define stb_p_wfopen _wfopen +#define stb_p_strcpy_s(a,s,b) strcpy(a,b) +#define stb_p_strncpy_s(a,s,b,c) strncpy(a,b,c) +#define stb_p_mktemp(s) (mktemp(s) != NULL) + +#define stb_p_sprintf sprintf +#define stb_p_size(x) +#endif + +#if defined(_WIN32) +#define stb_p_vsnprintf _vsnprintf +#else +#define stb_p_vsnprintf vsnprintf +#endif + +#if defined(_WIN32) && (_MSC_VER >= 1300) +#define stb_p_stricmp _stricmp +#define stb_p_strnicmp _strnicmp +#define stb_p_strdup _strdup +#else +#define stb_p_strdup strdup +#define stb_p_stricmp stricmp +#define stb_p_strnicmp strnicmp +#endif + +#endif // STB_DEFINE + + +STB_EXTERN void stb_wrapper_malloc(void *newp, size_t sz, char *file, int line); STB_EXTERN void stb_wrapper_free(void *oldp, char *file, int line); -STB_EXTERN void stb_wrapper_realloc(void *oldp, void *newp, int sz, char *file, int line); +STB_EXTERN void stb_wrapper_realloc(void *oldp, void *newp, size_t sz, char *file, int line); STB_EXTERN void stb_wrapper_calloc(size_t num, size_t sz, char *file, int line); -STB_EXTERN void stb_wrapper_listall(void (*func)(void *ptr, int sz, char *file, int line)); +STB_EXTERN void stb_wrapper_listall(void (*func)(void *ptr, size_t sz, char *file, int line)); STB_EXTERN void stb_wrapper_dump(char *filename); -STB_EXTERN int stb_wrapper_allocsize(void *oldp); +STB_EXTERN size_t stb_wrapper_allocsize(void *oldp); STB_EXTERN void stb_wrapper_check(void *oldp); #ifdef STB_DEFINE @@ -471,8 +537,8 @@ STB_EXTERN char * stb_sstrdup(char *s); #endif #ifdef STB_MALLOC_WRAPPER - STB_EXTERN void * stb__malloc(int, char *, int); - STB_EXTERN void * stb__realloc(void *, int, char *, int); + STB_EXTERN void * stb__malloc(size_t, char *, int); + STB_EXTERN void * stb__realloc(void *, size_t, char *, int); STB_EXTERN void * stb__calloc(size_t n, size_t s, char *, int); STB_EXTERN void stb__free(void *, char *file, int); STB_EXTERN char * stb__strdup(char *s, char *file, int); @@ -516,7 +582,7 @@ STB_EXTERN char * stb_sstrdup(char *s); return 1; } - static void stb__check2(void *p, int sz, char *file, int line) + static void stb__check2(void *p, size_t sz, char *file, int line) { stb_mcheck(p); } @@ -555,10 +621,10 @@ STB_EXTERN char * stb_sstrdup(char *s); #endif #endif - static void *stb__malloc_final(int sz) + static void *stb__malloc_final(size_t sz) { #ifdef STB_MALLOC_WRAPPER_PAGED - int aligned = (sz + STB__WINDOWS_PAGE - 1) & ~(STB__WINDOWS_PAGE-1); + size_t aligned = (sz + STB__WINDOWS_PAGE - 1) & ~(STB__WINDOWS_PAGE-1); char *p = VirtualAlloc(NULL, aligned + STB__WINDOWS_PAGE, 0x2000, 0x04); // RESERVE, READWRITE if (p == NULL) return p; VirtualAlloc(p, aligned, 0x1000, 0x04); // COMMIT, READWRITE @@ -578,9 +644,9 @@ STB_EXTERN char * stb_sstrdup(char *s); } int stb__malloc_failure; - static void *stb__realloc_final(void *p, int sz, int old_sz) + #ifdef STB_MALLOC_WRAPPER_PAGED + static void *stb__realloc_final(void *p, size_t sz, size_t old_sz) { - #ifdef STB_MALLOC_WRAPPER_PAGED void *q = stb__malloc_final(sz); if (q == NULL) return ++stb__malloc_failure, q; @@ -588,10 +654,8 @@ STB_EXTERN char * stb_sstrdup(char *s); memcpy(q, p, sz < old_sz ? sz : old_sz); stb__free_final(p); return q; - #else - return realloc(p,sz); - #endif } + #endif void stb__free(void *p, char *file, int line) { @@ -611,7 +675,7 @@ STB_EXTERN char * stb_sstrdup(char *s); stb__free_final(p); } - void * stb__malloc(int sz, char *file, int line) + void * stb__malloc(size_t sz, char *file, int line) { void *p; stb_mcheck_all(); @@ -641,7 +705,7 @@ STB_EXTERN char * stb_sstrdup(char *s); return p; } - void * stb__realloc(void *p, int sz, char *file, int line) + void * stb__realloc(void *p, size_t sz, char *file, int line) { void *q; @@ -655,7 +719,7 @@ STB_EXTERN char * stb_sstrdup(char *s); #endif #ifdef STB_MALLOC_WRAPPER_PAGED { - int n = stb_wrapper_allocsize(STB__ptr(p,STB__BIAS)); + size_t n = stb_wrapper_allocsize(STB__ptr(p,STB__BIAS)); if (!n) stb_wrapper_check(STB__ptr(p,STB__BIAS)); q = stb__realloc_final(p, STB__FIXSIZE(sz), STB__FIXSIZE(n)); @@ -682,7 +746,7 @@ STB_EXTERN char * stb_sstrdup(char *s); return q; } - STB_EXTERN int stb_log2_ceil(unsigned int); + STB_EXTERN int stb_log2_ceil(size_t); static void *stb__calloc(size_t n, size_t sz, char *file, int line) { void *q; @@ -700,7 +764,7 @@ STB_EXTERN char * stb_sstrdup(char *s); stb_mcheck_all(); p = stb__malloc(strlen(s)+1, file, line); if (!p) return p; - strcpy(p, s); + stb_p_strcpy_s(p, strlen(s)+1, s); return p; } #endif // STB_DEFINE @@ -723,7 +787,6 @@ STB_EXTERN char * stb_sstrdup(char *s); #define calloc(n,s) stb__calloc (n,s, __FILE__, __LINE__) #define free(p) stb__free (p, __FILE__, __LINE__) #define strdup(p) stb__strdup (p, __FILE__, __LINE__) - #endif ////////////////////////////////////////////////////////////////////////////// @@ -738,13 +801,15 @@ STB_EXTERN int stb_snprintf(char *s, size_t n, const char *fmt, ...); STB_EXTERN int stb_vsnprintf(char *s, size_t n, const char *fmt, va_list v); #ifdef STB_DEFINE - int stb_vsnprintf(char *s, size_t n, const char *fmt, va_list v) { int res; #ifdef _WIN32 - // Could use "_vsnprintf_s(s, n, _TRUNCATE, fmt, v)" ? - res = _vsnprintf(s,n,fmt,v); + #ifdef __STDC_WANT_SECURE_LIB__ + res = _vsnprintf_s(s, n, _TRUNCATE, fmt, v); + #else + res = stb_p_vsnprintf(s,n,fmt,v); + #endif #else res = vsnprintf(s,n,fmt,v); #endif @@ -780,7 +845,7 @@ char *stb_mprintf(const char *fmt, ...) va_start(v,fmt); stb_vsnprintf(buffer,1024,fmt,v); va_end(v); - return strdup(buffer); + return stb_p_strdup(buffer); } #ifdef _WIN32 @@ -791,11 +856,13 @@ STB_EXTERN __declspec(dllimport) void * __stdcall GetStdHandle(unsigned int); STB_EXTERN __declspec(dllimport) int __stdcall SetConsoleTextAttribute(void *, unsigned short); #endif -static void stb__print_one(void *handle, char *s, int len) +static void stb__print_one(void *handle, char *s, ptrdiff_t len) { if (len) - if (0==WriteConsoleA(handle, s, len, NULL,NULL)) - fwrite(s, 1, len, stdout); // if it fails, maybe redirected, so do normal + if (0==WriteConsoleA(handle, s, (unsigned) len, NULL,NULL)) + // if it fails, maybe redirected, so output normally... + // but it's supriously reporting failure now on Win7 and later + {}//fwrite(s, 1, (unsigned) len, stdout); } static void stb__print(char *s) @@ -853,7 +920,7 @@ static void stb__print(char *s) t = s+1; } - lpad = (t-s); + lpad = (int) (t-s); s = t; while (*s && *s != '}') ++s; if (!*s) break; @@ -885,7 +952,7 @@ void stbprint(const char *fmt, ...) if (res < 0) { tbuf = (char *) malloc(16384); va_start(v,fmt); - res = _vsnprintf(tbuf,16384, fmt, v); + res = stb_vsnprintf(tbuf,16384, fmt, v); va_end(v); tbuf[16383] = 0; } @@ -920,26 +987,26 @@ void stbprint(const char *fmt, ...) #ifdef _WIN32 - #define stb__fopen(x,y) _wfopen((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y)) + #define stb__fopen(x,y) stb_p_wfopen((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y)) #define stb__windows(x,y) x #else - #define stb__fopen(x,y) fopen(x,y) + #define stb__fopen(x,y) stb_p_fopen(x,y) #define stb__windows(x,y) y #endif typedef unsigned short stb__wchar; -STB_EXTERN stb__wchar * stb_from_utf8(stb__wchar *buffer, char *str, int n); -STB_EXTERN char * stb_to_utf8 (char *buffer, stb__wchar *str, int n); +STB_EXTERN stb__wchar * stb_from_utf8(stb__wchar *buffer, const char *str, int n); +STB_EXTERN char * stb_to_utf8 (char *buffer, const stb__wchar *str, int n); -STB_EXTERN stb__wchar *stb__from_utf8(char *str); -STB_EXTERN stb__wchar *stb__from_utf8_alt(char *str); -STB_EXTERN char *stb__to_utf8(stb__wchar *str); +STB_EXTERN stb__wchar *stb__from_utf8(const char *str); +STB_EXTERN stb__wchar *stb__from_utf8_alt(const char *str); +STB_EXTERN char *stb__to_utf8(const stb__wchar *str); #ifdef STB_DEFINE -stb__wchar * stb_from_utf8(stb__wchar *buffer, char *ostr, int n) +stb__wchar * stb_from_utf8(stb__wchar *buffer, const char *ostr, int n) { unsigned char *str = (unsigned char *) ostr; stb_uint32 c; @@ -989,7 +1056,7 @@ stb__wchar * stb_from_utf8(stb__wchar *buffer, char *ostr, int n) return buffer; } -char * stb_to_utf8(char *buffer, stb__wchar *str, int n) +char * stb_to_utf8(char *buffer, const stb__wchar *str, int n) { int i=0; --n; @@ -1025,19 +1092,19 @@ char * stb_to_utf8(char *buffer, stb__wchar *str, int n) return buffer; } -stb__wchar *stb__from_utf8(char *str) +stb__wchar *stb__from_utf8(const char *str) { static stb__wchar buffer[4096]; return stb_from_utf8(buffer, str, 4096); } -stb__wchar *stb__from_utf8_alt(char *str) +stb__wchar *stb__from_utf8_alt(const char *str) { static stb__wchar buffer[4096]; return stb_from_utf8(buffer, str, 4096); } -char *stb__to_utf8(stb__wchar *str) +char *stb__to_utf8(const stb__wchar *str) { static char buffer[4096]; return stb_to_utf8(buffer, str, 4096); @@ -1050,7 +1117,7 @@ char *stb__to_utf8(stb__wchar *str) // Miscellany // -STB_EXTERN void stb_fatal(char *fmt, ...); +STB_EXTERN void stb_fatal(const char *fmt, ...); STB_EXTERN void stb_(char *fmt, ...); STB_EXTERN void stb_append_to_file(char *file, char *fmt, ...); STB_EXTERN void stb_log(int active); @@ -1065,21 +1132,21 @@ STB_EXTERN void **stb_array_block_alloc(int count, int blocksize); #define stb_arrcount(x) (sizeof(x)/sizeof((x)[0])) -STB_EXTERN int stb__record_fileline(char *f, int n); +STB_EXTERN int stb__record_fileline(const char *f, int n); #ifdef STB_DEFINE static char *stb__file; static int stb__line; -int stb__record_fileline(char *f, int n) +int stb__record_fileline(const char *f, int n) { - stb__file = f; + stb__file = (char*) f; stb__line = n; return 0; } -void stb_fatal(char *s, ...) +void stb_fatal(const char *s, ...) { va_list a; if (stb__file) @@ -1116,9 +1183,9 @@ void stb_log_fileline(int active) } #ifdef STB_NO_STB_STRINGS -char *stb__log_filename = "temp.log"; +const char *stb__log_filename = "temp.log"; #else -char *stb__log_filename = "stb.log"; +const char *stb__log_filename = "stb.log"; #endif void stb_log_name(char *s) @@ -1129,7 +1196,7 @@ void stb_log_name(char *s) void stb_(char *s, ...) { if (stb__log_active) { - FILE *f = fopen(stb__log_filename, "a"); + FILE *f = stb_p_fopen(stb__log_filename, "a"); if (f) { va_list a; if (stb__log_fileline && stb__file) @@ -1145,7 +1212,7 @@ void stb_(char *s, ...) void stb_append_to_file(char *filename, char *s, ...) { - FILE *f = fopen(filename, "a"); + FILE *f = stb_p_fopen(filename, "a"); if (f) { va_list a; va_start(a,s); @@ -1428,9 +1495,9 @@ STB_EXTERN int stb_bitcount(unsigned int a); STB_EXTERN unsigned int stb_bitreverse8(unsigned char n); STB_EXTERN unsigned int stb_bitreverse(unsigned int n); -STB_EXTERN int stb_is_pow2(unsigned int n); -STB_EXTERN int stb_log2_ceil(unsigned int n); -STB_EXTERN int stb_log2_floor(unsigned int n); +STB_EXTERN int stb_is_pow2(size_t); +STB_EXTERN int stb_log2_ceil(size_t); +STB_EXTERN int stb_log2_floor(size_t); STB_EXTERN int stb_lowbit8(unsigned int n); STB_EXTERN int stb_highbit8(unsigned int n); @@ -1462,7 +1529,7 @@ unsigned int stb_bitreverse(unsigned int n) return (n >> 16) | (n << 16); } -int stb_is_pow2(unsigned int n) +int stb_is_pow2(size_t n) { return (n & (n-1)) == 0; } @@ -1472,11 +1539,15 @@ int stb_is_pow2(unsigned int n) #if defined(_WIN32) && !defined(__MINGW32__) #pragma warning(push) #pragma warning(disable: 4035) // disable warning about no return value -int stb_log2_floor(unsigned int n) +int stb_log2_floor(size_t n) { #if _MSC_VER > 1700 unsigned long i; + #ifdef STB_PTR64 + _BitScanReverse64(&i, n); + #else _BitScanReverse(&i, n); + #endif return i != 0 ? i : -1; #else __asm { @@ -1489,10 +1560,15 @@ int stb_log2_floor(unsigned int n) } #pragma warning(pop) #else -int stb_log2_floor(unsigned int n) +int stb_log2_floor(size_t n) { static signed char log2_4[16] = { -1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3 }; +#ifdef STB_PTR64 + if (n >= ((size_t) 1u << 32)) + return stb_log2_floor(n >> 32); +#endif + // 2 compares if n < 16, 3 compares otherwise if (n < (1U << 14)) if (n < (1U << 4)) return 0 + log2_4[n ]; @@ -1507,7 +1583,7 @@ int stb_log2_floor(unsigned int n) #endif // define ceil from floor -int stb_log2_ceil(unsigned int n) +int stb_log2_ceil(size_t n) { if (stb_is_pow2(n)) return stb_log2_floor(n); else return 1 + stb_log2_floor(n); @@ -1537,8 +1613,8 @@ int stb_lowbit8(unsigned int n) // #ifdef _WIN32 - #define stb_stricmp(a,b) stricmp(a,b) - #define stb_strnicmp(a,b,n) strnicmp(a,b,n) + #define stb_stricmp(a,b) stb_p_stricmp(a,b) + #define stb_strnicmp(a,b,n) stb_p_strnicmp(a,b,n) #else #define stb_stricmp(a,b) strcasecmp(a,b) #define stb_strnicmp(a,b,n) strncasecmp(a,b,n) @@ -1556,6 +1632,7 @@ STB_EXTERN int (*stb_charcmp(int offset))(const void *a, const void *b); #ifdef STB_DEFINE static int stb__intcmpoffset, stb__ucharcmpoffset, stb__strcmpoffset; static int stb__floatcmpoffset, stb__doublecmpoffset; +static int stb__memcmpoffset, stb__memcmpsize; int stb__intcmp(const void *a, const void *b) { @@ -1606,6 +1683,11 @@ int stb__qsort_stricmp(const void *a, const void *b) return stb_stricmp(p,q); } +int stb__memcmp(const void *a, const void *b) +{ + return memcmp((char *) a + stb__memcmpoffset, (char *) b + stb__memcmpoffset, stb__memcmpsize); +} + int (*stb_intcmp(int offset))(const void *, const void *) { stb__intcmpoffset = offset; @@ -1647,6 +1729,13 @@ int (*stb_doublecmp(int offset))(const void *, const void *) stb__doublecmpoffset = offset; return &stb__doublecmp; } + +int (*stb_memcmp(int offset, int size))(const void *, const void *) +{ + stb__memcmpoffset = offset; + stb__memcmpsize = size; + return &stb__memcmp; +} #endif ////////////////////////////////////////////////////////////////////////////// @@ -1836,7 +1925,7 @@ size_t stb_strscpy(char *d, const char *s, size_t n) if (n) d[0] = 0; return 0; } - strcpy(d,s); + stb_p_strcpy_s(d,n+1,s); return len + 1; } @@ -1918,7 +2007,7 @@ char *stb_trimwhite(char *s) char *stb_strncpy(char *s, char *t, int n) { - strncpy(s,t,n); + stb_p_strncpy_s(s,n+1,t,n); s[n-1] = 0; return s; } @@ -1929,14 +2018,14 @@ char *stb_substr(char *t, int n) int z = (int) strlen(t); if (z < n) n = z; a = (char *) malloc(n+1); - strncpy(a,t,n); + stb_p_strncpy_s(a,n+1,t,n); a[n] = 0; return a; } char *stb_duplower(char *s) { - char *p = strdup(s), *q = p; + char *p = stb_p_strdup(s), *q = p; while (*q) { *q = tolower(*q); ++q; @@ -2216,7 +2305,7 @@ char *stb_dupreplace(char *src, char *find, char *replace) char *s,*p,*q; s = strstr(src, find); - if (s == NULL) return strdup(src); + if (s == NULL) return stb_p_strdup(src); do { ++count; s = strstr(s + len_find, find); @@ -2229,7 +2318,7 @@ char *stb_dupreplace(char *src, char *find, char *replace) for (;;) { char *t = strstr(s, find); if (t == NULL) { - strcpy(q,s); + stb_p_strcpy_s(q,strlen(src)+count*(len_replace-len_find)+1,s); assert(strlen(p) == strlen(src) + count*(len_replace-len_find)); return p; } @@ -2249,7 +2338,7 @@ void stb_replaceinplace(char *src, char *find, char *replace) char *s,*p,*q; - delta = len_replace - len_find; + delta = (int) (len_replace - len_find); assert(delta <= 0); if (delta > 0) return; @@ -2277,10 +2366,10 @@ void stb_fixpath(char *path) *path = '/'; } -void stb__add_section(char *buffer, char *data, int curlen, int newlen) +void stb__add_section(char *buffer, char *data, ptrdiff_t curlen, ptrdiff_t newlen) { if (newlen < curlen) { - int z1 = newlen >> 1, z2 = newlen-z1; + ptrdiff_t z1 = newlen >> 1, z2 = newlen-z1; memcpy(buffer, data, z1-1); buffer[z1-1] = '.'; buffer[z1-0] = '.'; @@ -2292,7 +2381,7 @@ void stb__add_section(char *buffer, char *data, int curlen, int newlen) char * stb_shorten_path_readable(char *path, int len) { static char buffer[1024]; - int n = strlen(path),n1,n2,r1,r2; + ptrdiff_t n = strlen(path),n1,n2,r1,r2; char *s; if (n <= len) return path; if (len > 1024) return path; @@ -2329,7 +2418,7 @@ char * stb_shorten_path_readable(char *path, int len) static char *stb__splitpath_raw(char *buffer, char *path, int flag) { - int len=0,x,y, n = (int) strlen(path), f1,f2; + ptrdiff_t len=0,x,y, n = (int) strlen(path), f1,f2; char *s = stb_strrchr2(path, '/', '\\'); char *t = strrchr(path, '.'); if (s && t && t < s) t = NULL; @@ -2366,8 +2455,8 @@ static char *stb__splitpath_raw(char *buffer, char *path, int flag) if (!buffer) return NULL; } - if (len) { strcpy(buffer, "./"); return buffer; } - strncpy(buffer, path+x, y-x); + if (len) { stb_p_strcpy_s(buffer, sizeof(buffer), "./"); return buffer; } + stb_p_strncpy_s(buffer, sizeof(buffer),path+x, y-x); buffer[y-x] = 0; return buffer; } @@ -2387,9 +2476,9 @@ char *stb_replacedir(char *output, char *src, char *dir) char buffer[4096]; stb_splitpath(buffer, src, STB_FILE | STB_EXT); if (dir) - sprintf(output, "%s/%s", dir, buffer); + stb_p_sprintf(output stb_p_size(9999), "%s/%s", dir, buffer); else - strcpy(output, buffer); + stb_p_strcpy_s(output, sizeof(buffer), buffer); // @UNSAFE return output; } @@ -2398,9 +2487,9 @@ char *stb_replaceext(char *output, char *src, char *ext) char buffer[4096]; stb_splitpath(buffer, src, STB_PATH | STB_FILE); if (ext) - sprintf(output, "%s.%s", buffer, ext[0] == '.' ? ext+1 : ext); + stb_p_sprintf(output stb_p_size(9999), "%s.%s", buffer, ext[0] == '.' ? ext+1 : ext); else - strcpy(output, buffer); + stb_p_strcpy_s(output, sizeof(buffer), buffer); // @UNSAFE return output; } #endif @@ -2813,7 +2902,7 @@ static void * malloc_base(void *context, size_t size, stb__alloc_type t, int ali if (align <= 0) { // compute worst-case C packed alignment // e.g. a 24-byte struct is 8-aligned - int align_proposed = 1 << stb_lowbit8(size); + int align_proposed = 1 << stb_lowbit8((unsigned int) size); if (align_proposed < 0) align_proposed = 4; @@ -2863,7 +2952,7 @@ static void * malloc_base(void *context, size_t size, stb__alloc_type t, int ali } case STB__chunk_raw: { - p = stb__alloc_chunk(src, size, align, 0); + p = stb__alloc_chunk(src, (int) size, align, 0); if (p == NULL) return NULL; break; } @@ -2871,7 +2960,7 @@ static void * malloc_base(void *context, size_t size, stb__alloc_type t, int ali case STB__chunked: { stb__chunked *s; if (align < sizeof(stb_uintptr)) align = sizeof(stb_uintptr); - s = (stb__chunked *) stb__alloc_chunk(src, size, align, sizeof(*s)); + s = (stb__chunked *) stb__alloc_chunk(src, (int) size, align, sizeof(*s)); if (s == NULL) return NULL; stb__setparent(s, src); p = s+1; @@ -3414,12 +3503,7 @@ unsigned int stb_hash2(char *str, unsigned int *hash2_ptr) } // Paul Hsieh hash -#define stb__get16_slow(p) ((p)[0] + ((p)[1] << 8)) -#if defined(_MSC_VER) - #define stb__get16(p) (*((unsigned short *) (p))) -#else - #define stb__get16(p) stb__get16_slow(p) -#endif +#define stb__get16(p) ((p)[0] | ((p)[1] << 8)) unsigned int stb_hash_fast(void *p, int len) { @@ -3429,34 +3513,23 @@ unsigned int stb_hash_fast(void *p, int len) if (len <= 0 || q == NULL) return 0; /* Main loop */ - if (((int)(size_t) q & 1) == 0) { - for (;len > 3; len -= 4) { - unsigned int val; - hash += stb__get16(q); - val = (stb__get16(q+2) << 11); - hash = (hash << 16) ^ hash ^ val; - q += 4; - hash += hash >> 11; - } - } else { - for (;len > 3; len -= 4) { - unsigned int val; - hash += stb__get16_slow(q); - val = (stb__get16_slow(q+2) << 11); - hash = (hash << 16) ^ hash ^ val; - q += 4; - hash += hash >> 11; - } + for (;len > 3; len -= 4) { + unsigned int val; + hash += stb__get16(q); + val = (stb__get16(q+2) << 11); + hash = (hash << 16) ^ hash ^ val; + q += 4; + hash += hash >> 11; } /* Handle end cases */ switch (len) { - case 3: hash += stb__get16_slow(q); + case 3: hash += stb__get16(q); hash ^= hash << 16; hash ^= q[2] << 18; hash += hash >> 11; break; - case 2: hash += stb__get16_slow(q); + case 2: hash += stb__get16(q); hash ^= hash << 11; hash += hash >> 17; break; @@ -4159,7 +4232,7 @@ void stb_ptrmap_delete(stb_ptrmap *e, void (*free_func)(void *)) // extra fields needed for stua_dict #define STB_IEMPTY ((int) 1) #define STB_IDEL ((int) 3) -stb_define_hash_base(STB_noprefix, stb_idict, short type; short gc; STB_nofields, stb_idict_,stb_idict_,0.85f, +stb_define_hash_base(STB_noprefix, stb_idict, short type; short gc; STB_nofields, stb_idict_,stb_idict_,0.95f, stb_int32,STB_IEMPTY,STB_IDEL,STB_nocopy,STB_nodelete,STB_nosafe, STB_equal,STB_equal, return stb_rehash_improved(k);,stb_int32,STB_nonullvalue,0) @@ -4229,7 +4302,7 @@ static stb__ptrpair stb__ptrpair_del = { (void *) 2, (void *) 2 }; #define STB__equal_ptrpair(x,y) ((x).a == (y).a && (x).b == (y).b) -stb_define_hash_base(static, stb_spmatrix, int val_size; void *arena;, stb__spmatrix_,stb__spmatrix_, 0.85, +stb_define_hash_base(STB_noprefix, stb_spmatrix, int val_size; void *arena;, stb__spmatrix_,stb__spmatrix_, 0.85, stb__ptrpair, stb__ptrpair_empty, stb__ptrpair_del, STB_nocopy, STB_nodelete, STB_nosafe, STB__equal_ptrpair, STB__equal_ptrpair, return stb_rehash(stb_hashptr(k.a))+stb_hashptr(k.b);, @@ -4301,9 +4374,9 @@ STB_EXTERN void * stb_sdict_internal_value(stb_sdict *d, int n); #define STB_DEL ((void *) 1) #define STB_SDEL ((char *) 1) -#define stb_sdict__copy(x) \ - strcpy(a->arena ? stb_malloc_string(a->arena, strlen(x)+1) \ - : (char *) malloc(strlen(x)+1), x) +#define stb_sdict__copy(x) \ + stb_p_strcpy_s(a->arena ? stb_malloc_string(a->arena, strlen(x)+1) \ + : (char *) malloc(strlen(x)+1), strlen(x)+1, x) #define stb_sdict__dispose(x) if (!a->arena) free(x) @@ -5061,11 +5134,9 @@ void stb_nptr_recache(void) // -#ifdef _MSC_VER +#ifdef _WIN32 #define stb_rename(x,y) _wrename((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y)) - #define stb_mktemp _mktemp #else - #define stb_mktemp mktemp #define stb_rename rename #endif @@ -5091,7 +5162,7 @@ STB_EXTERN int stb_feq(char *s1, char *s2); STB_EXTERN time_t stb_ftimestamp(char *filename); STB_EXTERN int stb_fullpath(char *abs, int abs_size, char *rel); -STB_EXTERN FILE * stb_fopen(char *filename, char *mode); +STB_EXTERN FILE * stb_fopen(char *filename, const char *mode); STB_EXTERN int stb_fclose(FILE *f, int keep); enum @@ -5142,7 +5213,7 @@ STB_EXTERN int stb_tfwrite(void *data, size_t len, size_t count, STBF *f); STBF *stb_tfopen(char *filename, char *mode) { STBF *z; - FILE *f = fopen(filename, mode); + FILE *f = stb_p_fopen(filename, mode); if (!f) return NULL; z = (STBF *) malloc(sizeof(*z)); if (!z) { fclose(f); return NULL; } @@ -5191,7 +5262,7 @@ void stb_fwrite32(FILE *f, stb_uint32 x) fwrite(&x, 4, 1, f); } -#if defined(_MSC_VER) || defined(__MINGW32__) +#if defined(_WIN32) #define stb__stat _stat #else #define stb__stat stat @@ -5222,12 +5293,12 @@ time_t stb_ftimestamp(char *filename) size_t stb_filelen(FILE *f) { - size_t len, pos; + long len, pos; pos = ftell(f); fseek(f, 0, SEEK_END); len = ftell(f); fseek(f, pos, SEEK_SET); - return len; + return (size_t) len; } void *stb_file(char *filename, size_t *length) @@ -5331,7 +5402,7 @@ char ** stb_stringfile(char *filename, int *plen) memcpy(&list[count+1], buffer, len+1); free(buffer); buffer = (char *) &list[count+1]; - if (plen) *plen = count; + if (plen) *plen = (int) count; } } return list; @@ -5358,7 +5429,7 @@ char * stb_fgets(char *buffer, int buflen, FILE *f) buffer[0] = 0; p = fgets(buffer, buflen, f); if (p) { - int n = strlen(p)-1; + int n = (int) (strlen(p)-1); if (n >= 0) if (p[n] == '\n') p[n] = 0; @@ -5375,21 +5446,21 @@ char * stb_fgets_malloc(FILE *f) return NULL; if (quick_buffer[sizeof(quick_buffer)-2] == 0) { - int n = strlen(quick_buffer); + size_t n = strlen(quick_buffer); if (n > 0 && quick_buffer[n-1] == '\n') quick_buffer[n-1] = 0; - return strdup(quick_buffer); + return stb_p_strdup(quick_buffer); } else { char *p; - char *a = strdup(quick_buffer); - int len = sizeof(quick_buffer)-1; + char *a = stb_p_strdup(quick_buffer); + size_t len = sizeof(quick_buffer)-1; while (!feof(f)) { if (a[len-1] == '\n') break; a = (char *) realloc(a, len*2); p = &a[len]; p[len-2] = 0; - if (!fgets(p, len, f)) + if (!fgets(p, (int) len, f)) break; if (p[len-2] == 0) { len += strlen(p); @@ -5405,13 +5476,13 @@ char * stb_fgets_malloc(FILE *f) int stb_fullpath(char *abs, int abs_size, char *rel) { - #ifdef _MSC_VER + #ifdef _WIN32 return _fullpath(abs, rel, abs_size) != NULL; #else if (rel[0] == '/' || rel[0] == '~') { if ((int) strlen(rel) >= abs_size) return 0; - strcpy(abs,rel); + stb_p_strcpy_s(abs,65536,rel); return STB_TRUE; } else { int n; @@ -5419,7 +5490,7 @@ int stb_fullpath(char *abs, int abs_size, char *rel) n = strlen(abs); if (n+(int) strlen(rel)+2 <= abs_size) { abs[n] = '/'; - strcpy(abs+n+1, rel); + stb_p_strcpy_s(abs+n+1, 65536,rel); return STB_TRUE; } else { return STB_FALSE; @@ -5434,8 +5505,8 @@ static int stb_fcmp_core(FILE *f, FILE *g) int n1,n2, res=0; while (1) { - n1 = fread(buf1, 1, sizeof(buf1), f); - n2 = fread(buf2, 1, sizeof(buf2), g); + n1 = (int) fread(buf1, 1, sizeof(buf1), f); + n2 = (int) fread(buf2, 1, sizeof(buf2), g); res = memcmp(buf1,buf2,stb_min(n1,n2)); if (res) break; @@ -5499,9 +5570,9 @@ typedef struct int errors; } stb__file_data; -static FILE *stb__open_temp_file(char *temp_name, char *src_name, char *mode) +static FILE *stb__open_temp_file(char *temp_name, char *src_name, const char *mode) { - int p; + size_t p; #ifdef _MSC_VER int j; #endif @@ -5519,19 +5590,19 @@ static FILE *stb__open_temp_file(char *temp_name, char *src_name, char *mode) // try multiple times to make a temp file... just in // case some other process makes the name first for (j=0; j < 32; ++j) { - strcpy(temp_name+p, "stmpXXXXXX"); - if (stb_mktemp(temp_name) == NULL) + stb_p_strcpy_s(temp_name+p, 65536, "stmpXXXXXX"); + if (!stb_p_mktemp(temp_name)) return 0; - f = fopen(temp_name, mode); + f = stb_p_fopen(temp_name, mode); if (f != NULL) break; } #else { - strcpy(temp_name+p, "stmpXXXXXX"); + stb_p_strcpy_s(temp_name+p, 65536, "stmpXXXXXX"); #ifdef __MINGW32__ - int fd = open(mktemp(temp_name), O_RDWR); + int fd = open(stb_p_mktemp(temp_name), O_RDWR); #else int fd = mkstemp(temp_name); #endif @@ -5548,7 +5619,7 @@ static FILE *stb__open_temp_file(char *temp_name, char *src_name, char *mode) } -FILE * stb_fopen(char *filename, char *mode) +FILE * stb_fopen(char *filename, const char *mode) { FILE *f; char name_full[4096]; @@ -5570,8 +5641,8 @@ FILE * stb_fopen(char *filename, char *mode) stb__file_data *d = (stb__file_data *) malloc(sizeof(*d)); if (!d) { assert(0); /* NOTREACHED */fclose(f); return NULL; } if (stb__files == NULL) stb__files = stb_ptrmap_create(); - d->temp_name = strdup(temp_full); - d->name = strdup(name_full); + d->temp_name = stb_p_strdup(temp_full); + d->name = stb_p_strdup(name_full); d->errors = 0; stb_ptrmap_add(stb__files, f, d); return f; @@ -5701,7 +5772,7 @@ int stb_copyfile(char *src, char *dest) } while (!feof(f)) { - int n = fread(buffer, 1, buf_size, f); + size_t n = fread(buffer, 1, buf_size, f); if (n != 0) fwrite(buffer, 1, n, g); } @@ -5877,8 +5948,8 @@ int stb_size_ranged(int b, stb_uint n) void stb_fput_string(FILE *f, char *s) { - int len = strlen(s); - stb_fput_varlenu(f, len); + size_t len = strlen(s); + stb_fput_varlenu(f, (unsigned int) len); fwrite(s, 1, len, f); } @@ -5896,9 +5967,9 @@ char *stb_fget_string(FILE *f, void *p) char *stb_strdup(char *str, void *pool) { - int len = strlen(str); + size_t len = strlen(str); char *p = stb_malloc_string(pool, len+1); - strcpy(p, str); + stb_p_strcpy_s(p, len+1, str); return p; } @@ -5954,7 +6025,7 @@ void stb_getopt_free(char **opts) char **stb_getopt(int *argc, char **argv) { - return stb_getopt_param(argc, argv, ""); + return stb_getopt_param(argc, argv, (char*) ""); } char **stb_getopt_param(int *argc, char **argv, char *param) @@ -5972,7 +6043,7 @@ char **stb_getopt_param(int *argc, char **argv, char *param) break; } else if (argv[i][1] == '-') { // copy argument through including initial '-' for clarity - stb_arr_push(opts, strdup(argv[i])); + stb_arr_push(opts, stb_p_strdup(argv[i])); } else { int k; char *q = argv[i]; // traverse options list @@ -5980,7 +6051,7 @@ char **stb_getopt_param(int *argc, char **argv, char *param) char *s; if (strchr(param, q[k])) { // does it take a parameter? char *t = &q[k+1], z = q[k]; - int len=0; + size_t len=0; if (*t == 0) { if (i == *argc-1) { // takes a parameter, but none found *argc = 0; @@ -5989,12 +6060,12 @@ char **stb_getopt_param(int *argc, char **argv, char *param) } t = argv[++i]; } else - k += strlen(t); + k += (int) strlen(t); len = strlen(t); s = (char *) malloc(len+2); if (!s) return NULL; s[0] = z; - strcpy(s+1, t); + stb_p_strcpy_s(s+1, len+2, t); } else { // no parameter s = (char *) malloc(2); @@ -6130,7 +6201,7 @@ static char **readdir_raw(char *dir, int return_subdirs, char *mask) break; if (buffer[0] == '.' && buffer[1] == '/') p = buffer+2; - stb_arr_push(results, strdup(p)); + stb_arr_push(results, stb_p_strdup(p)); } } } @@ -6166,7 +6237,7 @@ static char **stb_readdir_rec(char **sofar, char *dir, char *filespec) files = stb_readdir_files_mask(dir, filespec); stb_arr_for(p, files) { - stb_arr_push(sofar, strdup(*p)); + stb_arr_push(sofar, stb_p_strdup(*p)); if (stb_arr_len(sofar) >= stb__rec_max) break; } stb_readdir_free(files); @@ -6245,7 +6316,7 @@ stb_dirtree2 *stb_dirtree2_from_files_relative(char *src, char **filelist, int c { char buffer1[1024]; int i; - int dlen = strlen(src), elen; + int dlen = (int) strlen(src), elen; stb_dirtree2 *d; char ** descendents = NULL; char ** files = NULL; @@ -6278,7 +6349,7 @@ stb_dirtree2 *stb_dirtree2_from_files_relative(char *src, char **filelist, int c d = (stb_dirtree2 *) malloc(sizeof(*d)); d->files = files; d->subdirs = NULL; - d->fullpath = strdup(src); + d->fullpath = stb_p_strdup(src); s = stb_strrchr2(d->fullpath, '/', '\\'); if (s) ++s; @@ -6293,11 +6364,11 @@ stb_dirtree2 *stb_dirtree2_from_files_relative(char *src, char **filelist, int c char *s = descendents[i] + elen, *t; t = stb_strchr2(s, '/', '\\'); assert(t); - stb_strncpy(buffer2, descendents[i], t-descendents[i]+1); + stb_strncpy(buffer2, descendents[i], (int) (t-descendents[i]+1)); if (stb_stricmp(buffer1, buffer2)) { stb_dirtree2 *t = stb_dirtree2_from_files_relative(buffer2, descendents, stb_arr_len(descendents)); assert(t != NULL); - strcpy(buffer1, buffer2); + stb_p_strcpy_s(buffer1, sizeof(buffer1), buffer2); stb_arr_push(d->subdirs, t); } } @@ -6308,7 +6379,7 @@ stb_dirtree2 *stb_dirtree2_from_files_relative(char *src, char **filelist, int c stb_dirtree2 *stb_dirtree2_from_files(char **filelist, int count) { - return stb_dirtree2_from_files_relative("", filelist, count); + return stb_dirtree2_from_files_relative((char*) "", filelist, count); } #endif @@ -6519,7 +6590,7 @@ int stb_sha1_file(stb_uchar output[20], char *file) h[4] = 0xc3d2e1f0; for(;;) { - int n = fread(buffer, 1, 64, f); + size_t n = fread(buffer, 1, 64, f); if (n == 64) { stb__sha1(buffer, h); length += n; @@ -6601,12 +6672,12 @@ void stb_sha1_readable(char display[27], unsigned char sha[20]) #if defined(_WIN32) -STB_EXTERN void * stb_reg_open(char *mode, char *where); // mode: "rHKLM" or "rHKCU" or "w.." +STB_EXTERN void * stb_reg_open(const char *mode, const char *where); // mode: "rHKLM" or "rHKCU" or "w.." STB_EXTERN void stb_reg_close(void *reg); -STB_EXTERN int stb_reg_read(void *zreg, char *str, void *data, unsigned long len); -STB_EXTERN int stb_reg_read_string(void *zreg, char *str, char *data, int len); -STB_EXTERN void stb_reg_write(void *zreg, char *str, void *data, unsigned long len); -STB_EXTERN void stb_reg_write_string(void *zreg, char *str, char *data); +STB_EXTERN int stb_reg_read(void *zreg, const char *str, void *data, unsigned long len); +STB_EXTERN int stb_reg_read_string(void *zreg, const char *str, char *data, int len); +STB_EXTERN void stb_reg_write(void *zreg, const char *str, const void *data, unsigned long len); +STB_EXTERN void stb_reg_write_string(void *zreg, const char *str, const char *data); #if defined(STB_DEFINE) && !defined(STB_NO_REGISTRY) @@ -6642,7 +6713,7 @@ STB_EXTERN __declspec(dllimport) long __stdcall RegOpenKeyExA ( HKEY hKey, cons #define STB__HKEY_LOCAL_MACHINE 0x80000002 #endif -void *stb_reg_open(char *mode, char *where) +void *stb_reg_open(const char *mode, const char *where) { long res; HKEY base; @@ -6673,7 +6744,7 @@ void stb_reg_close(void *reg) #define STB__REG_BINARY 3 #define STB__REG_DWORD 4 -int stb_reg_read(void *zreg, char *str, void *data, unsigned long len) +int stb_reg_read(void *zreg, const char *str, void *data, unsigned long len) { unsigned long type; unsigned long alen = len; @@ -6686,23 +6757,23 @@ int stb_reg_read(void *zreg, char *str, void *data, unsigned long len) return 0; } -void stb_reg_write(void *zreg, char *str, void *data, unsigned long len) +void stb_reg_write(void *zreg, const char *str, const void *data, unsigned long len) { if (zreg) RegSetValueExA((HKEY) zreg, str, 0, STB__REG_BINARY, (const unsigned char *) data, len); } -int stb_reg_read_string(void *zreg, char *str, char *data, int len) +int stb_reg_read_string(void *zreg, const char *str, char *data, int len) { if (!stb_reg_read(zreg, str, data, len)) return 0; data[len-1] = 0; // force a 0 at the end of the string no matter what return 1; } -void stb_reg_write_string(void *zreg, char *str, char *data) +void stb_reg_write_string(void *zreg, const char *str, const char *data) { if (zreg) - RegSetValueExA((HKEY) zreg, str, 0, STB__REG_SZ, (const unsigned char *) data, strlen(data)+1); + RegSetValueExA((HKEY) zreg, str, 0, STB__REG_SZ, (const unsigned char *) data, (int) strlen(data)+1); } #endif // STB_DEFINE #endif // _WIN32 @@ -6718,7 +6789,7 @@ void stb_reg_write_string(void *zreg, char *str, char *data) #ifndef STB_NO_STB_STRINGS typedef struct stb_cfg_st stb_cfg; -STB_EXTERN stb_cfg * stb_cfg_open(char *config, char *mode); // mode = "r", "w" +STB_EXTERN stb_cfg * stb_cfg_open(char *config, const char *mode); // mode = "r", "w" STB_EXTERN void stb_cfg_close(stb_cfg *cfg); STB_EXTERN int stb_cfg_read(stb_cfg *cfg, char *key, void *value, int len); STB_EXTERN void stb_cfg_write(stb_cfg *cfg, char *key, void *value, int len); @@ -6743,14 +6814,14 @@ struct stb_cfg_st FILE *f; // write the data to this file on close }; -static char *stb__cfg_sig = "sTbCoNfIg!\0\0"; +static const char *stb__cfg_sig = "sTbCoNfIg!\0\0"; static char stb__cfg_dir[512]; STB_EXTERN void stb_cfg_set_directory(char *dir) { - strcpy(stb__cfg_dir, dir); + stb_p_strcpy_s(stb__cfg_dir, sizeof(stb__cfg_dir), dir); } -STB_EXTERN stb_cfg * stb_cfg_open(char *config, char *mode) +STB_EXTERN stb_cfg * stb_cfg_open(char *config, const char *mode) { size_t len; stb_cfg *z; @@ -6759,7 +6830,7 @@ STB_EXTERN stb_cfg * stb_cfg_open(char *config, char *mode) if (!stb__cfg_dir[0]) { #ifdef _WIN32 - strcpy(stb__cfg_dir, "c:/stb"); + stb_p_strcpy_s(stb__cfg_dir, sizeof(stb__cfg_dir), "c:/stb"); #else strcpy(stb__cfg_dir, "~/.stbconfig"); #endif @@ -6775,7 +6846,7 @@ STB_EXTERN stb_cfg * stb_cfg_open(char *config, char *mode) #endif } - sprintf(file, "%s/%s.cfg", stb__cfg_dir, config); + stb_p_sprintf(file stb_p_size(sizeof(file)), "%s/%s.cfg", stb__cfg_dir, config); z = (stb_cfg *) stb_malloc(0, sizeof(*z)); z->data = NULL; @@ -6801,7 +6872,7 @@ STB_EXTERN stb_cfg * stb_cfg_open(char *config, char *mode) } if (mode[0] == 'w') - z->f = fopen(file, "wb"); + z->f = stb_p_fopen(file, "wb"); else z->f = NULL; @@ -6815,7 +6886,7 @@ void stb_cfg_close(stb_cfg *z) // write the file out fwrite(stb__cfg_sig, 12, 1, z->f); for (i=0; i < stb_arr_len(z->data); ++i) { - stb_int16 n = strlen(z->data[i].key)+1; + stb_int16 n = (stb_int16) strlen(z->data[i].key)+1; fwrite(&n, 2, 1, z->f); fwrite(z->data[i].key, n, 1, z->f); fwrite(&z->data[i].value_len, 4, 1, z->f); @@ -6880,7 +6951,7 @@ int stb_cfg_read_string(stb_cfg *z, char *key, char *value, int len) void stb_cfg_write_string(stb_cfg *z, char *key, char *value) { - stb_cfg_write(z, key, value, strlen(value)+1); + stb_cfg_write(z, key, value, (int) strlen(value)+1); } #endif @@ -6971,9 +7042,9 @@ static char stb__signature[12] = { 's', 'T', 'b', 'D', 'i', 'R', 't', 'R', 'e', static void stb__dirtree_save_db(char *filename, stb_dirtree *data, char *root) { int i, num_dirs_final=0, num_files_final; - char *info = root ? root : ""; + char *info = root ? root : (char*)""; int *remap; - FILE *f = fopen(filename, "wb"); + FILE *f = stb_p_fopen(filename, "wb"); if (!f) return; fwrite(stb__signature, sizeof(stb__signature), 1, f); @@ -7021,7 +7092,7 @@ static void stb__dirtree_load_db(char *filename, stb_dirtree *data, char *dir) { char sig[2048]; int i,n; - FILE *f = fopen(filename, "rb"); + FILE *f = stb_p_fopen(filename, "rb"); if (!f) return; @@ -7078,7 +7149,8 @@ static void stb__dirtree_scandir(char *path, time_t last_time, stb_dirtree *acti has_slash = (path[0] && path[strlen(path)-1] == '/'); // @TODO: do this concatenation without using swprintf to avoid this mess: -#if defined(_MSC_VER) && _MSC_VER < 1400 +#if (defined(_MSC_VER) && _MSC_VER < 1400) // || (defined(__clang__)) + // confusingly, Windows Kits\10 goes down this path?!? if (has_slash) swprintf(full_path, L"%s*", stb__from_utf8(path)); else @@ -7105,7 +7177,7 @@ static void stb__dirtree_scandir(char *path, time_t last_time, stb_dirtree *acti n = stb_arr_lastn(active->dirs); if (stb__showfile) printf("["); - if( (hFile = _wfindfirsti64( (wchar_t *) full_path, &c_file )) != -1L ) { + if( (hFile = (long) _wfindfirsti64( (wchar_t *) full_path, &c_file )) != -1L ) { do { if (stb__showfile) printf(")"); if (c_file.attrib & _A_SUBDIR) { @@ -7115,9 +7187,9 @@ static void stb__dirtree_scandir(char *path, time_t last_time, stb_dirtree *acti char *temp = stb__to_utf8((stb__wchar *) c_file.name); if (has_slash) - sprintf(new_path, "%s%s", path, temp); + stb_p_sprintf(new_path stb_p_size(sizeof(full_path)), "%s%s", path, temp); else - sprintf(new_path, "%s/%s", path, temp); + stb_p_sprintf(new_path stb_p_size(sizeof(full_path)), "%s/%s", path, temp); if (stb__dircount_mask) { ++stb__dircount; @@ -7125,8 +7197,8 @@ static void stb__dirtree_scandir(char *path, time_t last_time, stb_dirtree *acti char dummy_path[128], *pad; stb_strncpy(dummy_path, new_path, sizeof(dummy_path)-1); if (strlen(dummy_path) > 96) { - strcpy(dummy_path+96/2-1, "..."); - strcpy(dummy_path+96/2+2, new_path + strlen(new_path)-96/2+2); + stb_p_strcpy_s(dummy_path+96/2-1,128, "..."); + stb_p_strcpy_s(dummy_path+96/2+2,128, new_path + strlen(new_path)-96/2+2); } pad = dummy_path + strlen(dummy_path); while (pad < dummy_path+98) @@ -7135,7 +7207,7 @@ static void stb__dirtree_scandir(char *path, time_t last_time, stb_dirtree *acti printf("%s\r", dummy_path); #if 0 if (hlog == 0) { - hlog = fopen("c:/x/temp.log", "w"); + hlog = stb_p_fopen("c:/x/temp.log", "w"); fprintf(hlog, "%s\n", dummy_path); } #endif @@ -7257,7 +7329,7 @@ stb_dirtree *stb_dirtree_get_with_file(char *dir, char *cache_file) db.files = NULL; db.dirs = NULL; - stripped_dir = stb_strip_final_slash(strdup(dir)); + stripped_dir = stb_strip_final_slash(stb_p_strdup(dir)); if (cache_file != NULL) stb__dirtree_load_db(cache_file, &db, stripped_dir); @@ -7303,28 +7375,28 @@ stb_dirtree *stb_dirtree_get_dir(char *dir, char *cache_dir) char cache_file[1024],*s; if (cache_dir == NULL) return stb_dirtree_get_with_file(dir, NULL); - strcpy(dir_lower, dir); + stb_p_strcpy_s(dir_lower, sizeof(dir_lower), dir); stb_tolower(dir_lower); - stb_sha1(sha, (unsigned char *) dir_lower, strlen(dir_lower)); - strcpy(cache_file, cache_dir); + stb_sha1(sha, (unsigned char *) dir_lower, (unsigned int) strlen(dir_lower)); + stb_p_strcpy_s(cache_file, sizeof(cache_file), cache_dir); s = cache_file + strlen(cache_file); - if (s[-1] != '//' && s[-1] != '\\') *s++ = '/'; - strcpy(s, "dirtree_"); + if (s[-1] != '/' && s[-1] != '\\') *s++ = '/'; + stb_p_strcpy_s(s, sizeof(cache_file), "dirtree_"); s += strlen(s); for (i=0; i < 8; ++i) { - char *hex = "0123456789abcdef"; + char *hex = (char*)"0123456789abcdef"; stb_uint z = sha[i]; *s++ = hex[z >> 4]; *s++ = hex[z & 15]; } - strcpy(s, ".bin"); + stb_p_strcpy_s(s, sizeof(cache_file), ".bin"); return stb_dirtree_get_with_file(dir, cache_file); } stb_dirtree *stb_dirtree_get(char *dir) { char cache_dir[256]; - strcpy(cache_dir, "c:/bindata"); + stb_p_strcpy_s(cache_dir, sizeof(cache_dir), "c:/bindata"); #ifdef STB_HAS_REGISTRY { void *reg = stb_reg_open("rHKLM", "Software\\SilverSpaceship\\stb"); @@ -7355,7 +7427,7 @@ void stb_dirtree_db_add_file(stb_dirtree *active, char *name, int dir, stb_int64 void stb_dirtree_db_read(stb_dirtree *target, char *filename, char *dir) { - char *s = stb_strip_final_slash(strdup(dir)); + char *s = stb_strip_final_slash(stb_p_strdup(dir)); target->dirs = 0; target->files = 0; target->string_pool = 0; @@ -7390,7 +7462,7 @@ typedef struct void *p; char *file; int line; - int size; + size_t size; } stb_malloc_record; #ifndef STB_MALLOC_HISTORY_COUNT @@ -7420,7 +7492,7 @@ static int stb__hashfind(void *p) } } -int stb_wrapper_allocsize(void *p) +size_t stb_wrapper_allocsize(void *p) { int n = stb__hashfind(p); if (n < 0) return 0; @@ -7439,7 +7511,7 @@ static int stb__historyfind(void *p) return -1; } -static void stb__add_alloc(void *p, int sz, char *file, int line); +static void stb__add_alloc(void *p, size_t sz, char *file, int line); static void stb__grow_alloc(void) { int i,old_num = stb__alloc_size; @@ -7469,7 +7541,7 @@ static void stb__grow_alloc(void) stb__realloc_raw(old, 0); } -static void stb__add_alloc(void *p, int sz, char *file, int line) +static void stb__add_alloc(void *p, size_t sz, char *file, int line) { stb_uint32 h; int n; @@ -7502,7 +7574,7 @@ static void stb__remove_alloc(int n, char *file, int line) --stb__alloc_count; } -void stb_wrapper_malloc(void *p, int sz, char *file, int line) +void stb_wrapper_malloc(void *p, size_t sz, char *file, int line) { if (!p) return; stb__add_alloc(p,sz,file,line); @@ -7555,7 +7627,7 @@ void stb_wrapper_check(void *p) stb_fatal("Checked unknown block %p"); } -void stb_wrapper_realloc(void *p, void *q, int sz, char *file, int line) +void stb_wrapper_realloc(void *p, void *q, size_t sz, char *file, int line) { int n; if (p == NULL) { stb_wrapper_malloc(q, sz, file, line); return; } @@ -7586,7 +7658,7 @@ void stb_wrapper_realloc(void *p, void *q, int sz, char *file, int line) } } -void stb_wrapper_listall(void (*func)(void *ptr, int sz, char *file, int line)) +void stb_wrapper_listall(void (*func)(void *ptr, size_t sz, char *file, int line)) { int i; for (i=0; i < stb__alloc_size; ++i) @@ -7598,12 +7670,12 @@ void stb_wrapper_listall(void (*func)(void *ptr, int sz, char *file, int line)) void stb_wrapper_dump(char *filename) { int i; - FILE *f = fopen(filename, "w"); + FILE *f = stb_p_fopen(filename, "w"); if (!f) return; for (i=0; i < stb__alloc_size; ++i) if (stb__allocations[i].p > STB_DEL) fprintf(f, "%p %7d - %4d %s\n", - stb__allocations[i].p , stb__allocations[i].size, + stb__allocations[i].p , (int) stb__allocations[i].size, stb__allocations[i].line, stb__allocations[i].file); } #endif // STB_DEFINE @@ -8329,7 +8401,7 @@ void stb_shuffle(void *p, size_t n, size_t sz, unsigned int seed) old_seed = stb_srandLCG(seed); a = (char *) p + (n-1) * sz; - for (i=n; i > 1; --i) { + for (i=(int) n; i > 1; --i) { int j = stb_randLCG() % i; stb_swap(a, (char *) p + j * sz, sz); a -= sz; @@ -8340,7 +8412,7 @@ void stb_shuffle(void *p, size_t n, size_t sz, unsigned int seed) void stb_reverse(void *p, size_t n, size_t sz) { - int i,j = n-1; + size_t i,j = n-1; for (i=0; i < j; ++i,--j) { stb_swap((char *) p + i * sz, (char *) p + j * sz, sz); } @@ -9002,8 +9074,8 @@ STB_EXTERN int stb_matcher_find(stb_matcher *m, char *str); STB_EXTERN void stb_matcher_free(stb_matcher *f); STB_EXTERN stb_matcher *stb_lex_matcher(void); -STB_EXTERN int stb_lex_item(stb_matcher *m, char *str, int result); -STB_EXTERN int stb_lex_item_wild(stb_matcher *matcher, char *regex, int result); +STB_EXTERN int stb_lex_item(stb_matcher *m, const char *str, int result); +STB_EXTERN int stb_lex_item_wild(stb_matcher *matcher, const char *regex, int result); STB_EXTERN int stb_lex(stb_matcher *m, char *str, int *len); @@ -9156,7 +9228,7 @@ int stb__wildmatch_raw(char *expr, char *candidate, int search, int insensitive) int z; // need to allow for non-writeable strings... assume they're small if (s - last < 256) { - stb_strncpy(buffer, last, s-last+1); + stb_strncpy(buffer, last, (int) (s-last+1)); z = stb__wildmatch_raw2(buffer, candidate, search, insensitive); } else { *s = 0; @@ -9360,7 +9432,7 @@ static char *stb__reg_parse(stb_matcher *matcher, int start, char *regex, stb_ui // leading ] is special if (*regex == ']') { - flags[']'] = 1; + flags[(int) ']'] = 1; ++regex; } while (*regex != ']') { @@ -9599,12 +9671,12 @@ stb_matcher *stb_lex_matcher(void) return matcher; } -int stb_lex_item(stb_matcher *matcher, char *regex, int result) +int stb_lex_item(stb_matcher *matcher, const char *regex, int result) { char *z; stb_uint16 end; - z = stb__reg_parse_alt(matcher, matcher->start_node, regex, &end); + z = stb__reg_parse_alt(matcher, matcher->start_node, (char*) regex, &end); if (z == NULL) return 0; @@ -9615,12 +9687,12 @@ int stb_lex_item(stb_matcher *matcher, char *regex, int result) return 1; } -int stb_lex_item_wild(stb_matcher *matcher, char *regex, int result) +int stb_lex_item_wild(stb_matcher *matcher, const char *regex, int result) { char *z; stb_uint16 end; - z = stb__wild_parse(matcher, matcher->start_node, regex, &end); + z = stb__wild_parse(matcher, matcher->start_node, (char*) regex, &end); if (z == NULL) return 0; @@ -9857,7 +9929,7 @@ static int stb__matcher_dfa(stb_matcher *m, char *str_c, int *len) // special case for lex: need _longest_ match, so notice goal // state without stopping if (node <= STB__DFA_MGOAL) { - match_length = str - (stb_uint8 *) str_c; + match_length = (int) (str - (stb_uint8 *) str_c); node = -(node - STB__DFA_MGOAL); match_result = node; continue; @@ -9916,7 +9988,7 @@ static int stb__matcher_dfa(stb_matcher *m, char *str_c, int *len) // if it's a goal state, then that's all there is to it if (stb__clear_goalcheck(m, newstates)) { if (m->does_lex) { - match_length = str - (stb_uint8 *) str_c; + match_length = (int) (str - (stb_uint8 *) str_c); node = stb__get_dfa_node(m,newstates); match_result = node; node = -node + STB__DFA_MGOAL; @@ -9979,7 +10051,7 @@ int stb_regex(char *regex, char *str) stb_matcher_free(matchers[i]); free(regexp_cache[i]); regexps[i] = regex; - regexp_cache[i] = strdup(regex); + regexp_cache[i] = stb_p_strdup(regex); matchers[i] = stb_regex_matcher(regex); } } else { @@ -9997,7 +10069,7 @@ int stb_regex(char *regex, char *str) return -1; } stb_arr_push(regexps, regex); - stb_arr_push(regexp_cache, strdup(regex)); + stb_arr_push(regexp_cache, stb_p_strdup(regex)); stb_arr_push(matchers, stb_regex_matcher(regex)); stb_perfect_destroy(&p); n = stb_perfect_create(&p, (unsigned int *) (char **) regexps, stb_arr_len(regexps)); @@ -10077,9 +10149,9 @@ void stb_introspect_precompiled(stb_info_struct *compiled) static void stb__introspect_filename(char *buffer, char *path) { #if STB_INTROSPECT_CPP - sprintf(buffer, "%s/stb_introspect.cpp", path); + stb_p_sprintf(buffer stb_p_size(9999), "%s/stb_introspect.cpp", path); #else - sprintf(buffer, "%s/stb_introspect.c", path); + stb_p_sprintf(buffer stb_p_size(9999), "%s/stb_introspect.c", path); #endif } @@ -10089,7 +10161,7 @@ static void stb__introspect_compute(char *path, char *file) char ** include_list = NULL; char ** introspect_list = NULL; FILE *f; - f = fopen(file, "w"); + f = stb_p_fopen(file, "w"); if (!f) return; fputs("// if you get compiler errors, change the following 0 to a 1:\n", f); @@ -10188,7 +10260,7 @@ void stb__introspect(char *path, char *file, stb_info_struct *compiled) } } if (found) - stb_arr_push(introspect_h, strdup(all[i])); + stb_arr_push(introspect_h, stb_p_strdup(all[i])); free(z); } } @@ -10392,7 +10464,7 @@ char *stb_decompress_fromfile(char *filename, unsigned int *len) unsigned int n; char *q; unsigned char *p; - FILE *f = fopen(filename, "rb"); if (f == NULL) return NULL; + FILE *f = stb_p_fopen(filename, "rb"); if (f == NULL) return NULL; fseek(f, 0, SEEK_END); n = ftell(f); fseek(f, 0, SEEK_SET); @@ -10510,7 +10582,7 @@ static void stb_out3(stb_uint v) { stb_out(v >> 16); stb_out(v >> 8); stb_out(v) static void stb_out4(stb_uint v) { stb_out(v >> 24); stb_out(v >> 16); stb_out(v >> 8 ); stb_out(v); } -static void outliterals(stb_uchar *in, int numlit) +static void outliterals(stb_uchar *in, ptrdiff_t numlit) { while (numlit > 65536) { outliterals(in,65536); @@ -10519,9 +10591,9 @@ static void outliterals(stb_uchar *in, int numlit) } if (numlit == 0) ; - else if (numlit <= 32) stb_out (0x000020 + numlit-1); - else if (numlit <= 2048) stb_out2(0x000800 + numlit-1); - else /* numlit <= 65536) */ stb_out3(0x070000 + numlit-1); + else if (numlit <= 32) stb_out (0x000020 + (stb_uint) numlit-1); + else if (numlit <= 2048) stb_out2(0x000800 + (stb_uint) numlit-1); + else /* numlit <= 65536) */ stb_out3(0x070000 + (stb_uint) numlit-1); if (stb__out) { memcpy(stb__out,in,numlit); @@ -10586,17 +10658,17 @@ static int stb_compress_chunk(stb_uchar *history, int best = 2, dist=0; if (q+65536 > end) - match_max = end-q; + match_max = (stb_uint) (end-q); else - match_max = 65536; + match_max = 65536u; #define stb__nc(b,d) ((d) <= window && ((b) > 9 || stb_not_crap(b,d))) #define STB__TRY(t,p) /* avoid retrying a match we already tried */ \ - if (p ? dist != q-t : 1) \ - if ((m = stb_matchlen(t, q, match_max)) > best) \ - if (stb__nc(m,q-(t))) \ - best = m, dist = q - (t) + if (p ? dist != (int) (q-t) : 1) \ + if ((m = (int) stb_matchlen(t, q, match_max)) > best)\ + if (stb__nc(m,(int) (q-(t)))) \ + best = m, dist = (int) (q - (t)) // rather than search for all matches, only try 4 candidate locations, // chosen based on 4 different hash functions of different lengths. @@ -10659,10 +10731,10 @@ static int stb_compress_chunk(stb_uchar *history, q = start+length; // the literals are everything from lit_start to q - *pending_literals = (q - lit_start); + *pending_literals = (int) (q - lit_start); - stb__running_adler = stb_adler32(stb__running_adler, start, q - start); - return q - start; + stb__running_adler = stb_adler32(stb__running_adler, start, (int) (q - start)); + return (int) (q - start); } static int stb_compress_inner(stb_uchar *input, stb_uint length) @@ -10707,7 +10779,7 @@ stb_uint stb_compress(stb_uchar *out, stb_uchar *input, stb_uint length) stb_compress_inner(input, length); - return stb__out - out; + return (stb_uint) (stb__out - out); } int stb_compress_tofile(char *filename, char *input, unsigned int length) @@ -10717,7 +10789,7 @@ int stb_compress_tofile(char *filename, char *input, unsigned int length) //int blen = stb_compress((stb_uchar*)buffer, (stb_uchar*)input, length); stb__out = NULL; - stb__outfile = fopen(filename, "wb"); + stb__outfile = stb_p_fopen(filename, "wb"); if (!stb__outfile) return 0; stb__outbytes = 0; @@ -10761,13 +10833,12 @@ static size_t stb_out_backpatch_id(void) static void stb_out_backpatch(size_t id, stb_uint value) { - - stb_uchar data[4] = { (stb_uchar)(value >> 24), (stb_uchar)(value >> 16), (stb_uchar)(value >> 8), (stb_uchar)(value) }; + stb_uchar data[4] = { (stb_uchar)(value >> 24), (stb_uchar)(value >> 16), (stb_uchar)(value >> 8), (stb_uchar)(value) }; if (stb__out) { memcpy((void *) id, data, 4); } else { stb_uint where = ftell(stb__outfile); - fseek(stb__outfile, id, SEEK_SET); + fseek(stb__outfile, (long) id, SEEK_SET); fwrite(data, 4, 1, stb__outfile); fseek(stb__outfile, where, SEEK_SET); } @@ -10827,7 +10898,7 @@ static int stb_compress_streaming_start(void) stb_out4(0); // 64-bit length requires 32-bit leading 0 - xtb.length_id = stb_out_backpatch_id(); + xtb.length_id = (int) stb_out_backpatch_id(); stb_out4(0); // we don't know the output length yet stb_out4(stb__window); @@ -11013,10 +11084,10 @@ void stb_backpatch(stbfile *f, unsigned int tell, void *buffer, unsigned int len // FILE * implementation static int stb__fgetbyte(stbfile *f) { return fgetc(f->f); } static int stb__fputbyte(stbfile *f, int ch) { return fputc(ch, f->f)==0; } -static unsigned int stb__fgetdata(stbfile *f, void *buffer, unsigned int len) { return fread(buffer,1,len,f->f); } -static unsigned int stb__fputdata(stbfile *f, void *buffer, unsigned int len) { return fwrite(buffer,1,len,f->f); } -static unsigned int stb__fsize(stbfile *f) { return stb_filelen(f->f); } -static unsigned int stb__ftell(stbfile *f) { return ftell(f->f); } +static unsigned int stb__fgetdata(stbfile *f, void *buffer, unsigned int len) { return (unsigned int) fread(buffer,1,len,f->f); } +static unsigned int stb__fputdata(stbfile *f, void *buffer, unsigned int len) { return (unsigned int) fwrite(buffer,1,len,f->f); } +static unsigned int stb__fsize(stbfile *f) { return (unsigned int) stb_filelen(f->f); } +static unsigned int stb__ftell(stbfile *f) { return (unsigned int) ftell(f->f); } static void stb__fbackpatch(stbfile *f, unsigned int where, void *buffer, unsigned int len) { fseek(f->f, where, SEEK_SET); @@ -11056,13 +11127,13 @@ static int stb__bgetbyte(stbfile *s) static unsigned int stb__bgetdata(stbfile *s, void *buffer, unsigned int len) { if (s->indata + len > s->inend) - len = s->inend - s->indata; + len = (unsigned int) (s->inend - s->indata); memcpy(buffer, s->indata, len); s->indata += len; return len; } -static unsigned int stb__bsize(stbfile *s) { return s->inend - s->buffer; } -static unsigned int stb__btell(stbfile *s) { return s->indata - s->buffer; } +static unsigned int stb__bsize(stbfile *s) { return (unsigned int) (s->inend - s->buffer); } +static unsigned int stb__btell(stbfile *s) { return (unsigned int) (s->indata - s->buffer); } static void stb__bclose(stbfile *s) { @@ -11103,7 +11174,7 @@ static void stb__fclose2(stbfile *f) stbfile *stb_open(char *filename, char *mode) { - FILE *f = fopen(filename, mode); + FILE *f = stb_p_fopen(filename, mode); stbfile *s; if (f == NULL) return NULL; s = stb_openf(f); @@ -11355,96 +11426,6 @@ stbfile *stb_arith_decode_close(stb_arith *a) { return a->output; } - -// this is a simple power-of-two based model -- using -// power of two means we need one divide per decode, -// not two. -#define POW2_LIMIT 12 -stb_arith_symstate *stb_arith_state_create(int num_sym) -{ - stb_arith_symstate *s = (stb_arith_symstate *) malloc(sizeof(*s) + (num_sym-1) * sizeof(s->data[0])); - if (s) { - int i, cf, cf_next, next; - int start_freq, extra; - s->num_sym = num_sym; - s->pow2 = 4; - while (s->pow2 < 15 && (1 << s->pow2) < 3*num_sym) { - ++s->pow2; - } - start_freq = (1 << s->pow2) / num_sym; - assert(start_freq >= 1); - extra = (1 << s->pow2) % num_sym; - // now set up the initial stats - - if (s->pow2 < POW2_LIMIT) - next = 0; - else - next = 1; - - cf = cf_next = 0; - for (i=0; i < extra; ++i) { - s->data[i].cumfreq = cf; - s->data[i].samples = next; - cf += start_freq+1; - cf_next += next; - } - for (; i < num_sym; ++i) { - s->data[i].cumfreq = cf; - s->data[i].samples = next; - cf += start_freq; - cf_next += next; - } - assert(cf == (1 << s->pow2)); - // now, how long should we go until we have 2 << s->pow2 samples? - s->countdown = (2 << s->pow2) - cf - cf_next; - } - return s; -} - -static void stb_arith_state_rescale(stb_arith_symstate *s) -{ - if (s->pow2 < POW2_LIMIT) { - int pcf, cf, cf_next, next, i; - ++s->pow2; - if (s->pow2 < POW2_LIMIT) - next = 0; - else - next = 1; - cf = cf_next = 0; - pcf = 0; - for (i=0; i < s->num_sym; ++i) { - int sample = s->data[i].cumfreq - pcf + s->data[i].samples; - s->data[i].cumfreq = cf; - cf += sample; - s->data[i].samples = next; - cf_next += next; - } - assert(cf == (1 << s->pow2)); - s->countdown = (2 << s->pow2) - cf - cf_next; - } else { - int pcf, cf, cf_next, i; - cf = cf_next = 0; - pcf = 0; - for (i=0; i < s->num_sym; ++i) { - int sample = (s->data[i].cumfreq - pcf + s->data[i].samples) >> 1; - s->data[i].cumfreq = cf; - cf += sample; - s->data[i].samples = 1; - cf_next += 1; - } - assert(cf == (1 << s->pow2)); // this isn't necessarily true, due to rounding down! - s->countdown = (2 << s->pow2) - cf - cf_next; - } -} - -void stb_arith_encode_byte(stb_arith *a, int byte) -{ -} - -int stb_arith_decode_byte(stb_arith *a) -{ - return -1; -} #endif ////////////////////////////////////////////////////////////////////////////// @@ -12401,7 +12382,7 @@ int stb__io_add(char *fname, FILE *f, int off, int len, stb_uchar *out, stb_ucha int res; stb__io_init(); // do memory allocation outside of mutex - if (fname) fname = strdup(fname); + if (fname) fname = stb_p_strdup(fname); stb_mutex_begin(stb__diskio_mutex); { stb__disk_command *dc = &stb__dc_queue[stb__dc_offset]; @@ -12847,7 +12828,7 @@ char *stb_sstrdup(char *s) { int n = strlen(s); char *p = (char *) stb_smalloc(n+1); - if (p) strcpy(p,s); + if (p) stb_p_strcpy_s(p,n+1,s); return p; } #endif // STB_DEFINE @@ -12893,13 +12874,13 @@ char *stb__get_sourcefile_path(char *file) { static char filebuf[512]; if (stb__source_path) { - sprintf(filebuf, "%s/%s", stb__source_path, file); + stb_p_sprintf(filebuf stb_p_size(sizeof(filebuf)), "%s/%s", stb__source_path, file); if (stb_fexists(filebuf)) return filebuf; } if (stb_fexists(file)) return file; - sprintf(filebuf, "../%s", file); + stb_p_sprintf(filebuf stb_p_size(sizeof(filebuf)), "../%s", file); if (!stb_fexists(filebuf)) return filebuf; return file; @@ -13018,7 +12999,7 @@ stb__Entry *stb__constant_get_entry(char *filename, int line, int type) f = (stb__FileEntry *) malloc(sizeof(*f)); f->timestamp = stb_ftimestamp(s); f->file_data = stb_stringfile(s, &f->file_len); - f->filename = strdup(s); // cache the full path + f->filename = stb_p_strdup(s); // cache the full path f->entries = NULL; f->line_index = 0; stb_arr_setlen(f->line_index, f->file_len); @@ -13482,7 +13463,7 @@ stua_obj stua_error(char *z, ...) stua_obj a; char temp[4096], *x; va_list v; va_start(v,z); vsprintf(temp, z, v); va_end(v); - x = strdup(temp); + x = stb_p_strdup(temp); a = stua_box(STU___error, x, strlen(x)); stu__flow = FLOW_error; stu__flow_val = a; diff --git a/stb_c_lexer.h b/stb_c_lexer.h index b587ca7..f370b48 100644 --- a/stb_c_lexer.h +++ b/stb_c_lexer.h @@ -514,7 +514,7 @@ static int stb__clex_parse_string(stb_lexer *lexer, char *p, int type) } *out = 0; lexer->string = lexer->string_storage; - lexer->string_len = out - lexer->string_storage; + lexer->string_len = (int) (out - lexer->string_storage); return stb__clex_token(lexer, type, start, p); } @@ -824,7 +824,7 @@ int stb_c_lexer_get_token(stb_lexer *lexer) #endif // STB_C_LEXER_IMPLEMENTATION #ifdef STB_C_LEXER_SELF_TEST - +#define _CRT_SECURE_NO_WARNINGS #include #include @@ -884,11 +884,12 @@ void dummy(void) { double some_floats[] = { 1.0501, -10.4e12, 5E+10, -#if 0 // not support in C++ or C-pre-99, so don't try to compile it +#if 0 // not supported in C++ or C-pre-99, so don't try to compile it, but let our parser test it 0x1.0p+24, 0xff.FP-8, 0x1p-23, #endif 4. }; + (void) sizeof(some_floats); printf("test %d",1); // https://github.com/nothings/stb/issues/13 } @@ -897,7 +898,7 @@ int main(int argc, char **argv) { FILE *f = fopen("stb_c_lexer.h","rb"); char *text = (char *) malloc(1 << 20); - int len = f ? fread(text, 1, 1<<20, f) : -1; + int len = f ? (int) fread(text, 1, 1<<20, f) : -1; stb_lexer lex; if (len < 0) { fprintf(stderr, "Error opening file\n"); diff --git a/stb_connected_components.h b/stb_connected_components.h index 4c358fb..9f78cd3 100644 --- a/stb_connected_components.h +++ b/stb_connected_components.h @@ -709,7 +709,7 @@ static void stbcc__remove_clump_connection(stbcc_grid *g, int x1, int y1, int x2 static void stbcc__add_connections_to_adjacent_cluster(stbcc_grid *g, int cx, int cy, int dx, int dy) { - unsigned char connected[STBCC__MAX_EDGE_CLUMPS_PER_CLUSTER][STBCC__MAX_EDGE_CLUMPS_PER_CLUSTER/8] = { 0 }; + unsigned char connected[STBCC__MAX_EDGE_CLUMPS_PER_CLUSTER][STBCC__MAX_EDGE_CLUMPS_PER_CLUSTER/8] = { { 0 } }; int x = cx * STBCC__CLUSTER_SIZE_X; int y = cy * STBCC__CLUSTER_SIZE_Y; int step_x, step_y=0, i, j, k, n; @@ -751,6 +751,7 @@ static void stbcc__add_connections_to_adjacent_cluster(stbcc_grid *g, int cx, in n = STBCC__CLUSTER_SIZE_X; } else { assert(0); + return; } for (k=0; k < n; ++k) { @@ -772,7 +773,7 @@ static void stbcc__add_connections_to_adjacent_cluster(stbcc_grid *g, int cx, in static void stbcc__remove_connections_to_adjacent_cluster(stbcc_grid *g, int cx, int cy, int dx, int dy) { - unsigned char disconnected[STBCC__MAX_EDGE_CLUMPS_PER_CLUSTER][STBCC__MAX_EDGE_CLUMPS_PER_CLUSTER/8] = { 0 }; + unsigned char disconnected[STBCC__MAX_EDGE_CLUMPS_PER_CLUSTER][STBCC__MAX_EDGE_CLUMPS_PER_CLUSTER/8] = { { 0 } }; int x = cx * STBCC__CLUSTER_SIZE_X; int y = cy * STBCC__CLUSTER_SIZE_Y; int step_x, step_y=0, i, j, k, n; @@ -811,6 +812,7 @@ static void stbcc__remove_connections_to_adjacent_cluster(stbcc_grid *g, int cx, n = STBCC__CLUSTER_SIZE_X; } else { assert(0); + return; } for (k=0; k < n; ++k) { @@ -954,11 +956,12 @@ static void stbcc__build_clumps_for_cluster(stbcc_grid *g, int cx, int cy) for (j=1; j < STBCC__CLUSTER_SIZE_Y-1; ++j) { for (i=1; i < STBCC__CLUSTER_SIZE_X-1; ++i) { stbcc__tinypoint p = cbi.parent[j][i]; - if (p.x == i && p.y == j) + if (p.x == i && p.y == j) { if (STBCC__MAP_OPEN(g,x+i,y+j)) cbi.label[j][i] = label++; else cbi.label[j][i] = STBCC__NULL_CLUMPID; + } } } diff --git a/stb_ds.h b/stb_ds.h index fccc5f3..4972744 100644 --- a/stb_ds.h +++ b/stb_ds.h @@ -275,10 +275,10 @@ NOTES - HASH MAP * For compilers other than GCC and clang (e.g. Visual Studio), for hmput/hmget/hmdel and variants, the key must be an lvalue (so the macro can take the address of it). - For GCC and clang, extensions are used that eliminate this requirement if you're - using C99 and later or using C++. + Extensions are used that eliminate this requirement if you're using C99 and later + in GCC or clang, or if you're using C++ in GCC. - * To test for presence of a key in a hashmap, just do 'hmget(foo,key) >= 0'. + * To test for presence of a key in a hashmap, just do 'hmgeti(foo,key) >= 0'. * The iteration order of your data in the hashmap is determined solely by the order of insertions and deletions. In particular, if you never delete, new @@ -309,6 +309,10 @@ CREDITS Per Vognsen -- idea for hash table API/implementation */ +#ifdef STBDS_UNIT_TESTS +#define _CRT_SECURE_NO_WARNINGS +#endif + #ifndef INCLUDE_STB_DS_H #define INCLUDE_STB_DS_H @@ -419,7 +423,7 @@ extern void * stbds_shmode_func(size_t elemsize, int mode); #if __clang__ #define STBDS_ADDRESSOF(typevar, value) ((__typeof__(typevar)[1]){value}) // literal array decays to pointer to value #else - #define STBDS_ADDRESSOF(typevar, value) ((typeof(typevar)[]){value}) // literal array decays to pointer to value + #define STBDS_ADDRESSOF(typevar, value) ((typeof(typevar)[1]){value}) // literal array decays to pointer to value #endif #else #define STBDS_ADDRESSOF(typevar, value) &(value) @@ -596,6 +600,7 @@ template static T * stbds_shmode_func_wrapper(T *, size_t elemsize, int #include #ifndef STBDS_ASSERT +#define STBDS_ASSERT_WAS_UNDEFINED #define STBDS_ASSERT(x) ((void) 0) #endif @@ -651,10 +656,15 @@ void *stbds_arrgrowf(void *a, size_t elemsize, size_t addlen, size_t min_cap) // stbds_hm hash table implementation // -#define STBDS_CACHE_LINE_SIZE 64 +#ifdef STBDS_INTERNAL_SMALL_BUCKET +#define STBDS_BUCKET_LENGTH 4 +#else #define STBDS_BUCKET_LENGTH 8 -#define STBDS_BUCKET_SHIFT 3 +#endif + +#define STBDS_BUCKET_SHIFT (STBDS_BUCKET_LENGTH == 8 ? 3 : 2) #define STBDS_BUCKET_MASK (STBDS_BUCKET_LENGTH-1) +#define STBDS_CACHE_LINE_SIZE 64 #define STBDS_ALIGN_FWD(n,a) (((n) + (a) - 1) & ~((a)-1)) @@ -701,13 +711,12 @@ void stbds_rand_seed(size_t seed) static size_t stbds_probe_position(size_t hash, size_t slot_count, size_t slot_log2) { - #if 1 - size_t pos = (hash >> (STBDS_SIZE_T_BITS-slot_log2)); - STBDS_ASSERT(pos < slot_count); - return pos; - #else - return hash & (slot_count-1); + size_t pos; + pos = hash & (slot_count-1); + #ifdef STBDS_INTERNAL_BUCKET_START + pos &= ~STBDS_BUCKET_MASK; #endif + return pos; } static size_t stbds_log2(size_t slot_count) @@ -815,7 +824,6 @@ static stbds_hash_index *stbds_make_hash_index(size_t slot_count, stbds_hash_ind for (;;) { size_t limit,z; stbds_hash_bucket *bucket; - pos &= (t->slot_count-1); bucket = &t->storage[pos >> STBDS_BUCKET_SHIFT]; STBDS_STATS(++stbds_rehash_probes); @@ -838,6 +846,7 @@ static stbds_hash_index *stbds_make_hash_index(size_t slot_count, stbds_hash_ind pos += step; // quadratic probing step += STBDS_BUCKET_LENGTH; + pos &= (t->slot_count-1); } } done: @@ -942,7 +951,7 @@ static size_t stbds_siphash_bytes(void *p, size_t len, size_t seed) #ifdef STBDS_SIPHASH_2_4 return v0^v1^v2^v3; #else - return v1^v2^v3; // slightly stronger since v0^v3 in above cancels out final round operation + return v1^v2^v3; // slightly stronger since v0^v3 in above cancels out final round operation? I tweeted at the authors of SipHash about this but they didn't reply #endif } @@ -957,10 +966,11 @@ size_t stbds_hash_bytes(void *p, size_t len, size_t seed) unsigned int hash = d[0] | (d[1] << 8) | (d[2] << 16) | (d[3] << 24); #if 0 // HASH32-A Bob Jenkin's hash function w/o large constants - hash ^= seed ^ len; + hash ^= seed; hash -= (hash<<6); hash ^= (hash>>17); hash -= (hash<<9); + hash ^= seed; hash ^= (hash<<4); hash -= (hash<<3); hash ^= (hash<<10); @@ -969,22 +979,24 @@ size_t stbds_hash_bytes(void *p, size_t len, size_t seed) // HASH32-BB Bob Jenkin's presumably-accidental version of Thomas Wang hash with rotates turned into shifts. // Note that converting these back to rotates makes it run a lot slower, presumably due to collisions, so I'm // not really sure what's going on. - hash ^= seed ^ len; + hash ^= seed; hash = (hash ^ 61) ^ (hash >> 16); hash = hash + (hash << 3); hash = hash ^ (hash >> 4); hash = hash * 0x27d4eb2d; + hash ^= seed; hash = hash ^ (hash >> 15); #else // HASH32-C - Murmur3 + hash ^= seed; hash *= 0xcc9e2d51; hash = (hash << 17) | (hash >> 15); hash *= 0x1b873593; hash ^= seed; hash = (hash << 19) | (hash >> 13); hash = hash*5 + 0xe6546b64; - hash ^= len; hash ^= hash >> 16; hash *= 0x85ebca6b; + hash ^= seed; hash ^= hash >> 13; hash *= 0xc2b2ae35; hash ^= hash >> 16; @@ -1009,16 +1021,17 @@ size_t stbds_hash_bytes(void *p, size_t len, size_t seed) } else if (len == 8 && sizeof(size_t) == 8) { size_t hash = d[0] | (d[1] << 8) | (d[2] << 16) | (d[3] << 24); hash |= (size_t) (d[4] | (d[5] << 8) | (d[6] << 16) | (d[7] << 24)) << 16 << 16; // avoid warning if size_t == 4 - hash ^= seed ^ len; + hash ^= seed; hash = (~hash) + (hash << 21); hash ^= STBDS_ROTATE_RIGHT(hash,24); hash *= 265; hash ^= STBDS_ROTATE_RIGHT(hash,14); + hash ^= seed; hash *= 21; hash ^= STBDS_ROTATE_RIGHT(hash,28); hash += (hash << 31); hash = (~hash) + (hash << 18); - return hash^seed; + return hash; } else { return stbds_siphash_bytes(p,len,seed); } @@ -1275,6 +1288,8 @@ void * stbds_shmode_func(size_t elemsize, int mode) { void *a = stbds_arrgrowf(0, elemsize, 0, 1); stbds_hash_index *h; + memset(a, 0, elemsize); + stbds_header(a)->length = 1; stbds_header(a)->hash_table = h = (stbds_hash_index *) stbds_make_hash_index(STBDS_BUCKET_LENGTH, NULL); h->string.mode = mode; return STBDS_ARR_TO_HASH(a,elemsize); @@ -1435,6 +1450,9 @@ void stbds_strreset(stbds_string_arena *a) #ifdef STBDS_UNIT_TESTS #include +#ifdef STBDS_ASSERT_WAS_UNDEFINED +#undef STBDS_ASSERT +#endif #ifndef STBDS_ASSERT #define STBDS_ASSERT assert #include @@ -1445,7 +1463,11 @@ typedef struct { int key,b,c,d; } stbds_struct; static char buffer[256]; char *strkey(int n) { +#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__) + sprintf_s(buffer, sizeof(buffer), "test_%d", n); +#else sprintf(buffer, "test_%d", n); +#endif return buffer; } @@ -1588,9 +1610,10 @@ void stbds_unit_tests(void) for (i=0; i < testsize; i += 1) { stbds_struct s = { i,i*2,i*3,i*4 }; - stbds_struct t = { i,i*2,i*3,i*4 }; + stbds_struct t = { i,i*2,i*3+1,i*4 }; if (i & 1) STBDS_ASSERT(hmgets(map2, s.key).d == 0); else STBDS_ASSERT(hmgets(map2, s.key).d == i*4); + STBDS_ASSERT(hmget(map, t) == 0); } hmfree(map2); #endif diff --git a/stb_herringbone_wang_tile.h b/stb_herringbone_wang_tile.h index ba2cf60..d535122 100644 --- a/stb_herringbone_wang_tile.h +++ b/stb_herringbone_wang_tile.h @@ -166,7 +166,7 @@ int main(int argc, char **argv) typedef struct stbhw_tileset stbhw_tileset; // returns description of last error produced by any function (not thread-safe) -STBHW_EXTERN char *stbhw_get_last_error(void); +STBHW_EXTERN const char *stbhw_get_last_error(void); // build a tileset from an image that conforms to a template created by this // library. (you allocate storage for stbhw_tileset and function fills it out; @@ -345,10 +345,10 @@ static signed char c_color[STB_HBWANG_MAX_Y+6][STB_HBWANG_MAX_X+6]; static signed char v_color[STB_HBWANG_MAX_Y+6][STB_HBWANG_MAX_X+5]; static signed char h_color[STB_HBWANG_MAX_Y+5][STB_HBWANG_MAX_X+6]; -static char *stbhw_error; -STBHW_EXTERN char *stbhw_get_last_error(void) +static const char *stbhw_error; +STBHW_EXTERN const char *stbhw_get_last_error(void) { - char *temp = stbhw_error; + const char *temp = stbhw_error; stbhw_error = 0; return temp; } @@ -717,7 +717,7 @@ STBHW_EXTERN int stbhw_generate_image(stbhw_tileset *ts, int **weighting, unsign // to avoid really obvious repetition (which happens easily with extreme weights) for (j=0; j < ymax-3; ++j) { for (i=0; i < xmax-3; ++i) { - int p = (i-j+1) & 3; // corner type + //int p = (i-j+1) & 3; // corner type // unused, not sure what the intent was so commenting it out STB_HBWANG_ASSERT(i+3 < STB_HBWANG_MAX_X+6); STB_HBWANG_ASSERT(j+3 < STB_HBWANG_MAX_Y+6); if (stbhw__match(i,j) && stbhw__match(i,j+1) && stbhw__match(i,j+2) @@ -747,7 +747,7 @@ STBHW_EXTERN int stbhw_generate_image(stbhw_tileset *ts, int **weighting, unsign } else { i = phase-4; } - for (i;; i += 4) { + for (;; i += 4) { int xpos = i * sidelen; if (xpos >= w) break; @@ -798,7 +798,7 @@ STBHW_EXTERN int stbhw_generate_image(stbhw_tileset *ts, int **weighting, unsign } else { i = phase-4; } - for (i;; i += 4) { + for (;; i += 4) { int xpos = i * sidelen; if (xpos >= w) break; diff --git a/stb_image.h b/stb_image.h index 90cd54f..d97fa79 100644 --- a/stb_image.h +++ b/stb_image.h @@ -339,11 +339,13 @@ typedef unsigned short stbi_us; extern "C" { #endif +#ifndef STBIDEF #ifdef STB_IMAGE_STATIC #define STBIDEF static #else #define STBIDEF extern #endif +#endif ////////////////////////////////////////////////////////////////////////////// // @@ -1182,7 +1184,7 @@ STBI_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8) STBIDEF int stbi_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) { - return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, bufferlen, NULL, NULL); + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); } #endif diff --git a/stb_image_resize.h b/stb_image_resize.h index 031ca99..93f336b 100644 --- a/stb_image_resize.h +++ b/stb_image_resize.h @@ -193,6 +193,7 @@ typedef uint16_t stbir_uint16; typedef uint32_t stbir_uint32; #endif +#ifndef STBIRDEF #ifdef STB_IMAGE_RESIZE_STATIC #define STBIRDEF static #else @@ -202,7 +203,7 @@ typedef uint32_t stbir_uint32; #define STBIRDEF extern #endif #endif - +#endif ////////////////////////////////////////////////////////////////////////////// // @@ -2324,8 +2325,9 @@ static int stbir__resize_allocated(stbir__info *info, if (alpha_channel < 0) flags |= STBIR_FLAG_ALPHA_USES_COLORSPACE | STBIR_FLAG_ALPHA_PREMULTIPLIED; - if (!(flags&STBIR_FLAG_ALPHA_USES_COLORSPACE) || !(flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) + if (!(flags&STBIR_FLAG_ALPHA_USES_COLORSPACE) || !(flags&STBIR_FLAG_ALPHA_PREMULTIPLIED)) { STBIR_ASSERT(alpha_channel >= 0 && alpha_channel < info->channels); + } if (alpha_channel >= info->channels) return 0; diff --git a/stb_image_write.h b/stb_image_write.h index 9ef2db3..8e6a21b 100644 --- a/stb_image_write.h +++ b/stb_image_write.h @@ -299,7 +299,7 @@ STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned in STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input) { - return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, bufferlen, NULL, NULL); + return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL); } #endif @@ -737,8 +737,8 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n"; s->func(s->context, header, sizeof(header)-1); -#ifdef STBI_MSC_SECURE_CRT - len = sprintf_s(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); +#ifdef __STDC_WANT_SECURE_LIB__ + len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); #else len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x); #endif diff --git a/stb_tilemap_editor.h b/stb_tilemap_editor.h index cab2e24..fef4f64 100644 --- a/stb_tilemap_editor.h +++ b/stb_tilemap_editor.h @@ -971,7 +971,7 @@ struct stbte_tilemap short *undo_buffer; }; -static char *default_category = "[unassigned]"; +static char *default_category = (char*) "[unassigned]"; static void stbte__init_gui(void) { @@ -1172,7 +1172,9 @@ void stbte_set_property(stbte_tilemap *tm, int x, int y, int n, float val) tm->props[y][x][n] = val; } +#ifdef STBTE_ALLOW_LINK static void stbte__set_link(stbte_tilemap *tm, int src_x, int src_y, int dest_x, int dest_y, int undo_mode); +#endif enum { @@ -1254,7 +1256,7 @@ static int stbte__strequal(char *p, char *q) static void stbte__compute_tileinfo(stbte_tilemap *tm) { - int i,j,n=0; + int i,j; tm->num_categories=0; @@ -1649,6 +1651,7 @@ static void stbte__draw_rect(int x0, int y0, int x1, int y1, unsigned int color) STBTE_DRAW_RECT(x0,y0,x1,y1, color); } +#ifdef STBTE_ALLOW_LINK static void stbte__draw_line(int x0, int y0, int x1, int y1, unsigned int color) { int temp; @@ -1662,6 +1665,7 @@ static void stbte__draw_link(int x0, int y0, int x1, int y1, unsigned int color) stbte__draw_line(x0,y0,x0,y1, color); stbte__draw_line(x0,y1,x1,y1, color); } +#endif static void stbte__draw_frame(int x0, int y0, int x1, int y1, unsigned int color) { @@ -1671,12 +1675,6 @@ static void stbte__draw_frame(int x0, int y0, int x1, int y1, unsigned int color stbte__draw_rect(x0,y0+1,x0+1,y1,color); } -static void stbte__draw_halfframe(int x0, int y0, int x1, int y1, unsigned int color) -{ - stbte__draw_rect(x0,y0,x1,y0+1,color); - stbte__draw_rect(x0,y0+1,x0+1,y1,color); -} - static int stbte__get_char_width(int ch) { return stbte__fontdata[ch-16]; @@ -1817,15 +1815,13 @@ static void stbte__draw_textbox(int x0, int y0, int x1, int y1, char *text, int stbte__draw_text(x0+xoff,y0+yoff, text, x1-x0-xoff-1, stbte__color_table[colormode][STBTE__text][colorindex]); } -static int stbte__button(int colormode, char *label, int x, int y, int textoff, int width, int id, int toggled, int disabled) +static int stbte__button(int colormode, const char *label, int x, int y, int textoff, int width, int id, int toggled, int disabled) { int x0=x,y0=y, x1=x+width,y1=y+STBTE__BUTTON_HEIGHT; int s = STBTE__BUTTON_INTERNAL_SPACING; - int over = !disabled && stbte__hittest(x0,y0,x1,y1,id); - if (stbte__ui.event == STBTE__paint) - stbte__draw_textbox(x0,y0,x1,y1, label,s+textoff,s, colormode, STBTE__INDEX_FOR_ID(id,disabled,toggled)); + stbte__draw_textbox(x0,y0,x1,y1, (char*) label,s+textoff,s, colormode, STBTE__INDEX_FOR_ID(id,disabled,toggled)); if (disabled) return 0; return (stbte__button_core(id) == 1); @@ -1836,8 +1832,6 @@ static int stbte__button_icon(int colormode, char ch, int x, int y, int width, i int x0=x,y0=y, x1=x+width,y1=y+STBTE__BUTTON_HEIGHT; int s = STBTE__BUTTON_INTERNAL_SPACING; - int over = stbte__hittest(x0,y0,x1,y1,id); - if (stbte__ui.event == STBTE__paint) { char label[2] = { ch, 0 }; int pad = (9 - stbte__get_char_width(ch))/2; @@ -1851,7 +1845,6 @@ static int stbte__button_icon(int colormode, char ch, int x, int y, int width, i static int stbte__minibutton(int colormode, int x, int y, int ch, int id) { int x0 = x, y0 = y, x1 = x+8, y1 = y+7; - int over = stbte__hittest(x0,y0,x1,y1,id); if (stbte__ui.event == STBTE__paint) { char str[2] = { (char)ch, 0 }; stbte__draw_textbox(x0,y0,x1,y1, str,1,0,colormode, STBTE__INDEX_FOR_ID(id,0,0)); @@ -1862,7 +1855,6 @@ static int stbte__minibutton(int colormode, int x, int y, int ch, int id) static int stbte__layerbutton(int x, int y, int ch, int id, int toggled, int disabled, int colormode) { int x0 = x, y0 = y, x1 = x+10, y1 = y+11; - int over = !disabled && stbte__hittest(x0,y0,x1,y1,id); if (stbte__ui.event == STBTE__paint) { char str[2] = { (char)ch, 0 }; int off = (9-stbte__get_char_width(ch))/2; @@ -1876,7 +1868,6 @@ static int stbte__layerbutton(int x, int y, int ch, int id, int toggled, int dis static int stbte__microbutton(int x, int y, int size, int id, int colormode) { int x0 = x, y0 = y, x1 = x+size, y1 = y+size; - int over = stbte__hittest(x0,y0,x1,y1,id); if (stbte__ui.event == STBTE__paint) { stbte__draw_box(x0,y0,x1,y1, colormode, STBTE__INDEX_FOR_ID(id,0,0)); } @@ -1886,7 +1877,6 @@ static int stbte__microbutton(int x, int y, int size, int id, int colormode) static int stbte__microbutton_dragger(int x, int y, int size, int id, int *pos) { int x0 = x, y0 = y, x1 = x+size, y1 = y+size; - int over = stbte__hittest(x0,y0,x1,y1,id); switch (stbte__ui.event) { case STBTE__paint: stbte__draw_box(x0,y0,x1,y1, STBTE__cexpander, STBTE__INDEX_FOR_ID(id,0,0)); @@ -1912,15 +1902,13 @@ static int stbte__microbutton_dragger(int x, int y, int size, int id, int *pos) return 0; } -static int stbte__category_button(char *label, int x, int y, int width, int id, int toggled) +static int stbte__category_button(const char *label, int x, int y, int width, int id, int toggled) { int x0=x,y0=y, x1=x+width,y1=y+STBTE__BUTTON_HEIGHT; int s = STBTE__BUTTON_INTERNAL_SPACING; - - int over = stbte__hittest(x0,y0,x1,y1,id); if (stbte__ui.event == STBTE__paint) - stbte__draw_textbox(x0,y0,x1,y1, label, s,s, STBTE__ccategory_button, STBTE__INDEX_FOR_ID(id,0,toggled)); + stbte__draw_textbox(x0,y0,x1,y1, (char*) label, s,s, STBTE__ccategory_button, STBTE__INDEX_FOR_ID(id,0,toggled)); return (stbte__button_core(id) == 1); } @@ -1938,7 +1926,6 @@ static int stbte__slider(int x0, int w, int y, int range, int *value, int id) { int x1 = x0+w; int pos = *value * w / (range+1); - int over = stbte__hittest(x0,y-2,x1,y+3,id); int event_mouse_move = STBTE__change; switch (stbte__ui.event) { case STBTE__paint: @@ -1969,15 +1956,22 @@ static int stbte__slider(int x0, int w, int y, int range, int *value, int id) return STBTE__none; } -static int stbte__float_control(int x0, int y0, int w, float minv, float maxv, float scale, char *fmt, float *value, int colormode, int id) +#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__) + #define stbte__sprintf sprintf_s + #define stbte__sizeof(s) , sizeof(s) +#else + #define stbte__sprintf sprintf + #define stbte__sizeof(s) +#endif + +static int stbte__float_control(int x0, int y0, int w, float minv, float maxv, float scale, const char *fmt, float *value, int colormode, int id) { int x1 = x0+w; int y1 = y0+11; - int over = stbte__hittest(x0,y0,x1,y1,id); switch (stbte__ui.event) { case STBTE__paint: { char text[32]; - sprintf(text, fmt ? fmt : "%6.2f", *value); + stbte__sprintf(text stbte__sizeof(text), fmt ? fmt : "%6.2f", *value); stbte__draw_textbox(x0,y0,x1,y1, text, 1,2, colormode, STBTE__INDEX_FOR_ID(id,0,0)); break; } @@ -2283,7 +2277,6 @@ static void stbte__alert(const char *msg) static void stbte__brush_predict(stbte_tilemap *tm, short result[]) { - int layer_to_paint = tm->cur_layer; stbte__tileinfo *ti; int i; @@ -2322,7 +2315,6 @@ static void stbte__brush_predict(stbte_tilemap *tm, short result[]) static void stbte__brush(stbte_tilemap *tm, int x, int y) { - int layer_to_paint = tm->cur_layer; stbte__tileinfo *ti; // find lowest legit layer to paint it on, and put it there @@ -2634,7 +2626,6 @@ static void stbte__clear_stack(stbte_tilemap *tm, short result[]) static void stbte__fillrect(stbte_tilemap *tm, int x0, int y0, int x1, int y1, int fill) { int i,j; - int x=x0,y=y0; stbte__begin_undo(tm); if (x0 > x1) i=x0,x0=x1,x1=i; @@ -2734,6 +2725,7 @@ static int stbte__in_rect(int x, int y, int x0, int y0, int w, int h) return x >= x0 && x < x0+w && y >= y0 && y < y0+h; } +#ifdef STBTE_ALLOW_LINK static int stbte__in_src_rect(int x, int y) { return stbte__in_rect(x,y, stbte__ui.copy_src_x, stbte__ui.copy_src_y, stbte__ui.copy_width, stbte__ui.copy_height); @@ -2743,6 +2735,7 @@ static int stbte__in_dest_rect(int x, int y, int destx, int desty) { return stbte__in_rect(x,y, destx, desty, stbte__ui.copy_width, stbte__ui.copy_height); } +#endif static void stbte__paste(stbte_tilemap *tm, int mapx, int mapy) { @@ -2934,9 +2927,6 @@ static void stbte__tile_paint(stbte_tilemap *tm, int sx, int sy, int mapx, int m { int i; int id = STBTE__IDMAP(mapx,mapy); - int x0=sx, y0=sy; - int x1=sx+tm->spacing_x, y1=sy+tm->spacing_y; - int over = stbte__hittest(x0,y0,x1,y1, id); short *data = tm->data[mapy][mapx]; short temp[STBTE_MAX_LAYERS]; @@ -3366,7 +3356,7 @@ static int stbte__info_value(const char *label, int x, int y, int val, int digit if (stbte__ui.event == STBTE__paint) { int off = 9-stbte__get_char_width(label[0]); char text[16]; - sprintf(text, label, digits, val); + stbte__sprintf(text stbte__sizeof(text), label, digits, val); stbte__draw_text_core(x+off,y, text, 999, STBTE__TEXTCOLOR(STBTE__cpanel),1); } if (id) { @@ -3414,7 +3404,7 @@ static void stbte__info(stbte_tilemap *tm, int x0, int y0, int w, int h) static void stbte__layers(stbte_tilemap *tm, int x0, int y0, int w, int h) { - static char *propmodes[3] = { + static const char *propmodes[3] = { "default", "always", "never" }; int num_rows; @@ -3449,7 +3439,7 @@ static void stbte__layers(stbte_tilemap *tm, int x0, int y0, int w, int h) int disabled = (tm->solo_layer >= 0 && tm->solo_layer != i); if (i-tm->layer_scroll >= 0 && i-tm->layer_scroll < num_rows) { if (str == NULL) - sprintf(str=text, "%2d", i+1); + stbte__sprintf(str=text stbte__sizeof(text), "%2d", i+1); if (stbte__button(STBTE__clayer_button, str, x0,y,(i+1<10)*2,xoff-2, STBTE__ID(STBTE__layer,i), tm->cur_layer==i,0)) tm->cur_layer = (tm->cur_layer == i ? -1 : i); if (stbte__layerbutton(x0+xoff + 0,y+1,'H',STBTE__ID(STBTE__hide,i), tm->layerinfo[i].hidden,disabled,STBTE__clayer_hide)) @@ -3501,10 +3491,7 @@ static void stbte__categories(stbte_tilemap *tm, int x0, int y0, int w, int h) static void stbte__tile_in_palette(stbte_tilemap *tm, int x, int y, int slot) { - stbte__tileinfo *t = &tm->tiles[slot]; - int x0=x, y0=y, x1 = x+tm->palette_spacing_x - 1, y1 = y+tm->palette_spacing_y; int id = STBTE__ID(STBTE__palette, slot); - int over = stbte__hittest(x0,y0,x1,y1, id); switch (stbte__ui.event) { case STBTE__paint: stbte__draw_rect(x,y,x+tm->palette_spacing_x-1,y+tm->palette_spacing_x-1, STBTE_COLOR_TILEPALETTE_BACKGROUND); @@ -3561,15 +3548,10 @@ static void stbte__palette_of_tiles(stbte_tilemap *tm, int x0, int y0, int w, in stbte__scrollbar(x1-4, y0+6, y1-2, &tm->palette_scroll, 0, num_total_rows, num_vis_rows, STBTE__ID(STBTE__scrollbar_id, STBTE__palette)); } -static float stbte__linear_remap(float n, float x0, float x1, float y0, float y1) -{ - return (n-x0)/(x1-x0)*(y1-y0) + y0; -} - static float stbte__saved; static void stbte__props_panel(stbte_tilemap *tm, int x0, int y0, int w, int h) { - int x1 = x0+w, y1 = y0+h; + int x1 = x0+w; int i; int y = y0 + 5, x = x0+2; int slider_width = 60; @@ -3585,8 +3567,8 @@ static void stbte__props_panel(stbte_tilemap *tm, int x0, int y0, int w, int h) for (i=0; i < STBTE_MAX_PROPERTIES; ++i) { unsigned int n = STBTE_PROP_TYPE(i, data, p); if (n) { - char *s = STBTE_PROP_NAME(i, data, p); - if (s == NULL) s = ""; + char *s = (char*) STBTE_PROP_NAME(i, data, p); + if (s == NULL) s = (char*) ""; switch (n & 3) { case STBTE_PROP_bool: { int flag = (int) p[i]; diff --git a/stb_vorbis.c b/stb_vorbis.c index 93ac7ff..8ad5f0a 100644 --- a/stb_vorbis.c +++ b/stb_vorbis.c @@ -4990,7 +4990,13 @@ stb_vorbis * stb_vorbis_open_file(FILE *file, int close_on_free, int *error, con stb_vorbis * stb_vorbis_open_filename(const char *filename, int *error, const stb_vorbis_alloc *alloc) { - FILE *f = fopen(filename, "rb"); + FILE *f; +#if defined(_WIN32) && defined(__STDC_WANT_SECURE_LIB__) + if (0 != fopen_s(&f, filename, "rb")) + f = NULL; +#else + f = fopen(filename, "rb"); +#endif if (f) return stb_vorbis_open_file(f, TRUE, error, alloc); if (error) *error = VORBIS_file_open_failure; diff --git a/stb_voxel_render.h b/stb_voxel_render.h index c3ad981..19c6373 100644 --- a/stb_voxel_render.h +++ b/stb_voxel_render.h @@ -3552,7 +3552,7 @@ void stbvox_set_buffer(stbvox_mesh_maker *mm, int mesh, int slot, void *buffer, stbvox_bring_up_to_date(mm); mm->output_buffer[mesh][slot] = (char *) buffer; mm->output_cur [mesh][slot] = (char *) buffer; - mm->output_len [mesh][slot] = len; + mm->output_len [mesh][slot] = (int) len; mm->output_end [mesh][slot] = (char *) buffer + len; for (i=0; i < STBVOX_MAX_MESH_SLOTS; ++i) { if (mm->output_buffer[mesh][i]) { @@ -3568,7 +3568,7 @@ void stbvox_set_default_mesh(stbvox_mesh_maker *mm, int mesh) int stbvox_get_quad_count(stbvox_mesh_maker *mm, int mesh) { - return (mm->output_cur[mesh][0] - mm->output_buffer[mesh][0]) / mm->output_size[mesh][0]; + return (int) ((mm->output_cur[mesh][0] - mm->output_buffer[mesh][0]) / mm->output_size[mesh][0]); } stbvox_input_description *stbvox_get_input_description(stbvox_mesh_maker *mm) diff --git a/tests/image_test.c b/tests/image_test.c index b370b81..7f44016 100644 --- a/tests/image_test.c +++ b/tests/image_test.c @@ -113,7 +113,7 @@ int main(int argc, char **argv) printf("FAILED 4\n"); } } else { - int i, nope=0; + int i; #ifdef PNGSUITE_PRIMARY char **files = stb_readdir_files("pngsuite/primary"); #else diff --git a/tests/image_write_test.c b/tests/image_write_test.c index a7dd3dd..4e4a7e8 100644 --- a/tests/image_write_test.c +++ b/tests/image_write_test.c @@ -1,3 +1,6 @@ +#ifdef __clang__ +#define STBIWDEF static inline +#endif #define STB_IMAGE_WRITE_STATIC #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" diff --git a/tests/resample_test.cpp b/tests/resample_test.cpp index 882dcc0..21f874f 100644 --- a/tests/resample_test.cpp +++ b/tests/resample_test.cpp @@ -1,3 +1,4 @@ +#define _CRT_SECURE_NO_WARNINGS #include #include @@ -56,8 +57,11 @@ void stbir_progress(float p) STBIR_ASSERT(p >= 0 && p <= 1); } -#define STBIR_PROGRESS_REPORT stbir_progress +#ifdef __clang__ +#define STBIRDEF static inline +#endif +#define STBIR_PROGRESS_REPORT stbir_progress #define STB_IMAGE_RESIZE_IMPLEMENTATION #define STB_IMAGE_RESIZE_STATIC #include "stb_image_resize.h" @@ -127,7 +131,7 @@ inline float mtfrand() return (float)(mtrand() % ninenine)/ninenine; } -static void resizer(int argc, char **argv) +void resizer(int argc, char **argv) { unsigned char* input_pixels; unsigned char* output_pixels; @@ -144,7 +148,7 @@ static void resizer(int argc, char **argv) exit(0); } -static void performance(int argc, char **argv) +void performance(int argc, char **argv) { unsigned char* input_pixels; unsigned char* output_pixels; diff --git a/tests/stb.c b/tests/stb.c index 5a0b6eb..ee6941f 100644 --- a/tests/stb.c +++ b/tests/stb.c @@ -2,6 +2,7 @@ * Unit tests for "stb.h" */ +#define _CRT_SECURE_NO_WARNINGS //#include #include #include @@ -110,8 +111,8 @@ void test_classes(void) while ((psize % s) > (psize >> 3)) { psize += kPageSize; } - class_to_pages[cl] = psize >> kPageShift; - wasted_pages += psize; + class_to_pages[cl] = (int) (psize >> kPageShift); + wasted_pages += (int) psize; } printf("TCMalloc can waste as much as %d memory on one-shot allocations\n", wasted_pages); @@ -356,10 +357,10 @@ void test_threads2(void) char tc[] = "testing compression test quick test voila woohoo what the hell"; -char storage1[1 << 23]; -int test_compression(char *buffer, int length) +unsigned char storage1[1 << 23]; +int test_compression(unsigned char *buffer, int length) { - char *storage2; + unsigned char *storage2; int c_len = stb_compress(storage1, buffer, length); int dc_len; printf("Compressed %d to %d\n", length, c_len); @@ -421,7 +422,7 @@ stb_uint stb_adler32_old(stb_uint adler32, stb_uchar *buffer, stb_uint buflen) return (s2 << 16) + s1; } -static int sample_test[3][5] = +int sample_test[3][5] = { { 1,2,3,4,5 }, { 6,7,8,9,10, }, @@ -1579,10 +1580,10 @@ struct char *digest; } sha1_tests[] = { - 24, +{ 24, "616263", "a9993e364706816aba3e25717850c26c9cd0d89d", - +},{ 1304, "ec29561244ede706b6eb30a1c371d74450a105c3f9735f7fa9fe38cf67f304a5736a106e" "92e17139a6813b1c81a4f3d3fb9546ab4296fa9f722826c066869edacd73b25480351858" @@ -1590,7 +1591,7 @@ struct "e31cb413ae29810fd794cad5dfaf29ec43cb38d198fe4ae1da2359780221405bd6712a53" "05da4b1b737fce7cd21c0eb7728d08235a9011", "970111c4e77bcc88cc20459c02b69b4aa8f58217", - +},{ 2096, "5fc2c3f6a7e79dc94be526e5166a238899d54927ce470018fbfd668fd9dd97cbf64e2c91" "584d01da63be3cc9fdff8adfefc3ac728e1e335b9cdc87f069172e323d094b47fa1e652a" @@ -1601,7 +1602,7 @@ struct "e485050e4bbb6235574fc0102be8f7a306d6e8de6ba6becf80f37415b57f9898a5824e77" "414197422be3d36a6080", "0423dc76a8791107d14e13f5265b343f24cc0f19", - +},{ 2888, "0f865f46a8f3aed2da18482aa09a8f390dc9da07d51d1bd10fe0bf5f3928d5927d08733d" "32075535a6d1c8ac1b2dc6ba0f2f633dc1af68e3f0fa3d85e6c60cb7b56c239dc1519a00" @@ -1615,7 +1616,7 @@ struct "6afbb27dbbd300477d70c371e7b8963812f5ed4fb784fb2f3bd1d3afe883cdd47ef32bea" "ea", "6692a71d73e00f27df976bc56df4970650d90e45", - +},{ 3680, "4893f1c763625f2c6ce53aacf28026f14b3cd8687e1a1d3b60a81e80fcd1e2b038f9145a" "b64a0718f948f7c3c9ac92e3d86fb669a5257da1a18c776291653688338210a3242120f1" @@ -1631,7 +1632,7 @@ struct "73c30b39920e726fe861b72483a3f886269ab7a8eefe952f35d25c4eb7f443f4f3f26e43" "d51fb54591e6a6dad25fcdf5142033084e5624bdd51435e77dea86b8", "dc5859dd5163c4354d5d577b855fa98e37f04384", - +},{ 4472, "cf494c18a4e17bf03910631471bca5ba7edea8b9a63381e3463517961749848eb03abefd" "4ce676dece3740860255f57c261a558aa9c7f11432f549a9e4ce31d8e17c79450ce2ccfc" @@ -1650,7 +1651,7 @@ struct "317746270599424b9248791a0780449c1eabbb9459cc1e588bfd74df9b1b711c85c09d8a" "a171b309281947e8f4b6ac438753158f4f36fa", "4c17926feb6e87f5bca7890d8a5cde744f231dab", - +},{ 5264, "8236153781bd2f1b81ffe0def1beb46f5a70191142926651503f1b3bb1016acdb9e7f7ac" "ced8dd168226f118ff664a01a8800116fd023587bfba52a2558393476f5fc69ce9c65001" @@ -1672,7 +1673,7 @@ struct "5cf62845c2009980a4dfa69fbc7e5a0b1bb20a5958ca967aec68eb31dd8fccca9afcd30a" "26bab26279f1bf6724ff", "11863b483809ef88413ca9b0084ac4a5390640af", - +},{ 6056, "31ec3c3636618c7141441294fde7e72366a407fa7ec6a64a41a7c8dfda150ca417fac868" "1b3c5be253e3bff3ab7a5e2c01b72790d95ee09b5362be835b4d33bd20e307c3c702aa15" @@ -1697,7 +1698,7 @@ struct "386719b28a09a8e5934722202beb3429899b016dfeb972fee487cdd8d18f8a681042624f" "51", "f43937922444421042f76756fbed0338b354516f", - +},{ 6848, "21b9a9686ec200456c414f2e6963e2d59e8b57e654eced3d4b57fe565b51c9045c697566" "44c953178f0a64a6e44d1b46f58763c6a71ce4c373b0821c0b3927a64159c32125ec916b" @@ -1724,7 +1725,7 @@ struct "aac4130293f6f62ae6d50c0d0c3b9876f0728923a94843785966a27555dd3ce68602e7d9" "0f7c7c552f9bda4969ec2dc3e30a70620db6300e822a93e633ab9a7a", "5d4d18b24b877092188a44be4f2e80ab1d41e795", - +},{ 7640, "1c87f48f4409c3682e2cf34c63286dd52701b6c14e08669851a6dc8fa15530ad3bef692c" "7d2bf02238644561069df19bdec3bccae5311fce877afc58c7628d08d32d9bd2dc1df0a6" @@ -1754,7 +1755,7 @@ struct "e147c723aca999015230d22c917730b935e902092f83e0a8e6db9a75d2626e0346e67e40" "8d5b815439dab8ccb8ea23f828fff6916c4047", "32e0f5d40ceec1fbe45ddd151c76c0b3fef1c938", - +},{ 8432, "084f04f8d44b333dca539ad2f45f1d94065fbb1d86d2ccf32f9486fe98f7c64011160ec0" "cd66c9c7478ed74fde7945b9c2a95cbe14cedea849978cc2d0c8eb0df48d4834030dfac2" @@ -1787,7 +1788,7 @@ struct "b5200b7892554b59532ac63af3bdef590b57bd5df4fbf38d2b3fa540fa5bf89455802963" "036bd173fe3967ed1b7d", "ee976e4ad3cad933b283649eff9ffdb41fcccb18", - +},{ 9224, "bd8320703d0cac96a96aeefa3abf0f757456bf42b3e56f62070fc03e412d3b8f4e4e427b" "c47c4600bb423b96de6b4910c20bc5c476c45feb5b429d4b35088813836fa5060ceb26db" @@ -1823,7 +1824,7 @@ struct "42a756a3e22123cbf38c429373c6a8663130c24b24b2690b000013960b1c46a32d1d5397" "47", "2df09b10933afedfcd3f2532dfd29e7cb6213859", - +},{ 10016, "7a94978bec7f5034b12c96b86498068db28cd2726b676f54d81d8d7350804cc106bead8a" "252b465a1f413b1c41e5697f8cece49ec0dea4dfb9fa7b1bfe7a4a00981875b420d094bb" @@ -1861,7 +1862,7 @@ struct "5740090c1b165ecae7dec0b341d60a88f46d7ad8624aac231a90c93fad61fcfbbea12503" "59fcd203862a6b0f1d71ac43db6c58a6b60c2c546edc12dd658998e8", "f32e70862a16e3e8b199e9d81a9949d66f812cad", - +},{ 10808, "88dd7f273acbe799219c23184782ac0b07bade2bc46b4f8adbd25ed3d59c0fd3e2931638" "837d31998641bbb7374c7f03d533ca60439ac4290054ff7659cc519bdda3dff2129a7bdb" @@ -1902,7 +1903,7 @@ struct "1fd561274392ee6ee1a14424d5c134a69bcb4333079400f03615952fc4c99bf03f5733a8" "dc71524269fc5c648371f5f3098314d9d10258", "08632c75676571a5db5971f5d99cb8de6bf1792a", - +},{ 11600, "85d43615942fcaa449329fd1fe9efb17545eb252cac752228f1e9d90955a3cf4e72cb116" "3c3d8e93ccb7e4826206ff58b3e05009ee82ab70943db3f18a32925d6d5aed1525c91673" @@ -1946,7 +1947,7 @@ struct "b16dcde529248a477628067d13d0cb3bf51776f4d39fb3fbc5f669e91019323e40360e4b" "78b6584f077bf9e03b66", "ab7213f6becb980d40dc89fbda0ca39f225a2d33", - +},{ 12392, "7ae3ca60b3a96be914d24980fb5652eb68451fed5fa47abe8e771db8301fbd5331e64753" "93d96a4010d6551701e5c23f7ecb33bec7dd7bade21381e9865d410c383a139cb4863082" @@ -1993,7 +1994,7 @@ struct "09d1af296eb3121d782650e7d038063bab5fa854aac77de5ffebeb53d263f521e3fc02ac" "70", "b0e15d39025f5263e3efa255c1868d4a37041382", - +},{ 13184, "fa922061131282d91217a9ff07463843ae34ff7f8c28b6d93b23f1ea031d5020aa92f660" "8c3d3df0ee24a8958fd41af880ee454e36e26438defb2de8f09c018607c967d2f0e8b80a" @@ -2042,7 +2043,7 @@ struct "b409cc322354672a21ea383e870d047551a3af71aaf2f44f49a859cf001e61b592dd036f" "c6625bf7b91ea0fb78c1563cceb8c4345bf4a9fbe6ee2b6bf5e81083", "8b6d59106f04300cb57c7c961945cd77f3536b0a", - +},{ 13976, "162cca41155de90f6e4b76a34261be6666ef65bdb92b5831b47604ce42e0c6c8d2eda265" "ab9a3716809bf2e745e7831a41768d0f6349a268d9ac6e6adfb832a5d51b75d7951cf60e" @@ -2094,7 +2095,7 @@ struct "7635eed03558ac673d17280769b2368056276d5d72f5dbc75525f8a7558bd90b544aa6cb" "dd964e6c70be79441969bfdf471f17a2dc0c92", "6144c4786145852e2a01b20604c369d1b9721019", - +},{ 14768, "c9bed88d93806b89c2d028866842e6542ab88c895228c96c1f9f05125f8697c7402538b0" "6465b7ae33daef847500f73d20c598c86e4804e633e1c4466e61f3ed1e9baadc5723bbed" @@ -2149,6 +2150,7 @@ struct "f5e1f03c2280e71c6e1ae21312d4ff163eee16ebb1fdee8e887bb0d453829b4e6ed5fa70" "8f2053f29b81e277be46", "a757ead499a6ec3d8ab9814f839117354ae563c8" +} }; void test_sha1(void) @@ -2257,14 +2259,14 @@ void do_compressor(int argc,char**argv) { char *p; size_t slen; - int len; + unsigned int len; int window; if (argc == 2) { p = stb_file(argv[1], &slen); - len = (int) slen; + len = (unsigned int) slen; if (p) { - int dlen, clen = stb_compress_tofile("data/dummy.bin", p, len); + unsigned int dlen, clen = stb_compress_tofile("data/dummy.bin", p, len); char *q = stb_decompress_fromfile("data/dummy.bin", &dlen); if (len != dlen) { @@ -2398,7 +2400,7 @@ done: - +#if 0 // parser generator ////////////////////////////////////////////////////////////////////////// // // stb_parser @@ -2946,7 +2948,7 @@ void test_parser_generator(void) parser_destroy(p); } #endif - +#endif // parser generator #if 0 // stb_threadtest.c diff --git a/tests/stb_cpp.cpp b/tests/stb_cpp.cpp index f992108..9cd6670 100644 --- a/tests/stb_cpp.cpp +++ b/tests/stb_cpp.cpp @@ -11,7 +11,7 @@ //#include "stb_file.h" int count; -void c(int truth, char *error) +void c(int truth, const char *error) { if (!truth) { fprintf(stderr, "Test failed: %s\n", error); @@ -19,7 +19,7 @@ void c(int truth, char *error) } } -char *expects(stb_matcher *m, char *s, int result, int len, char *str) +char *expects(stb_matcher *m, char *s, int result, int len, const char *str) { int res2,len2=0; res2 = stb_lex(m, s, &len2); @@ -31,7 +31,7 @@ void test_lex(void) { stb_matcher *m = stb_lex_matcher(); // tok_en5 .3 20.1 20. .20 .1 - char *s = "tok_en5.3 20.1 20. .20.1"; + char *s = (char*) "tok_en5.3 20.1 20. .20.1"; stb_lex_item(m, "[a-zA-Z_][a-zA-Z0-9_]*", 1 ); stb_lex_item(m, "[0-9]*\\.?[0-9]*" , 2 ); @@ -53,22 +53,22 @@ void test_lex(void) int main(int argc, char **argv) { char *p; - p = "abcdefghijklmnopqrstuvwxyz"; + p = (char*) "abcdefghijklmnopqrstuvwxyz"; c(stb_ischar('c', p), "stb_ischar 1"); c(stb_ischar('x', p), "stb_ischar 2"); c(!stb_ischar('#', p), "stb_ischar 3"); c(!stb_ischar('X', p), "stb_ischar 4"); - p = "0123456789"; + p = (char*) "0123456789"; c(!stb_ischar('c', p), "stb_ischar 5"); c(!stb_ischar('x', p), "stb_ischar 6"); c(!stb_ischar('#', p), "stb_ischar 7"); c(!stb_ischar('X', p), "stb_ischar 8"); - p = "#####"; + p = (char*) "#####"; c(!stb_ischar('c', p), "stb_ischar a"); c(!stb_ischar('x', p), "stb_ischar b"); c(stb_ischar('#', p), "stb_ischar c"); c(!stb_ischar('X', p), "stb_ischar d"); - p = "xXyY"; + p = (char*) "xXyY"; c(!stb_ischar('c', p), "stb_ischar e"); c(stb_ischar('x', p), "stb_ischar f"); c(!stb_ischar('#', p), "stb_ischar g"); diff --git a/tests/stb_static.c b/tests/stb_static.c new file mode 100644 index 0000000..07ce1f9 --- /dev/null +++ b/tests/stb_static.c @@ -0,0 +1,12 @@ +#define STBI_WINDOWS_UTF8 +#define STB_IMAGE_STATIC +#define STB_IMAGE_IMPLEMENTATION +#include "stb_image.h" + +#define STB_IMAGE_WRITE_STATIC +#define STB_IMAGE_WRITE_IMPLEMENTATION +//#include "stb_image_write.h" + +#define STBTT_STATIC +#define STB_TRUETYPE_IMPLEMENTATION +#include "stb_truetype.h" diff --git a/tests/stretchy_buffer_test.c b/tests/stretchy_buffer_test.c index 5ced5bc..5f613f5 100644 --- a/tests/stretchy_buffer_test.c +++ b/tests/stretchy_buffer_test.c @@ -1 +1,7 @@ -#include "stretchy_buffer.h" \ No newline at end of file +#include "stretchy_buffer.h" + +void test_sb(void) +{ + char *x = NULL; + sb_push(x, 'x'); +} \ No newline at end of file diff --git a/tests/test.sbm b/tests/test.sbm new file mode 100644 index 0000000..356ddcd --- /dev/null +++ b/tests/test.sbm @@ -0,0 +1,37 @@ +[compilers] +VS2015 for x64, vcvars_2015_x64 +VC6 , vcvars_vc6 +VS2008 for x86, vcvars_2008_x86 +VS2013 for x86, vcvars_2013_x86 +VS2015 for x86, vcvars_2015_x86 +clang-cl for x64, vcvars_2015_x64, clang-cl +clang-cl for x86, vcvars_2015_x86, clang32-cl +#these batch files don't work on my machine +#VS2008 for x64, vcvars_2008_x64 +#VS2013 for x64, vcvars_2013_x64 + +[args] +-I .. -W3 -WX -D_DEBUG + +[link] +advapi32.lib + +[projects] +c_lexer_test.c +image_test.c image_write_test.c +test_cpp_compilation.cpp stb_cpp.cpp ../stb_vorbis.c +resample_test.cpp +-DTT_TEST test_c_compilation.c test_truetype.c +main.c stb.c +main.c stretchy_buffer_test.c +main.c test_c_compilation.c +main.c test_c_lexer.c +main.c test_dxt.c +main.c test_easyfont.c +main.c test_image.c +main.c test_image_write.c +main.c test_perlin.c +main.c test_sprintf.c +main.c test_vorbis.c ../stb_vorbis.c +main.c test_voxel.c +main.c textedit_sample.c diff --git a/tests/test_cpp_compilation.cpp b/tests/test_cpp_compilation.cpp index 558a236..a2093f4 100644 --- a/tests/test_cpp_compilation.cpp +++ b/tests/test_cpp_compilation.cpp @@ -3,6 +3,7 @@ #include "stb_sprintf.h" #define STB_IMAGE_WRITE_STATIC +#define STBIWDEF static inline #define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_TRUETYPE_IMPLEMENTATION @@ -57,9 +58,18 @@ void my_free(void *) { } #define STB_IMAGE_RESIZE_IMPLEMENTATION #include "stb_image_resize.h" -#include "stretchy_buffer.h" +//#include "stretchy_buffer.h" // deprecating +// avoid unused-function complaints +void dummy2(void) +{ + stb_easy_font_spacing(1.0); + stb_easy_font_print(0,0,NULL,NULL,NULL,0); + stb_easy_font_width(NULL); + stb_easy_font_height(NULL); +} + //////////////////////////////////////////////////////////// // @@ -113,7 +123,7 @@ int insert_chars(STB_TEXTEDIT_STRING *str, int pos, STB_TEXTEDIT_CHARTYPE *newte // define all the #defines needed -#define KEYDOWN_BIT 0x80000000 +#define KEYDOWN_BIT 0x40000000 #define STB_TEXTEDIT_STRINGLEN(tc) ((tc)->stringlen) #define STB_TEXTEDIT_LAYOUTROW layout_func @@ -125,8 +135,8 @@ int insert_chars(STB_TEXTEDIT_STRING *str, int pos, STB_TEXTEDIT_CHARTYPE *newte #define STB_TEXTEDIT_DELETECHARS delete_chars #define STB_TEXTEDIT_INSERTCHARS insert_chars -#define STB_TEXTEDIT_K_SHIFT 0x40000000 -#define STB_TEXTEDIT_K_CONTROL 0x20000000 +#define STB_TEXTEDIT_K_SHIFT 0x20000000 +#define STB_TEXTEDIT_K_CONTROL 0x10000000 #define STB_TEXTEDIT_K_LEFT (KEYDOWN_BIT | 1) // actually use VK_LEFT, SDLK_LEFT, etc #define STB_TEXTEDIT_K_RIGHT (KEYDOWN_BIT | 2) // VK_RIGHT #define STB_TEXTEDIT_K_UP (KEYDOWN_BIT | 3) // VK_UP @@ -149,3 +159,12 @@ int insert_chars(STB_TEXTEDIT_STRING *str, int pos, STB_TEXTEDIT_CHARTYPE *newte #include "stb_textedit.h" +void dummy3(void) +{ + stb_textedit_click(0,0,0,0); + stb_textedit_drag(0,0,0,0); + stb_textedit_cut(0,0); + stb_textedit_key(0,0,0); + stb_textedit_initialize_state(0,0); + stb_textedit_paste(0,0,0,0); +} diff --git a/tests/test_ds.c b/tests/test_ds.c index fce99df..b51e8f4 100644 --- a/tests/test_ds.c +++ b/tests/test_ds.c @@ -1,7 +1,25 @@ +#ifdef DS_PERF +#define _CRT_SECURE_NO_WARNINGS +#define _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NON_CONFORMING_SWPRINTFS + + +//#define STBDS_INTERNAL_SMALL_BUCKET // make 64-bit bucket fit both keys and hash bits +//#define STBDS_SIPHASH_2_4 // performance test 1_3 against 2_4 +//#define STBDS_INTERNAL_BUCKET_START // don't bother offseting differently within bucket for different hash values +//#define STBDS_FLUSH_CACHE (1u<<20) // do this much memory traffic to flush the cache between some benchmarking measurements + +#define WIN32_LEAN_AND_MEAN +#include +#define STB_DEFINE +#define STB_NO_REGISTRY +#include "../stb.h" #include +#endif #ifdef DS_TEST #define STBDS_UNIT_TESTS +#define STBDS_SMALL_BUCKET #endif #ifdef DS_STATS @@ -13,7 +31,6 @@ #include #endif -//#define STBDS_SIPHASH_2_4 #define STB_DS_IMPLEMENTATION #include "../stb_ds.h" @@ -141,30 +158,27 @@ int main(int arg, char **argv) } #endif + #ifdef DS_PERF -#define WIN32_LEAN_AND_MEAN -#include -#define STB_DEFINE -#define STB_NO_REGISTRY -//#include "../stb.h" +//char *strdup(const char *foo) { return 0; } +//int stricmp(const char *a, const char *b) { return 0; } +//int strnicmp(const char *a, const char *b, size_t n) { return 0; } - -size_t t0, sum, mn,mx,count; +unsigned __int64 t0, xsum, mn,mx,count; void begin(void) { - size_t t0; LARGE_INTEGER m; QueryPerformanceCounter(&m); t0 = m.QuadPart; - sum = 0; + xsum = 0; count = 0; mx = 0; - mn = ~(size_t) 0; + mn = ~(unsigned __int64) 0; } void measure(void) { - size_t t1, t; + unsigned __int64 t1, t; LARGE_INTEGER m; QueryPerformanceCounter(&m); t1 = m.QuadPart; @@ -173,40 +187,42 @@ void measure(void) printf("ALERT: QueryPerformanceCounter was unordered!\n"); if (t < mn) mn = t; if (t > mx) mx = t; - sum += t; + xsum += t; ++count; t0 = t1; } void dont_measure(void) { - size_t t1, t; LARGE_INTEGER m; QueryPerformanceCounter(&m); t0 = m.QuadPart; } double timer; -void end(void) +double end(void) { LARGE_INTEGER m; QueryPerformanceFrequency(&m); if (count > 3) { // discard the highest and lowest - sum -= mn; - sum -= mx; + xsum -= mn; + xsum -= mx; count -= 2; } - timer = (double) (sum) / count / m.QuadPart * 1000; + timer = (double) (xsum) / count / m.QuadPart * 1000; + return timer; } void build(int a, int b, int count, int step) { struct { int key,value; } *map=NULL; - int i,j,n,k; - for (i=0; i < a; ++i) - hmput(map,i*step,i+1); + int i,n; + for (i=0; i < a; ++i) { + n = i*step; + hmput(map,n,i+1); + } measure(); churn_inserts = i; hmfree(map); @@ -217,8 +233,7 @@ void build(int a, int b, int count, int step) void build_stb(int a, int b, int count, int step) { stb_idict *d = stb_idict_new_size(8); - struct { int key,value; } *map=NULL; - int i,j,n,k; + int i; for (i=0; i < a; ++i) stb_idict_add(d, i*step, i+1); measure(); @@ -226,8 +241,68 @@ void build_stb(int a, int b, int count, int step) stb_idict_destroy(d); dont_measure(); } + +void multibuild_stb(int a, int b, int count, int step, int tables) +{ + stb_idict *d[50000]; + int i,q; + for (q=0; q < tables; ++q) + d[q] = stb_idict_new_size(8); + dont_measure(); + for (i=0; i < a; ++i) + for (q=0; q < tables; ++q) + stb_idict_add(d[q], i*step+q*771, i+1); + measure(); + churn_inserts = i; + for (q=0; q < tables; ++q) + stb_idict_destroy(d[q]); + dont_measure(); +} + +int multisearch_stb(int a, int start, int end, int step, int tables) +{ + stb_idict *d[50000]; + int i,q,total=0,v; + for (q=0; q < tables; ++q) + d[q] = stb_idict_new_size(8); + for (q=0; q < tables; ++q) + for (i=0; i < a; ++i) + stb_idict_add(d[q], i*step+q*771, i+1); + dont_measure(); + for (i=start; i < end; ++i) + for (q=0; q < tables; ++q) + if (stb_idict_get_flag(d[q], i*step+q*771, &v)) + total += v; + measure(); + churn_inserts = i; + for (q=0; q < tables; ++q) + stb_idict_destroy(d[q]); + dont_measure(); + return total; +} #endif +int multisearch(int a, int start, int end, int step, int tables) +{ + struct { int key,value; } *hash[50000]; + int i,q,total=0; + for (q=0; q < tables; ++q) + hash[q] = NULL; + for (q=0; q < tables; ++q) + for (i=0; i < a; ++i) + hmput(hash[q], i*step+q*771, i+1); + dont_measure(); + for (i=start; i < end; ++i) + for (q=0; q < tables; ++q) + total += hmget(hash[q], i*step+q*771); + measure(); + churn_inserts = i; + for (q=0; q < tables; ++q) + hmfree(hash[q]); + dont_measure(); + return total; +} + void churn_skip(unsigned int a, unsigned int b, int count) { struct { unsigned int key,value; } *map=NULL; @@ -343,12 +418,526 @@ void churn8(int a, int b, int count, int include_startup) dont_measure(); } +void multichurn4(int a, int b, int count, int include_startup, int tables) +{ + struct { int key,value; } *map[50000]; + int i,j,n,k,q; + for (q=0; q < tables; ++q) + map[q] = NULL; + dont_measure(); + + for (i=0; i < a; ++i) + for (q=0; q < tables; ++q) + hmput(map[q],i,i+1); + if (!include_startup) + dont_measure(); + for (n=0; n < count; ++n) { + for (j=a; j < b; ++j,++i) { + for (q=0; q < tables; ++q) + hmput(map[q],i,i+1); + } + assert(hmlen(map[0]) == b); + for (j=a; j < b; ++j) { + k=i-j-1; + for (q=0; q < tables; ++q) + k = hmdel(map[q],k); + assert(k != 0); + } + assert(hmlen(map[0]) == a); + } + measure(); + for (q=0; q < tables; ++q) + hmfree(map[q]); + churn_inserts = i * tables; + churn_deletes = (b-a) * n * tables; + dont_measure(); +} + +struct { + unsigned __int64 start; + unsigned __int64 end; + int table_size; +} mstats[32][4000]; + +const int first_step = 64; +const int last_step = 384-48; // 32M + +void measure_build4(int step_log2) +{ + double length; + int i,j,k=0; + int step = 1 << step_log2; + unsigned __int64 t0,t1; + struct { int key,value; } *map=NULL; + double rdtsc_scale; + begin(); + t0 = __rdtsc(); + + mstats[0][0].start = __rdtsc(); + for (i=0; i < 256; ++i) { + hmput(map,k,k+1); + k += step; + } + mstats[0][first_step-1].end = __rdtsc(); + mstats[0][first_step-1].table_size = k >> step_log2; + for (j=first_step; j < last_step; ++j) { + for (i=0; i < (1<<(j>>4)); ++i) { + hmput(map, k,k+1); + k += step; + } + mstats[0][j].end = __rdtsc(); + mstats[0][j].table_size = k >> step_log2; + } + t1 = __rdtsc(); + measure(); + hmfree(map); + length = end(); + rdtsc_scale = length / (t1-t0) * 1000; + + for (j=1; j < last_step; ++j) + mstats[0][j].start = mstats[0][0].start; + for (j=first_step-1; j < last_step; ++j) { + printf("%12.4f,%12d,%12d,0,0,0\n", (mstats[0][j].end - mstats[0][j].start) * rdtsc_scale, mstats[0][j].table_size, mstats[0][j].table_size); + } +} + +#ifdef STBDS_FLUSH_CACHE +static int cache_index; +char dummy[8][STBDS_FLUSH_CACHE]; + +int flush_cache(void) +{ + memmove(dummy[cache_index],dummy[cache_index]+1, sizeof(dummy[cache_index])-1); + cache_index = (cache_index+1)%8; + return dummy[cache_index][0]; +} +#else +int flush_cache(void) { return 0; } +#endif + +int measure_average_lookup4(int step_log2) +{ + int total; + double length; + int i,j,k=0,q; + int step = 1 << step_log2; + unsigned __int64 t0,t1; + struct { int key,value; } *map=NULL; + double rdtsc_scale; + begin(); + t0 = __rdtsc(); + + for (i=0; i < 128; ++i) { + hmput(map,k,k+1); + k += step; + } + for (j=first_step; j <= last_step; ++j) { + total += flush_cache(); + mstats[0][j].start = __rdtsc(); + for (q=i=0; i < 50000; ++i) { + total += hmget(map, q); // hit + if (++q == k) q = 0; + } + mstats[0][j].end = __rdtsc(); + mstats[0][j].table_size = k; + total += flush_cache(); + mstats[1][j].start = __rdtsc(); + for (i=0; i < 50000; ++i) { + total += hmget(map, i+k); // miss + } + mstats[1][j].end = __rdtsc(); + mstats[1][j].table_size = k; + + // expand table + for (i=0; i < (1<<(j>>4)); ++i) { + hmput(map, k,k+1); + k += step; + } + } + + t1 = __rdtsc(); + measure(); + hmfree(map); + length = end(); + rdtsc_scale = length / (t1-t0) * 1000; + + for (j=first_step; j <= last_step; ++j) { + // time,table_size,numins,numhit,nummiss,numperflush + printf("%12.4f,%12d,0,50000,0,0\n", (mstats[0][j].end - mstats[0][j].start) * rdtsc_scale, mstats[0][j].table_size); + } + for (j=first_step; j <= last_step; ++j) { + printf("%12.4f,%12d,0,0,50000,0\n", (mstats[1][j].end - mstats[1][j].start) * rdtsc_scale, mstats[1][j].table_size); + } + return total; +} + +int measure_worst_lookup4_a(int step_log2) +{ + int total; + double length; + int i,j,k=0,q,worst_q,n,z,attempts; + int step = 1 << step_log2; + unsigned __int64 t0,t1; + unsigned __int64 m0,m1,worst; + struct { int key,value; } *map=NULL; + double rdtsc_scale; + begin(); + t0 = __rdtsc(); + + memset(mstats, 0, sizeof(mstats)); + for (j=first_step; j <= last_step; ++j) + mstats[0][j].end = mstats[1][j].end = ~(unsigned __int64) 0; + + for(attempts=0; attempts < 2; ++attempts) { + k = 0; + stbds_rand_seed(0); // force us to get the same table every time + for (i=0; i < 128; ++i) { + hmput(map,k,k+1); + k += step; + } + for (j=first_step; j <= last_step; ++j) { + unsigned __int64 times[32]; + + // find the worst hit time + for (z=0; z < 2; ++z) { // try the bisectioning measurement 4 times + worst = 0; + for (n=0; n < 10; ++n) { // test 400 keys total + // find the worst time to hit 20 keys + q=0; + worst_q = 0; + total += flush_cache(); + m0 = __rdtsc(); + for (i=0; i < 20; ++i) { + total += hmget(map, q); // hit + if (++q == k) q = 0; + } + m1 = __rdtsc(); + // for each n, check if this is the worst lookup we've seen + if (m1 - m0 > worst) { + worst = m1-m0; + worst_q = q - i; + if (worst_q < 0) q += k; + } + } + // after 400 keys, take the worst 20 keys, and try each one + worst = 0; + q = worst_q; + for (i=0; i < 20; ++i) { + total += flush_cache(); + m0 = __rdtsc(); + total += hmget(map, q); // hit + m1 = __rdtsc(); + if (m1 - m0 > worst) + worst = m1-m0; + if (++q == k) q = 0; + } + times[z] = worst; + } + // find the worst time in the bunch + worst = 0; + for (i=0; i < z; ++i) + if (times[i] > worst) + worst = times[i]; + // take the best of 'attempts', to discard outliers + if (worst < mstats[0][j].end) + mstats[0][j].end = worst; + mstats[0][j].start = 0; + mstats[0][j].table_size = k >> step_log2; + + // find the worst miss time + for (z=0; z < 8; ++z) { // try the bisectioning measurement 8 times + worst = 0; + for (n=0; n < 20; ++n) { // test 400 keys total + // find the worst time to hit 20 keys + q=k; + worst_q = 0; + total += flush_cache(); + m0 = __rdtsc(); + for (i=0; i < 20; ++i) { + total += hmget(map, q); // hit + } + m1 = __rdtsc(); + // for each n, check if this is the worst lookup we've seen + if (m1 - m0 > worst) { + worst = m1-m0; + worst_q = q - i; + } + } + // after 400 keys, take the worst 20 keys, and try each one + worst = 0; + q = worst_q; + for (i=0; i < 20; ++i) { + total += flush_cache(); + m0 = __rdtsc(); + total += hmget(map, q); // hit + m1 = __rdtsc(); + if (m1 - m0 > worst) + worst = m1-m0; + } + times[z] = worst; + } + // find the worst time in the bunch + worst = 0; + for (i=0; i < z; ++i) + if (times[i] > worst) + worst = times[i]; + if (worst < mstats[1][j].end) + mstats[1][j].end = worst; + mstats[1][j].start = 0; + mstats[1][j].table_size = k >> step_log2; + + // expand table + for (i=0; i < (1<<(j>>4)); ++i) { + hmput(map, k,k+1); + k += step; + } + } + hmfree(map); + } + + t1 = __rdtsc(); + measure(); + length = end(); + rdtsc_scale = length / (t1-t0) * 1000; + + for (j=first_step; j <= last_step; ++j) { + printf("%12.4f,%12d,0,1,0,1\n", (mstats[0][j].end - mstats[0][j].start) * rdtsc_scale, mstats[0][j].table_size); + } + for (j=first_step; j <= last_step; ++j) { + printf("%12.4f,%12d,0,0,1,1\n", (mstats[1][j].end - mstats[1][j].start) * rdtsc_scale, mstats[1][j].table_size); + } + return total; +} + +int measure_worst_lookup4_b(int step_log2) +{ + int total; + double length; + int i,j,k=0,q,worst_q,n,z,attempts; + int step = 1 << step_log2; + unsigned __int64 t0,t1; + unsigned __int64 m0,m1,worst; + struct { int key,value; } *map=NULL; + double rdtsc_scale; + begin(); + t0 = __rdtsc(); + + memset(mstats, 0, sizeof(mstats)); + for (j=first_step; j <= last_step; ++j) + mstats[0][j].end = mstats[1][j].end = ~(unsigned __int64) 0; + + k = 0; + stbds_rand_seed(0); // force us to get the same table every time + for (i=0; i < 128; ++i) { + hmput(map,k,k+1); + k += step; + } + for (j=first_step; j <= last_step; ++j) { + unsigned __int64 times[32]; + + // find the worst hit time + for (z=0; z < 8; ++z) { // try this 8 times + worst = 0; + q=0; + for (i=0; i < 5000; ++i) { + total += hmget(map, q); + m0 = __rdtsc(); + total += hmget(map, q); + m1 = __rdtsc(); + if (m1 - m0 > worst) { + worst = m1-m0; + worst_q = q - i; + } + if (++q == k) q = 0; + } + // now retry with the worst one, but find the shortest time for it + worst = ~(unsigned __int64) 0; + for (i=0; i < 4; ++i) { + total += flush_cache(); + m0 = __rdtsc(); + total += hmget(map,worst_q); + m1 = __rdtsc(); + if (m1-m0 < worst) + worst = m1-m0; + } + times[z] = worst; + } + + // find the worst of those + worst = 0; + for (i=0; i < z; ++i) + if (times[i] > worst) + worst = times[i]; + mstats[0][j].start = 0; + mstats[0][j].end = worst; + mstats[0][j].table_size = k; + + // find the worst miss time + for (z=0; z < 8; ++z) { // try this 8 times + worst = 0; + q=k; + for (i=0; i < 5000; ++i) { + total += hmget(map, q); + m0 = __rdtsc(); + total += hmget(map, q); + m1 = __rdtsc(); + if (m1 - m0 > worst) { + worst = m1-m0; + worst_q = q - i; + } + //printf("%6llu ", m1-m0); + } + // now retry with the worst one, but find the shortest time for it + worst = ~(unsigned __int64) 0; + for (i=0; i < 4; ++i) { + total += flush_cache(); + m0 = __rdtsc(); + total += hmget(map,worst_q); + m1 = __rdtsc(); + if (m1-m0 < worst) + worst = m1-m0; + } + times[z] = worst; + } + + // find the worst of those + worst = 0; + for (i=0; i < z; ++i) + if (times[i] > worst) + worst = times[i]; + mstats[1][j].start = 0; + mstats[1][j].end = worst; + mstats[1][j].table_size = k; + + // expand table + for (i=0; i < (1<<(j>>4)); ++i) { + hmput(map, k,k+1); + k += step; + } + } + hmfree(map); + + t1 = __rdtsc(); + measure(); + length = end(); + rdtsc_scale = length / (t1-t0) * 1000; + + for (j=first_step+1; j <= last_step; ++j) { + printf("%12.4f,%12d,0,1,0,1\n", (mstats[0][j].end - mstats[0][j].start) * rdtsc_scale, mstats[0][j].table_size); + } + for (j=first_step+1; j <= last_step; ++j) { + printf("%12.4f,%12d,0,0,1,1\n", (mstats[1][j].end - mstats[1][j].start) * rdtsc_scale, mstats[1][j].table_size); + } + return total; +} + +int measure_uncached_lookup4(int step_log2) +{ + int total; + double length; + int i,j,k=0,q; + int step = 1 << step_log2; + unsigned __int64 t0,t1; + struct { int key,value; } *map=NULL; + double rdtsc_scale; + begin(); + t0 = __rdtsc(); + + map = NULL; + for (i=0; i < 128; ++i) { + hmput(map,k,k+1); + k += step; + } + for (j=first_step; j <= last_step; ++j) { + mstats[0][j].start = __rdtsc(); + mstats[0][j].end = 0; + for (q=i=0; i < 512; ++i) { + if ((i & 3) == 0) { + mstats[0][j].end += __rdtsc(); + total += flush_cache(); + mstats[0][j].start += __rdtsc(); + } + total += hmget(map, q); // hit + if (++q == k) q = 0; + } + mstats[0][j].end += __rdtsc(); + mstats[0][j].table_size = k; + total += flush_cache(); + mstats[1][j].end = 0; + mstats[1][j].start = __rdtsc(); + for (i=0; i < 512; ++i) { + if ((i & 3) == 0) { + mstats[1][j].end += __rdtsc(); + total += flush_cache(); + mstats[1][j].start += __rdtsc(); + } + total += hmget(map, i+k); // miss + } + mstats[1][j].end += __rdtsc(); + mstats[1][j].table_size = k; + + // expand table + for (i=0; i < (1<<(j>>4)); ++i) { + hmput(map, k,k+1); + k += step; + } + } + hmfree(map); + + t1 = __rdtsc(); + measure(); + length = end(); + rdtsc_scale = length / (t1-t0) * 1000; + + for (j=first_step; j <= last_step; ++j) { + printf("%12.4f,%12d,0,512,0,4\n", (mstats[0][j].end - mstats[0][j].start) * rdtsc_scale, mstats[0][j].table_size); + } + for (j=first_step; j <= last_step; ++j) { + printf("%12.4f,%12d,0,0,512,4\n", (mstats[1][j].end - mstats[1][j].start) * rdtsc_scale, mstats[1][j].table_size); + } + return total; +} + + + int main(int arg, char **argv) { int n,s,w; double worst = 0; + printf("# size_t=%d,", (int) sizeof(size_t)); + +// number of cache-lines +#ifdef STBDS_SMALL_BUCKET + printf("cacheline=%d,", 1); +#else + printf("cacheline=%d,", sizeof(size_t)==8 ? 2 : 1); +#endif +#ifdef STBDS_FLUSH_CACHE + printf("%d,", (int) stbds_log2(STBDS_FLUSH_CACHE)); +#else + printf("0,"); +#endif +#ifdef STBDS_BUCKET_START // don't bother offseting differently within bucket for different hash values + printf("STBDS_BUCKET_START,"); +#else + printf(","); +#endif +#ifdef STBDS_SIPHASH_2_4 + printf("STBDS_SIPHASH_2_4,"); +#else + printf(","); +#endif + printf("\n"); + + measure_worst_lookup4_b(0); + //measure_worst_lookup4_a(0); + measure_average_lookup4(0); + measure_uncached_lookup4(0); + measure_build4(0); + return 0; + #if 0 begin(); for (n=0; n < 2000; ++n) { build_stb(2000,0,0,1); } end(); printf(" // %7.2fms : 2,000 inserts creating 2K table\n", timer); begin(); for (n=0; n < 500; ++n) { build_stb(20000,0,0,1); } end(); printf(" // %7.2fms : 20,000 inserts creating 20K table\n", timer); @@ -357,12 +946,6 @@ int main(int arg, char **argv) begin(); for (n=0; n < 5; ++n) { build_stb(20000000,0,0,1); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 20M table\n", timer); #endif - begin(); for (n=0; n < 2000; ++n) { churn8(2000,0,0,1); } end(); printf(" // %7.2fms : 2,000 inserts creating 2K table w/ 8-byte key\n", timer); - begin(); for (n=0; n < 500; ++n) { churn8(20000,0,0,1); } end(); printf(" // %7.2fms : 20,000 inserts creating 20K table w/ 8-byte key\n", timer); - begin(); for (n=0; n < 100; ++n) { churn8(200000,0,0,1); } end(); printf(" // %7.2fms : 200,000 inserts creating 200K table w/ 8-byte key\n", timer); - begin(); for (n=0; n < 10; ++n) { churn8(2000000,0,0,1); } end(); printf(" // %7.2fms : 2,000,000 inserts creating 2M table w/ 8-byte key\n", timer); - begin(); for (n=0; n < 5; ++n) { churn8(20000000,0,0,1); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 20M table w/ 8-byte key\n", timer); - #if 0 begin(); for (n=0; n < 2000; ++n) { churn32(2000,0,0,1); } end(); printf(" // %7.2fms : 2,000 inserts creating 2K table w/ 32-byte key\n", timer); begin(); for (n=0; n < 500; ++n) { churn32(20000,0,0,1); } end(); printf(" // %7.2fms : 20,000 inserts creating 20K table w/ 32-byte key\n", timer); @@ -377,12 +960,41 @@ int main(int arg, char **argv) begin(); for (n=0; n < 5; ++n) { churn256(20000000,0,0,1); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 20M table w/ 256-byte key\n", timer); #endif + begin(); for (n=0; n < 20; ++n) { multisearch_stb(2000,0,2000,1,1000); } end(); printf(" // %7.2fms : 2,000,000 hits on 1,000 2K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 10; ++n) { multisearch_stb(20000,0,2000,1,1000); } end(); printf(" // %7.2fms : 2,000,000 hits on 1,000 20K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 6; ++n) { multisearch_stb(200000,0,2000,1,1000); } end(); printf(" // %7.2fms : 2,000,000 hits on 1,000 200K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 2; ++n) { multisearch_stb(2000000,0,20000,1,100); } end(); printf(" // %7.2fms : 2,000,000 hits on 100 2M table w/ 4-byte key\n", timer); + + begin(); for (n=0; n < 20; ++n) { multisearch (2000,0,2000,1,1000); } end(); printf(" // %7.2fms : 2,000,000 hits on 1,000 2K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 10; ++n) { multisearch (20000,0,2000,1,1000); } end(); printf(" // %7.2fms : 2,000,000 hits on 1,000 20K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 6; ++n) { multisearch (200000,0,2000,1,1000); } end(); printf(" // %7.2fms : 2,000,000 hits on 1,000 200K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 2; ++n) { multisearch (2000000,0,20000,1,100); } end(); printf(" // %7.2fms : 2,000,000 hits on 100 2M table w/ 4-byte key\n", timer); + + +#if 1 + begin(); for (n=0; n < 2; ++n) { multibuild_stb(2000,0,0,1,10000); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 10,000 2K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 2; ++n) { multibuild_stb(20000,0,0,1,1000); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 1,000 20K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 2; ++n) { multibuild_stb(200000,0,0,1,100); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 100 200K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 2; ++n) { multibuild_stb(2000000,0,0,1,10); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 10 2M table w/ 4-byte key\n", timer); + + begin(); for (n=0; n < 2; ++n) { multichurn4(2000,0,0,1,10000); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 10,000 2K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 2; ++n) { multichurn4(20000,0,0,1,1000); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 1,000 20K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 2; ++n) { multichurn4(200000,0,0,1,100); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 100 200K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 2; ++n) { multichurn4(2000000,0,0,1,10); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 10 2M table w/ 4-byte key\n", timer); +#endif + begin(); for (n=0; n < 2000; ++n) { build(2000,0,0,1); } end(); printf(" // %7.2fms : 2,000 inserts creating 2K table w/ 4-byte key\n", timer); begin(); for (n=0; n < 500; ++n) { build(20000,0,0,1); } end(); printf(" // %7.2fms : 20,000 inserts creating 20K table w/ 4-byte key\n", timer); begin(); for (n=0; n < 100; ++n) { build(200000,0,0,1); } end(); printf(" // %7.2fms : 200,000 inserts creating 200K table w/ 4-byte key\n", timer); begin(); for (n=0; n < 10; ++n) { build(2000000,0,0,1); } end(); printf(" // %7.2fms : 2,000,000 inserts creating 2M table w/ 4-byte key\n", timer); begin(); for (n=0; n < 5; ++n) { build(20000000,0,0,1); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 20M table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 2000; ++n) { churn8(2000,0,0,1); } end(); printf(" // %7.2fms : 2,000 inserts creating 2K table w/ 8-byte key\n", timer); + begin(); for (n=0; n < 500; ++n) { churn8(20000,0,0,1); } end(); printf(" // %7.2fms : 20,000 inserts creating 20K table w/ 8-byte key\n", timer); + begin(); for (n=0; n < 100; ++n) { churn8(200000,0,0,1); } end(); printf(" // %7.2fms : 200,000 inserts creating 200K table w/ 8-byte key\n", timer); + begin(); for (n=0; n < 10; ++n) { churn8(2000000,0,0,1); } end(); printf(" // %7.2fms : 2,000,000 inserts creating 2M table w/ 8-byte key\n", timer); + begin(); for (n=0; n < 5; ++n) { churn8(20000000,0,0,1); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 20M table w/ 8-byte key\n", timer); + begin(); for (n=0; n < 60; ++n) { churn_skip(2000,2100,5000); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 2K table\n", timer); begin(); for (n=0; n < 30; ++n) { churn_skip(20000,21000,500); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 20K table\n", timer); begin(); for (n=0; n < 15; ++n) { churn_skip(200000,201000,500); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 200K table\n", timer); diff --git a/tests/test_ds_cpp.cpp b/tests/test_ds_cpp.cpp new file mode 100644 index 0000000..fce99df --- /dev/null +++ b/tests/test_ds_cpp.cpp @@ -0,0 +1,418 @@ +#include + +#ifdef DS_TEST +#define STBDS_UNIT_TESTS +#endif + +#ifdef DS_STATS +#define STBDS_STATISTICS +#endif + +#ifndef DS_PERF +#define STBDS_ASSERT assert +#include +#endif + +//#define STBDS_SIPHASH_2_4 +#define STB_DS_IMPLEMENTATION +#include "../stb_ds.h" + +size_t churn_inserts, churn_deletes; + +void churn(int a, int b, int count) +{ + struct { int key,value; } *map=NULL; + int i,j,n,k; + for (i=0; i < a; ++i) + hmput(map,i,i+1); + for (n=0; n < count; ++n) { + for (j=a; j < b; ++j,++i) { + hmput(map,i,i+1); + } + assert(hmlen(map) == b); + for (j=a; j < b; ++j) { + k=i-j-1; + k = hmdel(map,k); + assert(k != 0); + } + assert(hmlen(map) == a); + } + hmfree(map); + churn_inserts = i; + churn_deletes = (b-a) * n; +} + +#ifdef DS_TEST +#include +int main(int argc, char **argv) +{ + stbds_unit_tests(); + churn(0,100,1); + churn(3,7,50000); + churn(3,15,50000); + churn(16, 48, 25000); + churn(10, 15, 25000); + churn(200,500, 5000); + churn(2000,5000, 500); + churn(20000,50000, 50); + printf("Ok!"); + return 0; +} +#endif + +#ifdef DS_STATS +#define MAX(a,b) ((a) > (b) ? (a) : (b)) +size_t max_hit_probes, max_miss_probes, total_put_probes, total_miss_probes, churn_misses; +void churn_stats(int a, int b, int count) +{ + struct { int key,value; } *map=NULL; + int i,j,n,k; + churn_misses = 0; + for (i=0; i < a; ++i) { + hmput(map,i,i+1); + max_hit_probes = MAX(max_hit_probes, stbds_hash_probes); + total_put_probes += stbds_hash_probes; + stbds_hash_probes = 0; + } + + for (n=0; n < count; ++n) { + for (j=a; j < b; ++j,++i) { + hmput(map,i,i+1); + max_hit_probes = MAX(max_hit_probes, stbds_hash_probes); + total_put_probes += stbds_hash_probes; + stbds_hash_probes = 0; + } + for (j=0; j < (b-a)*10; ++j) { + k=i+j; + (void) hmgeti(map,k); // miss + max_miss_probes = MAX(max_miss_probes, stbds_hash_probes); + total_miss_probes += stbds_hash_probes; + stbds_hash_probes = 0; + ++churn_misses; + } + assert(hmlen(map) == b); + for (j=a; j < b; ++j) { + k=i-j-1; + k = hmdel(map,k); + stbds_hash_probes = 0; + assert(k); + } + assert(hmlen(map) == a); + } + hmfree(map); + churn_inserts = i; + churn_deletes = (b-a) * n; +} + +void reset_stats(void) +{ + stbds_array_grow=0, + stbds_hash_grow=0; + stbds_hash_shrink=0; + stbds_hash_rebuild=0; + stbds_hash_probes=0; + stbds_hash_alloc=0; + stbds_rehash_probes=0; + stbds_rehash_items=0; + max_hit_probes = 0; + max_miss_probes = 0; + total_put_probes = 0; + total_miss_probes = 0; +} + +void print_churn_probe_stats(char *str) +{ + printf("Probes: %3d max hit, %3d max miss, %4.2f avg hit, %4.2f avg miss: %s\n", + (int) max_hit_probes, (int) max_miss_probes, (float) total_put_probes / churn_inserts, (float) total_miss_probes / churn_misses, str); + reset_stats(); +} + +int main(int arg, char **argv) +{ + churn_stats(0,500000,1); print_churn_probe_stats("Inserting 500000 items"); + churn_stats(0,500000,1); print_churn_probe_stats("Inserting 500000 items"); + churn_stats(0,500000,1); print_churn_probe_stats("Inserting 500000 items"); + churn_stats(0,500000,1); print_churn_probe_stats("Inserting 500000 items"); + churn_stats(49000,50000,500); print_churn_probe_stats("Deleting/Inserting 500000 items"); + churn_stats(49000,50000,500); print_churn_probe_stats("Deleting/Inserting 500000 items"); + churn_stats(49000,50000,500); print_churn_probe_stats("Deleting/Inserting 500000 items"); + churn_stats(49000,50000,500); print_churn_probe_stats("Deleting/Inserting 500000 items"); + return 0; +} +#endif + +#ifdef DS_PERF +#define WIN32_LEAN_AND_MEAN +#include +#define STB_DEFINE +#define STB_NO_REGISTRY +//#include "../stb.h" + + +size_t t0, sum, mn,mx,count; +void begin(void) +{ + size_t t0; + LARGE_INTEGER m; + QueryPerformanceCounter(&m); + t0 = m.QuadPart; + sum = 0; + count = 0; + mx = 0; + mn = ~(size_t) 0; +} + +void measure(void) +{ + size_t t1, t; + LARGE_INTEGER m; + QueryPerformanceCounter(&m); + t1 = m.QuadPart; + t = t1-t0; + if (t1 < t0) + printf("ALERT: QueryPerformanceCounter was unordered!\n"); + if (t < mn) mn = t; + if (t > mx) mx = t; + sum += t; + ++count; + t0 = t1; +} + +void dont_measure(void) +{ + size_t t1, t; + LARGE_INTEGER m; + QueryPerformanceCounter(&m); + t0 = m.QuadPart; +} + +double timer; +void end(void) +{ + LARGE_INTEGER m; + QueryPerformanceFrequency(&m); + + if (count > 3) { + // discard the highest and lowest + sum -= mn; + sum -= mx; + count -= 2; + } + timer = (double) (sum) / count / m.QuadPart * 1000; +} + +void build(int a, int b, int count, int step) +{ + struct { int key,value; } *map=NULL; + int i,j,n,k; + for (i=0; i < a; ++i) + hmput(map,i*step,i+1); + measure(); + churn_inserts = i; + hmfree(map); + dont_measure(); +} + +#ifdef STB__INCLUDE_STB_H +void build_stb(int a, int b, int count, int step) +{ + stb_idict *d = stb_idict_new_size(8); + struct { int key,value; } *map=NULL; + int i,j,n,k; + for (i=0; i < a; ++i) + stb_idict_add(d, i*step, i+1); + measure(); + churn_inserts = i; + stb_idict_destroy(d); + dont_measure(); +} +#endif + +void churn_skip(unsigned int a, unsigned int b, int count) +{ + struct { unsigned int key,value; } *map=NULL; + unsigned int i,j,n,k; + for (i=0; i < a; ++i) + hmput(map,i,i+1); + dont_measure(); + for (n=0; n < count; ++n) { + for (j=a; j < b; ++j,++i) { + hmput(map,i,i+1); + } + assert(hmlen(map) == b); + for (j=a; j < b; ++j) { + k=i-j-1; + k = hmdel(map,k); + assert(k != 0); + } + assert(hmlen(map) == a); + } + measure(); + churn_inserts = i; + churn_deletes = (b-a) * n; + hmfree(map); + dont_measure(); +} + +typedef struct { int n[8]; } str32; +void churn32(int a, int b, int count, int include_startup) +{ + struct { str32 key; int value; } *map=NULL; + int i,j,n; + str32 key = { 0 }; + for (i=0; i < a; ++i) { + key.n[0] = i; + hmput(map,key,i+1); + } + if (!include_startup) + dont_measure(); + for (n=0; n < count; ++n) { + for (j=a; j < b; ++j,++i) { + key.n[0] = i; + hmput(map,key,i+1); + } + assert(hmlen(map) == b); + for (j=a; j < b; ++j) { + key.n[0] = i-j-1; + hmdel(map,key); + } + assert(hmlen(map) == a); + } + measure(); + hmfree(map); + churn_inserts = i; + churn_deletes = (b-a) * n; + dont_measure(); +} + +typedef struct { int n[32]; } str256; +void churn256(int a, int b, int count, int include_startup) +{ + struct { str256 key; int value; } *map=NULL; + int i,j,n; + str256 key = { 0 }; + for (i=0; i < a; ++i) { + key.n[0] = i; + hmput(map,key,i+1); + } + if (!include_startup) + dont_measure(); + for (n=0; n < count; ++n) { + for (j=a; j < b; ++j,++i) { + key.n[0] = i; + hmput(map,key,i+1); + } + assert(hmlen(map) == b); + for (j=a; j < b; ++j) { + key.n[0] = i-j-1; + hmdel(map,key); + } + assert(hmlen(map) == a); + } + measure(); + hmfree(map); + churn_inserts = i; + churn_deletes = (b-a) * n; + dont_measure(); +} + +void churn8(int a, int b, int count, int include_startup) +{ + struct { size_t key,value; } *map=NULL; + int i,j,n,k; + for (i=0; i < a; ++i) + hmput(map,i,i+1); + if (!include_startup) + dont_measure(); + for (n=0; n < count; ++n) { + for (j=a; j < b; ++j,++i) { + hmput(map,i,i+1); + } + assert(hmlen(map) == b); + for (j=a; j < b; ++j) { + k=i-j-1; + k = hmdel(map,k); + assert(k != 0); + } + assert(hmlen(map) == a); + } + measure(); + hmfree(map); + churn_inserts = i; + churn_deletes = (b-a) * n; + dont_measure(); +} + + +int main(int arg, char **argv) +{ + int n,s,w; + double worst = 0; + +#if 0 + begin(); for (n=0; n < 2000; ++n) { build_stb(2000,0,0,1); } end(); printf(" // %7.2fms : 2,000 inserts creating 2K table\n", timer); + begin(); for (n=0; n < 500; ++n) { build_stb(20000,0,0,1); } end(); printf(" // %7.2fms : 20,000 inserts creating 20K table\n", timer); + begin(); for (n=0; n < 100; ++n) { build_stb(200000,0,0,1); } end(); printf(" // %7.2fms : 200,000 inserts creating 200K table\n", timer); + begin(); for (n=0; n < 10; ++n) { build_stb(2000000,0,0,1); } end(); printf(" // %7.2fms : 2,000,000 inserts creating 2M table\n", timer); + begin(); for (n=0; n < 5; ++n) { build_stb(20000000,0,0,1); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 20M table\n", timer); +#endif + + begin(); for (n=0; n < 2000; ++n) { churn8(2000,0,0,1); } end(); printf(" // %7.2fms : 2,000 inserts creating 2K table w/ 8-byte key\n", timer); + begin(); for (n=0; n < 500; ++n) { churn8(20000,0,0,1); } end(); printf(" // %7.2fms : 20,000 inserts creating 20K table w/ 8-byte key\n", timer); + begin(); for (n=0; n < 100; ++n) { churn8(200000,0,0,1); } end(); printf(" // %7.2fms : 200,000 inserts creating 200K table w/ 8-byte key\n", timer); + begin(); for (n=0; n < 10; ++n) { churn8(2000000,0,0,1); } end(); printf(" // %7.2fms : 2,000,000 inserts creating 2M table w/ 8-byte key\n", timer); + begin(); for (n=0; n < 5; ++n) { churn8(20000000,0,0,1); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 20M table w/ 8-byte key\n", timer); + +#if 0 + begin(); for (n=0; n < 2000; ++n) { churn32(2000,0,0,1); } end(); printf(" // %7.2fms : 2,000 inserts creating 2K table w/ 32-byte key\n", timer); + begin(); for (n=0; n < 500; ++n) { churn32(20000,0,0,1); } end(); printf(" // %7.2fms : 20,000 inserts creating 20K table w/ 32-byte key\n", timer); + begin(); for (n=0; n < 100; ++n) { churn32(200000,0,0,1); } end(); printf(" // %7.2fms : 200,000 inserts creating 200K table w/ 32-byte key\n", timer); + begin(); for (n=0; n < 10; ++n) { churn32(2000000,0,0,1); } end(); printf(" // %7.2fms : 2,000,000 inserts creating 2M table w/ 32-byte key\n", timer); + begin(); for (n=0; n < 5; ++n) { churn32(20000000,0,0,1); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 20M table w/ 32-byte key\n", timer); + + begin(); for (n=0; n < 2000; ++n) { churn256(2000,0,0,1); } end(); printf(" // %7.2fms : 2,000 inserts creating 2K table w/ 256-byte key\n", timer); + begin(); for (n=0; n < 500; ++n) { churn256(20000,0,0,1); } end(); printf(" // %7.2fms : 20,000 inserts creating 20K table w/ 256-byte key\n", timer); + begin(); for (n=0; n < 100; ++n) { churn256(200000,0,0,1); } end(); printf(" // %7.2fms : 200,000 inserts creating 200K table w/ 256-byte key\n", timer); + begin(); for (n=0; n < 10; ++n) { churn256(2000000,0,0,1); } end(); printf(" // %7.2fms : 2,000,000 inserts creating 2M table w/ 256-byte key\n", timer); + begin(); for (n=0; n < 5; ++n) { churn256(20000000,0,0,1); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 20M table w/ 256-byte key\n", timer); +#endif + + begin(); for (n=0; n < 2000; ++n) { build(2000,0,0,1); } end(); printf(" // %7.2fms : 2,000 inserts creating 2K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 500; ++n) { build(20000,0,0,1); } end(); printf(" // %7.2fms : 20,000 inserts creating 20K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 100; ++n) { build(200000,0,0,1); } end(); printf(" // %7.2fms : 200,000 inserts creating 200K table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 10; ++n) { build(2000000,0,0,1); } end(); printf(" // %7.2fms : 2,000,000 inserts creating 2M table w/ 4-byte key\n", timer); + begin(); for (n=0; n < 5; ++n) { build(20000000,0,0,1); } end(); printf(" // %7.2fms : 20,000,000 inserts creating 20M table w/ 4-byte key\n", timer); + + begin(); for (n=0; n < 60; ++n) { churn_skip(2000,2100,5000); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 2K table\n", timer); + begin(); for (n=0; n < 30; ++n) { churn_skip(20000,21000,500); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 20K table\n", timer); + begin(); for (n=0; n < 15; ++n) { churn_skip(200000,201000,500); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 200K table\n", timer); + begin(); for (n=0; n < 8; ++n) { churn_skip(2000000,2001000,500); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 2M table\n", timer); + begin(); for (n=0; n < 5; ++n) { churn_skip(20000000,20001000,500); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 20M table\n", timer); + begin(); for (n=0; n < 1; ++n) { churn_skip(200000000u,200001000u,500); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 200M table\n", timer); + // even though the above measures a roughly fixed amount of work, we still have to build the table n times, hence the fewer measurements each time + + begin(); for (n=0; n < 60; ++n) { churn_skip(1000,3000,250); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 2K table\n", timer); + begin(); for (n=0; n < 15; ++n) { churn_skip(10000,30000,25); } end(); printf(" // %7.2fms : 500,000 inserts & deletes in 20K table\n", timer); + begin(); for (n=0; n < 7; ++n) { churn_skip(100000,300000,10); } end(); printf(" // %7.2fms : 2,000,000 inserts & deletes in 200K table\n", timer); + begin(); for (n=0; n < 2; ++n) { churn_skip(1000000,3000000,10); } end(); printf(" // %7.2fms : 20,000,000 inserts & deletes in 2M table\n", timer); + + // search for bad intervals.. in practice this just seems to measure execution variance + for (s = 2; s < 64; ++s) { + begin(); for (n=0; n < 50; ++n) { build(200000,0,0,s); } end(); + if (timer > worst) { + worst = timer; + w = s; + } + } + for (; s <= 1024; s *= 2) { + begin(); for (n=0; n < 50; ++n) { build(200000,0,0,s); } end(); + if (timer > worst) { + worst = timer; + w = s; + } + } + printf(" // %7.2fms(%d) : Worst time from inserting 200,000 items with spacing %d.\n", worst, w, w); + + return 0; +} +#endif diff --git a/tests/test_easyfont.c b/tests/test_easyfont.c index 70f284b..25d54ff 100644 --- a/tests/test_easyfont.c +++ b/tests/test_easyfont.c @@ -1 +1,10 @@ #include "stb_easy_font.h" + +void ef_dummy(void) +{ + // suppress unsused-function warning + stb_easy_font_spacing(0); + stb_easy_font_print(0,0,0,0,0,0); + stb_easy_font_width(0); + stb_easy_font_height(0); +} \ No newline at end of file diff --git a/tests/test_image.c b/tests/test_image.c index 764ce33..de2c8b0 100644 --- a/tests/test_image.c +++ b/tests/test_image.c @@ -1,3 +1,7 @@ +#ifdef __clang__ +#define STBIDEF static inline +#endif + #define STB_IMAGE_STATIC #define STB_IMAGE_IMPLEMENTATION #include "stb_image.h" \ No newline at end of file diff --git a/tests/test_image_write.c b/tests/test_image_write.c index 52c3b44..8c4c35c 100644 --- a/tests/test_image_write.c +++ b/tests/test_image_write.c @@ -1,3 +1,7 @@ +#ifdef __clang__ +#define STBIWDEF static inline +#endif + #define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_STATIC #include "stb_image_write.h" \ No newline at end of file diff --git a/tests/test_vorbis.c b/tests/test_vorbis.c index 341a102..d54ed23 100644 --- a/tests/test_vorbis.c +++ b/tests/test_vorbis.c @@ -1,7 +1,3 @@ -#define STB_IMAGE_STATIC -#define STB_IMAGE_IMPLEMENTATION -#include "stb_image.h" - #define STB_VORBIS_HEADER_ONLY #include "stb_vorbis.c" #include "stb.h" diff --git a/tests/textedit_sample.c b/tests/textedit_sample.c index 04dc31a..57250f3 100644 --- a/tests/textedit_sample.c +++ b/tests/textedit_sample.c @@ -82,3 +82,13 @@ int insert_chars(STB_TEXTEDIT_STRING *str, int pos, STB_TEXTEDIT_CHARTYPE *newte #define STB_TEXTEDIT_IMPLEMENTATION #include "stb_textedit.h" + +void dummy3(void) +{ + stb_textedit_click(0,0,0,0); + stb_textedit_drag(0,0,0,0); + stb_textedit_cut(0,0); + stb_textedit_key(0,0,0); + stb_textedit_initialize_state(0,0); + stb_textedit_paste(0,0,0,0); +}