Merge branch 'master' into working

This commit is contained in:
Sean Barrett 2019-03-04 14:56:00 -08:00
commit d940053a01
27 changed files with 1653 additions and 517 deletions

679
stb.h

File diff suppressed because it is too large Load Diff

View File

@ -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 <stdio.h>
#include <stdlib.h>
@ -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");

View File

@ -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;
}
}
}

View File

@ -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<class T> static T * stbds_shmode_func_wrapper(T *, size_t elemsize, int
#include <string.h>
#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 <stdio.h>
#ifdef STBDS_ASSERT_WAS_UNDEFINED
#undef STBDS_ASSERT
#endif
#ifndef STBDS_ASSERT
#define STBDS_ASSERT assert
#include <assert.h>
@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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];

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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"

View File

@ -1,3 +1,4 @@
#define _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <stdio.h>
@ -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;

View File

@ -2,6 +2,7 @@
* Unit tests for "stb.h"
*/
#define _CRT_SECURE_NO_WARNINGS
//#include <windows.h>
#include <stdio.h>
#include <string.h>
@ -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

View File

@ -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");

12
tests/stb_static.c Normal file
View File

@ -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"

View File

@ -1 +1,7 @@
#include "stretchy_buffer.h"
void test_sb(void)
{
char *x = NULL;
sb_push(x, 'x');
}

37
tests/test.sbm Normal file
View File

@ -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

View File

@ -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);
}

View File

@ -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 <windows.h>
#define STB_DEFINE
#define STB_NO_REGISTRY
#include "../stb.h"
#include <stdio.h>
#endif
#ifdef DS_TEST
#define STBDS_UNIT_TESTS
#define STBDS_SMALL_BUCKET
#endif
#ifdef DS_STATS
@ -13,7 +31,6 @@
#include <assert.h>
#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 <windows.h>
#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);

418
tests/test_ds_cpp.cpp Normal file
View File

@ -0,0 +1,418 @@
#include <stdio.h>
#ifdef DS_TEST
#define STBDS_UNIT_TESTS
#endif
#ifdef DS_STATS
#define STBDS_STATISTICS
#endif
#ifndef DS_PERF
#define STBDS_ASSERT assert
#include <assert.h>
#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 <stdio.h>
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 <windows.h>
#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

View File

@ -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);
}

View File

@ -1,3 +1,7 @@
#ifdef __clang__
#define STBIDEF static inline
#endif
#define STB_IMAGE_STATIC
#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

View File

@ -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"

View File

@ -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"

View File

@ -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);
}