DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/libs/decoders/stb.h
00001 /* stb.h - v2.35 - Sean's Tool Box -- public domain -- http://nothings.org/stb.h
00002           no warranty is offered or implied; use this code at your own risk
00003 
00004    This is a single header file with a bunch of useful utilities
00005    for getting stuff done in C/C++.
00006 
00007    Documentation: http://nothings.org/stb/stb_h.html
00008    Unit tests:    http://nothings.org/stb/stb.c
00009 
00010  ============================================================================
00011    You MUST
00012 
00013       #define STB_DEFINE
00014 
00015    in EXACTLY _one_ C or C++ file that includes this header, BEFORE the
00016    include, like this:
00017 
00018       #define STB_DEFINE
00019       #include "stb.h"
00020 
00021    All other files should just #include "stb.h" without the #define.
00022  ============================================================================
00023 
00024 Version History
00025 
00026    2.36   various fixes
00027    2.35   fix clang-cl issues with swprintf
00028    2.34   fix warnings
00029    2.33   more fixes to random numbers
00030    2.32   stb_intcmprev, stb_uidict, fix random numbers on Linux
00031    2.31   stb_ucharcmp
00032    2.30   MinGW fix
00033    2.29   attempt to fix use of swprintf()
00034    2.28   various new functionality
00035    2.27   test _WIN32 not WIN32 in STB_THREADS
00036    2.26   various warning & bugfixes
00037    2.25   various warning & bugfixes
00038    2.24   various warning & bugfixes
00039    2.23   fix 2.22
00040    2.22   64-bit fixes from '!='; fix stb_sdict_copy() to have preferred name
00041    2.21   utf-8 decoder rejects "overlong" encodings; attempted 64-bit improvements
00042    2.20   fix to hash "copy" function--reported by someone with handle "!="
00043    2.19   ???
00044    2.18   stb_readdir_subdirs_mask
00045    2.17   stb_cfg_dir
00046    2.16   fix stb_bgio_, add stb_bgio_stat(); begin a streaming wrapper
00047    2.15   upgraded hash table template to allow:
00048             - aggregate keys (explicit comparison func for EMPTY and DEL keys)
00049             - "static" implementations (so they can be culled if unused)
00050    2.14   stb_mprintf
00051    2.13   reduce identifiable strings in STB_NO_STB_STRINGS
00052    2.12   fix STB_ONLY -- lots of uint32s, TRUE/FALSE things had crept in
00053    2.11   fix bug in stb_dirtree_get() which caused "c://path" sorts of stuff
00054    2.10   STB_F(), STB_I() inline constants (also KI,KU,KF,KD)
00055    2.09   stb_box_face_vertex_axis_side
00056    2.08   bugfix stb_trimwhite()
00057    2.07   colored printing in windows (why are we in 1985?)
00058    2.06   comparison functions are now functions-that-return-functions and
00059           accept a struct-offset as a parameter (not thread-safe)
00060    2.05   compile and pass tests under Linux (but no threads); thread cleanup
00061    2.04   stb_cubic_bezier_1d, smoothstep, avoid dependency on registry
00062    2.03   ?
00063    2.02   remove integrated documentation
00064    2.01   integrate various fixes; stb_force_uniprocessor
00065    2.00   revised stb_dupe to use multiple hashes
00066    1.99   stb_charcmp
00067    1.98   stb_arr_deleten, stb_arr_insertn
00068    1.97   fix stb_newell_normal()
00069    1.96   stb_hash_number()
00070    1.95   hack stb__rec_max; clean up recursion code to use new functions
00071    1.94   stb_dirtree; rename stb_extra to stb_ptrmap
00072    1.93   stb_sem_new() API cleanup (no blockflag-starts blocked; use 'extra')
00073    1.92   stb_threadqueue--multi reader/writer queue, fixed size or resizeable
00074    1.91   stb_bgio_* for reading disk asynchronously
00075    1.90   stb_mutex uses CRITICAL_REGION; new stb_sync primitive for thread
00076           joining; workqueue supports stb_sync instead of stb_semaphore
00077    1.89   support ';' in constant-string wildcards; stb_mutex wrapper (can
00078           implement with EnterCriticalRegion eventually)
00079    1.88   portable threading API (only for win32 so far); worker thread queue
00080    1.87   fix wildcard handling in stb_readdir_recursive
00081    1.86   support ';' in wildcards
00082    1.85   make stb_regex work with non-constant strings;
00083                beginnings of stb_introspect()
00084    1.84   (forgot to make notes)
00085    1.83   whoops, stb_keep_if_different wasn't deleting the temp file
00086    1.82   bring back stb_compress from stb_file.h for cmirror
00087    1.81   various bugfixes, STB_FASTMALLOC_INIT inits FASTMALLOC in release
00088    1.80   stb_readdir returns utf8; write own utf8-utf16 because lib was wrong
00089    1.79   stb_write
00090    1.78   calloc() support for malloc wrapper, STB_FASTMALLOC
00091    1.77   STB_FASTMALLOC
00092    1.76   STB_STUA - Lua-like language; (stb_image, stb_csample, stb_bilinear)
00093    1.75   alloc/free array of blocks; stb_hheap bug; a few stb_ps_ funcs;
00094           hash*getkey, hash*copy; stb_bitset; stb_strnicmp; bugfix stb_bst
00095    1.74   stb_replaceinplace; use stdlib C function to convert utf8 to UTF-16
00096    1.73   fix performance bug & leak in stb_ischar (C++ port lost a 'static')
00097    1.72   remove stb_block, stb_block_manager, stb_decompress (to stb_file.h)
00098    1.71   stb_trimwhite, stb_tokens_nested, etc.
00099    1.70   back out 1.69 because it might problemize mixed builds; stb_filec()
00100    1.69   (stb_file returns 'char *' in C++)
00101    1.68   add a special 'tree root' data type for stb_bst; stb_arr_end
00102    1.67   full C++ port. (stb_block_manager)
00103    1.66   stb_newell_normal
00104    1.65   stb_lex_item_wild -- allow wildcard items which MUST match entirely
00105    1.64   stb_data
00106    1.63   stb_log_name
00107    1.62   stb_define_sort; C++ cleanup
00108    1.61   stb_hash_fast -- Paul Hsieh's hash function (beats Bob Jenkins'?)
00109    1.60   stb_delete_directory_recursive
00110    1.59   stb_readdir_recursive
00111    1.58   stb_bst variant with parent pointer for O(1) iteration, not O(log N)
00112    1.57   replace LCG random with Mersenne Twister (found a public domain one)
00113    1.56   stb_perfect_hash, stb_ischar, stb_regex
00114    1.55   new stb_bst API allows multiple BSTs per node (e.g. secondary keys)
00115    1.54   bugfix: stb_define_hash, stb_wildmatch, regexp
00116    1.53   stb_define_hash; recoded stb_extra, stb_sdict use it
00117    1.52   stb_rand_define, stb_bst, stb_reverse
00118    1.51   fix 'stb_arr_setlen(NULL, 0)'
00119    1.50   stb_wordwrap
00120    1.49   minor improvements to enable the scripting language
00121    1.48   better approach for stb_arr using stb_malloc; more invasive, clearer
00122    1.47   stb_lex (lexes stb.h at 1.5ML/s on 3Ghz P4; 60/70% of optimal/flex)
00123    1.46   stb_wrapper_*, STB_MALLOC_WRAPPER
00124    1.45   lightly tested DFA acceleration of regexp searching
00125    1.44   wildcard matching & searching; regexp matching & searching
00126    1.43   stb_temp
00127    1.42   allow stb_arr to use stb_malloc/realloc; note this is global
00128    1.41   make it compile in C++; (disable stb_arr in C++)
00129    1.40   stb_dupe tweak; stb_swap; stb_substr
00130    1.39   stb_dupe; improve stb_file_max to be less stupid
00131    1.38   stb_sha1_file: generate sha1 for file, even > 4GB
00132    1.37   stb_file_max; partial support for utf8 filenames in Windows
00133    1.36   remove STB__NO_PREFIX - poor interaction with IDE, not worth it
00134           streamline stb_arr to make it separately publishable
00135    1.35   bugfixes for stb_sdict, stb_malloc(0), stristr
00136    1.34   (streaming interfaces for stb_compress)
00137    1.33   stb_alloc; bug in stb_getopt; remove stb_overflow
00138    1.32   (stb_compress returns, smaller&faster; encode window & 64-bit len)
00139    1.31   stb_prefix_count
00140    1.30   (STB__NO_PREFIX - remove stb_ prefixes for personal projects)
00141    1.29   stb_fput_varlen64, etc.
00142    1.28   stb_sha1
00143    1.27   ?
00144    1.26   stb_extra
00145    1.25   ?
00146    1.24   stb_copyfile
00147    1.23   stb_readdir
00148    1.22   ?
00149    1.21   ?
00150    1.20   ?
00151    1.19   ?
00152    1.18   ?
00153    1.17   ?
00154    1.16   ?
00155    1.15   stb_fixpath, stb_splitpath, stb_strchr2
00156    1.14   stb_arr
00157    1.13   ?stb, stb_log, stb_fatal
00158    1.12   ?stb_hash2
00159    1.11   miniML
00160    1.10   stb_crc32, stb_adler32
00161    1.09   stb_sdict
00162    1.08   stb_bitreverse, stb_ispow2, stb_big32
00163           stb_fopen, stb_fput_varlen, stb_fput_ranged
00164           stb_fcmp, stb_feq
00165    1.07   (stb_encompress)
00166    1.06   stb_compress
00167    1.05   stb_tokens, (stb_hheap)
00168    1.04   stb_rand
00169    1.03   ?(s-strings)
00170    1.02   ?stb_filelen, stb_tokens
00171    1.01   stb_tolower
00172    1.00   stb_hash, stb_intcmp
00173           stb_file, stb_stringfile, stb_fgets
00174           stb_prefix, stb_strlower, stb_strtok
00175           stb_image
00176           (stb_array), (stb_arena)
00177 
00178 Parenthesized items have since been removed.
00179 
00180 LICENSE
00181 
00182  See end of file for license information.
00183 
00184 CREDITS
00185 
00186  Written by Sean Barrett.
00187 
00188  Fixes:
00189   Philipp Wiesemann
00190   Robert Nix
00191   r-lyeh
00192   blackpawn
00193   github:Mojofreem
00194   Ryan Whitworth
00195   Vincent Isambart
00196   Mike Sartain
00197   Eugene Opalev
00198   Tim Sjostrand
00199   github:infatum
00200   Dave Butler (Croepha)
00201   Ethan Lee (flibitijibibo)
00202   Brian Collins
00203 */
00204 
00205 #include <stdarg.h>
00206 
00207 #ifndef STB__INCLUDE_STB_H
00208 #define STB__INCLUDE_STB_H
00209 
00210 #define STB_VERSION  1
00211 
00212 #ifdef STB_INTROSPECT
00213    #define STB_DEFINE
00214 #endif
00215 
00216 #ifdef STB_DEFINE_THREADS
00217    #ifndef STB_DEFINE
00218    #define STB_DEFINE
00219    #endif
00220    #ifndef STB_THREADS
00221    #define STB_THREADS
00222    #endif
00223 #endif
00224 
00225 #if defined(_WIN32) && !defined(__MINGW32__)
00226    #ifndef _CRT_SECURE_NO_WARNINGS
00227    #define _CRT_SECURE_NO_WARNINGS
00228    #endif
00229    #ifndef _CRT_NONSTDC_NO_DEPRECATE
00230    #define _CRT_NONSTDC_NO_DEPRECATE
00231    #endif
00232    #ifndef _CRT_NON_CONFORMING_SWPRINTFS
00233    #define _CRT_NON_CONFORMING_SWPRINTFS
00234    #endif
00235    #if !defined(_MSC_VER) || _MSC_VER > 1700
00236    #include <intrin.h> // _BitScanReverse
00237    #endif
00238 #endif
00239 
00240 #include <stdlib.h>     // stdlib could have min/max
00241 #include <stdio.h>      // need FILE
00242 #include <string.h>     // stb_define_hash needs memcpy/memset
00243 #include <time.h>       // stb_dirtree
00244 #ifdef __MINGW32__
00245    #include <fcntl.h>   // O_RDWR
00246 #endif
00247 
00248 #ifdef STB_PERSONAL
00249    typedef int Bool;
00250    #define False 0
00251    #define True 1
00252 #endif
00253 
00254 #ifdef STB_MALLOC_WRAPPER_PAGED
00255    #define STB_MALLOC_WRAPPER_DEBUG
00256 #endif
00257 #ifdef STB_MALLOC_WRAPPER_DEBUG
00258    #define STB_MALLOC_WRAPPER
00259 #endif
00260 #ifdef STB_MALLOC_WRAPPER_FASTMALLOC
00261    #define STB_FASTMALLOC
00262    #define STB_MALLOC_WRAPPER
00263 #endif
00264 
00265 #ifdef STB_FASTMALLOC
00266    #ifndef _WIN32
00267       #undef STB_FASTMALLOC
00268    #endif
00269 #endif
00270 
00271 #ifdef STB_DEFINE
00272    #include <assert.h>
00273    #include <stdarg.h>
00274    #include <stddef.h>
00275    #include <ctype.h>
00276    #include <math.h>
00277    #ifndef _WIN32
00278    #include <unistd.h>
00279    #else
00280    #include <io.h>      // _mktemp
00281    #include <direct.h>  // _rmdir
00282    #endif
00283    #include <sys/types.h> // stat()/_stat()
00284    #include <sys/stat.h>  // stat()/_stat()
00285 #endif
00286 
00287 #define stb_min(a,b)   ((a) < (b) ? (a) : (b))
00288 #define stb_max(a,b)   ((a) > (b) ? (a) : (b))
00289 
00290 #ifndef STB_ONLY
00291    #if !defined(__cplusplus) && !defined(min) && !defined(max)
00292      #define min(x,y) stb_min(x,y)
00293      #define max(x,y) stb_max(x,y)
00294    #endif
00295 
00296    #ifndef M_PI
00297      #define M_PI  3.14159265358979323846f
00298    #endif
00299 
00300    #ifndef TRUE
00301      #define TRUE  1
00302      #define FALSE 0
00303    #endif
00304 
00305    #ifndef deg2rad
00306    #define deg2rad(a)  ((a)*(M_PI/180))
00307    #endif
00308    #ifndef rad2deg
00309    #define rad2deg(a)  ((a)*(180/M_PI))
00310    #endif
00311 
00312    #ifndef swap
00313    #ifndef __cplusplus
00314    #define swap(TYPE,a,b)  \
00315                do { TYPE stb__t; stb__t = (a); (a) = (b); (b) = stb__t; } while (0)
00316    #endif
00317    #endif
00318 
00319    typedef unsigned char  uint8 ;
00320    typedef   signed char   int8 ;
00321    typedef unsigned short uint16;
00322    typedef   signed short  int16;
00323   #if defined(STB_USE_LONG_FOR_32_BIT_INT) || defined(STB_LONG32)
00324    typedef unsigned long  uint32;
00325    typedef   signed long   int32;
00326   #else
00327    typedef unsigned int   uint32;
00328    typedef   signed int    int32;
00329   #endif
00330 
00331    typedef unsigned char  uchar ;
00332    typedef unsigned short ushort;
00333    typedef unsigned int   uint  ;
00334    typedef unsigned long  ulong ;
00335 
00336    // produce compile errors if the sizes aren't right
00337    typedef char stb__testsize16[sizeof(int16)==2];
00338    typedef char stb__testsize32[sizeof(int32)==4];
00339 #endif
00340 
00341 #ifndef STB_TRUE
00342   #define STB_TRUE 1
00343   #define STB_FALSE 0
00344 #endif
00345 
00346 // if we're STB_ONLY, can't rely on uint32 or even uint, so all the
00347 // variables we'll use herein need typenames prefixed with 'stb':
00348 typedef unsigned char stb_uchar;
00349 typedef unsigned char stb_uint8;
00350 typedef unsigned int  stb_uint;
00351 typedef unsigned short stb_uint16;
00352 typedef          short stb_int16;
00353 typedef   signed char  stb_int8;
00354 #if defined(STB_USE_LONG_FOR_32_BIT_INT) || defined(STB_LONG32)
00355   typedef unsigned long  stb_uint32;
00356   typedef          long  stb_int32;
00357 #else
00358   typedef unsigned int   stb_uint32;
00359   typedef          int   stb_int32;
00360 #endif
00361 typedef char stb__testsize2_16[sizeof(stb_uint16)==2 ? 1 : -1];
00362 typedef char stb__testsize2_32[sizeof(stb_uint32)==4 ? 1 : -1];
00363 
00364 #ifdef _MSC_VER
00365   typedef unsigned __int64 stb_uint64;
00366   typedef          __int64 stb_int64;
00367   #define STB_IMM_UINT64(literalui64) (literalui64##ui64)
00368   #define STB_IMM_INT64(literali64) (literali64##i64)
00369 #else
00370   // ??
00371   typedef unsigned long long stb_uint64;
00372   typedef          long long stb_int64;
00373   #define STB_IMM_UINT64(literalui64) (literalui64##ULL)
00374   #define STB_IMM_INT64(literali64) (literali64##LL)
00375 #endif
00376 typedef char stb__testsize2_64[sizeof(stb_uint64)==8 ? 1 : -1];
00377 
00378 // add platform-specific ways of checking for sizeof(char*) == 8,
00379 // and make those define STB_PTR64
00380 #if defined(_WIN64) || defined(__x86_64__) || defined(__ia64__) || defined(__LP64__)
00381   #define STB_PTR64
00382 #endif
00383 
00384 #ifdef STB_PTR64
00385 typedef char stb__testsize2_ptr[sizeof(char *) == 8];
00386 typedef stb_uint64 stb_uinta;
00387 typedef stb_int64  stb_inta;
00388 #else
00389 typedef char stb__testsize2_ptr[sizeof(char *) == 4];
00390 typedef stb_uint32 stb_uinta;
00391 typedef stb_int32  stb_inta;
00392 #endif
00393 typedef char stb__testsize2_uinta[sizeof(stb_uinta)==sizeof(char*) ? 1 : -1];
00394 
00395 // if so, we should define an int type that is the pointer size. until then,
00396 // we'll have to make do with this (which is not the same at all!)
00397 
00398 typedef union
00399 {
00400    unsigned int i;
00401    void * p;
00402 } stb_uintptr;
00403 
00404 
00405 #ifdef __cplusplus
00406    #define STB_EXTERN   extern "C"
00407 #else
00408    #define STB_EXTERN   extern
00409 #endif
00410 
00411 // check for well-known debug defines
00412 #if defined(DEBUG) || defined(_DEBUG) || defined(DBG)
00413    #ifndef NDEBUG
00414       #define STB_DEBUG
00415    #endif
00416 #endif
00417 
00418 #ifdef STB_DEBUG
00419    #include <assert.h>
00420 #endif
00421 
00423 //
00424 //                         C library function platform handling
00425 //
00426 
00427 #ifdef STB_DEFINE
00428 
00429 #if defined(_WIN32) &&  defined(__STDC_WANT_SECURE_LIB__)
00430 static FILE * stb_p_fopen(const char *filename, const char *mode)
00431 {
00432    FILE *f;
00433    if (0 == fopen_s(&f, filename, mode))
00434       return f;
00435    else
00436       return NULL;
00437 }
00438 static FILE * stb_p_wfopen(const wchar_t *filename, const wchar_t *mode)
00439 {
00440    FILE *f;
00441    if (0 == _wfopen_s(&f, filename, mode))
00442       return f;
00443    else
00444       return NULL;
00445 }
00446 static char *stb_p_strcpy_s(char *a, size_t size, const char *b)
00447 {
00448    strcpy_s(a,size,b);
00449    return a;
00450 }
00451 static char *stb_p_strncpy_s(char *a, size_t size, const char *b, size_t count)
00452 {
00453    strncpy_s(a,size,b,count);
00454    return a;
00455 }
00456 #define stb_p_mktemp(s)  (_mktemp_s(s, strlen(s)+1) == 0)
00457 #define stb_p_sprintf    sprintf_s
00458 #define stb_p_size(x)    ,(x)
00459 #else
00460 #define stb_p_fopen      fopen
00461 #define stb_p_wfopen     _wfopen
00462 #define stb_p_strcpy_s(a,s,b)     strcpy(a,b)
00463 #define stb_p_strncpy_s(a,s,b,c)  strncpy(a,b,c)
00464 #define stb_p_mktemp(s)  (mktemp(s) != NULL)
00465 
00466 #define stb_p_sprintf    sprintf
00467 #define stb_p_size(x)
00468 #endif
00469 
00470 #if defined(_WIN32)
00471 #define stb_p_vsnprintf  _vsnprintf
00472 #else
00473 #define stb_p_vsnprintf  vsnprintf
00474 #endif
00475 #endif // STB_DEFINE
00476 
00477 #if defined(_WIN32) && (_MSC_VER >= 1300)
00478 #define stb_p_stricmp    _stricmp
00479 #define stb_p_strnicmp   _strnicmp
00480 #define stb_p_strdup     _strdup
00481 #else
00482 #define stb_p_strdup     strdup
00483 #define stb_p_stricmp    stricmp
00484 #define stb_p_strnicmp   strnicmp
00485 #endif
00486 
00487 STB_EXTERN void stb_wrapper_malloc(void *newp, size_t sz, char *file, int line);
00488 STB_EXTERN void stb_wrapper_free(void *oldp, char *file, int line);
00489 STB_EXTERN void stb_wrapper_realloc(void *oldp, void *newp, size_t sz, char *file, int line);
00490 STB_EXTERN void stb_wrapper_calloc(size_t num, size_t sz, char *file, int line);
00491 STB_EXTERN void stb_wrapper_listall(void (*func)(void *ptr, size_t sz, char *file, int line));
00492 STB_EXTERN void stb_wrapper_dump(char *filename);
00493 STB_EXTERN size_t stb_wrapper_allocsize(void *oldp);
00494 STB_EXTERN void stb_wrapper_check(void *oldp);
00495 
00496 #ifdef STB_DEFINE
00497 // this is a special function used inside malloc wrapper
00498 // to do allocations that aren't tracked (to avoid
00499 // reentrancy). Of course if someone _else_ wraps realloc,
00500 // this breaks, but if they're doing that AND the malloc
00501 // wrapper they need to explicitly check for reentrancy.
00502 //
00503 // only define realloc_raw() and we do realloc(NULL,sz)
00504 // for malloc() and realloc(p,0) for free().
00505 static void * stb__realloc_raw(void *p, int sz)
00506 {
00507    if (p == NULL) return malloc(sz);
00508    if (sz == 0)   { free(p); return NULL; }
00509    return realloc(p,sz);
00510 }
00511 #endif
00512 
00513 #ifdef _WIN32
00514 STB_EXTERN void * stb_smalloc(size_t sz);
00515 STB_EXTERN void   stb_sfree(void *p);
00516 STB_EXTERN void * stb_srealloc(void *p, size_t sz);
00517 STB_EXTERN void * stb_scalloc(size_t n, size_t sz);
00518 STB_EXTERN char * stb_sstrdup(char *s);
00519 #endif
00520 
00521 #ifdef STB_FASTMALLOC
00522 #define malloc  stb_smalloc
00523 #define free    stb_sfree
00524 #define realloc stb_srealloc
00525 #define strdup  stb_sstrdup
00526 #define calloc  stb_scalloc
00527 #endif
00528 
00529 #ifndef STB_MALLOC_ALLCHECK
00530    #define stb__check(p)  1
00531 #else
00532    #ifndef STB_MALLOC_WRAPPER
00533       #error STB_MALLOC_ALLCHECK requires STB_MALLOC_WRAPPER
00534    #else
00535       #define stb__check(p) stb_mcheck(p)
00536    #endif
00537 #endif
00538 
00539 #ifdef STB_MALLOC_WRAPPER
00540    STB_EXTERN void * stb__malloc(size_t, char *, int);
00541    STB_EXTERN void * stb__realloc(void *, size_t, char *, int);
00542    STB_EXTERN void * stb__calloc(size_t n, size_t s, char *, int);
00543    STB_EXTERN void   stb__free(void *, char *file, int);
00544    STB_EXTERN char * stb__strdup(char *s, char *file, int);
00545    STB_EXTERN void   stb_malloc_checkall(void);
00546    STB_EXTERN void   stb_malloc_check_counter(int init_delay, int rep_delay);
00547    #ifndef STB_MALLOC_WRAPPER_DEBUG
00548       #define stb_mcheck(p) 1
00549    #else
00550       STB_EXTERN int   stb_mcheck(void *);
00551    #endif
00552 
00553 
00554    #ifdef STB_DEFINE
00555 
00556    #ifdef STB_MALLOC_WRAPPER_DEBUG
00557       #define STB__PAD   32
00558       #define STB__BIAS  16
00559       #define STB__SIG   0x51b01234
00560       #define STB__FIXSIZE(sz)  (((sz+3) & ~3) + STB__PAD)
00561       #define STB__ptr(x,y)   ((char *) (x) + (y))
00562    #else
00563       #define STB__ptr(x,y)   (x)
00564       #define STB__FIXSIZE(sz)  (sz)
00565    #endif
00566 
00567    #ifdef STB_MALLOC_WRAPPER_DEBUG
00568    int stb_mcheck(void *p)
00569    {
00570       unsigned int sz;
00571       if (p == NULL) return 1;
00572       p = ((char *) p) - STB__BIAS;
00573       sz = * (unsigned int *) p;
00574       assert(* (unsigned int *) STB__ptr(p,4) == STB__SIG);
00575       assert(* (unsigned int *) STB__ptr(p,8) == STB__SIG);
00576       assert(* (unsigned int *) STB__ptr(p,12) == STB__SIG);
00577       assert(* (unsigned int *) STB__ptr(p,sz-4) == STB__SIG+1);
00578       assert(* (unsigned int *) STB__ptr(p,sz-8) == STB__SIG+1);
00579       assert(* (unsigned int *) STB__ptr(p,sz-12) == STB__SIG+1);
00580       assert(* (unsigned int *) STB__ptr(p,sz-16) == STB__SIG+1);
00581       stb_wrapper_check(STB__ptr(p, STB__BIAS));
00582       return 1;
00583    }
00584 
00585    static void stb__check2(void *p, size_t sz, char *file, int line)
00586    {
00587       stb_mcheck(p);
00588    }
00589 
00590    void stb_malloc_checkall(void)
00591    {
00592       stb_wrapper_listall(stb__check2);
00593    }
00594    #else
00595    void stb_malloc_checkall(void) { }
00596    #endif
00597 
00598    static int stb__malloc_wait=(1 << 30), stb__malloc_next_wait = (1 << 30), stb__malloc_iter;
00599    void stb_malloc_check_counter(int init_delay, int rep_delay)
00600    {
00601       stb__malloc_wait = init_delay;
00602       stb__malloc_next_wait = rep_delay;
00603    }
00604 
00605    void stb_mcheck_all(void)
00606    {
00607       #ifdef STB_MALLOC_WRAPPER_DEBUG
00608       ++stb__malloc_iter;
00609       if (--stb__malloc_wait <= 0) {
00610          stb_malloc_checkall();
00611          stb__malloc_wait = stb__malloc_next_wait;
00612       }
00613       #endif
00614    }
00615 
00616    #ifdef STB_MALLOC_WRAPPER_PAGED
00617    #define STB__WINDOWS_PAGE (1 << 12)
00618    #ifndef _WINDOWS_
00619    STB_EXTERN __declspec(dllimport) void * __stdcall VirtualAlloc(void *p, unsigned long size, unsigned long type, unsigned long protect);
00620    STB_EXTERN __declspec(dllimport) int   __stdcall VirtualFree(void *p, unsigned long size, unsigned long freetype);
00621    #endif
00622    #endif
00623 
00624    static void *stb__malloc_final(size_t sz)
00625    {
00626       #ifdef STB_MALLOC_WRAPPER_PAGED
00627       size_t aligned = (sz + STB__WINDOWS_PAGE - 1) & ~(STB__WINDOWS_PAGE-1);
00628       char *p = VirtualAlloc(NULL, aligned + STB__WINDOWS_PAGE, 0x2000, 0x04); // RESERVE, READWRITE
00629       if (p == NULL) return p;
00630       VirtualAlloc(p, aligned,   0x1000, 0x04); // COMMIT, READWRITE
00631       return p;
00632       #else
00633       return malloc(sz);
00634       #endif
00635    }
00636 
00637    static void stb__free_final(void *p)
00638    {
00639       #ifdef STB_MALLOC_WRAPPER_PAGED
00640       VirtualFree(p, 0, 0x8000); // RELEASE
00641       #else
00642       free(p);
00643       #endif
00644    }
00645 
00646    int stb__malloc_failure;
00647    #ifdef STB_MALLOC_WRAPPER_PAGED
00648    static void *stb__realloc_final(void *p, size_t sz, size_t old_sz)
00649    {
00650       void *q = stb__malloc_final(sz);
00651       if (q == NULL)
00652           return ++stb__malloc_failure, q;
00653       // @TODO: deal with p being smaller!
00654       memcpy(q, p, sz < old_sz ? sz : old_sz);
00655       stb__free_final(p);
00656       return q;
00657    }
00658    #endif
00659 
00660    void stb__free(void *p, char *file, int line)
00661    {
00662       stb_mcheck_all();
00663       if (!p) return;
00664       #ifdef STB_MALLOC_WRAPPER_DEBUG
00665       stb_mcheck(p);
00666       #endif
00667       stb_wrapper_free(p,file,line);
00668       #ifdef STB_MALLOC_WRAPPER_DEBUG
00669          p = STB__ptr(p,-STB__BIAS);
00670          * (unsigned int *) STB__ptr(p,0) = 0xdeadbeef;
00671          * (unsigned int *) STB__ptr(p,4) = 0xdeadbeef;
00672          * (unsigned int *) STB__ptr(p,8) = 0xdeadbeef;
00673          * (unsigned int *) STB__ptr(p,12) = 0xdeadbeef;
00674       #endif
00675       stb__free_final(p);
00676    }
00677 
00678    void * stb__malloc(size_t sz, char *file, int line)
00679    {
00680       void *p;
00681       stb_mcheck_all();
00682       if (sz == 0) return NULL;
00683       p = stb__malloc_final(STB__FIXSIZE(sz));
00684       if (p == NULL) p = stb__malloc_final(STB__FIXSIZE(sz));
00685       if (p == NULL) p = stb__malloc_final(STB__FIXSIZE(sz));
00686       if (p == NULL) {
00687          ++stb__malloc_failure;
00688          #ifdef STB_MALLOC_WRAPPER_DEBUG
00689          stb_malloc_checkall();
00690          #endif
00691          return p;
00692       }
00693       #ifdef STB_MALLOC_WRAPPER_DEBUG
00694       * (int *) STB__ptr(p,0) = STB__FIXSIZE(sz);
00695       * (unsigned int *) STB__ptr(p,4) = STB__SIG;
00696       * (unsigned int *) STB__ptr(p,8) = STB__SIG;
00697       * (unsigned int *) STB__ptr(p,12) = STB__SIG;
00698       * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-4) = STB__SIG+1;
00699       * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-8) = STB__SIG+1;
00700       * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-12) = STB__SIG+1;
00701       * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-16) = STB__SIG+1;
00702       p = STB__ptr(p, STB__BIAS);
00703       #endif
00704       stb_wrapper_malloc(p,sz,file,line);
00705       return p;
00706    }
00707 
00708    void * stb__realloc(void *p, size_t sz, char *file, int line)
00709    {
00710       void *q;
00711 
00712       stb_mcheck_all();
00713       if (p == NULL) return stb__malloc(sz,file,line);
00714       if (sz == 0  ) { stb__free(p,file,line); return NULL; }
00715 
00716       #ifdef STB_MALLOC_WRAPPER_DEBUG
00717          stb_mcheck(p);
00718          p = STB__ptr(p,-STB__BIAS);
00719       #endif
00720       #ifdef STB_MALLOC_WRAPPER_PAGED
00721       {
00722          size_t n = stb_wrapper_allocsize(STB__ptr(p,STB__BIAS));
00723          if (!n)
00724             stb_wrapper_check(STB__ptr(p,STB__BIAS));
00725          q = stb__realloc_final(p, STB__FIXSIZE(sz), STB__FIXSIZE(n));
00726       }
00727       #else
00728       q = realloc(p, STB__FIXSIZE(sz));
00729       #endif
00730       if (q == NULL)
00731          return ++stb__malloc_failure, q;
00732       #ifdef STB_MALLOC_WRAPPER_DEBUG
00733       * (int *) STB__ptr(q,0) = STB__FIXSIZE(sz);
00734       * (unsigned int *) STB__ptr(q,4) = STB__SIG;
00735       * (unsigned int *) STB__ptr(q,8) = STB__SIG;
00736       * (unsigned int *) STB__ptr(q,12) = STB__SIG;
00737       * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-4) = STB__SIG+1;
00738       * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-8) = STB__SIG+1;
00739       * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-12) = STB__SIG+1;
00740       * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-16) = STB__SIG+1;
00741 
00742       q = STB__ptr(q, STB__BIAS);
00743       p = STB__ptr(p, STB__BIAS);
00744       #endif
00745       stb_wrapper_realloc(p,q,sz,file,line);
00746       return q;
00747    }
00748 
00749    STB_EXTERN int stb_log2_ceil(size_t);
00750    static void *stb__calloc(size_t n, size_t sz, char *file, int line)
00751    {
00752       void *q;
00753       stb_mcheck_all();
00754       if (n == 0 || sz == 0) return NULL;
00755       if (stb_log2_ceil(n) + stb_log2_ceil(sz) >= 32) return NULL;
00756       q = stb__malloc(n*sz, file, line);
00757       if (q) memset(q, 0, n*sz);
00758       return q;
00759    }
00760 
00761    char * stb__strdup(char *s, char *file, int line)
00762    {
00763       char *p;
00764       stb_mcheck_all();
00765       p = stb__malloc(strlen(s)+1, file, line);
00766       if (!p) return p;
00767       stb_p_strcpy_s(p, strlen(s)+1, s);
00768       return p;
00769    }
00770    #endif // STB_DEFINE
00771 
00772    #ifdef STB_FASTMALLOC
00773    #undef malloc
00774    #undef realloc
00775    #undef free
00776    #undef strdup
00777    #undef calloc
00778    #endif
00779 
00780    // include everything that might define these, BEFORE making macros
00781    #include <stdlib.h>
00782    #include <string.h>
00783    #include <malloc.h>
00784 
00785    #define malloc(s)      stb__malloc (  s, __FILE__, __LINE__)
00786    #define realloc(p,s)   stb__realloc(p,s, __FILE__, __LINE__)
00787    #define calloc(n,s)    stb__calloc (n,s, __FILE__, __LINE__)
00788    #define free(p)        stb__free   (p,   __FILE__, __LINE__)
00789    #define strdup(p)      stb__strdup (p,   __FILE__, __LINE__)
00790 #endif
00791 
00793 //
00794 //                         Windows pretty display
00795 //
00796 
00797 STB_EXTERN void stbprint(const char *fmt, ...);
00798 STB_EXTERN char *stb_sprintf(const char *fmt, ...);
00799 STB_EXTERN char *stb_mprintf(const char *fmt, ...);
00800 STB_EXTERN int  stb_snprintf(char *s, size_t n, const char *fmt, ...);
00801 STB_EXTERN int  stb_vsnprintf(char *s, size_t n, const char *fmt, va_list v);
00802 
00803 #ifdef STB_DEFINE
00804 int stb_vsnprintf(char *s, size_t n, const char *fmt, va_list v)
00805 {
00806    int res;
00807    #ifdef _WIN32
00808       #ifdef __STDC_WANT_SECURE_LIB__
00809       res = _vsnprintf_s(s, n, _TRUNCATE, fmt, v);
00810       #else
00811       res = stb_p_vsnprintf(s,n,fmt,v);
00812       #endif
00813    #else
00814    res = vsnprintf(s,n,fmt,v);
00815    #endif
00816    if (n) s[n-1] = 0;
00817    // Unix returns length output would require, Windows returns negative when truncated.
00818    return (res >= (int) n || res < 0) ? -1 : res;
00819 }
00820 
00821 int stb_snprintf(char *s, size_t n, const char *fmt, ...)
00822 {
00823    int res;
00824    va_list v;
00825    va_start(v,fmt);
00826    res = stb_vsnprintf(s, n, fmt, v);
00827    va_end(v);
00828    return res;
00829 }
00830 
00831 char *stb_sprintf(const char *fmt, ...)
00832 {
00833    static char buffer[1024];
00834    va_list v;
00835    va_start(v,fmt);
00836    stb_vsnprintf(buffer,1024,fmt,v);
00837    va_end(v);
00838    return buffer;
00839 }
00840 
00841 char *stb_mprintf(const char *fmt, ...)
00842 {
00843    static char buffer[1024];
00844    va_list v;
00845    va_start(v,fmt);
00846    stb_vsnprintf(buffer,1024,fmt,v);
00847    va_end(v);
00848    return stb_p_strdup(buffer);
00849 }
00850 
00851 #ifdef _WIN32
00852 
00853 #ifndef _WINDOWS_
00854 STB_EXTERN __declspec(dllimport) int __stdcall WriteConsoleA(void *, const void *, unsigned int, unsigned int *, void *);
00855 STB_EXTERN __declspec(dllimport) void * __stdcall GetStdHandle(unsigned int);
00856 STB_EXTERN __declspec(dllimport) int __stdcall SetConsoleTextAttribute(void *, unsigned short);
00857 #endif
00858 
00859 static void stb__print_one(void *handle, char *s, ptrdiff_t  len)
00860 {
00861    if (len)
00862       if (0==WriteConsoleA(handle, s, (unsigned) len, NULL,NULL))
00863          // if it fails, maybe redirected, so output normally...
00864          // but it's supriously reporting failure now on Win7 and later
00865          {}//fwrite(s, 1, (unsigned) len, stdout);
00866 }
00867 
00868 static void stb__print(char *s)
00869 {
00870    void *handle = GetStdHandle((unsigned int) -11); // STD_OUTPUT_HANDLE
00871    int pad=0; // number of padding characters to add
00872 
00873    char *t = s;
00874    while (*s) {
00875       int lpad;
00876       while (*s && *s != '{') {
00877          if (pad) {
00878             if (*s == '\r' || *s == '\n')
00879                pad = 0;
00880             else if (s[0] == ' ' && s[1] == ' ') {
00881                stb__print_one(handle, t, s-t);
00882                t = s;
00883                while (pad) {
00884                   stb__print_one(handle, t, 1);
00885                   --pad;
00886                }
00887             }
00888          }
00889          ++s;
00890       }
00891       if (!*s) break;
00892       stb__print_one(handle, t, s-t);
00893       if (s[1] == '{') {
00894          ++s;
00895          continue;
00896       }
00897 
00898       if (s[1] == '#') {
00899          t = s+3;
00900          if (isxdigit(s[2]))
00901             if (isdigit(s[2]))
00902                SetConsoleTextAttribute(handle, s[2] - '0');
00903             else
00904                SetConsoleTextAttribute(handle, tolower(s[2]) - 'a' + 10);
00905          else {
00906             SetConsoleTextAttribute(handle, 0x0f);
00907             t=s+2;
00908          }
00909       } else if (s[1] == '!') {
00910          SetConsoleTextAttribute(handle, 0x0c);
00911          t = s+2;
00912       } else if (s[1] == '@') {
00913          SetConsoleTextAttribute(handle, 0x09);
00914          t = s+2;
00915       } else if (s[1] == '$') {
00916          SetConsoleTextAttribute(handle, 0x0a);
00917          t = s+2;
00918       } else {
00919          SetConsoleTextAttribute(handle, 0x08); // 0,7,8,15 => shades of grey
00920          t = s+1;
00921       }
00922 
00923       lpad = (int) (t-s);
00924       s = t;
00925       while (*s && *s != '}') ++s;
00926       if (!*s) break;
00927       stb__print_one(handle, t, s-t);
00928       if (s[1] == '}') {
00929          t = s+2;
00930       } else {
00931          pad += 1+lpad;
00932          t = s+1;
00933       }
00934       s=t;
00935       SetConsoleTextAttribute(handle, 0x07);
00936    }
00937    stb__print_one(handle, t, s-t);
00938    SetConsoleTextAttribute(handle, 0x07);
00939 }
00940 
00941 void stbprint(const char *fmt, ...)
00942 {
00943    int res;
00944    char buffer[1024];
00945    char *tbuf = buffer;
00946    va_list v;
00947 
00948    va_start(v,fmt);
00949    res = stb_vsnprintf(buffer, sizeof(buffer), fmt, v);
00950    va_end(v);
00951 
00952    if (res < 0) {
00953       tbuf = (char *) malloc(16384);
00954       va_start(v,fmt);
00955       res = stb_vsnprintf(tbuf,16384, fmt, v);
00956       va_end(v);
00957       tbuf[16383] = 0;
00958    }
00959 
00960    stb__print(tbuf);
00961 
00962    if (tbuf != buffer)
00963       free(tbuf);
00964 }
00965 
00966 #else  // _WIN32
00967 void stbprint(const char *fmt, ...)
00968 {
00969    va_list v;
00970    va_start(v,fmt);
00971    vprintf(fmt,v);
00972    va_end(v);
00973 }
00974 #endif // _WIN32
00975 #endif // STB_DEFINE
00976 
00977 
00978 
00980 //
00981 //                         Windows UTF8 filename handling
00982 //
00983 // Windows stupidly treats 8-bit filenames as some dopey code page,
00984 // rather than utf-8. If we want to use utf8 filenames, we have to
00985 // convert them to WCHAR explicitly and call WCHAR versions of the
00986 // file functions. So, ok, we do.
00987 
00988 
00989 #ifdef _WIN32
00990    #define stb__fopen(x,y)    stb_p_wfopen((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y))
00991    #define stb__windows(x,y)  x
00992 #else
00993    #define stb__fopen(x,y)    stb_p_fopen(x,y)
00994    #define stb__windows(x,y)  y
00995 #endif
00996 
00997 
00998 typedef unsigned short stb__wchar;
00999 
01000 STB_EXTERN stb__wchar * stb_from_utf8(stb__wchar *buffer, const char *str, int n);
01001 STB_EXTERN char       * stb_to_utf8  (char *buffer, const stb__wchar *str, int n);
01002 
01003 STB_EXTERN stb__wchar *stb__from_utf8(const char *str);
01004 STB_EXTERN stb__wchar *stb__from_utf8_alt(const char *str);
01005 STB_EXTERN char *stb__to_utf8(const stb__wchar *str);
01006 
01007 
01008 #ifdef STB_DEFINE
01009 stb__wchar * stb_from_utf8(stb__wchar *buffer, const char *ostr, int n)
01010 {
01011    unsigned char *str = (unsigned char *) ostr;
01012    stb_uint32 c;
01013    int i=0;
01014    --n;
01015    while (*str) {
01016       if (i >= n)
01017          return NULL;
01018       if (!(*str & 0x80))
01019          buffer[i++] = *str++;
01020       else if ((*str & 0xe0) == 0xc0) {
01021          if (*str < 0xc2) return NULL;
01022          c = (*str++ & 0x1f) << 6;
01023          if ((*str & 0xc0) != 0x80) return NULL;
01024          buffer[i++] = c + (*str++ & 0x3f);
01025       } else if ((*str & 0xf0) == 0xe0) {
01026          if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return NULL;
01027          if (*str == 0xed && str[1] > 0x9f) return NULL; // str[1] < 0x80 is checked below
01028          c = (*str++ & 0x0f) << 12;
01029          if ((*str & 0xc0) != 0x80) return NULL;
01030          c += (*str++ & 0x3f) << 6;
01031          if ((*str & 0xc0) != 0x80) return NULL;
01032          buffer[i++] = c + (*str++ & 0x3f);
01033       } else if ((*str & 0xf8) == 0xf0) {
01034          if (*str > 0xf4) return NULL;
01035          if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return NULL;
01036          if (*str == 0xf4 && str[1] > 0x8f) return NULL; // str[1] < 0x80 is checked below
01037          c = (*str++ & 0x07) << 18;
01038          if ((*str & 0xc0) != 0x80) return NULL;
01039          c += (*str++ & 0x3f) << 12;
01040          if ((*str & 0xc0) != 0x80) return NULL;
01041          c += (*str++ & 0x3f) << 6;
01042          if ((*str & 0xc0) != 0x80) return NULL;
01043          c += (*str++ & 0x3f);
01044          // utf-8 encodings of values used in surrogate pairs are invalid
01045          if ((c & 0xFFFFF800) == 0xD800) return NULL;
01046          if (c >= 0x10000) {
01047             c -= 0x10000;
01048             if (i + 2 > n) return NULL;
01049             buffer[i++] = 0xD800 | (0x3ff & (c >> 10));
01050             buffer[i++] = 0xDC00 | (0x3ff & (c      ));
01051          }
01052       } else
01053          return NULL;
01054    }
01055    buffer[i] = 0;
01056    return buffer;
01057 }
01058 
01059 char * stb_to_utf8(char *buffer, const stb__wchar *str, int n)
01060 {
01061    int i=0;
01062    --n;
01063    while (*str) {
01064       if (*str < 0x80) {
01065          if (i+1 > n) return NULL;
01066          buffer[i++] = (char) *str++;
01067       } else if (*str < 0x800) {
01068          if (i+2 > n) return NULL;
01069          buffer[i++] = 0xc0 + (*str >> 6);
01070          buffer[i++] = 0x80 + (*str & 0x3f);
01071          str += 1;
01072       } else if (*str >= 0xd800 && *str < 0xdc00) {
01073          stb_uint32 c;
01074          if (i+4 > n) return NULL;
01075          c = ((str[0] - 0xd800) << 10) + ((str[1]) - 0xdc00) + 0x10000;
01076          buffer[i++] = 0xf0 + (c >> 18);
01077          buffer[i++] = 0x80 + ((c >> 12) & 0x3f);
01078          buffer[i++] = 0x80 + ((c >>  6) & 0x3f);
01079          buffer[i++] = 0x80 + ((c      ) & 0x3f);
01080          str += 2;
01081       } else if (*str >= 0xdc00 && *str < 0xe000) {
01082          return NULL;
01083       } else {
01084          if (i+3 > n) return NULL;
01085          buffer[i++] = 0xe0 + (*str >> 12);
01086          buffer[i++] = 0x80 + ((*str >> 6) & 0x3f);
01087          buffer[i++] = 0x80 + ((*str     ) & 0x3f);
01088          str += 1;
01089       }
01090    }
01091    buffer[i] = 0;
01092    return buffer;
01093 }
01094 
01095 stb__wchar *stb__from_utf8(const char *str)
01096 {
01097    static stb__wchar buffer[4096];
01098    return stb_from_utf8(buffer, str, 4096);
01099 }
01100 
01101 stb__wchar *stb__from_utf8_alt(const char *str)
01102 {
01103    static stb__wchar buffer[4096];
01104    return stb_from_utf8(buffer, str, 4096);
01105 }
01106 
01107 char *stb__to_utf8(const stb__wchar *str)
01108 {
01109    static char buffer[4096];
01110    return stb_to_utf8(buffer, str, 4096);
01111 }
01112 
01113 #endif
01114 
01116 //
01117 //                         Miscellany
01118 //
01119 
01120 STB_EXTERN void stb_fatal(const char *fmt, ...);
01121 STB_EXTERN void stb_(char *fmt, ...);
01122 STB_EXTERN void stb_append_to_file(char *file, char *fmt, ...);
01123 STB_EXTERN void stb_log(int active);
01124 STB_EXTERN void stb_log_fileline(int active);
01125 STB_EXTERN void stb_log_name(char *filename);
01126 
01127 STB_EXTERN void stb_swap(void *p, void *q, size_t sz);
01128 STB_EXTERN void *stb_copy(void *p, size_t sz);
01129 STB_EXTERN void stb_pointer_array_free(void *p, int len);
01130 STB_EXTERN void **stb_array_block_alloc(int count, int blocksize);
01131 
01132 #define stb_arrcount(x)   (sizeof(x)/sizeof((x)[0]))
01133 
01134 
01135 STB_EXTERN int  stb__record_fileline(const char *f, int n);
01136 
01137 #ifdef STB_DEFINE
01138 
01139 static char *stb__file;
01140 static int   stb__line;
01141 
01142 int  stb__record_fileline(const char *f, int n)
01143 {
01144    stb__file = (char*) f;
01145    stb__line = n;
01146    return 0;
01147 }
01148 
01149 void stb_fatal(const char *s, ...)
01150 {
01151    va_list a;
01152    if (stb__file)
01153       fprintf(stderr, "[%s:%d] ", stb__file, stb__line);
01154    va_start(a,s);
01155    fputs("Fatal error: ", stderr);
01156    vfprintf(stderr, s, a);
01157    va_end(a);
01158    fputs("\n", stderr);
01159    #ifdef STB_DEBUG
01160    #ifdef _MSC_VER
01161    #ifndef STB_PTR64
01162    __asm int 3;   // trap to debugger!
01163    #else
01164    __debugbreak();
01165    #endif
01166    #else
01167    __builtin_trap();
01168    #endif
01169    #endif
01170    exit(1);
01171 }
01172 
01173 static int stb__log_active=1, stb__log_fileline=1;
01174 
01175 void stb_log(int active)
01176 {
01177    stb__log_active = active;
01178 }
01179 
01180 void stb_log_fileline(int active)
01181 {
01182    stb__log_fileline = active;
01183 }
01184 
01185 #ifdef STB_NO_STB_STRINGS
01186 const char *stb__log_filename = "temp.log";
01187 #else
01188 const char *stb__log_filename = "stb.log";
01189 #endif
01190 
01191 void stb_log_name(char *s)
01192 {
01193    stb__log_filename = s;
01194 }
01195 
01196 void stb_(char *s, ...)
01197 {
01198    if (stb__log_active) {
01199       FILE *f = stb_p_fopen(stb__log_filename, "a");
01200       if (f) {
01201          va_list a;
01202          if (stb__log_fileline && stb__file)
01203             fprintf(f, "[%s:%4d] ", stb__file, stb__line);
01204          va_start(a,s);
01205          vfprintf(f, s, a);
01206          va_end(a);
01207          fputs("\n", f);
01208          fclose(f);
01209       }
01210    }
01211 }
01212 
01213 void stb_append_to_file(char *filename, char *s, ...)
01214 {
01215    FILE *f = stb_p_fopen(filename, "a");
01216    if (f) {
01217       va_list a;
01218       va_start(a,s);
01219       vfprintf(f, s, a);
01220       va_end(a);
01221       fputs("\n", f);
01222       fclose(f);
01223    }
01224 }
01225 
01226 
01227 typedef struct { char d[4]; } stb__4;
01228 typedef struct { char d[8]; } stb__8;
01229 
01230 // optimize the small cases, though you shouldn't be calling this for those!
01231 void stb_swap(void *p, void *q, size_t sz)
01232 {
01233    char buffer[256];
01234    if (p == q) return;
01235    if (sz == 4) {
01236       stb__4 temp    = * ( stb__4 *) p;
01237       * (stb__4 *) p = * ( stb__4 *) q;
01238       * (stb__4 *) q = temp;
01239       return;
01240    } else if (sz == 8) {
01241       stb__8 temp    = * ( stb__8 *) p;
01242       * (stb__8 *) p = * ( stb__8 *) q;
01243       * (stb__8 *) q = temp;
01244       return;
01245    }
01246 
01247    while (sz > sizeof(buffer)) {
01248       stb_swap(p, q, sizeof(buffer));
01249       p = (char *) p + sizeof(buffer);
01250       q = (char *) q + sizeof(buffer);
01251       sz -= sizeof(buffer);
01252    }
01253 
01254    memcpy(buffer, p     , sz);
01255    memcpy(p     , q     , sz);
01256    memcpy(q     , buffer, sz);
01257 }
01258 
01259 void *stb_copy(void *p, size_t sz)
01260 {
01261    void *q = malloc(sz);
01262    memcpy(q, p, sz);
01263    return q;
01264 }
01265 
01266 void stb_pointer_array_free(void *q, int len)
01267 {
01268    void **p = (void **) q;
01269    int i;
01270    for (i=0; i < len; ++i)
01271       free(p[i]);
01272 }
01273 
01274 void **stb_array_block_alloc(int count, int blocksize)
01275 {
01276    int i;
01277    char *p = (char *) malloc(sizeof(void *) * count + count * blocksize);
01278    void **q;
01279    if (p == NULL) return NULL;
01280    q = (void **) p;
01281    p += sizeof(void *) * count;
01282    for (i=0; i < count; ++i)
01283       q[i] = p + i * blocksize;
01284    return q;
01285 }
01286 #endif
01287 
01288 #ifdef STB_DEBUG
01289    // tricky hack to allow recording FILE,LINE even in varargs functions
01290    #define STB__RECORD_FILE(x)  (stb__record_fileline(__FILE__, __LINE__),(x))
01291    #define stb_log              STB__RECORD_FILE(stb_log)
01292    #define stb_                 STB__RECORD_FILE(stb_)
01293    #ifndef STB_FATAL_CLEAN
01294    #define stb_fatal            STB__RECORD_FILE(stb_fatal)
01295    #endif
01296    #define STB__DEBUG(x)        x
01297 #else
01298    #define STB__DEBUG(x)
01299 #endif
01300 
01302 //
01303 //                         stb_temp
01304 //
01305 
01306 #define stb_temp(block, sz)     stb__temp(block, sizeof(block), (sz))
01307 
01308 STB_EXTERN void * stb__temp(void *b, int b_sz, int want_sz);
01309 STB_EXTERN void   stb_tempfree(void *block, void *ptr);
01310 
01311 #ifdef STB_DEFINE
01312 
01313 void * stb__temp(void *b, int b_sz, int want_sz)
01314 {
01315    if (b_sz >= want_sz)
01316       return b;
01317    else
01318       return malloc(want_sz);
01319 }
01320 
01321 void   stb_tempfree(void *b, void *p)
01322 {
01323    if (p != b)
01324       free(p);
01325 }
01326 #endif
01327 
01328 
01330 //
01331 //                      math/sampling operations
01332 //
01333 
01334 
01335 #define stb_lerp(t,a,b)               ( (a) + (t) * (float) ((b)-(a)) )
01336 #define stb_unlerp(t,a,b)             ( ((t) - (a)) / (float) ((b) - (a)) )
01337 
01338 #define stb_clamp(x,xmin,xmax)  ((x) < (xmin) ? (xmin) : (x) > (xmax) ? (xmax) : (x))
01339 
01340 STB_EXTERN void stb_newell_normal(float *normal, int num_vert, float **vert, int normalize);
01341 STB_EXTERN int stb_box_face_vertex_axis_side(int face_number, int vertex_number, int axis);
01342 STB_EXTERN void stb_linear_controller(float *curpos, float target_pos, float acc, float deacc, float dt);
01343 
01344 STB_EXTERN int stb_float_eq(float x, float y, float delta, int max_ulps);
01345 STB_EXTERN int stb_is_prime(unsigned int m);
01346 STB_EXTERN unsigned int stb_power_of_two_nearest_prime(int n);
01347 
01348 STB_EXTERN float stb_smoothstep(float t);
01349 STB_EXTERN float stb_cubic_bezier_1d(float t, float p0, float p1, float p2, float p3);
01350 
01351 STB_EXTERN double stb_linear_remap(double x, double a, double b,
01352                                              double c, double d);
01353 
01354 #ifdef STB_DEFINE
01355 float stb_smoothstep(float t)
01356 {
01357    return (3 - 2*t)*(t*t);
01358 }
01359 
01360 float stb_cubic_bezier_1d(float t, float p0, float p1, float p2, float p3)
01361 {
01362    float it = 1-t;
01363    return it*it*it*p0 + 3*it*it*t*p1 + 3*it*t*t*p2 + t*t*t*p3;
01364 }
01365 
01366 void stb_newell_normal(float *normal, int num_vert, float **vert, int normalize)
01367 {
01368    int i,j;
01369    float p;
01370    normal[0] = normal[1] = normal[2] = 0;
01371    for (i=num_vert-1,j=0; j < num_vert; i=j++) {
01372       float *u = vert[i];
01373       float *v = vert[j];
01374       normal[0] += (u[1] - v[1]) * (u[2] + v[2]);
01375       normal[1] += (u[2] - v[2]) * (u[0] + v[0]);
01376       normal[2] += (u[0] - v[0]) * (u[1] + v[1]);
01377    }
01378    if (normalize) {
01379       p = normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2];
01380       p = (float) (1.0 / sqrt(p));
01381       normal[0] *= p;
01382       normal[1] *= p;
01383       normal[2] *= p;
01384    }
01385 }
01386 
01387 int stb_box_face_vertex_axis_side(int face_number, int vertex_number, int axis)
01388 {
01389    static int box_vertices[6][4][3] =
01390    {
01391       { { 1,1,1 }, { 1,0,1 }, { 1,0,0 }, { 1,1,0 } },
01392       { { 0,0,0 }, { 0,0,1 }, { 0,1,1 }, { 0,1,0 } },
01393       { { 0,0,0 }, { 0,1,0 }, { 1,1,0 }, { 1,0,0 } },
01394       { { 0,0,0 }, { 1,0,0 }, { 1,0,1 }, { 0,0,1 } },
01395       { { 1,1,1 }, { 0,1,1 }, { 0,0,1 }, { 1,0,1 } },
01396       { { 1,1,1 }, { 1,1,0 }, { 0,1,0 }, { 0,1,1 } },
01397    };
01398    assert(face_number >= 0 && face_number < 6);
01399    assert(vertex_number >= 0 && vertex_number < 4);
01400    assert(axis >= 0 && axis < 3);
01401    return box_vertices[face_number][vertex_number][axis];
01402 }
01403 
01404 void stb_linear_controller(float *curpos, float target_pos, float acc, float deacc, float dt)
01405 {
01406    float sign = 1, p, cp = *curpos;
01407    if (cp == target_pos) return;
01408    if (target_pos < cp) {
01409       target_pos = -target_pos;
01410       cp = -cp;
01411       sign = -1;
01412    }
01413    // first decelerate
01414    if (cp < 0) {
01415       p = cp + deacc * dt;
01416       if (p > 0) {
01417          p = 0;
01418          dt = dt - cp / deacc;
01419          if (dt < 0) dt = 0;
01420       } else {
01421          dt = 0;
01422       }
01423       cp = p;
01424    }
01425    // now accelerate
01426    p = cp + acc*dt;
01427    if (p > target_pos) p = target_pos;
01428    *curpos = p * sign;
01429    // @TODO: testing
01430 }
01431 
01432 float stb_quadratic_controller(float target_pos, float curpos, float maxvel, float maxacc, float dt, float *curvel)
01433 {
01434    return 0; // @TODO
01435 }
01436 
01437 int stb_float_eq(float x, float y, float delta, int max_ulps)
01438 {
01439    if (fabs(x-y) <= delta) return 1;
01440    if (abs(*(int *)&x - *(int *)&y) <= max_ulps) return 1;
01441    return 0;
01442 }
01443 
01444 int stb_is_prime(unsigned int m)
01445 {
01446    unsigned int i,j;
01447    if (m < 2) return 0;
01448    if (m == 2) return 1;
01449    if (!(m & 1)) return 0;
01450    if (m % 3 == 0) return (m == 3);
01451    for (i=5; (j=i*i), j <= m && j > i; i += 6) {
01452       if (m %   i   == 0) return 0;
01453       if (m % (i+2) == 0) return 0;
01454    }
01455    return 1;
01456 }
01457 
01458 unsigned int stb_power_of_two_nearest_prime(int n)
01459 {
01460    static signed char tab[32] = { 0,0,0,0,1,0,-1,0,1,-1,-1,3,-1,0,-1,2,1,
01461                                    0,2,0,-1,-4,-1,5,-1,18,-2,15,2,-1,2,0 };
01462    if (!tab[0]) {
01463       int i;
01464       for (i=0; i < 32; ++i)
01465          tab[i] = (1 << i) + 2*tab[i] - 1;
01466       tab[1] = 2;
01467       tab[0] = 1;
01468    }
01469    if (n >= 32) return 0xfffffffb;
01470    return tab[n];
01471 }
01472 
01473 double stb_linear_remap(double x, double x_min, double x_max,
01474                                   double out_min, double out_max)
01475 {
01476    return stb_lerp(stb_unlerp(x,x_min,x_max),out_min,out_max);
01477 }
01478 #endif
01479 
01480 // create a macro so it's faster, but you can get at the function pointer
01481 #define stb_linear_remap(t,a,b,c,d)   stb_lerp(stb_unlerp(t,a,b),c,d)
01482 
01483 
01485 //
01486 //                         bit operations
01487 //
01488 
01489 #define stb_big32(c)    (((c)[0]<<24) + (c)[1]*65536 + (c)[2]*256 + (c)[3])
01490 #define stb_little32(c) (((c)[3]<<24) + (c)[2]*65536 + (c)[1]*256 + (c)[0])
01491 #define stb_big16(c)    ((c)[0]*256 + (c)[1])
01492 #define stb_little16(c) ((c)[1]*256 + (c)[0])
01493 
01494 STB_EXTERN          int stb_bitcount(unsigned int a);
01495 STB_EXTERN unsigned int stb_bitreverse8(unsigned char n);
01496 STB_EXTERN unsigned int stb_bitreverse(unsigned int n);
01497 
01498 STB_EXTERN          int stb_is_pow2(size_t);
01499 STB_EXTERN          int stb_log2_ceil(size_t);
01500 STB_EXTERN          int stb_log2_floor(size_t);
01501 
01502 STB_EXTERN          int stb_lowbit8(unsigned int n);
01503 STB_EXTERN          int stb_highbit8(unsigned int n);
01504 
01505 #ifdef STB_DEFINE
01506 int stb_bitcount(unsigned int a)
01507 {
01508    a = (a & 0x55555555) + ((a >>  1) & 0x55555555); // max 2
01509    a = (a & 0x33333333) + ((a >>  2) & 0x33333333); // max 4
01510    a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits
01511    a = (a + (a >> 8)); // max 16 per 8 bits
01512    a = (a + (a >> 16)); // max 32 per 8 bits
01513    return a & 0xff;
01514 }
01515 
01516 unsigned int stb_bitreverse8(unsigned char n)
01517 {
01518    n = ((n & 0xAA) >> 1) + ((n & 0x55) << 1);
01519    n = ((n & 0xCC) >> 2) + ((n & 0x33) << 2);
01520    return (unsigned char) ((n >> 4) + (n << 4));
01521 }
01522 
01523 unsigned int stb_bitreverse(unsigned int n)
01524 {
01525   n = ((n & 0xAAAAAAAA) >>  1) | ((n & 0x55555555) << 1);
01526   n = ((n & 0xCCCCCCCC) >>  2) | ((n & 0x33333333) << 2);
01527   n = ((n & 0xF0F0F0F0) >>  4) | ((n & 0x0F0F0F0F) << 4);
01528   n = ((n & 0xFF00FF00) >>  8) | ((n & 0x00FF00FF) << 8);
01529   return (n >> 16) | (n << 16);
01530 }
01531 
01532 int stb_is_pow2(size_t n)
01533 {
01534    return (n & (n-1)) == 0;
01535 }
01536 
01537 // tricky use of 4-bit table to identify 5 bit positions (note the '-1')
01538 // 3-bit table would require another tree level; 5-bit table wouldn't save one
01539 #if defined(_WIN32) && !defined(__MINGW32__)
01540 #pragma warning(push)
01541 #pragma warning(disable: 4035)  // disable warning about no return value
01542 int stb_log2_floor(size_t n)
01543 {
01544    #if _MSC_VER > 1700
01545    unsigned long i;
01546    #ifdef STB_PTR64
01547    _BitScanReverse64(&i, n);
01548    #else
01549    _BitScanReverse(&i, n);
01550    #endif
01551    return i != 0 ? i : -1;
01552    #else
01553    __asm {
01554       bsr eax,n
01555       jnz done
01556       mov eax,-1
01557    }
01558    done:;
01559    #endif
01560 }
01561 #pragma warning(pop)
01562 #else
01563 int stb_log2_floor(size_t n)
01564 {
01565    static signed char log2_4[16] = { -1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3 };
01566 
01567 #ifdef STB_PTR64
01568    if (n >= ((size_t) 1u << 32))
01569         return stb_log2_floor(n >> 32);
01570 #endif
01571 
01572    // 2 compares if n < 16, 3 compares otherwise
01573    if (n < (1U << 14))
01574         if (n < (1U <<  4))        return     0 + log2_4[n      ];
01575         else if (n < (1U <<  9))      return  5 + log2_4[n >>  5];
01576              else                     return 10 + log2_4[n >> 10];
01577    else if (n < (1U << 24))
01578              if (n < (1U << 19))      return 15 + log2_4[n >> 15];
01579              else                     return 20 + log2_4[n >> 20];
01580         else if (n < (1U << 29))      return 25 + log2_4[n >> 25];
01581              else                     return 30 + log2_4[n >> 30];
01582 }
01583 #endif
01584 
01585 // define ceil from floor
01586 int stb_log2_ceil(size_t n)
01587 {
01588    if (stb_is_pow2(n))  return     stb_log2_floor(n);
01589    else                 return 1 + stb_log2_floor(n);
01590 }
01591 
01592 int stb_highbit8(unsigned int n)
01593 {
01594    return stb_log2_ceil(n&255);
01595 }
01596 
01597 int stb_lowbit8(unsigned int n)
01598 {
01599    static signed char lowbit4[16] = { -1,0,1,0, 2,0,1,0, 3,0,1,0, 2,0,1,0 };
01600    int k = lowbit4[n & 15];
01601    if (k >= 0) return k;
01602    k = lowbit4[(n >> 4) & 15];
01603    if (k >= 0) return k+4;
01604    return k;
01605 }
01606 #endif
01607 
01608 
01609 
01611 //
01612 //                            qsort Compare Routines
01613 //
01614 
01615 #ifdef _WIN32
01616    #define stb_stricmp(a,b) stb_p_stricmp(a,b)
01617    #define stb_strnicmp(a,b,n) stb_p_strnicmp(a,b,n)
01618 #else
01619    #define stb_stricmp(a,b) strcasecmp(a,b)
01620    #define stb_strnicmp(a,b,n) strncasecmp(a,b,n)
01621 #endif
01622 
01623 
01624 STB_EXTERN int (*stb_intcmp(int offset))(const void *a, const void *b);
01625 STB_EXTERN int (*stb_intcmprev(int offset))(const void *a, const void *b);
01626 STB_EXTERN int (*stb_qsort_strcmp(int offset))(const void *a, const void *b);
01627 STB_EXTERN int (*stb_qsort_stricmp(int offset))(const void *a, const void *b);
01628 STB_EXTERN int (*stb_floatcmp(int offset))(const void *a, const void *b);
01629 STB_EXTERN int (*stb_doublecmp(int offset))(const void *a, const void *b);
01630 STB_EXTERN int (*stb_charcmp(int offset))(const void *a, const void *b);
01631 
01632 #ifdef STB_DEFINE
01633 static int stb__intcmpoffset, stb__ucharcmpoffset, stb__strcmpoffset;
01634 static int stb__floatcmpoffset, stb__doublecmpoffset;
01635 static int stb__memcmpoffset, stb__memcmpsize;
01636 
01637 int stb__intcmp(const void *a, const void *b)
01638 {
01639    const int p = *(const int *) ((const char *) a + stb__intcmpoffset);
01640    const int q = *(const int *) ((const char *) b + stb__intcmpoffset);
01641    return p < q ? -1 : p > q;
01642 }
01643 
01644 int stb__intcmprev(const void *a, const void *b)
01645 {
01646    const int p = *(const int *) ((const char *) a + stb__intcmpoffset);
01647    const int q = *(const int *) ((const char *) b + stb__intcmpoffset);
01648    return q < p ? -1 : q > p;
01649 }
01650 
01651 int stb__ucharcmp(const void *a, const void *b)
01652 {
01653    const int p = *(const unsigned char *) ((const char *) a + stb__ucharcmpoffset);
01654    const int q = *(const unsigned char *) ((const char *) b + stb__ucharcmpoffset);
01655    return p < q ? -1 : p > q;
01656 }
01657 
01658 int stb__floatcmp(const void *a, const void *b)
01659 {
01660    const float p = *(const float *) ((const char *) a + stb__floatcmpoffset);
01661    const float q = *(const float *) ((const char *) b + stb__floatcmpoffset);
01662    return p < q ? -1 : p > q;
01663 }
01664 
01665 int stb__doublecmp(const void *a, const void *b)
01666 {
01667    const double p = *(const double *) ((const char *) a + stb__doublecmpoffset);
01668    const double q = *(const double *) ((const char *) b + stb__doublecmpoffset);
01669    return p < q ? -1 : p > q;
01670 }
01671 
01672 int stb__qsort_strcmp(const void *a, const void *b)
01673 {
01674    const char *p = *(const char **) ((const char *) a + stb__strcmpoffset);
01675    const char *q = *(const char **) ((const char *) b + stb__strcmpoffset);
01676    return strcmp(p,q);
01677 }
01678 
01679 int stb__qsort_stricmp(const void *a, const void *b)
01680 {
01681    const char *p = *(const char **) ((const char *) a + stb__strcmpoffset);
01682    const char *q = *(const char **) ((const char *) b + stb__strcmpoffset);
01683    return stb_stricmp(p,q);
01684 }
01685 
01686 int stb__memcmp(const void *a, const void *b)
01687 {
01688    return memcmp((char *) a + stb__memcmpoffset, (char *) b + stb__memcmpoffset, stb__memcmpsize);
01689 }
01690 
01691 int (*stb_intcmp(int offset))(const void *, const void *)
01692 {
01693    stb__intcmpoffset = offset;
01694    return &stb__intcmp;
01695 }
01696 
01697 int (*stb_intcmprev(int offset))(const void *, const void *)
01698 {
01699    stb__intcmpoffset = offset;
01700    return &stb__intcmprev;
01701 }
01702 
01703 int (*stb_ucharcmp(int offset))(const void *, const void *)
01704 {
01705    stb__ucharcmpoffset = offset;
01706    return &stb__ucharcmp;
01707 }
01708 
01709 int (*stb_qsort_strcmp(int offset))(const void *, const void *)
01710 {
01711    stb__strcmpoffset = offset;
01712    return &stb__qsort_strcmp;
01713 }
01714 
01715 int (*stb_qsort_stricmp(int offset))(const void *, const void *)
01716 {
01717    stb__strcmpoffset = offset;
01718    return &stb__qsort_stricmp;
01719 }
01720 
01721 int (*stb_floatcmp(int offset))(const void *, const void *)
01722 {
01723    stb__floatcmpoffset = offset;
01724    return &stb__floatcmp;
01725 }
01726 
01727 int (*stb_doublecmp(int offset))(const void *, const void *)
01728 {
01729    stb__doublecmpoffset = offset;
01730    return &stb__doublecmp;
01731 }
01732 
01733 int (*stb_memcmp(int offset, int size))(const void *, const void *)
01734 {
01735    stb__memcmpoffset = offset;
01736    stb__memcmpsize = size;
01737    return &stb__memcmp;
01738 }
01739 #endif
01740 
01742 //
01743 //                           Binary Search Toolkit
01744 //
01745 
01746 typedef struct
01747 {
01748    int minval, maxval, guess;
01749    int mode, step;
01750 } stb_search;
01751 
01752 STB_EXTERN int stb_search_binary(stb_search *s, int minv, int maxv, int find_smallest);
01753 STB_EXTERN int stb_search_open(stb_search *s, int minv, int find_smallest);
01754 STB_EXTERN int stb_probe(stb_search *s, int compare, int *result); // return 0 when done
01755 
01756 #ifdef STB_DEFINE
01757 enum
01758 {
01759    STB_probe_binary_smallest,
01760    STB_probe_binary_largest,
01761    STB_probe_open_smallest,
01762    STB_probe_open_largest,
01763 };
01764 
01765 static int stb_probe_guess(stb_search *s, int *result)
01766 {
01767    switch(s->mode) {
01768       case STB_probe_binary_largest:
01769          if (s->minval == s->maxval) {
01770             *result = s->minval;
01771             return 0;
01772          }
01773          assert(s->minval < s->maxval);
01774          // if a < b, then a < p <= b
01775          s->guess = s->minval + (((unsigned) s->maxval - s->minval + 1) >> 1);
01776          break;
01777 
01778       case STB_probe_binary_smallest:
01779          if (s->minval == s->maxval) {
01780             *result = s->minval;
01781             return 0;
01782          }
01783          assert(s->minval < s->maxval);
01784          // if a < b, then a <= p < b
01785          s->guess = s->minval + (((unsigned) s->maxval - s->minval) >> 1);
01786          break;
01787       case STB_probe_open_smallest:
01788       case STB_probe_open_largest:
01789          s->guess = s->maxval;  // guess the current maxval
01790          break;
01791    }
01792    *result = s->guess;
01793    return 1;
01794 }
01795 
01796 int stb_probe(stb_search *s, int compare, int *result)
01797 {
01798    switch(s->mode) {
01799       case STB_probe_open_smallest:
01800       case STB_probe_open_largest: {
01801          if (compare <= 0) {
01802             // then it lies within minval & maxval
01803             if (s->mode == STB_probe_open_smallest)
01804                s->mode = STB_probe_binary_smallest;
01805             else
01806                s->mode = STB_probe_binary_largest;
01807          } else {
01808             // otherwise, we need to probe larger
01809             s->minval  = s->maxval + 1;
01810             s->maxval  = s->minval + s->step;
01811             s->step   += s->step;
01812          }
01813          break;
01814       }
01815       case STB_probe_binary_smallest: {
01816          // if compare < 0, then s->minval <= a <  p
01817          // if compare = 0, then s->minval <= a <= p
01818          // if compare > 0, then         p <  a <= s->maxval
01819          if (compare <= 0)
01820             s->maxval = s->guess;
01821          else
01822             s->minval = s->guess+1;
01823          break;
01824       }
01825       case STB_probe_binary_largest: {
01826          // if compare < 0, then s->minval <= a < p
01827          // if compare = 0, then         p <= a <= s->maxval
01828          // if compare > 0, then         p <  a <= s->maxval
01829          if (compare < 0)
01830             s->maxval = s->guess-1;
01831          else
01832             s->minval = s->guess;
01833          break;
01834       }
01835    }
01836    return stb_probe_guess(s, result);
01837 }
01838 
01839 int stb_search_binary(stb_search *s, int minv, int maxv, int find_smallest)
01840 {
01841    int r;
01842    if (maxv < minv) return minv-1;
01843    s->minval = minv;
01844    s->maxval = maxv;
01845    s->mode = find_smallest ? STB_probe_binary_smallest : STB_probe_binary_largest;
01846    stb_probe_guess(s, &r);
01847    return r;
01848 }
01849 
01850 int stb_search_open(stb_search *s, int minv, int find_smallest)
01851 {
01852    int r;
01853    s->step   = 4;
01854    s->minval = minv;
01855    s->maxval = minv+s->step;
01856    s->mode = find_smallest ? STB_probe_open_smallest : STB_probe_open_largest;
01857    stb_probe_guess(s, &r);
01858    return r;
01859 }
01860 #endif
01861 
01863 //
01864 //                           String Processing
01865 //
01866 
01867 #define stb_prefixi(s,t)  (0==stb_strnicmp((s),(t),strlen(t)))
01868 
01869 enum stb_splitpath_flag
01870 {
01871    STB_PATH = 1,
01872    STB_FILE = 2,
01873    STB_EXT  = 4,
01874    STB_PATH_FILE = STB_PATH + STB_FILE,
01875    STB_FILE_EXT  = STB_FILE + STB_EXT,
01876    STB_EXT_NO_PERIOD = 8,
01877 };
01878 
01879 STB_EXTERN char * stb_skipwhite(char *s);
01880 STB_EXTERN char * stb_trimwhite(char *s);
01881 STB_EXTERN char * stb_skipnewline(char *s);
01882 STB_EXTERN char * stb_strncpy(char *s, char *t, int n);
01883 STB_EXTERN char * stb_substr(char *t, int n);
01884 STB_EXTERN char * stb_duplower(char *s);
01885 STB_EXTERN void   stb_tolower (char *s);
01886 STB_EXTERN char * stb_strchr2 (char *s, char p1, char p2);
01887 STB_EXTERN char * stb_strrchr2(char *s, char p1, char p2);
01888 STB_EXTERN char * stb_strtok(char *output, char *src, char *delimit);
01889 STB_EXTERN char * stb_strtok_keep(char *output, char *src, char *delimit);
01890 STB_EXTERN char * stb_strtok_invert(char *output, char *src, char *allowed);
01891 STB_EXTERN char * stb_dupreplace(char *s, char *find, char *replace);
01892 STB_EXTERN void   stb_replaceinplace(char *s, char *find, char *replace);
01893 STB_EXTERN char * stb_splitpath(char *output, char *src, int flag);
01894 STB_EXTERN char * stb_splitpathdup(char *src, int flag);
01895 STB_EXTERN char * stb_replacedir(char *output, char *src, char *dir);
01896 STB_EXTERN char * stb_replaceext(char *output, char *src, char *ext);
01897 STB_EXTERN void   stb_fixpath(char *path);
01898 STB_EXTERN char * stb_shorten_path_readable(char *path, int max_len);
01899 STB_EXTERN int    stb_suffix (char *s, char *t);
01900 STB_EXTERN int    stb_suffixi(char *s, char *t);
01901 STB_EXTERN int    stb_prefix (char *s, char *t);
01902 STB_EXTERN char * stb_strichr(char *s, char t);
01903 STB_EXTERN char * stb_stristr(char *s, char *t);
01904 STB_EXTERN int    stb_prefix_count(char *s, char *t);
01905 STB_EXTERN const char * stb_plural(int n);  // "s" or ""
01906 STB_EXTERN size_t stb_strscpy(char *d, const char *s, size_t n);
01907 
01908 STB_EXTERN char **stb_tokens(char *src, char *delimit, int *count);
01909 STB_EXTERN char **stb_tokens_nested(char *src, char *delimit, int *count, char *nest_in, char *nest_out);
01910 STB_EXTERN char **stb_tokens_nested_empty(char *src, char *delimit, int *count, char *nest_in, char *nest_out);
01911 STB_EXTERN char **stb_tokens_allowempty(char *src, char *delimit, int *count);
01912 STB_EXTERN char **stb_tokens_stripwhite(char *src, char *delimit, int *count);
01913 STB_EXTERN char **stb_tokens_withdelim(char *src, char *delimit, int *count);
01914 STB_EXTERN char **stb_tokens_quoted(char *src, char *delimit, int *count);
01915 // with 'quoted', allow delimiters to appear inside quotation marks, and don't
01916 // strip whitespace inside them (and we delete the quotation marks unless they
01917 // appear back to back, in which case they're considered escaped)
01918 
01919 #ifdef STB_DEFINE
01920 
01921 size_t stb_strscpy(char *d, const char *s, size_t n)
01922 {
01923    size_t len = strlen(s);
01924    if (len >= n) {
01925       if (n) d[0] = 0;
01926       return 0;
01927    }
01928    stb_p_strcpy_s(d,n+1,s);
01929    return len + 1;
01930 }
01931 
01932 const char *stb_plural(int n)
01933 {
01934    return n == 1 ? "" : "s";
01935 }
01936 
01937 int stb_prefix(char *s, char *t)
01938 {
01939    while (*t)
01940       if (*s++ != *t++)
01941          return STB_FALSE;
01942    return STB_TRUE;
01943 }
01944 
01945 int stb_prefix_count(char *s, char *t)
01946 {
01947    int c=0;
01948    while (*t) {
01949       if (*s++ != *t++)
01950          break;
01951       ++c;
01952    }
01953    return c;
01954 }
01955 
01956 int stb_suffix(char *s, char *t)
01957 {
01958    size_t n = strlen(s);
01959    size_t m = strlen(t);
01960    if (m <= n)
01961       return 0 == strcmp(s+n-m, t);
01962    else
01963       return 0;
01964 }
01965 
01966 int stb_suffixi(char *s, char *t)
01967 {
01968    size_t n = strlen(s);
01969    size_t m = strlen(t);
01970    if (m <= n)
01971       return 0 == stb_stricmp(s+n-m, t);
01972    else
01973       return 0;
01974 }
01975 
01976 // originally I was using this table so that I could create known sentinel
01977 // values--e.g. change whitetable[0] to be true if I was scanning for whitespace,
01978 // and false if I was scanning for nonwhite. I don't appear to be using that
01979 // functionality anymore (I do for tokentable, though), so just replace it
01980 // with isspace()
01981 char *stb_skipwhite(char *s)
01982 {
01983    while (isspace((unsigned char) *s)) ++s;
01984    return s;
01985 }
01986 
01987 char *stb_skipnewline(char *s)
01988 {
01989    if (s[0] == '\r' || s[0] == '\n') {
01990       if (s[0]+s[1] == '\r' + '\n') ++s;
01991       ++s;
01992    }
01993    return s;
01994 }
01995 
01996 char *stb_trimwhite(char *s)
01997 {
01998    int i,n;
01999    s = stb_skipwhite(s);
02000    n = (int) strlen(s);
02001    for (i=n-1; i >= 0; --i)
02002       if (!isspace(s[i]))
02003          break;
02004    s[i+1] = 0;
02005    return s;
02006 }
02007 
02008 char *stb_strncpy(char *s, char *t, int n)
02009 {
02010    stb_p_strncpy_s(s,n+1,t,n);
02011    s[n] = 0;
02012    return s;
02013 }
02014 
02015 char *stb_substr(char *t, int n)
02016 {
02017    char *a;
02018    int z = (int) strlen(t);
02019    if (z < n) n = z;
02020    a = (char *) malloc(n+1);
02021    stb_p_strncpy_s(a,n+1,t,n);
02022    a[n] = 0;
02023    return a;
02024 }
02025 
02026 char *stb_duplower(char *s)
02027 {
02028    char *p = stb_p_strdup(s), *q = p;
02029    while (*q) {
02030       *q = tolower(*q);
02031       ++q;
02032    }
02033    return p;
02034 }
02035 
02036 void stb_tolower(char *s)
02037 {
02038    while (*s) {
02039       *s = tolower(*s);
02040       ++s;
02041    }
02042 }
02043 
02044 char *stb_strchr2(char *s, char x, char y)
02045 {
02046    for(; *s; ++s)
02047       if (*s == x || *s == y)
02048          return s;
02049    return NULL;
02050 }
02051 
02052 char *stb_strrchr2(char *s, char x, char y)
02053 {
02054    char *r = NULL;
02055    for(; *s; ++s)
02056       if (*s == x || *s == y)
02057          r = s;
02058    return r;
02059 }
02060 
02061 char *stb_strichr(char *s, char t)
02062 {
02063    if (tolower(t) == toupper(t))
02064       return strchr(s,t);
02065    return stb_strchr2(s, (char) tolower(t), (char) toupper(t));
02066 }
02067 
02068 char *stb_stristr(char *s, char *t)
02069 {
02070    size_t n = strlen(t);
02071    char *z;
02072    if (n==0) return s;
02073    while ((z = stb_strichr(s, *t)) != NULL) {
02074       if (0==stb_strnicmp(z, t, n))
02075          return z;
02076       s = z+1;
02077    }
02078    return NULL;
02079 }
02080 
02081 static char *stb_strtok_raw(char *output, char *src, char *delimit, int keep, int invert)
02082 {
02083    if (invert) {
02084       while (*src && strchr(delimit, *src) != NULL) {
02085          *output++ = *src++;
02086       }
02087    } else {
02088       while (*src && strchr(delimit, *src) == NULL) {
02089          *output++ = *src++;
02090       }
02091    }
02092    *output = 0;
02093    if (keep)
02094       return src;
02095    else
02096       return *src ? src+1 : src;
02097 }
02098 
02099 char *stb_strtok(char *output, char *src, char *delimit)
02100 {
02101    return stb_strtok_raw(output, src, delimit, 0, 0);
02102 }
02103 
02104 char *stb_strtok_keep(char *output, char *src, char *delimit)
02105 {
02106    return stb_strtok_raw(output, src, delimit, 1, 0);
02107 }
02108 
02109 char *stb_strtok_invert(char *output, char *src, char *delimit)
02110 {
02111    return stb_strtok_raw(output, src, delimit, 1,1);
02112 }
02113 
02114 static char **stb_tokens_raw(char *src_, char *delimit, int *count,
02115                              int stripwhite, int allow_empty, char *start, char *end)
02116 {
02117    int nested = 0;
02118    unsigned char *src = (unsigned char *) src_;
02119    static char stb_tokentable[256]; // rely on static initializion to 0
02120    static char stable[256],etable[256];
02121    char *out;
02122    char **result;
02123    int num=0;
02124    unsigned char *s;
02125 
02126    s = (unsigned char *) delimit; while (*s) stb_tokentable[*s++] = 1;
02127    if (start) {
02128       s = (unsigned char *) start;         while (*s) stable[*s++] = 1;
02129       s = (unsigned char *) end;   if (s)  while (*s) stable[*s++] = 1;
02130       s = (unsigned char *) end;   if (s)  while (*s) etable[*s++] = 1;
02131    }
02132    stable[0] = 1;
02133 
02134    // two passes through: the first time, counting how many
02135    s = (unsigned char *) src;
02136    while (*s) {
02137       // state: just found delimiter
02138       // skip further delimiters
02139       if (!allow_empty) {
02140          stb_tokentable[0] = 0;
02141          while (stb_tokentable[*s])
02142             ++s;
02143          if (!*s) break;
02144       }
02145       ++num;
02146       // skip further non-delimiters
02147       stb_tokentable[0] = 1;
02148       if (stripwhite == 2) { // quoted strings
02149          while (!stb_tokentable[*s]) {
02150             if (*s != '"')
02151                ++s;
02152             else {
02153                ++s;
02154                if (*s == '"')
02155                   ++s;   // "" -> ", not start a string
02156                else {
02157                   // begin a string
02158                   while (*s) {
02159                      if (s[0] == '"') {
02160                         if (s[1] == '"') s += 2; // "" -> "
02161                         else { ++s; break; } // terminating "
02162                      } else
02163                         ++s;
02164                   }
02165                }
02166             }
02167          }
02168       } else
02169          while (nested || !stb_tokentable[*s]) {
02170             if (stable[*s]) {
02171                if (!*s) break;
02172                if (end ? etable[*s] : nested)
02173                   --nested;
02174                else
02175                   ++nested;
02176             }
02177             ++s;
02178          }
02179       if (allow_empty) {
02180          if (*s) ++s;
02181       }
02182    }
02183    // now num has the actual count... malloc our output structure
02184    // need space for all the strings: strings won't be any longer than
02185    // original input, since for every '\0' there's at least one delimiter
02186    result = (char **) malloc(sizeof(*result) * (num+1) + (s-src+1));
02187    if (result == NULL) return result;
02188    out = (char *) (result + (num+1));
02189    // second pass: copy out the data
02190    s = (unsigned char *) src;
02191    num = 0;
02192    nested = 0;
02193    while (*s) {
02194       char *last_nonwhite;
02195       // state: just found delimiter
02196       // skip further delimiters
02197       if (!allow_empty) {
02198          stb_tokentable[0] = 0;
02199          if (stripwhite)
02200             while (stb_tokentable[*s] || isspace(*s))
02201                ++s;
02202          else
02203             while (stb_tokentable[*s])
02204                ++s;
02205       } else if (stripwhite) {
02206          while (isspace(*s)) ++s;
02207       }
02208       if (!*s) break;
02209       // we're past any leading delimiters and whitespace
02210       result[num] = out;
02211       ++num;
02212       // copy non-delimiters
02213       stb_tokentable[0] = 1;
02214       last_nonwhite = out-1;
02215       if (stripwhite == 2) {
02216          while (!stb_tokentable[*s]) {
02217             if (*s != '"') {
02218                if (!isspace(*s)) last_nonwhite = out;
02219                *out++ = *s++;
02220             } else {
02221                ++s;
02222                if (*s == '"') {
02223                   if (!isspace(*s)) last_nonwhite = out;
02224                   *out++ = *s++; // "" -> ", not start string
02225                } else {
02226                   // begin a quoted string
02227                   while (*s) {
02228                      if (s[0] == '"') {
02229                         if (s[1] == '"') { *out++ = *s; s += 2; }
02230                         else { ++s; break; } // terminating "
02231                      } else
02232                         *out++ = *s++;
02233                   }
02234                   last_nonwhite = out-1; // all in quotes counts as non-white
02235                }
02236             }
02237          }
02238       } else {
02239          while (nested || !stb_tokentable[*s]) {
02240             if (!isspace(*s)) last_nonwhite = out;
02241             if (stable[*s]) {
02242                if (!*s) break;
02243                if (end ? etable[*s] : nested)
02244                   --nested;
02245                else
02246                   ++nested;
02247             }
02248             *out++ = *s++;
02249          }
02250       }
02251 
02252       if (stripwhite) // rewind to last non-whitespace char
02253          out = last_nonwhite+1;
02254       *out++ = '\0';
02255 
02256       if (*s) ++s; // skip delimiter
02257    }
02258    s = (unsigned char *) delimit; while (*s) stb_tokentable[*s++] = 0;
02259    if (start) {
02260       s = (unsigned char *) start;         while (*s) stable[*s++] = 1;
02261       s = (unsigned char *) end;   if (s)  while (*s) stable[*s++] = 1;
02262       s = (unsigned char *) end;   if (s)  while (*s) etable[*s++] = 1;
02263    }
02264    if (count != NULL) *count = num;
02265    result[num] = 0;
02266    return result;
02267 }
02268 
02269 char **stb_tokens(char *src, char *delimit, int *count)
02270 {
02271    return stb_tokens_raw(src,delimit,count,0,0,0,0);
02272 }
02273 
02274 char **stb_tokens_nested(char *src, char *delimit, int *count, char *nest_in, char *nest_out)
02275 {
02276    return stb_tokens_raw(src,delimit,count,0,0,nest_in,nest_out);
02277 }
02278 
02279 char **stb_tokens_nested_empty(char *src, char *delimit, int *count, char *nest_in, char *nest_out)
02280 {
02281    return stb_tokens_raw(src,delimit,count,0,1,nest_in,nest_out);
02282 }
02283 
02284 char **stb_tokens_allowempty(char *src, char *delimit, int *count)
02285 {
02286    return stb_tokens_raw(src,delimit,count,0,1,0,0);
02287 }
02288 
02289 char **stb_tokens_stripwhite(char *src, char *delimit, int *count)
02290 {
02291    return stb_tokens_raw(src,delimit,count,1,1,0,0);
02292 }
02293 
02294 char **stb_tokens_quoted(char *src, char *delimit, int *count)
02295 {
02296    return stb_tokens_raw(src,delimit,count,2,1,0,0);
02297 }
02298 
02299 char *stb_dupreplace(char *src, char *find, char *replace)
02300 {
02301    size_t len_find = strlen(find);
02302    size_t len_replace = strlen(replace);
02303    int count = 0;
02304 
02305    char *s,*p,*q;
02306 
02307    s = strstr(src, find);
02308    if (s == NULL) return stb_p_strdup(src);
02309    do {
02310       ++count;
02311       s = strstr(s + len_find, find);
02312    } while (s != NULL);
02313 
02314    p = (char *)  malloc(strlen(src) + count * (len_replace - len_find) + 1);
02315    if (p == NULL) return p;
02316    q = p;
02317    s = src;
02318    for (;;) {
02319       char *t = strstr(s, find);
02320       if (t == NULL) {
02321          stb_p_strcpy_s(q,strlen(src)+count*(len_replace-len_find)+1,s);
02322          assert(strlen(p) == strlen(src) + count*(len_replace-len_find));
02323          return p;
02324       }
02325       memcpy(q, s, t-s);
02326       q += t-s;
02327       memcpy(q, replace, len_replace);
02328       q += len_replace;
02329       s = t + len_find;
02330    }
02331 }
02332 
02333 void stb_replaceinplace(char *src, char *find, char *replace)
02334 {
02335    size_t len_find = strlen(find);
02336    size_t len_replace = strlen(replace);
02337    int delta;
02338 
02339    char *s,*p,*q;
02340 
02341    delta = (int) (len_replace - len_find);
02342    assert(delta <= 0);
02343    if (delta > 0) return;
02344 
02345    p = strstr(src, find);
02346    if (p == NULL) return;
02347 
02348    s = q = p;
02349    while (*s) {
02350       memcpy(q, replace, len_replace);
02351       p += len_find;
02352       q += len_replace;
02353       s = strstr(p, find);
02354       if (s == NULL) s = p + strlen(p);
02355       memmove(q, p, s-p);
02356       q += s-p;
02357       p = s;
02358    }
02359    *q = 0;
02360 }
02361 
02362 void stb_fixpath(char *path)
02363 {
02364    for(; *path; ++path)
02365       if (*path == '\\')
02366          *path = '/';
02367 }
02368 
02369 void stb__add_section(char *buffer, char *data, ptrdiff_t curlen, ptrdiff_t newlen)
02370 {
02371    if (newlen < curlen) {
02372       ptrdiff_t z1 = newlen >> 1, z2 = newlen-z1;
02373       memcpy(buffer, data, z1-1);
02374       buffer[z1-1] = '.';
02375       buffer[z1-0] = '.';
02376       memcpy(buffer+z1+1, data+curlen-z2+1, z2-1);
02377    } else
02378       memcpy(buffer, data, curlen);
02379 }
02380 
02381 char * stb_shorten_path_readable(char *path, int len)
02382 {
02383    static char buffer[1024];
02384    ptrdiff_t n = strlen(path),n1,n2,r1,r2;
02385    char *s;
02386    if (n <= len) return path;
02387    if (len > 1024) return path;
02388    s = stb_strrchr2(path, '/', '\\');
02389    if (s) {
02390       n1 = s - path + 1;
02391       n2 = n - n1;
02392       ++s;
02393    } else {
02394       n1 = 0;
02395       n2 = n;
02396       s = path;
02397    }
02398    // now we need to reduce r1 and r2 so that they fit in len
02399    if (n1 < len>>1) {
02400       r1 = n1;
02401       r2 = len - r1;
02402    } else if (n2 < len >> 1) {
02403       r2 = n2;
02404       r1 = len - r2;
02405    } else {
02406       r1 = n1 * len / n;
02407       r2 = n2 * len / n;
02408       if (r1 < len>>2) r1 = len>>2, r2 = len-r1;
02409       if (r2 < len>>2) r2 = len>>2, r1 = len-r2;
02410    }
02411    assert(r1 <= n1 && r2 <= n2);
02412    if (n1)
02413       stb__add_section(buffer, path, n1, r1);
02414    stb__add_section(buffer+r1, s, n2, r2);
02415    buffer[len] = 0;
02416    return buffer;
02417 }
02418 
02419 static char *stb__splitpath_raw(char *buffer, char *path, int flag)
02420 {
02421    ptrdiff_t len=0,x,y, n = (int) strlen(path), f1,f2;
02422    char *s = stb_strrchr2(path, '/', '\\');
02423    char *t = strrchr(path, '.');
02424    if (s && t && t < s) t = NULL;
02425    if (s) ++s;
02426 
02427    if (flag == STB_EXT_NO_PERIOD)
02428       flag |= STB_EXT;
02429 
02430    if (!(flag & (STB_PATH | STB_FILE | STB_EXT))) return NULL;
02431 
02432    f1 = s == NULL ? 0 : s-path; // start of filename
02433    f2 = t == NULL ? n : t-path; // just past end of filename
02434 
02435    if (flag & STB_PATH) {
02436       x = 0; if (f1 == 0 && flag == STB_PATH) len=2;
02437    } else if (flag & STB_FILE) {
02438       x = f1;
02439    } else {
02440       x = f2;
02441       if (flag & STB_EXT_NO_PERIOD)
02442          if (path[x] == '.')
02443             ++x;
02444    }
02445 
02446    if (flag & STB_EXT)
02447       y = n;
02448    else if (flag & STB_FILE)
02449       y = f2;
02450    else
02451       y = f1;
02452 
02453    if (buffer == NULL) {
02454       buffer = (char *) malloc(y-x + len + 1);
02455       if (!buffer) return NULL;
02456    }
02457 
02458    if (len) { stb_p_strcpy_s(buffer, 3, "./"); return buffer; }
02459    stb_strncpy(buffer, path+(int)x, (int)(y-x));
02460    return buffer;
02461 }
02462 
02463 char *stb_splitpath(char *output, char *src, int flag)
02464 {
02465    return stb__splitpath_raw(output, src, flag);
02466 }
02467 
02468 char *stb_splitpathdup(char *src, int flag)
02469 {
02470    return stb__splitpath_raw(NULL, src, flag);
02471 }
02472 
02473 char *stb_replacedir(char *output, char *src, char *dir)
02474 {
02475    char buffer[4096];
02476    stb_splitpath(buffer, src, STB_FILE | STB_EXT);
02477    if (dir)
02478       stb_p_sprintf(output stb_p_size(9999), "%s/%s", dir, buffer);
02479    else
02480       stb_p_strcpy_s(output, sizeof(buffer),  buffer); // @UNSAFE
02481    return output;
02482 }
02483 
02484 char *stb_replaceext(char *output, char *src, char *ext)
02485 {
02486    char buffer[4096];
02487    stb_splitpath(buffer, src, STB_PATH | STB_FILE);
02488    if (ext)
02489       stb_p_sprintf(output stb_p_size(9999), "%s.%s", buffer, ext[0] == '.' ? ext+1 : ext);
02490    else
02491       stb_p_strcpy_s(output, sizeof(buffer), buffer); // @UNSAFE
02492    return output;
02493 }
02494 #endif
02495 
02497 //
02498 //                   stb_alloc - hierarchical allocator
02499 //
02500 //                                     inspired by http://swapped.cc/halloc
02501 //
02502 //
02503 // When you alloc a given block through stb_alloc, you have these choices:
02504 //
02505 //       1. does it have a parent?
02506 //       2. can it have children?
02507 //       3. can it be freed directly?
02508 //       4. is it transferrable?
02509 //       5. what is its alignment?
02510 //
02511 // Here are interesting combinations of those:
02512 //
02513 //                              children   free    transfer     alignment
02514 //  arena                          Y         Y         N           n/a
02515 //  no-overhead, chunked           N         N         N         normal
02516 //  string pool alloc              N         N         N            1
02517 //  parent-ptr, chunked            Y         N         N         normal
02518 //  low-overhead, unchunked        N         Y         Y         normal
02519 //  general purpose alloc          Y         Y         Y         normal
02520 //
02521 // Unchunked allocations will probably return 16-aligned pointers. If
02522 // we 16-align the results, we have room for 4 pointers. For smaller
02523 // allocations that allow finer alignment, we can reduce the pointers.
02524 //
02525 // The strategy is that given a pointer, assuming it has a header (only
02526 // the no-overhead allocations have no header), we can determine the
02527 // type of the header fields, and the number of them, by stepping backwards
02528 // through memory and looking at the tags in the bottom bits.
02529 //
02530 // Implementation strategy:
02531 //     chunked allocations come from the middle of chunks, and can't
02532 //     be freed. thefore they do not need to be on a sibling chain.
02533 //     they may need child pointers if they have children.
02534 //
02535 // chunked, with-children
02536 //     void *parent;
02537 //
02538 // unchunked, no-children -- reduced storage
02539 //     void *next_sibling;
02540 //     void *prev_sibling_nextp;
02541 //
02542 // unchunked, general
02543 //     void *first_child;
02544 //     void *next_sibling;
02545 //     void *prev_sibling_nextp;
02546 //     void *chunks;
02547 //
02548 // so, if we code each of these fields with different bit patterns
02549 // (actually same one for next/prev/child), then we can identify which
02550 // each one is from the last field.
02551 
02552 STB_EXTERN void  stb_free(void *p);
02553 STB_EXTERN void *stb_malloc_global(size_t size);
02554 STB_EXTERN void *stb_malloc(void *context, size_t size);
02555 STB_EXTERN void *stb_malloc_nofree(void *context, size_t size);
02556 STB_EXTERN void *stb_malloc_leaf(void *context, size_t size);
02557 STB_EXTERN void *stb_malloc_raw(void *context, size_t size);
02558 STB_EXTERN void *stb_realloc(void *ptr, size_t newsize);
02559 
02560 STB_EXTERN void stb_reassign(void *new_context, void *ptr);
02561 STB_EXTERN void stb_malloc_validate(void *p, void *parent);
02562 
02563 extern int stb_alloc_chunk_size ;
02564 extern int stb_alloc_count_free ;
02565 extern int stb_alloc_count_alloc;
02566 extern int stb_alloc_alignment  ;
02567 
02568 #ifdef STB_DEFINE
02569 
02570 int stb_alloc_chunk_size  = 65536;
02571 int stb_alloc_count_free  = 0;
02572 int stb_alloc_count_alloc = 0;
02573 int stb_alloc_alignment   = -16;
02574 
02575 typedef struct stb__chunk
02576 {
02577    struct stb__chunk *next;
02578    int                data_left;
02579    int                alloc;
02580 } stb__chunk;
02581 
02582 typedef struct
02583 {
02584    void *  next;
02585    void ** prevn;
02586 } stb__nochildren;
02587 
02588 typedef struct
02589 {
02590    void ** prevn;
02591    void *  child;
02592    void *  next;
02593    stb__chunk *chunks;
02594 } stb__alloc;
02595 
02596 typedef struct
02597 {
02598    stb__alloc *parent;
02599 } stb__chunked;
02600 
02601 #define STB__PARENT          1
02602 #define STB__CHUNKS          2
02603 
02604 typedef enum
02605 {
02606    STB__nochildren = 0,
02607    STB__chunked    = STB__PARENT,
02608    STB__alloc      = STB__CHUNKS,
02609 
02610    STB__chunk_raw  = 4,
02611 } stb__alloc_type;
02612 
02613 // these functions set the bottom bits of a pointer efficiently
02614 #define STB__DECODE(x,v)  ((void *) ((char *) (x) - (v)))
02615 #define STB__ENCODE(x,v)  ((void *) ((char *) (x) + (v)))
02616 
02617 #define stb__parent(z)       (stb__alloc *) STB__DECODE((z)->parent, STB__PARENT)
02618 #define stb__chunks(z)       (stb__chunk *) STB__DECODE((z)->chunks, STB__CHUNKS)
02619 
02620 #define stb__setparent(z,p)  (z)->parent = (stb__alloc *) STB__ENCODE((p), STB__PARENT)
02621 #define stb__setchunks(z,c)  (z)->chunks = (stb__chunk *) STB__ENCODE((c), STB__CHUNKS)
02622 
02623 static stb__alloc stb__alloc_global =
02624 {
02625    NULL,
02626    NULL,
02627    NULL,
02628    (stb__chunk *) STB__ENCODE(NULL, STB__CHUNKS)
02629 };
02630 
02631 static stb__alloc_type stb__identify(void *p)
02632 {
02633    void **q = (void **) p;
02634    return (stb__alloc_type) ((stb_uinta) q[-1] & 3);
02635 }
02636 
02637 static void *** stb__prevn(void *p)
02638 {
02639    if (stb__identify(p) == STB__alloc) {
02640       stb__alloc      *s = (stb__alloc *) p - 1;
02641       return &s->prevn;
02642    } else {
02643       stb__nochildren *s = (stb__nochildren *) p - 1;
02644       return &s->prevn;
02645    }
02646 }
02647 
02648 void stb_free(void *p)
02649 {
02650    if (p == NULL) return;
02651 
02652    // count frees so that unit tests can see what's happening
02653    ++stb_alloc_count_free;
02654 
02655    switch(stb__identify(p)) {
02656       case STB__chunked:
02657          // freeing a chunked-block with children does nothing;
02658          // they only get freed when the parent does
02659          // surely this is wrong, and it should free them immediately?
02660          // otherwise how are they getting put on the right chain?
02661          return;
02662       case STB__nochildren: {
02663          stb__nochildren *s = (stb__nochildren *) p - 1;
02664          // unlink from sibling chain
02665          *(s->prevn) = s->next;
02666          if (s->next)
02667             *stb__prevn(s->next) = s->prevn;
02668          free(s);
02669          return;
02670       }
02671       case STB__alloc: {
02672          stb__alloc *s = (stb__alloc *) p - 1;
02673          stb__chunk *c, *n;
02674          void *q;
02675 
02676          // unlink from sibling chain, if any
02677          *(s->prevn) = s->next;
02678          if (s->next)
02679             *stb__prevn(s->next) = s->prevn;
02680 
02681          // first free chunks
02682          c = (stb__chunk *) stb__chunks(s);
02683          while (c != NULL) {
02684             n = c->next;
02685             stb_alloc_count_free += c->alloc;
02686             free(c);
02687             c = n;
02688          }
02689 
02690          // validating
02691          stb__setchunks(s,NULL);
02692          s->prevn = NULL;
02693          s->next = NULL;
02694 
02695          // now free children
02696          while ((q = s->child) != NULL) {
02697             stb_free(q);
02698          }
02699 
02700          // now free self
02701          free(s);
02702          return;
02703       }
02704       default:
02705          assert(0); /* NOTREACHED */
02706    }
02707 }
02708 
02709 void stb_malloc_validate(void *p, void *parent)
02710 {
02711    if (p == NULL) return;
02712 
02713    switch(stb__identify(p)) {
02714       case STB__chunked:
02715          return;
02716       case STB__nochildren: {
02717          stb__nochildren *n = (stb__nochildren *) p - 1;
02718          if (n->prevn)
02719             assert(*n->prevn == p);
02720          if (n->next) {
02721             assert(*stb__prevn(n->next) == &n->next);
02722             stb_malloc_validate(n, parent);
02723          }
02724          return;
02725       }
02726       case STB__alloc: {
02727          stb__alloc *s = (stb__alloc *) p - 1;
02728 
02729          if (s->prevn)
02730             assert(*s->prevn == p);
02731 
02732          if (s->child) {
02733             assert(*stb__prevn(s->child) == &s->child);
02734             stb_malloc_validate(s->child, p);
02735          }
02736 
02737          if (s->next) {
02738             assert(*stb__prevn(s->next) == &s->next);
02739             stb_malloc_validate(s->next, parent);
02740          }
02741          return;
02742       }
02743       default:
02744          assert(0); /* NOTREACHED */
02745    }
02746 }
02747 
02748 static void * stb__try_chunk(stb__chunk *c, int size, int align, int pre_align)
02749 {
02750    char *memblock = (char *) (c+1), *q;
02751    stb_inta iq;
02752    int start_offset;
02753 
02754    // we going to allocate at the end of the chunk, not the start. confusing,
02755    // but it means we don't need both a 'limit' and a 'cur', just a 'cur'.
02756    // the block ends at: p + c->data_left
02757    //   then we move back by size
02758    start_offset = c->data_left - size;
02759 
02760    // now we need to check the alignment of that
02761    q = memblock + start_offset;
02762    iq = (stb_inta) q;
02763    assert(sizeof(q) == sizeof(iq));
02764 
02765    // suppose align = 2
02766    // then we need to retreat iq far enough that (iq & (2-1)) == 0
02767    // to get (iq & (align-1)) = 0 requires subtracting (iq & (align-1))
02768 
02769    start_offset -= iq & (align-1);
02770    assert(((stb_uinta) (memblock+start_offset) & (align-1)) == 0);
02771 
02772    // now, if that + pre_align works, go for it!
02773    start_offset -= pre_align;
02774 
02775    if (start_offset >= 0) {
02776       c->data_left = start_offset;
02777       return memblock + start_offset;
02778    }
02779 
02780    return NULL;
02781 }
02782 
02783 static void stb__sort_chunks(stb__alloc *src)
02784 {
02785    // of the first two chunks, put the chunk with more data left in it first
02786    stb__chunk *c = stb__chunks(src), *d;
02787    if (c == NULL) return;
02788    d = c->next;
02789    if (d == NULL) return;
02790    if (c->data_left > d->data_left) return;
02791 
02792    c->next = d->next;
02793    d->next = c;
02794    stb__setchunks(src, d);
02795 }
02796 
02797 static void * stb__alloc_chunk(stb__alloc *src, int size, int align, int pre_align)
02798 {
02799    void *p;
02800    stb__chunk *c = stb__chunks(src);
02801 
02802    if (c && size <= stb_alloc_chunk_size) {
02803 
02804       p = stb__try_chunk(c, size, align, pre_align);
02805       if (p) { ++c->alloc; return p; }
02806 
02807       // try a second chunk to reduce wastage
02808       if (c->next) {
02809          p = stb__try_chunk(c->next, size, align, pre_align);
02810          if (p) { ++c->alloc; return p; }
02811 
02812          // put the bigger chunk first, since the second will get buried
02813          // the upshot of this is that, until it gets allocated from, chunk #2
02814          // is always the largest remaining chunk. (could formalize
02815          // this with a heap!)
02816          stb__sort_chunks(src);
02817          c = stb__chunks(src);
02818       }
02819    }
02820 
02821    // allocate a new chunk
02822    {
02823       stb__chunk *n;
02824 
02825       int chunk_size = stb_alloc_chunk_size;
02826       // we're going to allocate a new chunk to put this in
02827       if (size > chunk_size)
02828          chunk_size = size;
02829 
02830       assert(sizeof(*n) + pre_align <= 16);
02831 
02832       // loop trying to allocate a large enough chunk
02833       // the loop is because the alignment may cause problems if it's big...
02834       // and we don't know what our chunk alignment is going to be
02835       while (1) {
02836          n = (stb__chunk *) malloc(16 + chunk_size);
02837          if (n == NULL) return NULL;
02838 
02839          n->data_left = chunk_size - sizeof(*n);
02840 
02841          p = stb__try_chunk(n, size, align, pre_align);
02842          if (p != NULL) {
02843             n->next = c;
02844             stb__setchunks(src, n);
02845 
02846             // if we just used up the whole block immediately,
02847             // move the following chunk up
02848             n->alloc = 1;
02849             if (size == chunk_size)
02850                stb__sort_chunks(src);
02851 
02852             return p;
02853          }
02854 
02855          free(n);
02856          chunk_size += 16+align;
02857       }
02858    }
02859 }
02860 
02861 static stb__alloc * stb__get_context(void *context)
02862 {
02863    if (context == NULL) {
02864       return &stb__alloc_global;
02865    } else {
02866       int u = stb__identify(context);
02867       // if context is chunked, grab parent
02868       if (u == STB__chunked) {
02869          stb__chunked *s = (stb__chunked *) context - 1;
02870          return stb__parent(s);
02871       } else {
02872          return (stb__alloc *) context - 1;
02873       }
02874    }
02875 }
02876 
02877 static void stb__insert_alloc(stb__alloc *src, stb__alloc *s)
02878 {
02879    s->prevn = &src->child;
02880    s->next  = src->child;
02881    src->child = s+1;
02882    if (s->next)
02883       *stb__prevn(s->next) = &s->next;
02884 }
02885 
02886 static void stb__insert_nochild(stb__alloc *src, stb__nochildren *s)
02887 {
02888    s->prevn = &src->child;
02889    s->next  = src->child;
02890    src->child = s+1;
02891    if (s->next)
02892       *stb__prevn(s->next) = &s->next;
02893 }
02894 
02895 static void * malloc_base(void *context, size_t size, stb__alloc_type t, int align)
02896 {
02897    void *p;
02898 
02899    stb__alloc *src = stb__get_context(context);
02900 
02901    if (align <= 0) {
02902       // compute worst-case C packed alignment
02903       // e.g. a 24-byte struct is 8-aligned
02904       int align_proposed = 1 << stb_lowbit8((unsigned int) size);
02905 
02906       if (align_proposed < 0)
02907          align_proposed = 4;
02908 
02909       if (align_proposed == 0) {
02910          if (size == 0)
02911             align_proposed = 1;
02912          else
02913             align_proposed = 256;
02914       }
02915 
02916       // a negative alignment means 'don't align any larger
02917       // than this'; so -16 means we align 1,2,4,8, or 16
02918 
02919       if (align < 0) {
02920          if (align_proposed > -align)
02921             align_proposed = -align;
02922       }
02923 
02924       align = align_proposed;
02925    }
02926 
02927    assert(stb_is_pow2(align));
02928 
02929    // don't cause misalignment when allocating nochildren
02930    if (t == STB__nochildren && align > 8)
02931       t = STB__alloc;
02932 
02933    switch (t) {
02934       case STB__alloc: {
02935          stb__alloc *s = (stb__alloc *) malloc(size + sizeof(*s));
02936          if (s == NULL) return NULL;
02937          p = s+1;
02938          s->child = NULL;
02939          stb__insert_alloc(src, s);
02940 
02941          stb__setchunks(s,NULL);
02942          break;
02943       }
02944 
02945       case STB__nochildren: {
02946          stb__nochildren *s = (stb__nochildren *) malloc(size + sizeof(*s));
02947          if (s == NULL) return NULL;
02948          p = s+1;
02949          stb__insert_nochild(src, s);
02950          break;
02951       }
02952 
02953       case STB__chunk_raw: {
02954          p = stb__alloc_chunk(src, (int) size, align, 0);
02955          if (p == NULL) return NULL;
02956          break;
02957       }
02958 
02959       case STB__chunked: {
02960          stb__chunked *s;
02961          if (align < sizeof(stb_uintptr)) align = sizeof(stb_uintptr);
02962          s = (stb__chunked *) stb__alloc_chunk(src, (int) size, align, sizeof(*s));
02963          if (s == NULL) return NULL;
02964          stb__setparent(s, src);
02965          p = s+1;
02966          break;
02967       }
02968 
02969       default: p = NULL; assert(0); /* NOTREACHED */
02970    }
02971 
02972    ++stb_alloc_count_alloc;
02973    return p;
02974 }
02975 
02976 void *stb_malloc_global(size_t size)
02977 {
02978    return malloc_base(NULL, size, STB__alloc, stb_alloc_alignment);
02979 }
02980 
02981 void *stb_malloc(void *context, size_t size)
02982 {
02983    return malloc_base(context, size, STB__alloc, stb_alloc_alignment);
02984 }
02985 
02986 void *stb_malloc_nofree(void *context, size_t size)
02987 {
02988    return malloc_base(context, size, STB__chunked, stb_alloc_alignment);
02989 }
02990 
02991 void *stb_malloc_leaf(void *context, size_t size)
02992 {
02993    return malloc_base(context, size, STB__nochildren, stb_alloc_alignment);
02994 }
02995 
02996 void *stb_malloc_raw(void *context, size_t size)
02997 {
02998    return malloc_base(context, size, STB__chunk_raw, stb_alloc_alignment);
02999 }
03000 
03001 char *stb_malloc_string(void *context, size_t size)
03002 {
03003    return (char *) malloc_base(context, size, STB__chunk_raw, 1);
03004 }
03005 
03006 void *stb_realloc(void *ptr, size_t newsize)
03007 {
03008    stb__alloc_type t;
03009 
03010    if (ptr == NULL) return stb_malloc(NULL, newsize);
03011    if (newsize == 0) { stb_free(ptr); return NULL; }
03012 
03013    t = stb__identify(ptr);
03014    assert(t == STB__alloc || t == STB__nochildren);
03015 
03016    if (t == STB__alloc) {
03017       stb__alloc *s = (stb__alloc *) ptr - 1;
03018 
03019       s = (stb__alloc *) realloc(s, newsize + sizeof(*s));
03020       if (s == NULL) return NULL;
03021 
03022       ptr = s+1;
03023 
03024       // update pointers
03025       (*s->prevn) = ptr;
03026       if (s->next)
03027          *stb__prevn(s->next) = &s->next;
03028 
03029       if (s->child)
03030          *stb__prevn(s->child) = &s->child;
03031 
03032       return ptr;
03033    } else {
03034       stb__nochildren *s = (stb__nochildren *) ptr - 1;
03035 
03036       s = (stb__nochildren *) realloc(ptr, newsize + sizeof(s));
03037       if (s == NULL) return NULL;
03038 
03039       // update pointers
03040       (*s->prevn) = s+1;
03041       if (s->next)
03042          *stb__prevn(s->next) = &s->next;
03043 
03044       return s+1;
03045    }
03046 }
03047 
03048 void *stb_realloc_c(void *context, void *ptr, size_t newsize)
03049 {
03050    if (ptr == NULL) return stb_malloc(context, newsize);
03051    if (newsize == 0) { stb_free(ptr); return NULL; }
03052    // @TODO: verify you haven't changed contexts
03053    return stb_realloc(ptr, newsize);
03054 }
03055 
03056 void stb_reassign(void *new_context, void *ptr)
03057 {
03058    stb__alloc *src = stb__get_context(new_context);
03059 
03060    stb__alloc_type t = stb__identify(ptr);
03061    assert(t == STB__alloc || t == STB__nochildren);
03062 
03063    if (t == STB__alloc) {
03064       stb__alloc *s = (stb__alloc *) ptr - 1;
03065 
03066       // unlink from old
03067       *(s->prevn) = s->next;
03068       if (s->next)
03069          *stb__prevn(s->next) = s->prevn;
03070 
03071       stb__insert_alloc(src, s);
03072    } else {
03073       stb__nochildren *s = (stb__nochildren *) ptr - 1;
03074 
03075       // unlink from old
03076       *(s->prevn) = s->next;
03077       if (s->next)
03078          *stb__prevn(s->next) = s->prevn;
03079 
03080       stb__insert_nochild(src, s);
03081    }
03082 }
03083 
03084 #endif
03085 
03086 
03088 //
03089 //                                stb_arr
03090 //
03091 //  An stb_arr is directly useable as a pointer (use the actual type in your
03092 //  definition), but when it resizes, it returns a new pointer and you can't
03093 //  use the old one, so you have to be careful to copy-in-out as necessary.
03094 //
03095 //  Use a NULL pointer as a 0-length array.
03096 //
03097 //     float *my_array = NULL, *temp;
03098 //
03099 //     // add elements on the end one at a time
03100 //     stb_arr_push(my_array, 0.0f);
03101 //     stb_arr_push(my_array, 1.0f);
03102 //     stb_arr_push(my_array, 2.0f);
03103 //
03104 //     assert(my_array[1] == 2.0f);
03105 //
03106 //     // add an uninitialized element at the end, then assign it
03107 //     *stb_arr_add(my_array) = 3.0f;
03108 //
03109 //     // add three uninitialized elements at the end
03110 //     temp = stb_arr_addn(my_array,3);
03111 //     temp[0] = 4.0f;
03112 //     temp[1] = 5.0f;
03113 //     temp[2] = 6.0f;
03114 //
03115 //     assert(my_array[5] == 5.0f);
03116 //
03117 //     // remove the last one
03118 //     stb_arr_pop(my_array);
03119 //
03120 //     assert(stb_arr_len(my_array) == 6);
03121 
03122 
03123 #ifdef STB_MALLOC_WRAPPER
03124   #define STB__PARAMS    , char *file, int line
03125   #define STB__ARGS      ,       file,     line
03126 #else
03127   #define STB__PARAMS
03128   #define STB__ARGS
03129 #endif
03130 
03131 // calling this function allocates an empty stb_arr attached to p
03132 // (whereas NULL isn't attached to anything)
03133 STB_EXTERN void stb_arr_malloc(void **target, void *context);
03134 
03135 // call this function with a non-NULL value to have all successive
03136 // stbs that are created be attached to the associated parent. Note
03137 // that once a given stb_arr is non-empty, it stays attached to its
03138 // current parent, even if you call this function again.
03139 // it turns the previous value, so you can restore it
03140 STB_EXTERN void* stb_arr_malloc_parent(void *p);
03141 
03142 // simple functions written on top of other functions
03143 #define stb_arr_empty(a)       (  stb_arr_len(a) == 0 )
03144 #define stb_arr_add(a)         (  stb_arr_addn((a),1) )
03145 #define stb_arr_push(a,v)      ( *stb_arr_add(a)=(v)  )
03146 
03147 typedef struct
03148 {
03149    int len, limit;
03150    int stb_malloc;
03151    unsigned int signature;
03152 } stb__arr;
03153 
03154 #define stb_arr_signature      0x51bada7b  // ends with 0123 in decimal
03155 
03156 // access the header block stored before the data
03157 #define stb_arrhead(a)         /*lint --e(826)*/ (((stb__arr *) (a)) - 1)
03158 #define stb_arrhead2(a)        /*lint --e(826)*/ (((stb__arr *) (a)) - 1)
03159 
03160 #ifdef STB_DEBUG
03161 #define stb_arr_check(a)       assert(!a || stb_arrhead(a)->signature == stb_arr_signature)
03162 #define stb_arr_check2(a)      assert(!a || stb_arrhead2(a)->signature == stb_arr_signature)
03163 #else
03164 #define stb_arr_check(a)       ((void) 0)
03165 #define stb_arr_check2(a)      ((void) 0)
03166 #endif
03167 
03168 // ARRAY LENGTH
03169 
03170 // get the array length; special case if pointer is NULL
03171 #define stb_arr_len(a)         (a ? stb_arrhead(a)->len : 0)
03172 #define stb_arr_len2(a)        ((stb__arr *) (a) ? stb_arrhead2(a)->len : 0)
03173 #define stb_arr_lastn(a)       (stb_arr_len(a)-1)
03174 
03175 // check whether a given index is valid -- tests 0 <= i < stb_arr_len(a)
03176 #define stb_arr_valid(a,i)     (a ? (int) (i) < stb_arrhead(a)->len : 0)
03177 
03178 // change the array length so is is exactly N entries long, creating
03179 // uninitialized entries as needed
03180 #define stb_arr_setlen(a,n)  \
03181             (stb__arr_setlen((void **) &(a), sizeof(a[0]), (n)))
03182 
03183 // change the array length so that N is a valid index (that is, so
03184 // it is at least N entries long), creating uninitialized entries as needed
03185 #define stb_arr_makevalid(a,n)  \
03186             (stb_arr_len(a) < (n)+1 ? stb_arr_setlen(a,(n)+1),(a) : (a))
03187 
03188 // remove the last element of the array, returning it
03189 #define stb_arr_pop(a)         ((stb_arr_check(a), (a))[--stb_arrhead(a)->len])
03190 
03191 // access the last element in the array
03192 #define stb_arr_last(a)        ((stb_arr_check(a), (a))[stb_arr_len(a)-1])
03193 
03194 // is iterator at end of list?
03195 #define stb_arr_end(a,i)       ((i) >= &(a)[stb_arr_len(a)])
03196 
03197 // (internal) change the allocated length of the array
03198 #define stb_arr__grow(a,n)     (stb_arr_check(a), stb_arrhead(a)->len += (n))
03199 
03200 // add N new uninitialized elements to the end of the array
03201 #define stb_arr__addn(a,n)     /*lint --e(826)*/ \
03202                                ((stb_arr_len(a)+(n) > stb_arrcurmax(a))      \
03203                                  ? (stb__arr_addlen((void **) &(a),sizeof(*a),(n)),0) \
03204                                  : ((stb_arr__grow(a,n), 0)))
03205 
03206 // add N new uninitialized elements to the end of the array, and return
03207 // a pointer to the first new one
03208 #define stb_arr_addn(a,n)      (stb_arr__addn((a),n),(a)+stb_arr_len(a)-(n))
03209 
03210 // add N new uninitialized elements starting at index 'i'
03211 #define stb_arr_insertn(a,i,n) (stb__arr_insertn((void **) &(a), sizeof(*a), (i), (n)))
03212 
03213 // insert an element at i
03214 #define stb_arr_insert(a,i,v)  (stb__arr_insertn((void **) &(a), sizeof(*a), (i), (1)), ((a)[i] = v))
03215 
03216 // delete N elements from the middle starting at index 'i'
03217 #define stb_arr_deleten(a,i,n) (stb__arr_deleten((void **) &(a), sizeof(*a), (i), (n)))
03218 
03219 // delete the i'th element
03220 #define stb_arr_delete(a,i)   stb_arr_deleten(a,i,1)
03221 
03222 // delete the i'th element, swapping down from the end
03223 #define stb_arr_fastdelete(a,i)  \
03224    (stb_swap(&a[i], &a[stb_arrhead(a)->len-1], sizeof(*a)), stb_arr_pop(a))
03225 
03226 
03227 // ARRAY STORAGE
03228 
03229 // get the array maximum storage; special case if NULL
03230 #define stb_arrcurmax(a)       (a ? stb_arrhead(a)->limit : 0)
03231 #define stb_arrcurmax2(a)      (a ? stb_arrhead2(a)->limit : 0)
03232 
03233 // set the maxlength of the array to n in anticipation of further growth
03234 #define stb_arr_setsize(a,n)   (stb_arr_check(a), stb__arr_setsize((void **) &(a),sizeof((a)[0]),n))
03235 
03236 // make sure maxlength is large enough for at least N new allocations
03237 #define stb_arr_atleast(a,n)   (stb_arr_len(a)+(n) > stb_arrcurmax(a)      \
03238                                  ? stb_arr_setsize((a), (n)) : 0)
03239 
03240 // make a copy of a given array (copies contents via 'memcpy'!)
03241 #define stb_arr_copy(a)        stb__arr_copy(a, sizeof((a)[0]))
03242 
03243 // compute the storage needed to store all the elements of the array
03244 #define stb_arr_storage(a)     (stb_arr_len(a) * sizeof((a)[0]))
03245 
03246 #define stb_arr_for(v,arr)     for((v)=(arr); (v) < (arr)+stb_arr_len(arr); ++(v))
03247 
03248 // IMPLEMENTATION
03249 
03250 STB_EXTERN void stb_arr_free_(void **p);
03251 STB_EXTERN void *stb__arr_copy_(void *p, int elem_size);
03252 STB_EXTERN void stb__arr_setsize_(void **p, int size, int limit  STB__PARAMS);
03253 STB_EXTERN void stb__arr_setlen_(void **p, int size, int newlen  STB__PARAMS);
03254 STB_EXTERN void stb__arr_addlen_(void **p, int size, int addlen  STB__PARAMS);
03255 STB_EXTERN void stb__arr_deleten_(void **p, int size, int loc, int n  STB__PARAMS);
03256 STB_EXTERN void stb__arr_insertn_(void **p, int size, int loc, int n  STB__PARAMS);
03257 
03258 #define stb_arr_free(p)            stb_arr_free_((void **) &(p))
03259 #define stb__arr_copy              stb__arr_copy_
03260 
03261 #ifndef STB_MALLOC_WRAPPER
03262   #define stb__arr_setsize         stb__arr_setsize_
03263   #define stb__arr_setlen          stb__arr_setlen_
03264   #define stb__arr_addlen          stb__arr_addlen_
03265   #define stb__arr_deleten         stb__arr_deleten_
03266   #define stb__arr_insertn         stb__arr_insertn_
03267 #else
03268   #define stb__arr_addlen(p,s,n)    stb__arr_addlen_(p,s,n,__FILE__,__LINE__)
03269   #define stb__arr_setlen(p,s,n)    stb__arr_setlen_(p,s,n,__FILE__,__LINE__)
03270   #define stb__arr_setsize(p,s,n)   stb__arr_setsize_(p,s,n,__FILE__,__LINE__)
03271   #define stb__arr_deleten(p,s,i,n) stb__arr_deleten_(p,s,i,n,__FILE__,__LINE__)
03272   #define stb__arr_insertn(p,s,i,n) stb__arr_insertn_(p,s,i,n,__FILE__,__LINE__)
03273 #endif
03274 
03275 #ifdef STB_DEFINE
03276 static void *stb__arr_context;
03277 
03278 void *stb_arr_malloc_parent(void *p)
03279 {
03280    void *q = stb__arr_context;
03281    stb__arr_context = p;
03282    return q;
03283 }
03284 
03285 void stb_arr_malloc(void **target, void *context)
03286 {
03287    stb__arr *q = (stb__arr *) stb_malloc(context, sizeof(*q));
03288    q->len = q->limit = 0;
03289    q->stb_malloc = 1;
03290    q->signature = stb_arr_signature;
03291    *target = (void *) (q+1);
03292 }
03293 
03294 static void * stb__arr_malloc(int size)
03295 {
03296    if (stb__arr_context)
03297       return stb_malloc(stb__arr_context, size);
03298    return malloc(size);
03299 }
03300 
03301 void * stb__arr_copy_(void *p, int elem_size)
03302 {
03303    stb__arr *q;
03304    if (p == NULL) return p;
03305    q = (stb__arr *) stb__arr_malloc(sizeof(*q) + elem_size * stb_arrhead2(p)->limit);
03306    stb_arr_check2(p);
03307    memcpy(q, stb_arrhead2(p), sizeof(*q) + elem_size * stb_arrhead2(p)->len);
03308    q->stb_malloc = !!stb__arr_context;
03309    return q+1;
03310 }
03311 
03312 void stb_arr_free_(void **pp)
03313 {
03314    void *p = *pp;
03315    stb_arr_check2(p);
03316    if (p) {
03317       stb__arr *q = stb_arrhead2(p);
03318       if (q->stb_malloc)
03319          stb_free(q);
03320       else
03321          free(q);
03322    }
03323    *pp = NULL;
03324 }
03325 
03326 static void stb__arrsize_(void **pp, int size, int limit, int len  STB__PARAMS)
03327 {
03328    void *p = *pp;
03329    stb__arr *a;
03330    stb_arr_check2(p);
03331    if (p == NULL) {
03332       if (len == 0 && size == 0) return;
03333       a = (stb__arr *) stb__arr_malloc(sizeof(*a) + size*limit);
03334       a->limit = limit;
03335       a->len   = len;
03336       a->stb_malloc = !!stb__arr_context;
03337       a->signature = stb_arr_signature;
03338    } else {
03339       a = stb_arrhead2(p);
03340       a->len = len;
03341       if (a->limit < limit) {
03342          void *p;
03343          if (a->limit >= 4 && limit < a->limit * 2)
03344             limit = a->limit * 2;
03345          if (a->stb_malloc)
03346             p = stb_realloc(a, sizeof(*a) + limit*size);
03347          else
03348             #ifdef STB_MALLOC_WRAPPER
03349             p = stb__realloc(a, sizeof(*a) + limit*size, file, line);
03350             #else
03351             p = realloc(a, sizeof(*a) + limit*size);
03352             #endif
03353          if (p) {
03354             a = (stb__arr *) p;
03355             a->limit = limit;
03356          } else {
03357             // throw an error!
03358          }
03359       }
03360    }
03361    a->len   = stb_min(a->len, a->limit);
03362    *pp = a+1;
03363 }
03364 
03365 void stb__arr_setsize_(void **pp, int size, int limit  STB__PARAMS)
03366 {
03367    void *p = *pp;
03368    stb_arr_check2(p);
03369    stb__arrsize_(pp, size, limit, stb_arr_len2(p)  STB__ARGS);
03370 }
03371 
03372 void stb__arr_setlen_(void **pp, int size, int newlen  STB__PARAMS)
03373 {
03374    void *p = *pp;
03375    stb_arr_check2(p);
03376    if (stb_arrcurmax2(p) < newlen || p == NULL) {
03377       stb__arrsize_(pp, size, newlen, newlen  STB__ARGS);
03378    } else {
03379       stb_arrhead2(p)->len = newlen;
03380    }
03381 }
03382 
03383 void stb__arr_addlen_(void **p, int size, int addlen  STB__PARAMS)
03384 {
03385    stb__arr_setlen_(p, size, stb_arr_len2(*p) + addlen  STB__ARGS);
03386 }
03387 
03388 void stb__arr_insertn_(void **pp, int size, int i, int n  STB__PARAMS)
03389 {
03390    void *p = *pp;
03391    if (n) {
03392       int z;
03393 
03394       if (p == NULL) {
03395          stb__arr_addlen_(pp, size, n  STB__ARGS);
03396          return;
03397       }
03398 
03399       z = stb_arr_len2(p);
03400       stb__arr_addlen_(&p, size, n  STB__ARGS);
03401       memmove((char *) p + (i+n)*size, (char *) p + i*size, size * (z-i));
03402    }
03403    *pp = p;
03404 }
03405 
03406 void stb__arr_deleten_(void **pp, int size, int i, int n  STB__PARAMS)
03407 {
03408    void *p = *pp;
03409    if (n) {
03410       memmove((char *) p + i*size, (char *) p + (i+n)*size, size * (stb_arr_len2(p)-(i+n)));
03411       stb_arrhead2(p)->len -= n;
03412    }
03413    *pp = p;
03414 }
03415 
03416 #endif
03417 
03419 //
03420 //                               Hashing
03421 //
03422 //      typical use for this is to make a power-of-two hash table.
03423 //
03424 //      let N = size of table (2^n)
03425 //      let H = stb_hash(str)
03426 //      let S = stb_rehash(H) | 1
03427 //
03428 //      then hash probe sequence P(i) for i=0..N-1
03429 //         P(i) = (H + S*i) & (N-1)
03430 //
03431 //      the idea is that H has 32 bits of hash information, but the
03432 //      table has only, say, 2^20 entries so only uses 20 of the bits.
03433 //      then by rehashing the original H we get 2^12 different probe
03434 //      sequences for a given initial probe location. (So it's optimal
03435 //      for 64K tables and its optimality decreases past that.)
03436 //
03437 //      ok, so I've added something that generates _two separate_
03438 //      32-bit hashes simultaneously which should scale better to
03439 //      very large tables.
03440 
03441 
03442 STB_EXTERN unsigned int stb_hash(char *str);
03443 STB_EXTERN unsigned int stb_hashptr(void *p);
03444 STB_EXTERN unsigned int stb_hashlen(char *str, int len);
03445 STB_EXTERN unsigned int stb_rehash_improved(unsigned int v);
03446 STB_EXTERN unsigned int stb_hash_fast(void *p, int len);
03447 STB_EXTERN unsigned int stb_hash2(char *str, unsigned int *hash2_ptr);
03448 STB_EXTERN unsigned int stb_hash_number(unsigned int hash);
03449 
03450 #define stb_rehash(x)  ((x) + ((x) >> 6) + ((x) >> 19))
03451 
03452 #ifdef STB_DEFINE
03453 unsigned int stb_hash(char *str)
03454 {
03455    unsigned int hash = 0;
03456    while (*str)
03457       hash = (hash << 7) + (hash >> 25) + *str++;
03458    return hash + (hash >> 16);
03459 }
03460 
03461 unsigned int stb_hashlen(char *str, int len)
03462 {
03463    unsigned int hash = 0;
03464    while (len-- > 0 && *str)
03465       hash = (hash << 7) + (hash >> 25) + *str++;
03466    return hash + (hash >> 16);
03467 }
03468 
03469 unsigned int stb_hashptr(void *p)
03470 {
03471     unsigned int x = (unsigned int)(size_t) p;
03472 
03473    // typically lacking in low bits and high bits
03474    x = stb_rehash(x);
03475    x += x << 16;
03476 
03477    // pearson's shuffle
03478    x ^= x << 3;
03479    x += x >> 5;
03480    x ^= x << 2;
03481    x += x >> 15;
03482    x ^= x << 10;
03483    return stb_rehash(x);
03484 }
03485 
03486 unsigned int stb_rehash_improved(unsigned int v)
03487 {
03488    return stb_hashptr((void *)(size_t) v);
03489 }
03490 
03491 unsigned int stb_hash2(char *str, unsigned int *hash2_ptr)
03492 {
03493    unsigned int hash1 = 0x3141592c;
03494    unsigned int hash2 = 0x77f044ed;
03495    while (*str) {
03496       hash1 = (hash1 << 7) + (hash1 >> 25) + *str;
03497       hash2 = (hash2 << 11) + (hash2 >> 21) + *str;
03498       ++str;
03499    }
03500    *hash2_ptr = hash2 + (hash1 >> 16);
03501    return       hash1 + (hash2 >> 16);
03502 }
03503 
03504 // Paul Hsieh hash
03505 #define stb__get16(p) ((p)[0] | ((p)[1] << 8))
03506 
03507 unsigned int stb_hash_fast(void *p, int len)
03508 {
03509    unsigned char *q = (unsigned char *) p;
03510    unsigned int hash = len;
03511 
03512    if (len <= 0 || q == NULL) return 0;
03513 
03514    /* Main loop */
03515    for (;len > 3; len -= 4) {
03516       unsigned int val;
03517       hash +=  stb__get16(q);
03518       val   = (stb__get16(q+2) << 11);
03519       hash  = (hash << 16) ^ hash ^ val;
03520       q    += 4;
03521       hash += hash >> 11;
03522    }
03523 
03524    /* Handle end cases */
03525    switch (len) {
03526       case 3: hash += stb__get16(q);
03527               hash ^= hash << 16;
03528               hash ^= q[2] << 18;
03529               hash += hash >> 11;
03530               break;
03531       case 2: hash += stb__get16(q);
03532               hash ^= hash << 11;
03533               hash += hash >> 17;
03534               break;
03535       case 1: hash += q[0];
03536               hash ^= hash << 10;
03537               hash += hash >> 1;
03538               break;
03539       case 0: break;
03540    }
03541 
03542    /* Force "avalanching" of final 127 bits */
03543    hash ^= hash << 3;
03544    hash += hash >> 5;
03545    hash ^= hash << 4;
03546    hash += hash >> 17;
03547    hash ^= hash << 25;
03548    hash += hash >> 6;
03549 
03550    return hash;
03551 }
03552 
03553 unsigned int stb_hash_number(unsigned int hash)
03554 {
03555    hash ^= hash << 3;
03556    hash += hash >> 5;
03557    hash ^= hash << 4;
03558    hash += hash >> 17;
03559    hash ^= hash << 25;
03560    hash += hash >> 6;
03561    return hash;
03562 }
03563 
03564 #endif
03565 
03566 #ifdef STB_PERFECT_HASH
03567 
03568 //
03569 //                     Perfect hashing for ints/pointers
03570 //
03571 //   This is mainly useful for making faster pointer-indexed tables
03572 //   that don't change frequently. E.g. for stb_ischar().
03573 //
03574 
03575 typedef struct
03576 {
03577    stb_uint32  addend;
03578    stb_uint    multiplicand;
03579    stb_uint    b_mask;
03580    stb_uint8   small_bmap[16];
03581    stb_uint16  *large_bmap;
03582 
03583    stb_uint table_mask;
03584    stb_uint32 *table;
03585 } stb_perfect;
03586 
03587 STB_EXTERN int stb_perfect_create(stb_perfect *,unsigned int*,int n);
03588 STB_EXTERN void stb_perfect_destroy(stb_perfect *);
03589 STB_EXTERN int stb_perfect_hash(stb_perfect *, unsigned int x);
03590 extern int stb_perfect_hash_max_failures;
03591 
03592 #ifdef STB_DEFINE
03593 
03594 int stb_perfect_hash_max_failures;
03595 
03596 int stb_perfect_hash(stb_perfect *p, unsigned int x)
03597 {
03598    stb_uint m = x * p->multiplicand;
03599    stb_uint y = x >> 16;
03600    stb_uint bv = (m >> 24) + y;
03601    stb_uint av = (m + y) >> 12;
03602    if (p->table == NULL) return -1;  // uninitialized table fails
03603    bv &= p->b_mask;
03604    av &= p->table_mask;
03605    if (p->large_bmap)
03606       av ^= p->large_bmap[bv];
03607    else
03608       av ^= p->small_bmap[bv];
03609    return p->table[av] == x ? av : -1;
03610 }
03611 
03612 static void stb__perfect_prehash(stb_perfect *p, stb_uint x, stb_uint16 *a, stb_uint16 *b)
03613 {
03614    stb_uint m = x * p->multiplicand;
03615    stb_uint y = x >> 16;
03616    stb_uint bv = (m >> 24) + y;
03617    stb_uint av = (m + y) >> 12;
03618    bv &= p->b_mask;
03619    av &= p->table_mask;
03620    *b = bv;
03621    *a = av;
03622 }
03623 
03624 static unsigned long stb__perfect_rand(void)
03625 {
03626    static unsigned long stb__rand;
03627    stb__rand = stb__rand * 2147001325 + 715136305;
03628    return 0x31415926 ^ ((stb__rand >> 16) + (stb__rand << 16));
03629 }
03630 
03631 typedef struct {
03632    unsigned short count;
03633    unsigned short b;
03634    unsigned short map;
03635    unsigned short *entries;
03636 } stb__slot;
03637 
03638 static int stb__slot_compare(const void *p, const void *q)
03639 {
03640    stb__slot *a = (stb__slot *) p;
03641    stb__slot *b = (stb__slot *) q;
03642    return a->count > b->count ? -1 : a->count < b->count;  // sort large to small
03643 }
03644 
03645 int stb_perfect_create(stb_perfect *p, unsigned int *v, int n)
03646 {
03647    unsigned int buffer1[64], buffer2[64], buffer3[64], buffer4[64], buffer5[32];
03648    unsigned short *as = (unsigned short *) stb_temp(buffer1, sizeof(*v)*n);
03649    unsigned short *bs = (unsigned short *) stb_temp(buffer2, sizeof(*v)*n);
03650    unsigned short *entries = (unsigned short *) stb_temp(buffer4, sizeof(*entries) * n);
03651    int size = 1 << stb_log2_ceil(n), bsize=8;
03652    int failure = 0,i,j,k;
03653 
03654    assert(n <= 32768);
03655    p->large_bmap = NULL;
03656 
03657    for(;;) {
03658       stb__slot *bcount = (stb__slot *) stb_temp(buffer3, sizeof(*bcount) * bsize);
03659       unsigned short *bloc = (unsigned short *) stb_temp(buffer5, sizeof(*bloc) * bsize);
03660       unsigned short *e;
03661       int bad=0;
03662 
03663       p->addend = stb__perfect_rand();
03664       p->multiplicand = stb__perfect_rand() | 1;
03665       p->table_mask = size-1;
03666       p->b_mask = bsize-1;
03667       p->table = (stb_uint32 *) malloc(size * sizeof(*p->table));
03668 
03669       for (i=0; i < bsize; ++i) {
03670          bcount[i].b     = i;
03671          bcount[i].count = 0;
03672          bcount[i].map   = 0;
03673       }
03674       for (i=0; i < n; ++i) {
03675          stb__perfect_prehash(p, v[i], as+i, bs+i);
03676          ++bcount[bs[i]].count;
03677       }
03678       qsort(bcount, bsize, sizeof(*bcount), stb__slot_compare);
03679       e = entries; // now setup up their entries index
03680       for (i=0; i < bsize; ++i) {
03681          bcount[i].entries = e;
03682          e += bcount[i].count;
03683          bcount[i].count = 0;
03684          bloc[bcount[i].b] = i;
03685       }
03686       // now fill them out
03687       for (i=0; i < n; ++i) {
03688          int b = bs[i];
03689          int w = bloc[b];
03690          bcount[w].entries[bcount[w].count++] = i;
03691       }
03692       stb_tempfree(buffer5,bloc);
03693       // verify
03694       for (i=0; i < bsize; ++i)
03695          for (j=0; j < bcount[i].count; ++j)
03696             assert(bs[bcount[i].entries[j]] == bcount[i].b);
03697       memset(p->table, 0, size*sizeof(*p->table));
03698 
03699       // check if any b has duplicate a
03700       for (i=0; i < bsize; ++i) {
03701          if (bcount[i].count > 1) {
03702             for (j=0; j < bcount[i].count; ++j) {
03703                if (p->table[as[bcount[i].entries[j]]])
03704                   bad = 1;
03705                p->table[as[bcount[i].entries[j]]] = 1;
03706             }
03707             for (j=0; j < bcount[i].count; ++j) {
03708                p->table[as[bcount[i].entries[j]]] = 0;
03709             }
03710             if (bad) break;
03711          }
03712       }
03713 
03714       if (!bad) {
03715          // go through the bs and populate the table, first fit
03716          for (i=0; i < bsize; ++i) {
03717             if (bcount[i].count) {
03718                // go through the candidate table[b] values
03719                for (j=0; j < size; ++j) {
03720                   // go through the a values and see if they fit
03721                   for (k=0; k < bcount[i].count; ++k) {
03722                      int a = as[bcount[i].entries[k]];
03723                      if (p->table[(a^j)&p->table_mask]) {
03724                         break; // fails
03725                      }
03726                   }
03727                   // if succeeded, accept
03728                   if (k == bcount[i].count) {
03729                      bcount[i].map = j;
03730                      for (k=0; k < bcount[i].count; ++k) {
03731                         int a = as[bcount[i].entries[k]];
03732                         p->table[(a^j)&p->table_mask] = 1;
03733                      }
03734                      break;
03735                   }
03736                }
03737                if (j == size)
03738                   break; // no match for i'th entry, so break out in failure
03739             }
03740          }
03741          if (i == bsize) {
03742             // success... fill out map
03743             if (bsize <= 16 && size <= 256) {
03744                p->large_bmap = NULL;
03745                for (i=0; i < bsize; ++i)
03746                   p->small_bmap[bcount[i].b] = (stb_uint8) bcount[i].map;
03747             } else {
03748                p->large_bmap = (unsigned short *) malloc(sizeof(*p->large_bmap) * bsize);
03749                for (i=0; i < bsize; ++i)
03750                   p->large_bmap[bcount[i].b] = bcount[i].map;
03751             }
03752 
03753             // initialize table to v[0], so empty slots will fail
03754             for (i=0; i < size; ++i)
03755                p->table[i] = v[0];
03756 
03757             for (i=0; i < n; ++i)
03758                if (p->large_bmap)
03759                   p->table[as[i] ^ p->large_bmap[bs[i]]] = v[i];
03760                else
03761                   p->table[as[i] ^ p->small_bmap[bs[i]]] = v[i];
03762 
03763             // and now validate that none of them collided
03764             for (i=0; i < n; ++i)
03765                assert(stb_perfect_hash(p, v[i]) >= 0);
03766 
03767             stb_tempfree(buffer3, bcount);
03768             break;
03769          }
03770       }
03771       free(p->table);
03772       p->table = NULL;
03773       stb_tempfree(buffer3, bcount);
03774 
03775       ++failure;
03776       if (failure >= 4 && bsize < size) bsize *= 2;
03777       if (failure >= 8 && (failure & 3) == 0 && size < 4*n) {
03778          size *= 2;
03779          bsize *= 2;
03780       }
03781       if (failure == 6) {
03782          // make sure the input data is unique, so we don't infinite loop
03783          unsigned int *data = (unsigned int *) stb_temp(buffer3, n * sizeof(*data));
03784          memcpy(data, v, sizeof(*data) * n);
03785          qsort(data, n, sizeof(*data), stb_intcmp(0));
03786          for (i=1; i < n; ++i) {
03787             if (data[i] == data[i-1])
03788                size = 0; // size is return value, so 0 it
03789          }
03790          stb_tempfree(buffer3, data);
03791          if (!size) break;
03792       }
03793    }
03794 
03795    if (failure > stb_perfect_hash_max_failures)
03796       stb_perfect_hash_max_failures = failure;
03797 
03798    stb_tempfree(buffer1, as);
03799    stb_tempfree(buffer2, bs);
03800    stb_tempfree(buffer4, entries);
03801 
03802    return size;
03803 }
03804 
03805 void stb_perfect_destroy(stb_perfect *p)
03806 {
03807    if (p->large_bmap) free(p->large_bmap);
03808    if (p->table     ) free(p->table);
03809    p->large_bmap = NULL;
03810    p->table      = NULL;
03811    p->b_mask     = 0;
03812    p->table_mask = 0;
03813 }
03814 #endif
03815 
03817 //
03818 //                     Perfect hash clients
03819 
03820 STB_EXTERN int    stb_ischar(char s, char *set);
03821 
03822 #ifdef STB_DEFINE
03823 
03824 int stb_ischar(char c, char *set)
03825 {
03826    static unsigned char bit[8] = { 1,2,4,8,16,32,64,128 };
03827    static stb_perfect p;
03828    static unsigned char (*tables)[256];
03829    static char ** sets = NULL;
03830 
03831    int z = stb_perfect_hash(&p, (int)(size_t) set);
03832    if (z < 0) {
03833       int i,k,n,j,f;
03834       // special code that means free all existing data
03835       if (set == NULL) {
03836          stb_arr_free(sets);
03837          free(tables);
03838          tables = NULL;
03839          stb_perfect_destroy(&p);
03840          return 0;
03841       }
03842       stb_arr_push(sets, set);
03843       stb_perfect_destroy(&p);
03844       n = stb_perfect_create(&p, (unsigned int *) (char **) sets, stb_arr_len(sets));
03845       assert(n != 0);
03846       k = (n+7) >> 3;
03847       tables = (unsigned char (*)[256]) realloc(tables, sizeof(*tables) * k);
03848       memset(tables, 0, sizeof(*tables) * k);
03849       for (i=0; i < stb_arr_len(sets); ++i) {
03850           k = stb_perfect_hash(&p, (int)(size_t) sets[i]);
03851          assert(k >= 0);
03852          n = k >> 3;
03853          f = bit[k&7];
03854          for (j=0; !j || sets[i][j]; ++j) {
03855             tables[n][(unsigned char) sets[i][j]] |= f;
03856          }
03857       }
03858       z = stb_perfect_hash(&p, (int)(size_t) set);
03859    }
03860    return tables[z >> 3][(unsigned char) c] & bit[z & 7];
03861 }
03862 
03863 #endif
03864 #endif
03865 
03867 //
03868 //                     Instantiated data structures
03869 //
03870 // This is an attempt to implement a templated data structure.
03871 //
03872 // Hash table: call stb_define_hash(TYPE,N,KEY,K1,K2,HASH,VALUE)
03873 //     TYPE     -- will define a structure type containing the hash table
03874 //     N        -- the name, will prefix functions named:
03875 //                        N create
03876 //                        N destroy
03877 //                        N get
03878 //                        N set, N add, N update,
03879 //                        N remove
03880 //     KEY      -- the type of the key. 'x == y' must be valid
03881 //       K1,K2  -- keys never used by the app, used as flags in the hashtable
03882 //       HASH   -- a piece of code ending with 'return' that hashes key 'k'
03883 //     VALUE    -- the type of the value. 'x = y' must be valid
03884 //
03885 //  Note that stb_define_hash_base can be used to define more sophisticated
03886 //  hash tables, e.g. those that make copies of the key or use special
03887 //  comparisons (e.g. strcmp).
03888 
03889 #define STB_(prefix,name)     stb__##prefix##name
03890 #define STB__(prefix,name)    prefix##name
03891 #define STB__use(x)           x
03892 #define STB__skip(x)
03893 
03894 #define stb_declare_hash(PREFIX,TYPE,N,KEY,VALUE) \
03895    typedef struct stb__st_##TYPE TYPE;\
03896    PREFIX int STB__(N, init)(TYPE *h, int count);\
03897    PREFIX int STB__(N, memory_usage)(TYPE *h);\
03898    PREFIX TYPE * STB__(N, create)(void);\
03899    PREFIX TYPE * STB__(N, copy)(TYPE *h);\
03900    PREFIX void STB__(N, destroy)(TYPE *h);\
03901    PREFIX int STB__(N,get_flag)(TYPE *a, KEY k, VALUE *v);\
03902    PREFIX VALUE STB__(N,get)(TYPE *a, KEY k);\
03903    PREFIX int STB__(N, set)(TYPE *a, KEY k, VALUE v);\
03904    PREFIX int STB__(N, add)(TYPE *a, KEY k, VALUE v);\
03905    PREFIX int STB__(N, update)(TYPE*a,KEY k,VALUE v);\
03906    PREFIX int STB__(N, remove)(TYPE *a, KEY k, VALUE *v);
03907 
03908 #define STB_nocopy(x)        (x)
03909 #define STB_nodelete(x)      0
03910 #define STB_nofields
03911 #define STB_nonullvalue(x)
03912 #define STB_nullvalue(x)     x
03913 #define STB_safecompare(x)   x
03914 #define STB_nosafe(x)
03915 #define STB_noprefix
03916 
03917 #ifdef __GNUC__
03918 #define STB__nogcc(x)
03919 #else
03920 #define STB__nogcc(x)  x
03921 #endif
03922 
03923 #define stb_define_hash_base(PREFIX,TYPE,FIELDS,N,NC,LOAD_FACTOR,             \
03924                              KEY,EMPTY,DEL,COPY,DISPOSE,SAFE,                 \
03925                              VCOMPARE,CCOMPARE,HASH,                          \
03926                              VALUE,HASVNULL,VNULL)                            \
03927                                                                               \
03928 typedef struct                                                                \
03929 {                                                                             \
03930    KEY   k;                                                                   \
03931    VALUE v;                                                                   \
03932 } STB_(N,_hashpair);                                                          \
03933                                                                               \
03934 STB__nogcc( typedef struct stb__st_##TYPE TYPE;  )                            \
03935 struct stb__st_##TYPE {                                                       \
03936    FIELDS                                                                     \
03937    STB_(N,_hashpair) *table;                                                  \
03938    unsigned int mask;                                                         \
03939    int count, limit;                                                          \
03940    int deleted;                                                               \
03941                                                                               \
03942    int delete_threshhold;                                                     \
03943    int grow_threshhold;                                                       \
03944    int shrink_threshhold;                                                     \
03945    unsigned char alloced, has_empty, has_del;                                 \
03946    VALUE ev; VALUE dv;                                                        \
03947 };                                                                            \
03948                                                                               \
03949 static unsigned int STB_(N, hash)(KEY k)                                      \
03950 {                                                                             \
03951    HASH                                                                       \
03952 }                                                                             \
03953                                                                               \
03954 PREFIX int STB__(N, init)(TYPE *h, int count)                                        \
03955 {                                                                             \
03956    int i;                                                                     \
03957    if (count < 4) count = 4;                                                  \
03958    h->limit = count;                                                          \
03959    h->count = 0;                                                              \
03960    h->mask  = count-1;                                                        \
03961    h->deleted = 0;                                                            \
03962    h->grow_threshhold = (int) (count * LOAD_FACTOR);                          \
03963    h->has_empty = h->has_del = 0;                                             \
03964    h->alloced = 0;                                                            \
03965    if (count <= 64)                                                           \
03966       h->shrink_threshhold = 0;                                               \
03967    else                                                                       \
03968       h->shrink_threshhold = (int) (count * (LOAD_FACTOR/2.25));              \
03969    h->delete_threshhold = (int) (count * (1-LOAD_FACTOR)/2);                  \
03970    h->table = (STB_(N,_hashpair)*) malloc(sizeof(h->table[0]) * count);       \
03971    if (h->table == NULL) return 0;                                            \
03972    /* ideally this gets turned into a memset32 automatically */               \
03973    for (i=0; i < count; ++i)                                                  \
03974       h->table[i].k = EMPTY;                                                  \
03975    return 1;                                                                  \
03976 }                                                                             \
03977                                                                               \
03978 PREFIX int STB__(N, memory_usage)(TYPE *h)                                           \
03979 {                                                                             \
03980    return sizeof(*h) + h->limit * sizeof(h->table[0]);                        \
03981 }                                                                             \
03982                                                                               \
03983 PREFIX TYPE * STB__(N, create)(void)                                                 \
03984 {                                                                             \
03985    TYPE *h = (TYPE *) malloc(sizeof(*h));                                     \
03986    if (h) {                                                                   \
03987       if (STB__(N, init)(h, 16))                                              \
03988          h->alloced = 1;                                                      \
03989       else { free(h); h=NULL; }                                               \
03990    }                                                                          \
03991    return h;                                                                  \
03992 }                                                                             \
03993                                                                               \
03994 PREFIX void STB__(N, destroy)(TYPE *a)                                               \
03995 {                                                                             \
03996    int i;                                                                     \
03997    for (i=0; i < a->limit; ++i)                                               \
03998       if (!CCOMPARE(a->table[i].k,EMPTY) && !CCOMPARE(a->table[i].k, DEL))    \
03999          DISPOSE(a->table[i].k);                                              \
04000    free(a->table);                                                            \
04001    if (a->alloced)                                                            \
04002       free(a);                                                                \
04003 }                                                                             \
04004                                                                               \
04005 static void STB_(N, rehash)(TYPE *a, int count);                              \
04006                                                                               \
04007 PREFIX int STB__(N,get_flag)(TYPE *a, KEY k, VALUE *v)                               \
04008 {                                                                             \
04009    unsigned int h = STB_(N, hash)(k);                                         \
04010    unsigned int n = h & a->mask, s;                                           \
04011    if (CCOMPARE(k,EMPTY)){ if (a->has_empty) *v = a->ev; return a->has_empty;}\
04012    if (CCOMPARE(k,DEL)) { if (a->has_del  ) *v = a->dv; return a->has_del;   }\
04013    if (CCOMPARE(a->table[n].k,EMPTY)) return 0;                               \
04014    SAFE(if (!CCOMPARE(a->table[n].k,DEL)))                                    \
04015    if (VCOMPARE(a->table[n].k,k)) { *v = a->table[n].v; return 1; }            \
04016    s = stb_rehash(h) | 1;                                                     \
04017    for(;;) {                                                                  \
04018       n = (n + s) & a->mask;                                                  \
04019       if (CCOMPARE(a->table[n].k,EMPTY)) return 0;                            \
04020       SAFE(if (CCOMPARE(a->table[n].k,DEL)) continue;)                        \
04021       if (VCOMPARE(a->table[n].k,k))                                           \
04022          { *v = a->table[n].v; return 1; }                                    \
04023    }                                                                          \
04024 }                                                                             \
04025                                                                               \
04026 HASVNULL(                                                                     \
04027    PREFIX VALUE STB__(N,get)(TYPE *a, KEY k)                                         \
04028    {                                                                          \
04029       VALUE v;                                                                \
04030       if (STB__(N,get_flag)(a,k,&v)) return v;                                \
04031       else                           return VNULL;                            \
04032    }                                                                          \
04033 )                                                                             \
04034                                                                               \
04035 PREFIX int STB__(N,getkey)(TYPE *a, KEY k, KEY *kout)                                \
04036 {                                                                             \
04037    unsigned int h = STB_(N, hash)(k);                                         \
04038    unsigned int n = h & a->mask, s;                                           \
04039    if (CCOMPARE(k,EMPTY)||CCOMPARE(k,DEL)) return 0;                          \
04040    if (CCOMPARE(a->table[n].k,EMPTY)) return 0;                               \
04041    SAFE(if (!CCOMPARE(a->table[n].k,DEL)))                                    \
04042    if (VCOMPARE(a->table[n].k,k)) { *kout = a->table[n].k; return 1; }         \
04043    s = stb_rehash(h) | 1;                                                     \
04044    for(;;) {                                                                  \
04045       n = (n + s) & a->mask;                                                  \
04046       if (CCOMPARE(a->table[n].k,EMPTY)) return 0;                            \
04047       SAFE(if (CCOMPARE(a->table[n].k,DEL)) continue;)                        \
04048       if (VCOMPARE(a->table[n].k,k))                                          \
04049          { *kout = a->table[n].k; return 1; }                                 \
04050    }                                                                          \
04051 }                                                                             \
04052                                                                               \
04053 static int STB_(N,addset)(TYPE *a, KEY k, VALUE v,                            \
04054                              int allow_new, int allow_old, int copy)          \
04055 {                                                                             \
04056    unsigned int h = STB_(N, hash)(k);                                         \
04057    unsigned int n = h & a->mask;                                              \
04058    int b = -1;                                                                \
04059    if (CCOMPARE(k,EMPTY)) {                                                   \
04060       if (a->has_empty ? allow_old : allow_new) {                             \
04061           n=a->has_empty; a->ev = v; a->has_empty = 1; return !n;             \
04062       } else return 0;                                                        \
04063    }                                                                          \
04064    if (CCOMPARE(k,DEL)) {                                                     \
04065       if (a->has_del ? allow_old : allow_new) {                               \
04066           n=a->has_del; a->dv = v; a->has_del = 1; return !n;                 \
04067       } else return 0;                                                        \
04068    }                                                                          \
04069    if (!CCOMPARE(a->table[n].k, EMPTY)) {                                     \
04070       unsigned int s;                                                         \
04071       if (CCOMPARE(a->table[n].k, DEL))                                       \
04072          b = n;                                                               \
04073       else if (VCOMPARE(a->table[n].k,k)) {                                   \
04074          if (allow_old)                                                       \
04075             a->table[n].v = v;                                                \
04076          return !allow_new;                                                   \
04077       }                                                                       \
04078       s = stb_rehash(h) | 1;                                                  \
04079       for(;;) {                                                               \
04080          n = (n + s) & a->mask;                                               \
04081          if (CCOMPARE(a->table[n].k, EMPTY)) break;                           \
04082          if (CCOMPARE(a->table[n].k, DEL)) {                                  \
04083             if (b < 0) b = n;                                                 \
04084          } else if (VCOMPARE(a->table[n].k,k)) {                              \
04085             if (allow_old)                                                    \
04086                a->table[n].v = v;                                             \
04087             return !allow_new;                                                \
04088          }                                                                    \
04089       }                                                                       \
04090    }                                                                          \
04091    if (!allow_new) return 0;                                                  \
04092    if (b < 0) b = n; else --a->deleted;                                       \
04093    a->table[b].k = copy ? COPY(k) : k;                                        \
04094    a->table[b].v = v;                                                         \
04095    ++a->count;                                                                \
04096    if (a->count > a->grow_threshhold)                                         \
04097       STB_(N,rehash)(a, a->limit*2);                                          \
04098    return 1;                                                                  \
04099 }                                                                             \
04100                                                                               \
04101 PREFIX int STB__(N, set)(TYPE *a, KEY k, VALUE v){return STB_(N,addset)(a,k,v,1,1,1);}\
04102 PREFIX int STB__(N, add)(TYPE *a, KEY k, VALUE v){return STB_(N,addset)(a,k,v,1,0,1);}\
04103 PREFIX int STB__(N, update)(TYPE*a,KEY k,VALUE v){return STB_(N,addset)(a,k,v,0,1,1);}\
04104                                                                               \
04105 PREFIX int STB__(N, remove)(TYPE *a, KEY k, VALUE *v)                                \
04106 {                                                                             \
04107    unsigned int h = STB_(N, hash)(k);                                         \
04108    unsigned int n = h & a->mask, s;                                           \
04109    if (CCOMPARE(k,EMPTY)) { if (a->has_empty) { if(v)*v = a->ev; a->has_empty=0; return 1; } return 0; } \
04110    if (CCOMPARE(k,DEL))   { if (a->has_del  ) { if(v)*v = a->dv; a->has_del  =0; return 1; } return 0; } \
04111    if (CCOMPARE(a->table[n].k,EMPTY)) return 0;                               \
04112    if (SAFE(CCOMPARE(a->table[n].k,DEL) || ) !VCOMPARE(a->table[n].k,k)) {     \
04113       s = stb_rehash(h) | 1;                                                  \
04114       for(;;) {                                                               \
04115          n = (n + s) & a->mask;                                               \
04116          if (CCOMPARE(a->table[n].k,EMPTY)) return 0;                         \
04117          SAFE(if (CCOMPARE(a->table[n].k, DEL)) continue;)                    \
04118          if (VCOMPARE(a->table[n].k,k)) break;                                 \
04119       }                                                                       \
04120    }                                                                          \
04121    DISPOSE(a->table[n].k);                                                    \
04122    a->table[n].k = DEL;                                                       \
04123    --a->count;                                                                \
04124    ++a->deleted;                                                              \
04125    if (v != NULL)                                                             \
04126       *v = a->table[n].v;                                                     \
04127    if (a->count < a->shrink_threshhold)                                       \
04128       STB_(N, rehash)(a, a->limit >> 1);                                      \
04129    else if (a->deleted > a->delete_threshhold)                                \
04130       STB_(N, rehash)(a, a->limit);                                           \
04131    return 1;                                                                  \
04132 }                                                                             \
04133                                                                               \
04134 PREFIX TYPE * STB__(NC, copy)(TYPE *a)                                        \
04135 {                                                                             \
04136    int i;                                                                     \
04137    TYPE *h = (TYPE *) malloc(sizeof(*h));                                     \
04138    if (!h) return NULL;                                                       \
04139    if (!STB__(N, init)(h, a->limit)) { free(h); return NULL; }                \
04140    h->count = a->count;                                                       \
04141    h->deleted = a->deleted;                                                   \
04142    h->alloced = 1;                                                            \
04143    h->ev = a->ev; h->dv = a->dv;                                              \
04144    h->has_empty = a->has_empty; h->has_del = a->has_del;                      \
04145    memcpy(h->table, a->table, h->limit * sizeof(h->table[0]));                \
04146    for (i=0; i < a->limit; ++i)                                               \
04147       if (!CCOMPARE(h->table[i].k,EMPTY) && !CCOMPARE(h->table[i].k,DEL))     \
04148          h->table[i].k = COPY(h->table[i].k);                                 \
04149    return h;                                                                  \
04150 }                                                                             \
04151                                                                               \
04152 static void STB_(N, rehash)(TYPE *a, int count)                               \
04153 {                                                                             \
04154    int i;                                                                     \
04155    TYPE b;                                                                    \
04156    STB__(N, init)(&b, count);                                                 \
04157    for (i=0; i < a->limit; ++i)                                               \
04158       if (!CCOMPARE(a->table[i].k,EMPTY) && !CCOMPARE(a->table[i].k,DEL))     \
04159          STB_(N,addset)(&b, a->table[i].k, a->table[i].v,1,1,0);              \
04160    free(a->table);                                                            \
04161    a->table = b.table;                                                        \
04162    a->mask = b.mask;                                                          \
04163    a->count = b.count;                                                        \
04164    a->limit = b.limit;                                                        \
04165    a->deleted = b.deleted;                                                    \
04166    a->delete_threshhold = b.delete_threshhold;                                \
04167    a->grow_threshhold = b.grow_threshhold;                                    \
04168    a->shrink_threshhold = b.shrink_threshhold;                                \
04169 }
04170 
04171 #define STB_equal(a,b)  ((a) == (b))
04172 
04173 #define stb_define_hash(TYPE,N,KEY,EMPTY,DEL,HASH,VALUE)                      \
04174    stb_define_hash_base(STB_noprefix, TYPE,STB_nofields,N,NC,0.85f,           \
04175               KEY,EMPTY,DEL,STB_nocopy,STB_nodelete,STB_nosafe,               \
04176               STB_equal,STB_equal,HASH,                                       \
04177               VALUE,STB_nonullvalue,0)
04178 
04179 #define stb_define_hash_vnull(TYPE,N,KEY,EMPTY,DEL,HASH,VALUE,VNULL)          \
04180    stb_define_hash_base(STB_noprefix, TYPE,STB_nofields,N,NC,0.85f,           \
04181               KEY,EMPTY,DEL,STB_nocopy,STB_nodelete,STB_nosafe,               \
04182               STB_equal,STB_equal,HASH,                                       \
04183               VALUE,STB_nullvalue,VNULL)
04184 
04186 //
04187 //                        stb_ptrmap
04188 //
04189 // An stb_ptrmap data structure is an O(1) hash table between pointers. One
04190 // application is to let you store "extra" data associated with pointers,
04191 // which is why it was originally called stb_extra.
04192 
04193 stb_declare_hash(STB_EXTERN, stb_ptrmap, stb_ptrmap_, void *, void *)
04194 stb_declare_hash(STB_EXTERN, stb_idict, stb_idict_, stb_int32, stb_int32)
04195 stb_declare_hash(STB_EXTERN, stb_uidict, stbi_uidict_, stb_uint32, stb_uint32)
04196 
04197 STB_EXTERN void        stb_ptrmap_delete(stb_ptrmap *e, void (*free_func)(void *));
04198 STB_EXTERN stb_ptrmap *stb_ptrmap_new(void);
04199 
04200 STB_EXTERN stb_idict * stb_idict_new_size(int size);
04201 STB_EXTERN void        stb_idict_remove_all(stb_idict *e);
04202 STB_EXTERN void        stb_uidict_reset(stb_uidict *e);
04203 
04204 #ifdef STB_DEFINE
04205 
04206 #define STB_EMPTY ((void *) 2)
04207 #define STB_EDEL  ((void *) 6)
04208 
04209 stb_define_hash_base(STB_noprefix,stb_ptrmap, STB_nofields, stb_ptrmap_,stb_ptrmap_,0.85f,
04210               void *,STB_EMPTY,STB_EDEL,STB_nocopy,STB_nodelete,STB_nosafe,
04211               STB_equal,STB_equal,return stb_hashptr(k);,
04212               void *,STB_nullvalue,NULL)
04213 
04214 stb_ptrmap *stb_ptrmap_new(void)
04215 {
04216    return stb_ptrmap_create();
04217 }
04218 
04219 void stb_ptrmap_delete(stb_ptrmap *e, void (*free_func)(void *))
04220 {
04221    int i;
04222    if (free_func)
04223       for (i=0; i < e->limit; ++i)
04224          if (e->table[i].k != STB_EMPTY && e->table[i].k != STB_EDEL) {
04225             if (free_func == free)
04226                free(e->table[i].v); // allow STB_MALLOC_WRAPPER to operate
04227             else
04228                free_func(e->table[i].v);
04229          }
04230    stb_ptrmap_destroy(e);
04231 }
04232 
04233 // extra fields needed for stua_dict
04234 #define STB_IEMPTY  ((int) 1)
04235 #define STB_IDEL    ((int) 3)
04236 stb_define_hash_base(STB_noprefix, stb_idict, short type; short gc; STB_nofields, stb_idict_,stb_idict_,0.95f,
04237               stb_int32,STB_IEMPTY,STB_IDEL,STB_nocopy,STB_nodelete,STB_nosafe,
04238               STB_equal,STB_equal,
04239               return stb_rehash_improved(k);,stb_int32,STB_nonullvalue,0)
04240 
04241 stb_idict * stb_idict_new_size(int size)
04242 {
04243    stb_idict *e = (stb_idict *) malloc(sizeof(*e));
04244    if (e) {
04245       if (!stb_is_pow2(size))
04246          size = 1 << stb_log2_ceil(size);
04247       stb_idict_init(e, size);
04248       e->alloced = 1;
04249    }
04250    return e;
04251 }
04252 
04253 void stb_idict_remove_all(stb_idict *e)
04254 {
04255    int n;
04256    for (n=0; n < e->limit; ++n)
04257       e->table[n].k = STB_IEMPTY;
04258    e->has_empty = e->has_del = 0;
04259    e->count = 0;
04260    e->deleted = 0;
04261 }
04262 
04263 stb_define_hash_base(STB_noprefix, stb_uidict, STB_nofields, stb_uidict_,stb_uidict_,0.85f,
04264               stb_int32,0xffffffff,0xfffffffe,STB_nocopy,STB_nodelete,STB_nosafe,
04265               STB_equal,STB_equal,
04266               return stb_rehash_improved(k);,stb_uint32,STB_nonullvalue,0)
04267 
04268 void stb_uidict_reset(stb_uidict *e)
04269 {
04270    int n;
04271    for (n=0; n < e->limit; ++n)
04272       e->table[n].k = 0xffffffff;
04273    e->has_empty = e->has_del = 0;
04274    e->count = 0;
04275    e->deleted = 0;
04276 }
04277 #endif
04278 
04280 //
04281 //                        stb_sparse_ptr_matrix
04282 //
04283 // An stb_ptrmap data structure is an O(1) hash table storing an arbitrary
04284 // block of data for a given pair of pointers.
04285 //
04286 // If create=0, returns
04287 
04288 typedef struct stb__st_stb_spmatrix stb_spmatrix;
04289 
04290 STB_EXTERN stb_spmatrix * stb_sparse_ptr_matrix_new(int val_size);
04291 STB_EXTERN void           stb_sparse_ptr_matrix_free(stb_spmatrix *z);
04292 STB_EXTERN void         * stb_sparse_ptr_matrix_get(stb_spmatrix *z, void *a, void *b, int create);
04293 
04294 #ifdef STB_DEFINE
04295 typedef struct
04296 {
04297    void *a;
04298    void *b;
04299 } stb__ptrpair;
04300 
04301 static stb__ptrpair stb__ptrpair_empty = { (void *) 1, (void *) 1 };
04302 static stb__ptrpair stb__ptrpair_del   = { (void *) 2, (void *) 2 };
04303 
04304 #define STB__equal_ptrpair(x,y) ((x).a == (y).a && (x).b == (y).b)
04305 
04306 stb_define_hash_base(STB_noprefix, stb_spmatrix, int val_size; void *arena;, stb__spmatrix_,stb__spmatrix_, 0.85,
04307      stb__ptrpair, stb__ptrpair_empty, stb__ptrpair_del,
04308      STB_nocopy, STB_nodelete, STB_nosafe,
04309      STB__equal_ptrpair, STB__equal_ptrpair, return stb_rehash(stb_hashptr(k.a))+stb_hashptr(k.b);,
04310      void *, STB_nullvalue, 0)
04311 
04312 stb_spmatrix *stb_sparse_ptr_matrix_new(int val_size)
04313 {
04314    stb_spmatrix *m = stb__spmatrix_create();
04315    if (m) m->val_size = val_size;
04316    if (m) m->arena = stb_malloc_global(1);
04317    return m;
04318 }
04319 
04320 void stb_sparse_ptr_matrix_free(stb_spmatrix *z)
04321 {
04322    if (z->arena) stb_free(z->arena);
04323    stb__spmatrix_destroy(z);
04324 }
04325 
04326 void *stb_sparse_ptr_matrix_get(stb_spmatrix *z, void *a, void *b, int create)
04327 {
04328    stb__ptrpair t = { a,b };
04329    void *data = stb__spmatrix_get(z, t);
04330    if (!data && create) {
04331       data = stb_malloc_raw(z->arena, z->val_size);
04332       if (!data) return NULL;
04333       memset(data, 0, z->val_size);
04334       stb__spmatrix_add(z, t, data);
04335    }
04336    return data;
04337 }
04338 #endif
04339 
04340 
04341 
04343 //
04344 //                  SDICT: Hash Table for Strings (symbol table)
04345 //
04346 //           if "use_arena=1", then strings will be copied
04347 //           into blocks and never freed until the sdict is freed;
04348 //           otherwise they're malloc()ed and free()d on the fly.
04349 //           (specify use_arena=1 if you never stb_sdict_remove)
04350 
04351 stb_declare_hash(STB_EXTERN, stb_sdict, stb_sdict_, char *, void *)
04352 
04353 STB_EXTERN stb_sdict * stb_sdict_new(int use_arena);
04354 STB_EXTERN stb_sdict * stb_sdict_copy(stb_sdict*);
04355 STB_EXTERN void        stb_sdict_delete(stb_sdict *);
04356 STB_EXTERN void *      stb_sdict_change(stb_sdict *, char *str, void *p);
04357 STB_EXTERN int         stb_sdict_count(stb_sdict *d);
04358 
04359 STB_EXTERN int         stb_sdict_internal_limit(stb_sdict *d);
04360 STB_EXTERN char *      stb_sdict_internal_key(stb_sdict *d, int n);
04361 STB_EXTERN void *      stb_sdict_internal_value(stb_sdict *d, int n);
04362 
04363 #define stb_sdict_for(d,i,q,z)                                          \
04364    for(i=0; i < stb_sdict_internal_limit(d) ? (q=stb_sdict_internal_key(d,i),z=stb_sdict_internal_value(d,i),1) : 0; ++i)    \
04365       if (q==NULL||q==(void *) 1);else   // reversed makes macro friendly
04366 
04367 #ifdef STB_DEFINE
04368 
04369 // if in same translation unit, for speed, don't call accessors
04370 #undef stb_sdict_for
04371 #define stb_sdict_for(d,i,q,z)                                          \
04372    for(i=0; i < (d)->limit ? (q=(d)->table[i].k,z=(d)->table[i].v,1) : 0; ++i)    \
04373       if (q==NULL||q==(void *) 1);else   // reversed makes macro friendly
04374 
04375 #define STB_DEL ((void *) 1)
04376 #define STB_SDEL  ((char *) 1)
04377 
04378 #define stb_sdict__copy(x)                                             \
04379    stb_p_strcpy_s(a->arena ? stb_malloc_string(a->arena, strlen(x)+1)    \
04380                          : (char *) malloc(strlen(x)+1), strlen(x)+1, x)
04381 
04382 #define stb_sdict__dispose(x)  if (!a->arena) free(x)
04383 
04384 stb_define_hash_base(STB_noprefix, stb_sdict, void*arena;, stb_sdict_,stb_sdictinternal_, 0.85f,
04385         char *, NULL, STB_SDEL, stb_sdict__copy, stb_sdict__dispose,
04386                         STB_safecompare, !strcmp, STB_equal, return stb_hash(k);,
04387         void *, STB_nullvalue, NULL)
04388 
04389 int stb_sdict_count(stb_sdict *a)
04390 {
04391    return a->count;
04392 }
04393 
04394 int stb_sdict_internal_limit(stb_sdict *a)
04395 {
04396    return a->limit;
04397 }
04398 char* stb_sdict_internal_key(stb_sdict *a, int n)
04399 {
04400    return a->table[n].k;
04401 }
04402 void* stb_sdict_internal_value(stb_sdict *a, int n)
04403 {
04404    return a->table[n].v;
04405 }
04406 
04407 stb_sdict * stb_sdict_new(int use_arena)
04408 {
04409    stb_sdict *d = stb_sdict_create();
04410    if (d == NULL) return NULL;
04411    d->arena = use_arena ? stb_malloc_global(1) : NULL;
04412    return d;
04413 }
04414 
04415 stb_sdict* stb_sdict_copy(stb_sdict *old)
04416 {
04417    stb_sdict *n;
04418    void *old_arena = old->arena;
04419    void *new_arena = old_arena ? stb_malloc_global(1) : NULL;
04420    old->arena = new_arena;
04421    n = stb_sdictinternal_copy(old);
04422    old->arena = old_arena;
04423    if (n)
04424       n->arena = new_arena;
04425    else if (new_arena)
04426       stb_free(new_arena);
04427    return n;
04428 }
04429 
04430 
04431 void stb_sdict_delete(stb_sdict *d)
04432 {
04433    if (d->arena)
04434       stb_free(d->arena);
04435    stb_sdict_destroy(d);
04436 }
04437 
04438 void * stb_sdict_change(stb_sdict *d, char *str, void *p)
04439 {
04440    void *q = stb_sdict_get(d, str);
04441    stb_sdict_set(d, str, p);
04442    return q;
04443 }
04444 #endif
04445 
04447 //
04448 //                     Instantiated data structures
04449 //
04450 // This is an attempt to implement a templated data structure.
04451 // What you do is define a struct foo, and then include several
04452 // pointer fields to struct foo in your struct. Then you call
04453 // the instantiator, which creates the functions that implement
04454 // the data structure. This requires massive undebuggable #defines,
04455 // so we limit the cases where we do this.
04456 //
04457 // AA tree is an encoding of a 2-3 tree whereas RB trees encode a 2-3-4 tree;
04458 // much simpler code due to fewer cases.
04459 
04460 #define stb__bst_parent(x)    x
04461 #define stb__bst_noparent(x)
04462 
04463 #define stb_bst_fields(N)                                   \
04464     *STB_(N,left), *STB_(N,right);                          \
04465     unsigned char STB_(N,level)
04466 
04467 #define stb_bst_fields_parent(N)                            \
04468     *STB_(N,left), *STB_(N,right),  *STB_(N,parent);        \
04469     unsigned char STB_(N,level)
04470 
04471 #define STB__level(N,x)         ((x) ? (x)->STB_(N,level) : 0)
04472 
04473 #define stb_bst_base(TYPE, N, TREE, M, compare, PAR)                         \
04474                                                                              \
04475 static int STB_(N,_compare)(TYPE *p, TYPE *q)                                \
04476 {                                                                            \
04477    compare                                                                   \
04478 }                                                                            \
04479                                                                              \
04480 static void STB_(N,setleft)(TYPE *q, TYPE *v)                                \
04481 {                                                                            \
04482    q->STB_(N,left) = v;                                                      \
04483    PAR(if (v) v->STB_(N,parent) = q;)                                        \
04484 }                                                                            \
04485                                                                              \
04486 static void STB_(N,setright)(TYPE *q, TYPE *v)                               \
04487 {                                                                            \
04488    q->STB_(N,right) = v;                                                     \
04489    PAR(if (v) v->STB_(N,parent) = q;)                                        \
04490 }                                                                            \
04491                                                                              \
04492 static TYPE *STB_(N,skew)(TYPE *q)                                           \
04493 {                                                                            \
04494    if (q == NULL) return q;                                                  \
04495    if (q->STB_(N,left)                                                       \
04496         && q->STB_(N,left)->STB_(N,level) == q->STB_(N,level)) {             \
04497       TYPE *p       = q->STB_(N,left);                                       \
04498       STB_(N,setleft)(q, p->STB_(N,right));                                  \
04499       STB_(N,setright)(p, q);                                                \
04500       return p;                                                              \
04501    }                                                                         \
04502    return q;                                                                 \
04503 }                                                                            \
04504                                                                              \
04505 static TYPE *STB_(N,split)(TYPE *p)                                          \
04506 {                                                                            \
04507    TYPE *q = p->STB_(N,right);                                               \
04508    if (q && q->STB_(N,right)                                                 \
04509          && q->STB_(N,right)->STB_(N,level) == p->STB_(N,level)) {           \
04510       STB_(N,setright)(p, q->STB_(N,left));                                  \
04511       STB_(N,setleft)(q,p);                                                  \
04512       ++q->STB_(N,level);                                                    \
04513       return q;                                                              \
04514    }                                                                         \
04515    return p;                                                                 \
04516 }                                                                            \
04517                                                                              \
04518 TYPE *STB__(N,insert)(TYPE *tree, TYPE *item)                                \
04519 {                                                                            \
04520    int c;                                                                    \
04521    if (tree == NULL) {                                                       \
04522       item->STB_(N,left) = NULL;                                             \
04523       item->STB_(N,right) = NULL;                                            \
04524       item->STB_(N,level) = 1;                                               \
04525       PAR(item->STB_(N,parent) = NULL;)                                      \
04526       return item;                                                           \
04527    }                                                                         \
04528    c = STB_(N,_compare)(item,tree);                                          \
04529    if (c == 0) {                                                             \
04530       if (item != tree) {                                                    \
04531          STB_(N,setleft)(item, tree->STB_(N,left));                          \
04532          STB_(N,setright)(item, tree->STB_(N,right));                        \
04533          item->STB_(N,level) = tree->STB_(N,level);                          \
04534          PAR(item->STB_(N,parent) = NULL;)                                   \
04535       }                                                                      \
04536       return item;                                                           \
04537    }                                                                         \
04538    if (c < 0)                                                                \
04539       STB_(N,setleft )(tree, STB__(N,insert)(tree->STB_(N,left), item));     \
04540    else                                                                      \
04541       STB_(N,setright)(tree, STB__(N,insert)(tree->STB_(N,right), item));    \
04542    tree = STB_(N,skew)(tree);                                                \
04543    tree = STB_(N,split)(tree);                                               \
04544    PAR(tree->STB_(N,parent) = NULL;)                                         \
04545    return tree;                                                              \
04546 }                                                                            \
04547                                                                              \
04548 TYPE *STB__(N,remove)(TYPE *tree, TYPE *item)                                \
04549 {                                                                            \
04550    static TYPE *delnode, *leaf, *restore;                                    \
04551    if (tree == NULL) return NULL;                                            \
04552    leaf = tree;                                                              \
04553    if (STB_(N,_compare)(item, tree) < 0) {                                   \
04554       STB_(N,setleft)(tree, STB__(N,remove)(tree->STB_(N,left), item));      \
04555    } else {                                                                  \
04556       TYPE *r;                                                               \
04557       delnode = tree;                                                        \
04558       r = STB__(N,remove)(tree->STB_(N,right), item);                        \
04559       /* maybe move 'leaf' up to this location */                            \
04560       if (restore == tree) { tree = leaf; leaf = restore = NULL;  }          \
04561       STB_(N,setright)(tree,r);                                              \
04562       assert(tree->STB_(N,right) != tree);                                   \
04563    }                                                                         \
04564    if (tree == leaf) {                                                       \
04565       if (delnode == item) {                                                 \
04566          tree = tree->STB_(N,right);                                         \
04567          assert(leaf->STB_(N,left) == NULL);                                 \
04568          /* move leaf (the right sibling) up to delnode */                   \
04569          STB_(N,setleft )(leaf, item->STB_(N,left ));                        \
04570          STB_(N,setright)(leaf, item->STB_(N,right));                        \
04571          leaf->STB_(N,level) = item->STB_(N,level);                          \
04572          if (leaf != item)                                                   \
04573             restore = delnode;                                               \
04574       }                                                                      \
04575       delnode = NULL;                                                        \
04576    } else {                                                                  \
04577       if (STB__level(N,tree->STB_(N,left) ) < tree->STB_(N,level)-1 ||       \
04578           STB__level(N,tree->STB_(N,right)) < tree->STB_(N,level)-1) {       \
04579          --tree->STB_(N,level);                                              \
04580          if (STB__level(N,tree->STB_(N,right)) > tree->STB_(N,level))        \
04581             tree->STB_(N,right)->STB_(N,level) = tree->STB_(N,level);        \
04582          tree = STB_(N,skew)(tree);                                          \
04583          STB_(N,setright)(tree, STB_(N,skew)(tree->STB_(N,right)));          \
04584          if (tree->STB_(N,right))                                            \
04585             STB_(N,setright)(tree->STB_(N,right),                            \
04586                   STB_(N,skew)(tree->STB_(N,right)->STB_(N,right)));         \
04587          tree = STB_(N,split)(tree);                                         \
04588          if (tree->STB_(N,right))                                            \
04589             STB_(N,setright)(tree,  STB_(N,split)(tree->STB_(N,right)));     \
04590       }                                                                      \
04591    }                                                                         \
04592    PAR(if (tree) tree->STB_(N,parent) = NULL;)                               \
04593    return tree;                                                              \
04594 }                                                                            \
04595                                                                              \
04596 TYPE *STB__(N,last)(TYPE *tree)                                              \
04597 {                                                                            \
04598    if (tree)                                                                 \
04599       while (tree->STB_(N,right)) tree = tree->STB_(N,right);                \
04600    return tree;                                                              \
04601 }                                                                            \
04602                                                                              \
04603 TYPE *STB__(N,first)(TYPE *tree)                                             \
04604 {                                                                            \
04605    if (tree)                                                                 \
04606       while (tree->STB_(N,left)) tree = tree->STB_(N,left);                  \
04607    return tree;                                                              \
04608 }                                                                            \
04609                                                                              \
04610 TYPE *STB__(N,next)(TYPE *tree, TYPE *item)                                  \
04611 {                                                                            \
04612    TYPE *next = NULL;                                                        \
04613    if (item->STB_(N,right))                                                  \
04614       return STB__(N,first)(item->STB_(N,right));                            \
04615    PAR(                                                                      \
04616       while(item->STB_(N,parent)) {                                          \
04617          TYPE *up = item->STB_(N,parent);                                    \
04618          if (up->STB_(N,left) == item) return up;                            \
04619          item = up;                                                          \
04620       }                                                                      \
04621       return NULL;                                                           \
04622    )                                                                         \
04623    while (tree != item) {                                                    \
04624       if (STB_(N,_compare)(item, tree) < 0) {                                \
04625          next = tree;                                                        \
04626          tree = tree->STB_(N,left);                                          \
04627       } else {                                                               \
04628          tree = tree->STB_(N,right);                                         \
04629       }                                                                      \
04630    }                                                                         \
04631    return next;                                                              \
04632 }                                                                            \
04633                                                                              \
04634 TYPE *STB__(N,prev)(TYPE *tree, TYPE *item)                                  \
04635 {                                                                            \
04636    TYPE *next = NULL;                                                        \
04637    if (item->STB_(N,left))                                                   \
04638       return STB__(N,last)(item->STB_(N,left));                              \
04639    PAR(                                                                      \
04640       while(item->STB_(N,parent)) {                                          \
04641          TYPE *up = item->STB_(N,parent);                                    \
04642          if (up->STB_(N,right) == item) return up;                           \
04643          item = up;                                                          \
04644       }                                                                      \
04645       return NULL;                                                           \
04646    )                                                                         \
04647    while (tree != item) {                                                    \
04648       if (STB_(N,_compare)(item, tree) < 0) {                                \
04649          tree = tree->STB_(N,left);                                          \
04650       } else {                                                               \
04651          next = tree;                                                        \
04652          tree = tree->STB_(N,right);                                         \
04653       }                                                                      \
04654    }                                                                         \
04655    return next;                                                              \
04656 }                                                                            \
04657                                                                              \
04658 STB__DEBUG(                                                                  \
04659    void STB__(N,_validate)(TYPE *tree, int root)                             \
04660    {                                                                         \
04661       if (tree == NULL) return;                                              \
04662       PAR(if(root) assert(tree->STB_(N,parent) == NULL);)                    \
04663       assert(STB__level(N,tree->STB_(N,left) ) == tree->STB_(N,level)-1);    \
04664       assert(STB__level(N,tree->STB_(N,right)) <= tree->STB_(N,level));      \
04665       assert(STB__level(N,tree->STB_(N,right)) >= tree->STB_(N,level)-1);    \
04666       if (tree->STB_(N,right)) {                                             \
04667         assert(STB__level(N,tree->STB_(N,right)->STB_(N,right))              \
04668                                                !=    tree->STB_(N,level));   \
04669         PAR(assert(tree->STB_(N,right)->STB_(N,parent) == tree);)            \
04670       }                                                                      \
04671       PAR(if(tree->STB_(N,left)) assert(tree->STB_(N,left)->STB_(N,parent) == tree);) \
04672       STB__(N,_validate)(tree->STB_(N,left) ,0);                             \
04673       STB__(N,_validate)(tree->STB_(N,right),0);                             \
04674    }                                                                         \
04675 )                                                                            \
04676                                                                              \
04677 typedef struct                                                               \
04678 {                                                                            \
04679    TYPE *root;                                                               \
04680 } TREE;                                                                      \
04681                                                                              \
04682 void  STB__(M,Insert)(TREE *tree, TYPE *item)                                \
04683 { tree->root = STB__(N,insert)(tree->root, item); }                          \
04684 void  STB__(M,Remove)(TREE *tree, TYPE *item)                                \
04685 { tree->root = STB__(N,remove)(tree->root, item); }                          \
04686 TYPE *STB__(M,Next)(TREE *tree, TYPE *item)                                  \
04687 { return STB__(N,next)(tree->root, item); }                                  \
04688 TYPE *STB__(M,Prev)(TREE *tree, TYPE *item)                                  \
04689 { return STB__(N,prev)(tree->root, item); }                                  \
04690 TYPE *STB__(M,First)(TREE *tree) { return STB__(N,first)(tree->root); }      \
04691 TYPE *STB__(M,Last) (TREE *tree) { return STB__(N,last) (tree->root); }      \
04692 void STB__(M,Init)(TREE *tree) { tree->root = NULL; }
04693 
04694 
04695 #define stb_bst_find(N,tree,fcompare)                                        \
04696 {                                                                            \
04697    int c;                                                                    \
04698    while (tree != NULL) {                                                    \
04699       fcompare                                                               \
04700       if (c == 0) return tree;                                               \
04701       if (c < 0)  tree = tree->STB_(N,left);                                 \
04702       else        tree = tree->STB_(N,right);                                \
04703    }                                                                         \
04704    return NULL;                                                              \
04705 }
04706 
04707 #define stb_bst_raw(TYPE,N,TREE,M,vfield,VTYPE,compare,PAR)                  \
04708    stb_bst_base(TYPE,N,TREE,M,                                               \
04709          VTYPE a = p->vfield; VTYPE b = q->vfield; return (compare);, PAR )  \
04710                                                                              \
04711 TYPE *STB__(N,find)(TYPE *tree, VTYPE a)                                     \
04712    stb_bst_find(N,tree,VTYPE b = tree->vfield; c = (compare);)               \
04713 TYPE *STB__(M,Find)(TREE *tree, VTYPE a)                                     \
04714 { return STB__(N,find)(tree->root, a); }
04715 
04716 #define stb_bst(TYPE,N,TREE,M,vfield,VTYPE,compare) \
04717    stb_bst_raw(TYPE,N,TREE,M,vfield,VTYPE,compare,stb__bst_noparent)
04718 #define stb_bst_parent(TYPE,N,TREE,M,vfield,VTYPE,compare) \
04719    stb_bst_raw(TYPE,N,TREE,M,vfield,VTYPE,compare,stb__bst_parent)
04720 
04721 
04722 
04724 //
04725 //                             Pointer Nulling
04726 //
04727 //  This lets you automatically NULL dangling pointers to "registered"
04728 //  objects. Note that you have to make sure you call the appropriate
04729 //  functions when you free or realloc blocks of memory that contain
04730 //  pointers or pointer targets. stb.h can automatically do this for
04731 //  stb_arr, or for all frees/reallocs if it's wrapping them.
04732 //
04733 
04734 #ifdef STB_NPTR
04735 
04736 STB_EXTERN void stb_nptr_set(void *address_of_pointer, void *value_to_write);
04737 STB_EXTERN void stb_nptr_didset(void *address_of_pointer);
04738 
04739 STB_EXTERN void stb_nptr_didfree(void *address_being_freed, int len);
04740 STB_EXTERN void stb_nptr_free(void *address_being_freed, int len);
04741 
04742 STB_EXTERN void stb_nptr_didrealloc(void *new_address, void *old_address, int len);
04743 STB_EXTERN void stb_nptr_recache(void); // recache all known pointers
04744                                        // do this after pointer sets outside your control, slow
04745 
04746 #ifdef STB_DEFINE
04747 // for fast updating on free/realloc, we need to be able to find
04748 // all the objects (pointers and targets) within a given block;
04749 // this precludes hashing
04750 
04751 // we use a three-level hierarchy of memory to minimize storage:
04752 //   level 1: 65536 pointers to stb__memory_node (always uses 256 KB)
04753 //   level 2: each stb__memory_node represents a 64K block of memory
04754 //            with 256 stb__memory_leafs (worst case 64MB)
04755 //   level 3: each stb__memory_leaf represents 256 bytes of memory
04756 //            using a list of target locations and a list of pointers
04757 //            (which are hopefully fairly short normally!)
04758 
04759 // this approach won't work in 64-bit, which has a much larger address
04760 // space. need to redesign
04761 
04762 #define STB__NPTR_ROOT_LOG2   16
04763 #define STB__NPTR_ROOT_NUM    (1 << STB__NPTR_ROOT_LOG2)
04764 #define STB__NPTR_ROOT_SHIFT  (32 - STB__NPTR_ROOT_LOG2)
04765 
04766 #define STB__NPTR_NODE_LOG2   5
04767 #define STB__NPTR_NODE_NUM    (1 << STB__NPTR_NODE_LOG2)
04768 #define STB__NPTR_NODE_MASK   (STB__NPTR_NODE_NUM-1)
04769 #define STB__NPTR_NODE_SHIFT  (STB__NPTR_ROOT_SHIFT - STB__NPTR_NODE_LOG2)
04770 #define STB__NPTR_NODE_OFFSET(x)   (((x) >> STB__NPTR_NODE_SHIFT) & STB__NPTR_NODE_MASK)
04771 
04772 typedef struct stb__st_nptr
04773 {
04774    void *ptr;   // address of actual pointer
04775    struct stb__st_nptr *next;   // next pointer with same target
04776    struct stb__st_nptr **prev;  // prev pointer with same target, address of 'next' field (or first)
04777    struct stb__st_nptr *next_in_block;
04778 } stb__nptr;
04779 
04780 typedef struct stb__st_nptr_target
04781 {
04782    void *ptr;   // address of target
04783    stb__nptr *first; // address of first nptr pointing to this
04784    struct stb__st_nptr_target *next_in_block;
04785 } stb__nptr_target;
04786 
04787 typedef struct
04788 {
04789    stb__nptr *pointers;
04790    stb__nptr_target *targets;
04791 } stb__memory_leaf;
04792 
04793 typedef struct
04794 {
04795    stb__memory_leaf *children[STB__NPTR_NODE_NUM];
04796 } stb__memory_node;
04797 
04798 stb__memory_node *stb__memtab_root[STB__NPTR_ROOT_NUM];
04799 
04800 static stb__memory_leaf *stb__nptr_find_leaf(void *mem)
04801 {
04802    stb_uint32 address = (stb_uint32) mem;
04803    stb__memory_node *z = stb__memtab_root[address >> STB__NPTR_ROOT_SHIFT];
04804    if (z)
04805       return z->children[STB__NPTR_NODE_OFFSET(address)];
04806    else
04807       return NULL;
04808 }
04809 
04810 static void * stb__nptr_alloc(int size)
04811 {
04812    return stb__realloc_raw(0,size);
04813 }
04814 
04815 static void stb__nptr_free(void *p)
04816 {
04817    stb__realloc_raw(p,0);
04818 }
04819 
04820 static stb__memory_leaf *stb__nptr_make_leaf(void *mem)
04821 {
04822    stb_uint32 address = (stb_uint32) mem;
04823    stb__memory_node *z = stb__memtab_root[address >> STB__NPTR_ROOT_SHIFT];
04824    stb__memory_leaf *f;
04825    if (!z) {
04826       int i;
04827       z = (stb__memory_node *) stb__nptr_alloc(sizeof(*stb__memtab_root[0]));
04828       stb__memtab_root[address >> STB__NPTR_ROOT_SHIFT] = z;
04829       for (i=0; i < 256; ++i)
04830          z->children[i] = 0;
04831    }
04832    f = (stb__memory_leaf *) stb__nptr_alloc(sizeof(*f));
04833    z->children[STB__NPTR_NODE_OFFSET(address)] = f;
04834    f->pointers = NULL;
04835    f->targets = NULL;
04836    return f;
04837 }
04838 
04839 static stb__nptr_target *stb__nptr_find_target(void *target, int force)
04840 {
04841    stb__memory_leaf *p = stb__nptr_find_leaf(target);
04842    if (p) {
04843       stb__nptr_target *t = p->targets;
04844       while (t) {
04845          if (t->ptr == target)
04846             return t;
04847          t = t->next_in_block;
04848       }
04849    }
04850    if (force) {
04851       stb__nptr_target *t = (stb__nptr_target*) stb__nptr_alloc(sizeof(*t));
04852       if (!p) p = stb__nptr_make_leaf(target);
04853       t->ptr = target;
04854       t->first = NULL;
04855       t->next_in_block = p->targets;
04856       p->targets = t;
04857       return t;
04858    } else
04859       return NULL;
04860 }
04861 
04862 static stb__nptr *stb__nptr_find_pointer(void *ptr, int force)
04863 {
04864    stb__memory_leaf *p = stb__nptr_find_leaf(ptr);
04865    if (p) {
04866       stb__nptr *t = p->pointers;
04867       while (t) {
04868          if (t->ptr == ptr)
04869             return t;
04870          t = t->next_in_block;
04871       }
04872    }
04873    if (force) {
04874       stb__nptr *t = (stb__nptr *) stb__nptr_alloc(sizeof(*t));
04875       if (!p) p = stb__nptr_make_leaf(ptr);
04876       t->ptr = ptr;
04877       t->next = NULL;
04878       t->prev = NULL;
04879       t->next_in_block = p->pointers;
04880       p->pointers = t;
04881       return t;
04882    } else
04883       return NULL;
04884 }
04885 
04886 void stb_nptr_set(void *address_of_pointer, void *value_to_write)
04887 {
04888    if (*(void **)address_of_pointer != value_to_write) {
04889       *(void **) address_of_pointer = value_to_write;
04890       stb_nptr_didset(address_of_pointer);
04891    }
04892 }
04893 
04894 void stb_nptr_didset(void *address_of_pointer)
04895 {
04896    // first unlink from old chain
04897    void *new_address;
04898    stb__nptr *p = stb__nptr_find_pointer(address_of_pointer, 1); // force building if doesn't exist
04899    if (p->prev) { // if p->prev is NULL, we just built it, or it was NULL
04900       *(p->prev) = p->next;
04901       if (p->next) p->next->prev = p->prev;
04902    }
04903    // now add to new chain
04904    new_address = *(void **)address_of_pointer;
04905    if (new_address != NULL) {
04906       stb__nptr_target *t = stb__nptr_find_target(new_address, 1);
04907       p->next = t->first;
04908       if (p->next) p->next->prev = &p->next;
04909       p->prev = &t->first;
04910       t->first = p;
04911    } else {
04912       p->prev = NULL;
04913       p->next = NULL;
04914    }
04915 }
04916 
04917 void stb__nptr_block(void *address, int len, void (*function)(stb__memory_leaf *f, int datum, void *start, void *end), int datum)
04918 {
04919    void *end_address = (void *) ((char *) address + len - 1);
04920    stb__memory_node *n;
04921    stb_uint32 start = (stb_uint32) address;
04922    stb_uint32 end   = start + len - 1;
04923 
04924    int b0 = start >> STB__NPTR_ROOT_SHIFT;
04925    int b1 = end >> STB__NPTR_ROOT_SHIFT;
04926    int b=b0,i,e0,e1;
04927 
04928    e0 = STB__NPTR_NODE_OFFSET(start);
04929 
04930    if (datum <= 0) {
04931       // first block
04932       n = stb__memtab_root[b0];
04933       if (n) {
04934          if (b0 != b1)
04935             e1 = STB__NPTR_NODE_NUM-1;
04936          else
04937             e1 = STB__NPTR_NODE_OFFSET(end);
04938          for (i=e0; i <= e1; ++i)
04939             if (n->children[i])
04940                function(n->children[i], datum, address, end_address);
04941       }
04942       if (b1 > b0) {
04943          // blocks other than the first and last block
04944          for (b=b0+1; b < b1; ++b) {
04945             n = stb__memtab_root[b];
04946             if (n)
04947                for (i=0; i <= STB__NPTR_NODE_NUM-1; ++i)
04948                   if (n->children[i])
04949                      function(n->children[i], datum, address, end_address);
04950          }
04951          // last block
04952          n = stb__memtab_root[b1];
04953          if (n) {
04954             e1 = STB__NPTR_NODE_OFFSET(end);
04955             for (i=0; i <= e1; ++i)
04956                if (n->children[i])
04957                   function(n->children[i], datum, address, end_address);
04958          }
04959       }
04960    } else {
04961       if (b1 > b0) {
04962          // last block
04963          n = stb__memtab_root[b1];
04964          if (n) {
04965             e1 = STB__NPTR_NODE_OFFSET(end);
04966             for (i=e1; i >= 0; --i)
04967                if (n->children[i])
04968                   function(n->children[i], datum, address, end_address);
04969          }
04970          // blocks other than the first and last block
04971          for (b=b1-1; b > b0; --b) {
04972             n = stb__memtab_root[b];
04973             if (n)
04974                for (i=STB__NPTR_NODE_NUM-1; i >= 0; --i)
04975                   if (n->children[i])
04976                      function(n->children[i], datum, address, end_address);
04977          }
04978       }
04979       // first block
04980       n = stb__memtab_root[b0];
04981       if (n) {
04982          if (b0 != b1)
04983             e1 = STB__NPTR_NODE_NUM-1;
04984          else
04985             e1 = STB__NPTR_NODE_OFFSET(end);
04986          for (i=e1; i >= e0; --i)
04987             if (n->children[i])
04988                function(n->children[i], datum, address, end_address);
04989       }
04990    }
04991 }
04992 
04993 static void stb__nptr_delete_pointers(stb__memory_leaf *f, int offset, void *start, void *end)
04994 {
04995    stb__nptr **p = &f->pointers;
04996    while (*p) {
04997       stb__nptr *n = *p;
04998       if (n->ptr >= start && n->ptr <= end) {
04999          // unlink
05000          if (n->prev) {
05001             *(n->prev) = n->next;
05002             if (n->next) n->next->prev = n->prev;
05003          }
05004          *p = n->next_in_block;
05005          stb__nptr_free(n);
05006       } else
05007          p = &(n->next_in_block);
05008    }
05009 }
05010 
05011 static void stb__nptr_delete_targets(stb__memory_leaf *f, int offset, void *start, void *end)
05012 {
05013    stb__nptr_target **p = &f->targets;
05014    while (*p) {
05015       stb__nptr_target *n = *p;
05016       if (n->ptr >= start && n->ptr <= end) {
05017          // null pointers
05018          stb__nptr *z = n->first;
05019          while (z) {
05020             stb__nptr *y = z->next;
05021             z->prev = NULL;
05022             z->next = NULL;
05023             *(void **) z->ptr = NULL;
05024             z = y;
05025          }
05026          // unlink this target
05027          *p = n->next_in_block;
05028          stb__nptr_free(n);
05029       } else
05030          p = &(n->next_in_block);
05031    }
05032 }
05033 
05034 void stb_nptr_didfree(void *address_being_freed, int len)
05035 {
05036    // step one: delete all pointers in this block
05037    stb__nptr_block(address_being_freed, len, stb__nptr_delete_pointers, 0);
05038    // step two: NULL all pointers to this block; do this second to avoid NULLing deleted pointers
05039    stb__nptr_block(address_being_freed, len, stb__nptr_delete_targets, 0);
05040 }
05041 
05042 void stb_nptr_free(void *address_being_freed, int len)
05043 {
05044    free(address_being_freed);
05045    stb_nptr_didfree(address_being_freed, len);
05046 }
05047 
05048 static void stb__nptr_move_targets(stb__memory_leaf *f, int offset, void *start, void *end)
05049 {
05050    stb__nptr_target **t = &f->targets;
05051    while (*t) {
05052       stb__nptr_target *n = *t;
05053       if (n->ptr >= start && n->ptr <= end) {
05054          stb__nptr *z;
05055          stb__memory_leaf *f;
05056          // unlink n
05057          *t = n->next_in_block;
05058          // update n to new address
05059          n->ptr = (void *) ((char *) n->ptr + offset);
05060          f = stb__nptr_find_leaf(n->ptr);
05061          if (!f) f = stb__nptr_make_leaf(n->ptr);
05062          n->next_in_block = f->targets;
05063          f->targets = n;
05064          // now go through all pointers and make them point here
05065          z = n->first;
05066          while (z) {
05067             *(void**) z->ptr = n->ptr;
05068             z = z->next;
05069          }
05070       } else
05071          t = &(n->next_in_block);
05072    }
05073 }
05074 
05075 static void stb__nptr_move_pointers(stb__memory_leaf *f, int offset, void *start, void *end)
05076 {
05077    stb__nptr **p = &f->pointers;
05078    while (*p) {
05079       stb__nptr *n = *p;
05080       if (n->ptr >= start && n->ptr <= end) {
05081          // unlink
05082          *p = n->next_in_block;
05083          n->ptr = (void *) ((int) n->ptr + offset);
05084          // move to new block
05085          f = stb__nptr_find_leaf(n->ptr);
05086          if (!f) f = stb__nptr_make_leaf(n->ptr);
05087          n->next_in_block = f->pointers;
05088          f->pointers = n;
05089       } else
05090          p = &(n->next_in_block);
05091    }
05092 }
05093 
05094 void stb_nptr_realloc(void *new_address, void *old_address, int len)
05095 {
05096    if (new_address == old_address) return;
05097 
05098    // have to move the pointers first, because moving the targets
05099    //      requires writing to the pointers-to-the-targets, and if some of those moved too,
05100    //      we need to make sure we don't write to the old memory
05101 
05102    // step one: move all pointers within the block
05103    stb__nptr_block(old_address, len, stb__nptr_move_pointers, (char *) new_address - (char *) old_address);
05104    // step two: move all targets within the block
05105    stb__nptr_block(old_address, len, stb__nptr_move_targets, (char *) new_address - (char *) old_address);
05106 }
05107 
05108 void stb_nptr_move(void *new_address, void *old_address)
05109 {
05110    stb_nptr_realloc(new_address, old_address, 1);
05111 }
05112 
05113 void stb_nptr_recache(void)
05114 {
05115    int i,j;
05116    for (i=0; i < STB__NPTR_ROOT_NUM; ++i)
05117       if (stb__memtab_root[i])
05118          for (j=0; j < STB__NPTR_NODE_NUM; ++j)
05119             if (stb__memtab_root[i]->children[j]) {
05120                stb__nptr *p = stb__memtab_root[i]->children[j]->pointers;
05121                while (p) {
05122                   stb_nptr_didset(p->ptr);
05123                   p = p->next_in_block;
05124                }
05125             }
05126 }
05127 
05128 #endif // STB_DEFINE
05129 #endif // STB_NPTR
05130 
05131 
05133 //
05134 //                             File Processing
05135 //
05136 
05137 
05138 #ifdef _WIN32
05139   #define stb_rename(x,y)   _wrename((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y))
05140 #else
05141   #define stb_rename   rename
05142 #endif
05143 
05144 STB_EXTERN void     stb_fput_varlen64(FILE *f, stb_uint64 v);
05145 STB_EXTERN stb_uint64  stb_fget_varlen64(FILE *f);
05146 STB_EXTERN int      stb_size_varlen64(stb_uint64 v);
05147 
05148 
05149 #define stb_filec    (char *) stb_file
05150 #define stb_fileu    (unsigned char *) stb_file
05151 STB_EXTERN void *  stb_file(char *filename, size_t *length);
05152 STB_EXTERN void *  stb_file_max(char *filename, size_t *length);
05153 STB_EXTERN size_t  stb_filelen(FILE *f);
05154 STB_EXTERN int     stb_filewrite(char *filename, void *data, size_t length);
05155 STB_EXTERN int     stb_filewritestr(char *filename, char *data);
05156 STB_EXTERN char ** stb_stringfile(char *filename, int *len);
05157 STB_EXTERN char ** stb_stringfile_trimmed(char *name, int *len, char comm);
05158 STB_EXTERN char *  stb_fgets(char *buffer, int buflen, FILE *f);
05159 STB_EXTERN char *  stb_fgets_malloc(FILE *f);
05160 STB_EXTERN int     stb_fexists(char *filename);
05161 STB_EXTERN int     stb_fcmp(char *s1, char *s2);
05162 STB_EXTERN int     stb_feq(char *s1, char *s2);
05163 STB_EXTERN time_t  stb_ftimestamp(char *filename);
05164 
05165 STB_EXTERN int     stb_fullpath(char *abs, int abs_size, char *rel);
05166 STB_EXTERN FILE *  stb_fopen(char *filename, const char *mode);
05167 STB_EXTERN int     stb_fclose(FILE *f, int keep);
05168 
05169 enum
05170 {
05171    stb_keep_no = 0,
05172    stb_keep_yes = 1,
05173    stb_keep_if_different = 2,
05174 };
05175 
05176 STB_EXTERN int     stb_copyfile(char *src, char *dest);
05177 
05178 STB_EXTERN void     stb_fput_varlen64(FILE *f, stb_uint64 v);
05179 STB_EXTERN stb_uint64  stb_fget_varlen64(FILE *f);
05180 STB_EXTERN int      stb_size_varlen64(stb_uint64 v);
05181 
05182 STB_EXTERN void    stb_fwrite32(FILE *f, stb_uint32 datum);
05183 STB_EXTERN void    stb_fput_varlen (FILE *f, int v);
05184 STB_EXTERN void    stb_fput_varlenu(FILE *f, unsigned int v);
05185 STB_EXTERN int     stb_fget_varlen (FILE *f);
05186 STB_EXTERN stb_uint stb_fget_varlenu(FILE *f);
05187 STB_EXTERN void    stb_fput_ranged (FILE *f, int v, int b, stb_uint n);
05188 STB_EXTERN int     stb_fget_ranged (FILE *f, int b, stb_uint n);
05189 STB_EXTERN int     stb_size_varlen (int v);
05190 STB_EXTERN int     stb_size_varlenu(unsigned int v);
05191 STB_EXTERN int     stb_size_ranged (int b, stb_uint n);
05192 
05193 STB_EXTERN int     stb_fread(void *data, size_t len, size_t count, void *f);
05194 STB_EXTERN int     stb_fwrite(void *data, size_t len, size_t count, void *f);
05195 
05196 #if 0
05197 typedef struct
05198 {
05199    FILE  *base_file;
05200    char  *buffer;
05201    int    buffer_size;
05202    int    buffer_off;
05203    int    buffer_left;
05204 } STBF;
05205 
05206 STB_EXTERN STBF *stb_tfopen(char *filename, char *mode);
05207 STB_EXTERN int stb_tfread(void *data, size_t len, size_t count, STBF *f);
05208 STB_EXTERN int stb_tfwrite(void *data, size_t len, size_t count, STBF *f);
05209 #endif
05210 
05211 #ifdef STB_DEFINE
05212 
05213 #if 0
05214 STBF *stb_tfopen(char *filename, char *mode)
05215 {
05216    STBF *z;
05217    FILE *f = stb_p_fopen(filename, mode);
05218    if (!f) return NULL;
05219    z = (STBF *) malloc(sizeof(*z));
05220    if (!z) { fclose(f); return NULL; }
05221    z->base_file = f;
05222    if (!strcmp(mode, "rb") || !strcmp(mode, "wb")) {
05223       z->buffer_size = 4096;
05224       z->buffer_off = z->buffer_size;
05225       z->buffer_left = 0;
05226       z->buffer = malloc(z->buffer_size);
05227       if (!z->buffer) { free(z); fclose(f); return NULL; }
05228    } else {
05229       z->buffer = 0;
05230       z->buffer_size = 0;
05231       z->buffer_left = 0;
05232    }
05233    return z;
05234 }
05235 
05236 int stb_tfread(void *data, size_t len, size_t count, STBF *f)
05237 {
05238    int total = len*count, done=0;
05239    if (!total) return 0;
05240    if (total <= z->buffer_left) {
05241       memcpy(data, z->buffer + z->buffer_off, total);
05242       z->buffer_off += total;
05243       z->buffer_left -= total;
05244       return count;
05245    } else {
05246       char *out = (char *) data;
05247 
05248       // consume all buffered data
05249       memcpy(data, z->buffer + z->buffer_off, z->buffer_left);
05250       done = z->buffer_left;
05251       out += z->buffer_left;
05252       z->buffer_left=0;
05253 
05254       if (total-done > (z->buffer_size >> 1)) {
05255          done += fread(out
05256       }
05257    }
05258 }
05259 #endif
05260 
05261 void stb_fwrite32(FILE *f, stb_uint32 x)
05262 {
05263    fwrite(&x, 4, 1, f);
05264 }
05265 
05266 #if defined(_WIN32)
05267    #define stb__stat   _stat
05268 #else
05269    #define stb__stat   stat
05270 #endif
05271 
05272 int stb_fexists(char *filename)
05273 {
05274    struct stb__stat buf;
05275    return stb__windows(
05276              _wstat((const wchar_t *)stb__from_utf8(filename), &buf),
05277                stat(filename,&buf)
05278           ) == 0;
05279 }
05280 
05281 time_t stb_ftimestamp(char *filename)
05282 {
05283    struct stb__stat buf;
05284    if (stb__windows(
05285              _wstat((const wchar_t *)stb__from_utf8(filename), &buf),
05286                stat(filename,&buf)
05287           ) == 0)
05288    {
05289       return buf.st_mtime;
05290    } else {
05291       return 0;
05292    }
05293 }
05294 
05295 size_t  stb_filelen(FILE *f)
05296 {
05297    long len, pos;
05298    pos = ftell(f);
05299    fseek(f, 0, SEEK_END);
05300    len = ftell(f);
05301    fseek(f, pos, SEEK_SET);
05302    return (size_t) len;
05303 }
05304 
05305 void *stb_file(char *filename, size_t *length)
05306 {
05307    FILE *f = stb__fopen(filename, "rb");
05308    char *buffer;
05309    size_t len, len2;
05310    if (!f) return NULL;
05311    len = stb_filelen(f);
05312    buffer = (char *) malloc(len+2); // nul + extra
05313    len2 = fread(buffer, 1, len, f);
05314    if (len2 == len) {
05315       if (length) *length = len;
05316       buffer[len] = 0;
05317    } else {
05318       free(buffer);
05319       buffer = NULL;
05320    }
05321    fclose(f);
05322    return buffer;
05323 }
05324 
05325 int stb_filewrite(char *filename, void *data, size_t length)
05326 {
05327    FILE *f = stb_fopen(filename, "wb");
05328    if (f) {
05329       unsigned char *data_ptr = (unsigned char *) data;
05330       size_t remaining = length;
05331       while (remaining > 0) {
05332          size_t len2 = remaining > 65536 ? 65536 : remaining;
05333          size_t len3 = fwrite(data_ptr, 1, len2, f);
05334          if (len2 != len3) {
05335             fprintf(stderr, "Failed while writing %s\n", filename);
05336             break;
05337          }
05338          remaining -= len2;
05339          data_ptr += len2;
05340       }
05341       stb_fclose(f, stb_keep_if_different);
05342    }
05343    return f != NULL;
05344 }
05345 
05346 int stb_filewritestr(char *filename, char *data)
05347 {
05348    return stb_filewrite(filename, data, strlen(data));
05349 }
05350 
05351 void *  stb_file_max(char *filename, size_t *length)
05352 {
05353    FILE *f = stb__fopen(filename, "rb");
05354    char *buffer;
05355    size_t len, maxlen;
05356    if (!f) return NULL;
05357    maxlen = *length;
05358    buffer = (char *) malloc(maxlen+1);
05359    len = fread(buffer, 1, maxlen, f);
05360    buffer[len] = 0;
05361    fclose(f);
05362    *length = len;
05363    return buffer;
05364 }
05365 
05366 char ** stb_stringfile(char *filename, int *plen)
05367 {
05368    FILE *f = stb__fopen(filename, "rb");
05369    char *buffer, **list=NULL, *s;
05370    size_t len, count, i;
05371 
05372    if (!f) return NULL;
05373    len = stb_filelen(f);
05374    buffer = (char *) malloc(len+1);
05375    len = fread(buffer, 1, len, f);
05376    buffer[len] = 0;
05377    fclose(f);
05378 
05379    // two passes through: first time count lines, second time set them
05380    for (i=0; i < 2; ++i) {
05381       s = buffer;
05382       if (i == 1)
05383          list[0] = s;
05384       count = 1;
05385       while (*s) {
05386          if (*s == '\n' || *s == '\r') {
05387             // detect if both cr & lf are together
05388             int crlf = (s[0] + s[1]) == ('\n' + '\r');
05389             if (i == 1) *s = 0;
05390             if (crlf) ++s;
05391             if (s[1]) {  // it's not over yet
05392                if (i == 1) list[count] = s+1;
05393                ++count;
05394             }
05395          }
05396          ++s;
05397       }
05398       if (i == 0) {
05399          list = (char **) malloc(sizeof(*list) * (count+1) + len+1);
05400          if (!list) return NULL;
05401          list[count] = 0;
05402          // recopy the file so there's just a single allocation to free
05403          memcpy(&list[count+1], buffer, len+1);
05404          free(buffer);
05405          buffer = (char *) &list[count+1];
05406          if (plen) *plen = (int) count;
05407       }
05408    }
05409    return list;
05410 }
05411 
05412 char ** stb_stringfile_trimmed(char *name, int *len, char comment)
05413 {
05414    int i,n,o=0;
05415    char **s = stb_stringfile(name, &n);
05416    if (s == NULL) return NULL;
05417    for (i=0; i < n; ++i) {
05418       char *p = stb_skipwhite(s[i]);
05419       if (*p && *p != comment)
05420          s[o++] = p;
05421    }
05422    s[o] = NULL;
05423    if (len) *len = o;
05424    return s;
05425 }
05426 
05427 char * stb_fgets(char *buffer, int buflen, FILE *f)
05428 {
05429    char *p;
05430    buffer[0] = 0;
05431    p = fgets(buffer, buflen, f);
05432    if (p) {
05433       int n = (int) (strlen(p)-1);
05434       if (n >= 0)
05435          if (p[n] == '\n')
05436             p[n] = 0;
05437    }
05438    return p;
05439 }
05440 
05441 char * stb_fgets_malloc(FILE *f)
05442 {
05443    // avoid reallocing for small strings
05444    char quick_buffer[800];
05445    quick_buffer[sizeof(quick_buffer)-2] = 0;
05446    if (!fgets(quick_buffer, sizeof(quick_buffer), f))
05447       return NULL;
05448 
05449    if (quick_buffer[sizeof(quick_buffer)-2] == 0) {
05450       size_t n = strlen(quick_buffer);
05451       if (n > 0 && quick_buffer[n-1] == '\n')
05452          quick_buffer[n-1] = 0;
05453       return stb_p_strdup(quick_buffer);
05454    } else {
05455       char *p;
05456       char *a = stb_p_strdup(quick_buffer);
05457       size_t len = sizeof(quick_buffer)-1;
05458 
05459       while (!feof(f)) {
05460          if (a[len-1] == '\n') break;
05461          a = (char *) realloc(a, len*2);
05462          p = &a[len];
05463          p[len-2] = 0;
05464          if (!fgets(p, (int) len, f))
05465             break;
05466          if (p[len-2] == 0) {
05467             len += strlen(p);
05468             break;
05469          }
05470          len = len + (len-1);
05471       }
05472       if (a[len-1] == '\n')
05473          a[len-1] = 0;
05474       return a;
05475    }
05476 }
05477 
05478 int stb_fullpath(char *abs, int abs_size, char *rel)
05479 {
05480    #ifdef _WIN32
05481    return _fullpath(abs, rel, abs_size) != NULL;
05482    #else
05483    if (rel[0] == '/' || rel[0] == '~') {
05484       if ((int) strlen(rel) >= abs_size)
05485          return 0;
05486       stb_p_strcpy_s(abs,65536,rel);
05487       return STB_TRUE;
05488    } else {
05489       int n;
05490       getcwd(abs, abs_size);
05491       n = strlen(abs);
05492       if (n+(int) strlen(rel)+2 <= abs_size) {
05493          abs[n] = '/';
05494          stb_p_strcpy_s(abs+n+1, 65536,rel);
05495          return STB_TRUE;
05496       } else {
05497          return STB_FALSE;
05498       }
05499    }
05500    #endif
05501 }
05502 
05503 static int stb_fcmp_core(FILE *f, FILE *g)
05504 {
05505    char buf1[1024],buf2[1024];
05506    int n1,n2, res=0;
05507 
05508    while (1) {
05509       n1 = (int) fread(buf1, 1, sizeof(buf1), f);
05510       n2 = (int) fread(buf2, 1, sizeof(buf2), g);
05511       res = memcmp(buf1,buf2,stb_min(n1,n2));
05512       if (res)
05513          break;
05514       if (n1 != n2) {
05515          res = n1 < n2 ? -1 : 1;
05516          break;
05517       }
05518       if (n1 == 0)
05519          break;
05520    }
05521 
05522    fclose(f);
05523    fclose(g);
05524    return res;
05525 }
05526 
05527 int stb_fcmp(char *s1, char *s2)
05528 {
05529    FILE *f = stb__fopen(s1, "rb");
05530    FILE *g = stb__fopen(s2, "rb");
05531 
05532    if (f == NULL || g == NULL) {
05533       if (f) fclose(f);
05534       if (g) {
05535          fclose(g);
05536          return STB_TRUE;
05537       }
05538       return f != NULL;
05539    }
05540 
05541    return stb_fcmp_core(f,g);
05542 }
05543 
05544 int stb_feq(char *s1, char *s2)
05545 {
05546    FILE *f = stb__fopen(s1, "rb");
05547    FILE *g = stb__fopen(s2, "rb");
05548 
05549    if (f == NULL || g == NULL) {
05550       if (f) fclose(f);
05551       if (g) fclose(g);
05552       return f == g;
05553    }
05554 
05555    // feq is faster because it shortcuts if they're different length
05556    if (stb_filelen(f) != stb_filelen(g)) {
05557       fclose(f);
05558       fclose(g);
05559       return 0;
05560    }
05561 
05562    return !stb_fcmp_core(f,g);
05563 }
05564 
05565 static stb_ptrmap *stb__files;
05566 
05567 typedef struct
05568 {
05569    char *temp_name;
05570    char *name;
05571    int   errors;
05572 } stb__file_data;
05573 
05574 static FILE *stb__open_temp_file(char *temp_name, char *src_name, const char *mode)
05575 {
05576    size_t p;
05577 #ifdef _MSC_VER
05578    int j;
05579 #endif
05580    FILE *f;
05581    // try to generate a temporary file in the same directory
05582    p = strlen(src_name)-1;
05583    while (p > 0 && src_name[p] != '/' && src_name[p] != '\\'
05584                 && src_name[p] != ':' && src_name[p] != '~')
05585       --p;
05586    ++p;
05587 
05588    memcpy(temp_name, src_name, p);
05589 
05590    #ifdef _MSC_VER
05591    // try multiple times to make a temp file... just in
05592    // case some other process makes the name first
05593    for (j=0; j < 32; ++j) {
05594       stb_p_strcpy_s(temp_name+p, 65536, "stmpXXXXXX");
05595       if (!stb_p_mktemp(temp_name))
05596          return 0;
05597 
05598       f = stb_p_fopen(temp_name, mode);
05599       if (f != NULL)
05600          break;
05601    }
05602    #else
05603    {
05604       stb_p_strcpy_s(temp_name+p, 65536, "stmpXXXXXX");
05605       #ifdef __MINGW32__
05606          int fd = open(stb_p_mktemp(temp_name), O_RDWR);
05607       #else
05608          int fd = mkstemp(temp_name);
05609       #endif
05610       if (fd == -1) return NULL;
05611       f = fdopen(fd, mode);
05612       if (f == NULL) {
05613          unlink(temp_name);
05614          close(fd);
05615          return NULL;
05616       }
05617    }
05618    #endif
05619    return f;
05620 }
05621 
05622 
05623 FILE *  stb_fopen(char *filename, const char *mode)
05624 {
05625    FILE *f;
05626    char name_full[4096];
05627    char temp_full[sizeof(name_full) + 12];
05628 
05629    // @TODO: if the file doesn't exist, we can also use the fastpath here
05630    if (mode[0] != 'w' && !strchr(mode, '+'))
05631       return stb__fopen(filename, mode);
05632 
05633    // save away the full path to the file so if the program
05634    // changes the cwd everything still works right! unix has
05635    // better ways to do this, but we have to work in windows
05636    name_full[0] = '\0'; // stb_fullpath reads name_full[0]
05637    if (stb_fullpath(name_full, sizeof(name_full), filename)==0)
05638       return 0;
05639 
05640    f = stb__open_temp_file(temp_full, name_full, mode);
05641    if (f != NULL) {
05642       stb__file_data *d = (stb__file_data *) malloc(sizeof(*d));
05643       if (!d) { assert(0);  /* NOTREACHED */fclose(f); return NULL; }
05644       if (stb__files == NULL) stb__files = stb_ptrmap_create();
05645       d->temp_name = stb_p_strdup(temp_full);
05646       d->name      = stb_p_strdup(name_full);
05647       d->errors    = 0;
05648       stb_ptrmap_add(stb__files, f, d);
05649       return f;
05650    }
05651 
05652    return NULL;
05653 }
05654 
05655 int     stb_fclose(FILE *f, int keep)
05656 {
05657    stb__file_data *d;
05658 
05659    int ok = STB_FALSE;
05660    if (f == NULL) return 0;
05661 
05662    if (ferror(f))
05663       keep = stb_keep_no;
05664 
05665    fclose(f);
05666 
05667    if (stb__files && stb_ptrmap_remove(stb__files, f, (void **) &d)) {
05668       if (stb__files->count == 0) {
05669          stb_ptrmap_destroy(stb__files);
05670          stb__files = NULL;
05671       }
05672    } else
05673       return STB_TRUE; // not special
05674 
05675    if (keep == stb_keep_if_different) {
05676       // check if the files are identical
05677       if (stb_feq(d->name, d->temp_name)) {
05678          keep = stb_keep_no;
05679          ok = STB_TRUE;  // report success if no change
05680       }
05681    }
05682 
05683    if (keep == stb_keep_no) {
05684       remove(d->temp_name);
05685    } else {
05686       if (!stb_fexists(d->name)) {
05687          // old file doesn't exist, so just move the new file over it
05688          stb_rename(d->temp_name, d->name);
05689       } else {
05690          // don't delete the old file yet in case there are troubles! First rename it!
05691          char preserved_old_file[4096];
05692 
05693          // generate a temp filename in the same directory (also creates it, which we don't need)
05694          FILE *dummy = stb__open_temp_file(preserved_old_file, d->name, "wb");
05695          if (dummy != NULL) {
05696             // we don't actually want the open file
05697             fclose(dummy);
05698 
05699             // discard what we just created
05700             remove(preserved_old_file);  // if this fails, there's nothing we can do, and following logic handles it as best as possible anyway
05701 
05702             // move the existing file to the preserved name
05703             if (0 != stb_rename(d->name, preserved_old_file)) {  // 0 on success
05704                // failed, state is:
05705                //    filename  -> old file
05706                //    tempname  -> new file
05707                // keep tempname around so we don't lose data
05708             } else {
05709                //  state is:
05710                //    preserved -> old file
05711                //    tempname  -> new file
05712                // move the new file to the old name
05713                if (0 == stb_rename(d->temp_name, d->name)) {
05714                   //  state is:
05715                   //    preserved -> old file
05716                   //    filename  -> new file
05717                   ok = STB_TRUE;
05718 
05719                   // 'filename -> new file' has always been the goal, so clean up
05720                   remove(preserved_old_file); // nothing to be done if it fails
05721                } else {
05722                   // couldn't rename, so try renaming preserved file back
05723 
05724                   //  state is:
05725                   //    preserved -> old file
05726                   //    tempname  -> new file
05727                   stb_rename(preserved_old_file, d->name);
05728                   // if the rename failed, there's nothing more we can do
05729                }
05730             }
05731          } else {
05732             // we couldn't get a temp filename. do this the naive way; the worst case failure here
05733             // leaves the filename pointing to nothing and the new file as a tempfile
05734             remove(d->name);
05735             stb_rename(d->temp_name, d->name);
05736          }
05737       }
05738    }
05739 
05740    free(d->temp_name);
05741    free(d->name);
05742    free(d);
05743 
05744    return ok;
05745 }
05746 
05747 int stb_copyfile(char *src, char *dest)
05748 {
05749    char raw_buffer[1024];
05750    char *buffer;
05751    int buf_size = 65536;
05752 
05753    FILE *f, *g;
05754 
05755    // if file already exists at destination, do nothing
05756    if (stb_feq(src, dest)) return STB_TRUE;
05757 
05758    // open file
05759    f = stb__fopen(src, "rb");
05760    if (f == NULL) return STB_FALSE;
05761 
05762    // open file for writing
05763    g = stb__fopen(dest, "wb");
05764    if (g == NULL) {
05765       fclose(f);
05766       return STB_FALSE;
05767    }
05768 
05769    buffer = (char *) malloc(buf_size);
05770    if (buffer == NULL) {
05771       buffer = raw_buffer;
05772       buf_size = sizeof(raw_buffer);
05773    }
05774 
05775    while (!feof(f)) {
05776       size_t n = fread(buffer, 1, buf_size, f);
05777       if (n != 0)
05778          fwrite(buffer, 1, n, g);
05779    }
05780 
05781    fclose(f);
05782    if (buffer != raw_buffer)
05783       free(buffer);
05784 
05785    fclose(g);
05786    return STB_TRUE;
05787 }
05788 
05789 // varlen:
05790 //    v' = (v >> 31) + (v < 0 ? ~v : v)<<1;  // small abs(v) => small v'
05791 // output v as big endian v'+k for v' <= k:
05792 //   1 byte :  v' <= 0x00000080          (  -64 <= v <   64)   7 bits
05793 //   2 bytes:  v' <= 0x00004000          (-8192 <= v < 8192)  14 bits
05794 //   3 bytes:  v' <= 0x00200000                               21 bits
05795 //   4 bytes:  v' <= 0x10000000                               28 bits
05796 // the number of most significant 1-bits in the first byte
05797 // equals the number of bytes after the first
05798 
05799 #define stb__varlen_xform(v)     (v<0 ? (~v << 1)+1 : (v << 1))
05800 
05801 int stb_size_varlen(int v) { return stb_size_varlenu(stb__varlen_xform(v)); }
05802 int stb_size_varlenu(unsigned int v)
05803 {
05804    if (v < 0x00000080) return 1;
05805    if (v < 0x00004000) return 2;
05806    if (v < 0x00200000) return 3;
05807    if (v < 0x10000000) return 4;
05808    return 5;
05809 }
05810 
05811 void    stb_fput_varlen(FILE *f, int v) { stb_fput_varlenu(f, stb__varlen_xform(v)); }
05812 
05813 void    stb_fput_varlenu(FILE *f, unsigned int z)
05814 {
05815    if (z >= 0x10000000) fputc(0xF0,f);
05816    if (z >= 0x00200000) fputc((z < 0x10000000 ? 0xE0 : 0)+(z>>24),f);
05817    if (z >= 0x00004000) fputc((z < 0x00200000 ? 0xC0 : 0)+(z>>16),f);
05818    if (z >= 0x00000080) fputc((z < 0x00004000 ? 0x80 : 0)+(z>> 8),f);
05819    fputc(z,f);
05820 }
05821 
05822 #define stb_fgetc(f)    ((unsigned char) fgetc(f))
05823 
05824 int     stb_fget_varlen(FILE *f)
05825 {
05826    unsigned int z = stb_fget_varlenu(f);
05827    return (z & 1) ? ~(z>>1) : (z>>1);
05828 }
05829 
05830 unsigned int stb_fget_varlenu(FILE *f)
05831 {
05832    unsigned int z;
05833    unsigned char d;
05834    d = stb_fgetc(f);
05835 
05836    if (d >= 0x80) {
05837       if (d >= 0xc0) {
05838          if (d >= 0xe0) {
05839             if (d == 0xf0) z = stb_fgetc(f) << 24;
05840             else           z = (d - 0xe0) << 24;
05841             z += stb_fgetc(f) << 16;
05842          }
05843          else
05844             z = (d - 0xc0) << 16;
05845          z += stb_fgetc(f) << 8;
05846       } else
05847          z = (d - 0x80) <<  8;
05848       z += stb_fgetc(f);
05849    } else
05850       z = d;
05851    return z;
05852 }
05853 
05854 stb_uint64   stb_fget_varlen64(FILE *f)
05855 {
05856    stb_uint64 z;
05857    unsigned char d;
05858    d = stb_fgetc(f);
05859 
05860    if (d >= 0x80) {
05861       if (d >= 0xc0) {
05862          if (d >= 0xe0) {
05863             if (d >= 0xf0) {
05864                if (d >= 0xf8) {
05865                   if (d >= 0xfc) {
05866                      if (d >= 0xfe) {
05867                         if (d >= 0xff)
05868                            z = (stb_uint64) stb_fgetc(f) << 56;
05869                         else
05870                            z = (stb_uint64) (d - 0xfe) << 56;
05871                         z |= (stb_uint64) stb_fgetc(f) << 48;
05872                      } else z = (stb_uint64) (d - 0xfc) << 48;
05873                      z |= (stb_uint64) stb_fgetc(f) << 40;
05874                   } else z = (stb_uint64) (d - 0xf8) << 40;
05875                   z |= (stb_uint64) stb_fgetc(f) << 32;
05876                } else z = (stb_uint64) (d - 0xf0) << 32;
05877                z |= (stb_uint) stb_fgetc(f) << 24;
05878             } else z = (stb_uint) (d - 0xe0) << 24;
05879             z |= (stb_uint) stb_fgetc(f) << 16;
05880          } else z = (stb_uint) (d - 0xc0) << 16;
05881          z |= (stb_uint) stb_fgetc(f) << 8;
05882       } else z = (stb_uint) (d - 0x80) << 8;
05883       z |= stb_fgetc(f);
05884    } else
05885       z = d;
05886 
05887    return (z & 1) ? ~(z >> 1) : (z >> 1);
05888 }
05889 
05890 int stb_size_varlen64(stb_uint64 v)
05891 {
05892    if (v < 0x00000080) return 1;
05893    if (v < 0x00004000) return 2;
05894    if (v < 0x00200000) return 3;
05895    if (v < 0x10000000) return 4;
05896    if (v < STB_IMM_UINT64(0x0000000800000000)) return 5;
05897    if (v < STB_IMM_UINT64(0x0000040000000000)) return 6;
05898    if (v < STB_IMM_UINT64(0x0002000000000000)) return 7;
05899    if (v < STB_IMM_UINT64(0x0100000000000000)) return 8;
05900    return 9;
05901 }
05902 
05903 void    stb_fput_varlen64(FILE *f, stb_uint64 v)
05904 {
05905    stb_uint64 z = stb__varlen_xform(v);
05906    int first=1;
05907    if (z >= STB_IMM_UINT64(0x100000000000000)) {
05908       fputc(0xff,f);
05909       first=0;
05910    }
05911    if (z >= STB_IMM_UINT64(0x02000000000000)) fputc((first ? 0xFE : 0)+(char)(z>>56),f), first=0;
05912    if (z >= STB_IMM_UINT64(0x00040000000000)) fputc((first ? 0xFC : 0)+(char)(z>>48),f), first=0;
05913    if (z >= STB_IMM_UINT64(0x00000800000000)) fputc((first ? 0xF8 : 0)+(char)(z>>40),f), first=0;
05914    if (z >= STB_IMM_UINT64(0x00000010000000)) fputc((first ? 0xF0 : 0)+(char)(z>>32),f), first=0;
05915    if (z >= STB_IMM_UINT64(0x00000000200000)) fputc((first ? 0xE0 : 0)+(char)(z>>24),f), first=0;
05916    if (z >= STB_IMM_UINT64(0x00000000004000)) fputc((first ? 0xC0 : 0)+(char)(z>>16),f), first=0;
05917    if (z >= STB_IMM_UINT64(0x00000000000080)) fputc((first ? 0x80 : 0)+(char)(z>> 8),f), first=0;
05918    fputc((char)z,f);
05919 }
05920 
05921 void    stb_fput_ranged(FILE *f, int v, int b, stb_uint n)
05922 {
05923    v -= b;
05924    if (n <= (1 << 31))
05925       assert((stb_uint) v < n);
05926    if (n > (1 << 24)) fputc(v >> 24, f);
05927    if (n > (1 << 16)) fputc(v >> 16, f);
05928    if (n > (1 <<  8)) fputc(v >>  8, f);
05929    fputc(v,f);
05930 }
05931 
05932 int     stb_fget_ranged(FILE *f, int b, stb_uint n)
05933 {
05934    unsigned int v=0;
05935    if (n > (1 << 24)) v += stb_fgetc(f) << 24;
05936    if (n > (1 << 16)) v += stb_fgetc(f) << 16;
05937    if (n > (1 <<  8)) v += stb_fgetc(f) <<  8;
05938    v += stb_fgetc(f);
05939    return b+v;
05940 }
05941 
05942 int     stb_size_ranged(int b, stb_uint n)
05943 {
05944    if (n > (1 << 24)) return 4;
05945    if (n > (1 << 16)) return 3;
05946    if (n > (1 <<  8)) return 2;
05947    return 1;
05948 }
05949 
05950 void stb_fput_string(FILE *f, char *s)
05951 {
05952    size_t len = strlen(s);
05953    stb_fput_varlenu(f, (unsigned int) len);
05954    fwrite(s, 1, len, f);
05955 }
05956 
05957 // inverse of the above algorithm
05958 char *stb_fget_string(FILE *f, void *p)
05959 {
05960    char *s;
05961    int len = stb_fget_varlenu(f);
05962    if (len > 4096) return NULL;
05963    s = p ? stb_malloc_string(p, len+1) : (char *) malloc(len+1);
05964    fread(s, 1, len, f);
05965    s[len] = 0;
05966    return s;
05967 }
05968 
05969 char *stb_strdup(char *str, void *pool)
05970 {
05971    size_t len = strlen(str);
05972    char *p = stb_malloc_string(pool, len+1);
05973    stb_p_strcpy_s(p, len+1, str);
05974    return p;
05975 }
05976 
05977 // strip the trailing '/' or '\\' from a directory so we can refer to it
05978 // as a file for _stat()
05979 char *stb_strip_final_slash(char *t)
05980 {
05981    if (t[0]) {
05982       char *z = t + strlen(t) - 1;
05983       // *z is the last character
05984       if (*z == '\\' || *z == '/')
05985          if (z != t+2 || t[1] != ':') // but don't strip it if it's e.g. "c:/"
05986             *z = 0;
05987       if (*z == '\\')
05988          *z = '/'; // canonicalize to make sure it matches db
05989    }
05990    return t;
05991 }
05992 
05993 char *stb_strip_final_slash_regardless(char *t)
05994 {
05995    if (t[0]) {
05996       char *z = t + strlen(t) - 1;
05997       // *z is the last character
05998       if (*z == '\\' || *z == '/')
05999          *z = 0;
06000       if (*z == '\\')
06001          *z = '/'; // canonicalize to make sure it matches db
06002    }
06003    return t;
06004 }
06005 #endif
06006 
06008 //
06009 //                 Options parsing
06010 //
06011 
06012 STB_EXTERN char **stb_getopt_param(int *argc, char **argv, char *param);
06013 STB_EXTERN char **stb_getopt(int *argc, char **argv);
06014 STB_EXTERN void   stb_getopt_free(char **opts);
06015 
06016 #ifdef STB_DEFINE
06017 
06018 void   stb_getopt_free(char **opts)
06019 {
06020    int i;
06021    char ** o2 = opts;
06022    for (i=0; i < stb_arr_len(o2); ++i)
06023       free(o2[i]);
06024    stb_arr_free(o2);
06025 }
06026 
06027 char **stb_getopt(int *argc, char **argv)
06028 {
06029    return stb_getopt_param(argc, argv, (char*) "");
06030 }
06031 
06032 char **stb_getopt_param(int *argc, char **argv, char *param)
06033 {
06034    char ** opts=NULL;
06035    int i,j=1;
06036    for (i=1; i < *argc; ++i) {
06037       if (argv[i][0] != '-') {
06038          argv[j++] = argv[i];
06039       } else {
06040          if (argv[i][1] == 0) { // plain - == don't parse further options
06041             ++i;
06042             while (i < *argc)
06043                argv[j++] = argv[i++];
06044             break;
06045          } else if (argv[i][1] == '-') {
06046             // copy argument through including initial '-' for clarity
06047             stb_arr_push(opts, stb_p_strdup(argv[i]));
06048          } else {
06049             int k;
06050             char *q = argv[i];  // traverse options list
06051             for (k=1; q[k]; ++k) {
06052                char *s;
06053                if (strchr(param, q[k])) {  // does it take a parameter?
06054                   char *t = &q[k+1], z = q[k];
06055                   size_t len=0;
06056                   if (*t == 0) {
06057                      if (i == *argc-1) { // takes a parameter, but none found
06058                         *argc = 0;
06059                         stb_getopt_free(opts);
06060                         return NULL;
06061                      }
06062                      t = argv[++i];
06063                   } else
06064                      k += (int) strlen(t);
06065                   len = strlen(t);
06066                   s = (char *) malloc(len+2);
06067                   if (!s) return NULL;
06068                   s[0] = z;
06069                   stb_p_strcpy_s(s+1, len+2, t);
06070                } else {
06071                   // no parameter
06072                   s = (char *) malloc(2);
06073                   if (!s) return NULL;
06074                   s[0] = q[k];
06075                   s[1] = 0;
06076                }
06077                stb_arr_push(opts, s);
06078             }
06079          }
06080       }
06081    }
06082    stb_arr_push(opts, NULL);
06083    *argc = j;
06084    return opts;
06085 }
06086 #endif
06087 
06088 
06090 //
06091 //                 Portable directory reading
06092 //
06093 
06094 STB_EXTERN char **stb_readdir_files  (char *dir);
06095 STB_EXTERN char **stb_readdir_files_mask(char *dir, char *wild);
06096 STB_EXTERN char **stb_readdir_subdirs(char *dir);
06097 STB_EXTERN char **stb_readdir_subdirs_mask(char *dir, char *wild);
06098 STB_EXTERN void   stb_readdir_free   (char **files);
06099 STB_EXTERN char **stb_readdir_recursive(char *dir, char *filespec);
06100 STB_EXTERN void stb_delete_directory_recursive(char *dir);
06101 
06102 #ifdef STB_DEFINE
06103 
06104 #ifdef _MSC_VER
06105 #include <io.h>
06106 #else
06107 #include <unistd.h>
06108 #include <dirent.h>
06109 #endif
06110 
06111 void stb_readdir_free(char **files)
06112 {
06113    char **f2 = files;
06114    int i;
06115    for (i=0; i < stb_arr_len(f2); ++i)
06116       free(f2[i]);
06117    stb_arr_free(f2);
06118 }
06119 
06120 static int isdotdirname(char *name)
06121 {
06122    if (name[0] == '.')
06123       return (name[1] == '.') ? !name[2] : !name[1];
06124    return 0;
06125 }
06126 
06127 STB_EXTERN int stb_wildmatchi(char *expr, char *candidate);
06128 static char **readdir_raw(char *dir, int return_subdirs, char *mask)
06129 {
06130    char **results = NULL;
06131    char buffer[4096], with_slash[4096];
06132    size_t n;
06133 
06134    #ifdef _MSC_VER
06135       stb__wchar *ws;
06136       struct _wfinddata_t data;
06137    #ifdef _WIN64
06138       const intptr_t none = -1;
06139       intptr_t z;
06140    #else
06141       const long none = -1;
06142       long z;
06143    #endif
06144    #else // !_MSC_VER
06145       const DIR *none = NULL;
06146       DIR *z;
06147    #endif
06148 
06149    n = stb_strscpy(buffer,dir,sizeof(buffer));
06150    if (!n || n >= sizeof(buffer))
06151       return NULL;
06152    stb_fixpath(buffer);
06153    n--;
06154 
06155    if (n > 0 && (buffer[n-1] != '/')) {
06156       buffer[n++] = '/';
06157    }
06158    buffer[n] = 0;
06159    if (!stb_strscpy(with_slash,buffer,sizeof(with_slash)))
06160       return NULL;
06161 
06162    #ifdef _MSC_VER
06163       if (!stb_strscpy(buffer+n,"*.*",sizeof(buffer)-n))
06164          return NULL;
06165       ws = stb__from_utf8(buffer);
06166       z = _wfindfirst((const wchar_t *)ws, &data);
06167    #else
06168       z = opendir(dir);
06169    #endif
06170 
06171    if (z != none) {
06172       int nonempty = STB_TRUE;
06173       #ifndef _MSC_VER
06174       struct dirent *data = readdir(z);
06175       nonempty = (data != NULL);
06176       #endif
06177 
06178       if (nonempty) {
06179 
06180          do {
06181             int is_subdir;
06182             #ifdef _MSC_VER
06183             char *name = stb__to_utf8((stb__wchar *)data.name);
06184             if (name == NULL) {
06185                fprintf(stderr, "%s to convert '%S' to %s!\n", "Unable", data.name, "utf8");
06186                continue;
06187             }
06188             is_subdir = !!(data.attrib & _A_SUBDIR);
06189             #else
06190             char *name = data->d_name;
06191             if (!stb_strscpy(buffer+n,name,sizeof(buffer)-n))
06192                break;
06193             // Could follow DT_LNK, but would need to check for recursive links.
06194             is_subdir = !!(data->d_type & DT_DIR);
06195             #endif
06196 
06197             if (is_subdir == return_subdirs) {
06198                if (!is_subdir || !isdotdirname(name)) {
06199                   if (!mask || stb_wildmatchi(mask, name)) {
06200                      char buffer[4096],*p=buffer;
06201                      if ( stb_snprintf(buffer, sizeof(buffer), "%s%s", with_slash, name) < 0 )
06202                         break;
06203                      if (buffer[0] == '.' && buffer[1] == '/')
06204                         p = buffer+2;
06205                      stb_arr_push(results, stb_p_strdup(p));
06206                   }
06207                }
06208             }
06209          }
06210          #ifdef _MSC_VER
06211          while (0 == _wfindnext(z, &data));
06212          #else
06213          while ((data = readdir(z)) != NULL);
06214          #endif
06215       }
06216       #ifdef _MSC_VER
06217          _findclose(z);
06218       #else
06219          closedir(z);
06220       #endif
06221    }
06222    return results;
06223 }
06224 
06225 char **stb_readdir_files  (char *dir) { return readdir_raw(dir, 0, NULL); }
06226 char **stb_readdir_subdirs(char *dir) { return readdir_raw(dir, 1, NULL); }
06227 char **stb_readdir_files_mask(char *dir, char *wild) { return readdir_raw(dir, 0, wild); }
06228 char **stb_readdir_subdirs_mask(char *dir, char *wild) { return readdir_raw(dir, 1, wild); }
06229 
06230 int stb__rec_max=0x7fffffff;
06231 static char **stb_readdir_rec(char **sofar, char *dir, char *filespec)
06232 {
06233    char **files;
06234    char ** dirs;
06235    char **p;
06236 
06237    if (stb_arr_len(sofar) >= stb__rec_max) return sofar;
06238 
06239    files = stb_readdir_files_mask(dir, filespec);
06240    stb_arr_for(p, files) {
06241       stb_arr_push(sofar, stb_p_strdup(*p));
06242       if (stb_arr_len(sofar) >= stb__rec_max) break;
06243    }
06244    stb_readdir_free(files);
06245    if (stb_arr_len(sofar) >= stb__rec_max) return sofar;
06246 
06247    dirs = stb_readdir_subdirs(dir);
06248    stb_arr_for(p, dirs)
06249       sofar = stb_readdir_rec(sofar, *p, filespec);
06250    stb_readdir_free(dirs);
06251    return sofar;
06252 }
06253 
06254 char **stb_readdir_recursive(char *dir, char *filespec)
06255 {
06256    return stb_readdir_rec(NULL, dir, filespec);
06257 }
06258 
06259 void stb_delete_directory_recursive(char *dir)
06260 {
06261    char **list = stb_readdir_subdirs(dir);
06262    int i;
06263    for (i=0; i < stb_arr_len(list); ++i)
06264       stb_delete_directory_recursive(list[i]);
06265    stb_arr_free(list);
06266    list = stb_readdir_files(dir);
06267    for (i=0; i < stb_arr_len(list); ++i)
06268       if (!remove(list[i])) {
06269          // on windows, try again after making it writeable; don't ALWAYS
06270          // do this first since that would be slow in the normal case
06271          #ifdef _MSC_VER
06272          _chmod(list[i], _S_IWRITE);
06273          remove(list[i]);
06274          #endif
06275       }
06276    stb_arr_free(list);
06277    stb__windows(_rmdir,rmdir)(dir);
06278 }
06279 
06280 #endif
06281 
06283 //
06284 //   construct trees from filenames; useful for cmirror summaries
06285 
06286 typedef struct stb_dirtree2 stb_dirtree2;
06287 
06288 struct stb_dirtree2
06289 {
06290    stb_dirtree2 **subdirs;
06291 
06292    // make convenient for stb_summarize_tree
06293    int num_subdir;
06294    float weight;
06295 
06296    // actual data
06297    char *fullpath;
06298    char *relpath;
06299    char **files;
06300 };
06301 
06302 STB_EXTERN stb_dirtree2 *stb_dirtree2_from_files_relative(char *src, char **filelist, int count);
06303 STB_EXTERN stb_dirtree2 *stb_dirtree2_from_files(char **filelist, int count);
06304 STB_EXTERN int stb_dir_is_prefix(char *dir, int dirlen, char *file);
06305 
06306 #ifdef STB_DEFINE
06307 
06308 int stb_dir_is_prefix(char *dir, int dirlen, char *file)
06309 {
06310    if (dirlen == 0) return STB_TRUE;
06311    if (stb_strnicmp(dir, file, dirlen)) return STB_FALSE;
06312    if (file[dirlen] == '/' || file[dirlen] == '\\') return STB_TRUE;
06313    return STB_FALSE;
06314 }
06315 
06316 stb_dirtree2 *stb_dirtree2_from_files_relative(char *src, char **filelist, int count)
06317 {
06318    char buffer1[1024];
06319    int i;
06320    int dlen = (int) strlen(src), elen;
06321    stb_dirtree2 *d;
06322    char ** descendents = NULL;
06323    char ** files = NULL;
06324    char *s;
06325    if (!count) return NULL;
06326    // first find all the ones that belong here... note this is will take O(NM) with N files and M subdirs
06327    for (i=0; i < count; ++i) {
06328       if (stb_dir_is_prefix(src, dlen, filelist[i])) {
06329          stb_arr_push(descendents, filelist[i]);
06330       }
06331    }
06332    if (descendents == NULL)
06333       return NULL;
06334    elen = dlen;
06335    // skip a leading slash
06336    if (elen == 0 && (descendents[0][0] == '/' || descendents[0][0] == '\\'))
06337       ++elen;
06338    else if (elen)
06339       ++elen;
06340    // now extract all the ones that have their root here
06341    for (i=0; i < stb_arr_len(descendents);) {
06342       if (!stb_strchr2(descendents[i]+elen, '/', '\\')) {
06343          stb_arr_push(files, descendents[i]);
06344          descendents[i] = descendents[stb_arr_len(descendents)-1];
06345          stb_arr_pop(descendents);
06346       } else
06347          ++i;
06348    }
06349    // now create a record
06350    d = (stb_dirtree2 *) malloc(sizeof(*d));
06351    d->files = files;
06352    d->subdirs = NULL;
06353    d->fullpath = stb_p_strdup(src);
06354    s = stb_strrchr2(d->fullpath, '/', '\\');
06355    if (s)
06356       ++s;
06357    else
06358       s = d->fullpath;
06359    d->relpath = s;
06360    // now create the children
06361    qsort(descendents, stb_arr_len(descendents), sizeof(char *), stb_qsort_stricmp(0));
06362    buffer1[0] = 0;
06363    for (i=0; i < stb_arr_len(descendents); ++i) {
06364       char buffer2[1024];
06365       char *s = descendents[i] + elen, *t;
06366       t = stb_strchr2(s, '/', '\\');
06367       assert(t);
06368       stb_strncpy(buffer2, descendents[i], (int) (t-descendents[i]+1));
06369       if (stb_stricmp(buffer1, buffer2)) {
06370          stb_dirtree2 *t = stb_dirtree2_from_files_relative(buffer2, descendents, stb_arr_len(descendents));
06371          assert(t != NULL);
06372          stb_p_strcpy_s(buffer1, sizeof(buffer1), buffer2);
06373          stb_arr_push(d->subdirs, t);
06374       }
06375    }
06376    d->num_subdir = stb_arr_len(d->subdirs);
06377    d->weight = 0;
06378    return d;
06379 }
06380 
06381 stb_dirtree2 *stb_dirtree2_from_files(char **filelist, int count)
06382 {
06383    return stb_dirtree2_from_files_relative((char*) "", filelist, count);
06384 }
06385 #endif
06386 
06388 //
06389 //                 Checksums: CRC-32, ADLER32, SHA-1
06390 //
06391 //    CRC-32 and ADLER32 allow streaming blocks
06392 //    SHA-1 requires either a complete buffer, max size 2^32 - 73
06393 //          or it can checksum directly from a file, max 2^61
06394 
06395 #define STB_ADLER32_SEED   1
06396 #define STB_CRC32_SEED     0    // note that we logical NOT this in the code
06397 
06398 STB_EXTERN stb_uint
06399   stb_adler32(stb_uint adler32, stb_uchar *buffer, stb_uint buflen);
06400 STB_EXTERN stb_uint
06401   stb_crc32_block(stb_uint crc32, stb_uchar *buffer, stb_uint len);
06402 STB_EXTERN stb_uint stb_crc32(unsigned char *buffer, stb_uint len);
06403 
06404 STB_EXTERN void stb_sha1(
06405   unsigned char output[20], unsigned char *buffer, unsigned int len);
06406 STB_EXTERN int stb_sha1_file(unsigned char output[20], char *file);
06407 
06408 STB_EXTERN void stb_sha1_readable(char display[27], unsigned char sha[20]);
06409 
06410 #ifdef STB_DEFINE
06411 stb_uint stb_crc32_block(stb_uint crc, unsigned char *buffer, stb_uint len)
06412 {
06413    static stb_uint crc_table[256];
06414    stb_uint i,j,s;
06415    crc = ~crc;
06416 
06417    if (crc_table[1] == 0)
06418       for(i=0; i < 256; i++) {
06419          for (s=i, j=0; j < 8; ++j)
06420             s = (s >> 1) ^ (s & 1 ? 0xedb88320 : 0);
06421          crc_table[i] = s;
06422       }
06423    for (i=0; i < len; ++i)
06424       crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
06425    return ~crc;
06426 }
06427 
06428 stb_uint stb_crc32(unsigned char *buffer, stb_uint len)
06429 {
06430    return stb_crc32_block(0, buffer, len);
06431 }
06432 
06433 stb_uint stb_adler32(stb_uint adler32, stb_uchar *buffer, stb_uint buflen)
06434 {
06435    const unsigned long ADLER_MOD = 65521;
06436    unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
06437    unsigned long blocklen, i;
06438 
06439    blocklen = buflen % 5552;
06440    while (buflen) {
06441       for (i=0; i + 7 < blocklen; i += 8) {
06442          s1 += buffer[0], s2 += s1;
06443          s1 += buffer[1], s2 += s1;
06444          s1 += buffer[2], s2 += s1;
06445          s1 += buffer[3], s2 += s1;
06446          s1 += buffer[4], s2 += s1;
06447          s1 += buffer[5], s2 += s1;
06448          s1 += buffer[6], s2 += s1;
06449          s1 += buffer[7], s2 += s1;
06450 
06451          buffer += 8;
06452       }
06453 
06454       for (; i < blocklen; ++i)
06455          s1 += *buffer++, s2 += s1;
06456 
06457       s1 %= ADLER_MOD, s2 %= ADLER_MOD;
06458       buflen -= blocklen;
06459       blocklen = 5552;
06460    }
06461    return (s2 << 16) + s1;
06462 }
06463 
06464 static void stb__sha1(stb_uchar *chunk, stb_uint h[5])
06465 {
06466    int i;
06467    stb_uint a,b,c,d,e;
06468    stb_uint w[80];
06469 
06470    for (i=0; i < 16; ++i)
06471       w[i] = stb_big32(&chunk[i*4]);
06472    for (i=16; i < 80; ++i) {
06473       stb_uint t;
06474       t = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
06475       w[i] = (t + t) | (t >> 31);
06476    }
06477 
06478    a = h[0];
06479    b = h[1];
06480    c = h[2];
06481    d = h[3];
06482    e = h[4];
06483 
06484    #define STB__SHA1(k,f)                                            \
06485    {                                                                 \
06486       stb_uint temp = (a << 5) + (a >> 27) + (f) + e + (k) + w[i];  \
06487       e = d;                                                       \
06488       d = c;                                                     \
06489       c = (b << 30) + (b >> 2);                               \
06490       b = a;                                              \
06491       a = temp;                                    \
06492    }
06493 
06494    i=0;
06495    for (; i < 20; ++i) STB__SHA1(0x5a827999, d ^ (b & (c ^ d))       );
06496    for (; i < 40; ++i) STB__SHA1(0x6ed9eba1, b ^ c ^ d               );
06497    for (; i < 60; ++i) STB__SHA1(0x8f1bbcdc, (b & c) + (d & (b ^ c)) );
06498    for (; i < 80; ++i) STB__SHA1(0xca62c1d6, b ^ c ^ d               );
06499 
06500    #undef STB__SHA1
06501 
06502    h[0] += a;
06503    h[1] += b;
06504    h[2] += c;
06505    h[3] += d;
06506    h[4] += e;
06507 }
06508 
06509 void stb_sha1(stb_uchar output[20], stb_uchar *buffer, stb_uint len)
06510 {
06511    unsigned char final_block[128];
06512    stb_uint end_start, final_len, j;
06513    int i;
06514 
06515    stb_uint h[5];
06516 
06517    h[0] = 0x67452301;
06518    h[1] = 0xefcdab89;
06519    h[2] = 0x98badcfe;
06520    h[3] = 0x10325476;
06521    h[4] = 0xc3d2e1f0;
06522 
06523    // we need to write padding to the last one or two
06524    // blocks, so build those first into 'final_block'
06525 
06526    // we have to write one special byte, plus the 8-byte length
06527 
06528    // compute the block where the data runs out
06529    end_start = len & ~63;
06530 
06531    // compute the earliest we can encode the length
06532    if (((len+9) & ~63) == end_start) {
06533       // it all fits in one block, so fill a second-to-last block
06534       end_start -= 64;
06535    }
06536 
06537    final_len = end_start + 128;
06538 
06539    // now we need to copy the data in
06540    assert(end_start + 128 >= len+9);
06541    assert(end_start < len || len < 64-9);
06542 
06543    j = 0;
06544    if (end_start > len)
06545       j = (stb_uint) - (int) end_start;
06546 
06547    for (; end_start + j < len; ++j)
06548       final_block[j] = buffer[end_start + j];
06549    final_block[j++] = 0x80;
06550    while (j < 128-5) // 5 byte length, so write 4 extra padding bytes
06551       final_block[j++] = 0;
06552    // big-endian size
06553    final_block[j++] = len >> 29;
06554    final_block[j++] = len >> 21;
06555    final_block[j++] = len >> 13;
06556    final_block[j++] = len >>  5;
06557    final_block[j++] = len <<  3;
06558    assert(j == 128 && end_start + j == final_len);
06559 
06560    for (j=0; j < final_len; j += 64) { // 512-bit chunks
06561       if (j+64 >= end_start+64)
06562          stb__sha1(&final_block[j - end_start], h);
06563       else
06564          stb__sha1(&buffer[j], h);
06565    }
06566 
06567    for (i=0; i < 5; ++i) {
06568       output[i*4 + 0] = h[i] >> 24;
06569       output[i*4 + 1] = h[i] >> 16;
06570       output[i*4 + 2] = h[i] >>  8;
06571       output[i*4 + 3] = h[i] >>  0;
06572    }
06573 }
06574 
06575 #ifdef _MSC_VER
06576 int stb_sha1_file(stb_uchar output[20], char *file)
06577 {
06578    int i;
06579    stb_uint64 length=0;
06580    unsigned char buffer[128];
06581 
06582    FILE *f = stb__fopen(file, "rb");
06583    stb_uint h[5];
06584 
06585    if (f == NULL) return 0; // file not found
06586 
06587    h[0] = 0x67452301;
06588    h[1] = 0xefcdab89;
06589    h[2] = 0x98badcfe;
06590    h[3] = 0x10325476;
06591    h[4] = 0xc3d2e1f0;
06592 
06593    for(;;) {
06594       size_t n = fread(buffer, 1, 64, f);
06595       if (n == 64) {
06596          stb__sha1(buffer, h);
06597          length += n;
06598       } else {
06599          int block = 64;
06600 
06601          length += n;
06602 
06603          buffer[n++] = 0x80;
06604 
06605          // if there isn't enough room for the length, double the block
06606          if (n + 8 > 64)
06607             block = 128;
06608 
06609          // pad to end
06610          memset(buffer+n, 0, block-8-n);
06611 
06612          i = block - 8;
06613          buffer[i++] = (stb_uchar) (length >> 53);
06614          buffer[i++] = (stb_uchar) (length >> 45);
06615          buffer[i++] = (stb_uchar) (length >> 37);
06616          buffer[i++] = (stb_uchar) (length >> 29);
06617          buffer[i++] = (stb_uchar) (length >> 21);
06618          buffer[i++] = (stb_uchar) (length >> 13);
06619          buffer[i++] = (stb_uchar) (length >>  5);
06620          buffer[i++] = (stb_uchar) (length <<  3);
06621          assert(i == block);
06622          stb__sha1(buffer, h);
06623          if (block == 128)
06624             stb__sha1(buffer+64, h);
06625          else
06626             assert(block == 64);
06627          break;
06628       }
06629    }
06630    fclose(f);
06631 
06632    for (i=0; i < 5; ++i) {
06633       output[i*4 + 0] = h[i] >> 24;
06634       output[i*4 + 1] = h[i] >> 16;
06635       output[i*4 + 2] = h[i] >>  8;
06636       output[i*4 + 3] = h[i] >>  0;
06637    }
06638 
06639    return 1;
06640 }
06641 #endif // _MSC_VER
06642 
06643 // client can truncate this wherever they like
06644 void stb_sha1_readable(char display[27], unsigned char sha[20])
06645 {
06646    char encoding[65] = "0123456789abcdefghijklmnopqrstuv"
06647                        "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%$";
06648    int num_bits = 0, acc=0;
06649    int i=0,o=0;
06650    while (o < 26) {
06651       int v;
06652       // expand the accumulator
06653       if (num_bits < 6) {
06654          assert(i != 20);
06655          acc += sha[i++] << num_bits;
06656          num_bits += 8;
06657       }
06658       v = acc & ((1 << 6) - 1);
06659       display[o++] = encoding[v];
06660       acc >>= 6;
06661       num_bits -= 6;
06662    }
06663    assert(num_bits == 20*8 - 26*6);
06664    display[o++] = encoding[acc];
06665 }
06666 
06667 #endif // STB_DEFINE
06668 
06670 //
06671 // simplified WINDOWS registry interface... hopefully
06672 // we'll never actually use this?
06673 
06674 #if defined(_WIN32)
06675 
06676 STB_EXTERN void * stb_reg_open(const char *mode, const char *where); // mode: "rHKLM" or "rHKCU" or "w.."
06677 STB_EXTERN void   stb_reg_close(void *reg);
06678 STB_EXTERN int    stb_reg_read(void *zreg, const char *str, void *data, unsigned long len);
06679 STB_EXTERN int    stb_reg_read_string(void *zreg, const char *str, char *data, int len);
06680 STB_EXTERN void   stb_reg_write(void *zreg, const char *str, const void *data, unsigned long len);
06681 STB_EXTERN void   stb_reg_write_string(void *zreg, const char *str, const char *data);
06682 
06683 #if defined(STB_DEFINE) && !defined(STB_NO_REGISTRY)
06684 
06685 #define STB_HAS_REGISTRY
06686 
06687 #ifndef _WINDOWS_
06688 
06689 #define HKEY void *
06690 
06691 STB_EXTERN __declspec(dllimport) long __stdcall RegCloseKey ( HKEY hKey );
06692 STB_EXTERN __declspec(dllimport) long __stdcall RegCreateKeyExA ( HKEY hKey, const char * lpSubKey,
06693     int  Reserved, char * lpClass, int  dwOptions,
06694     int samDesired, void *lpSecurityAttributes,     HKEY * phkResult,     int * lpdwDisposition );
06695 STB_EXTERN __declspec(dllimport) long __stdcall RegDeleteKeyA ( HKEY hKey, const char * lpSubKey );
06696 STB_EXTERN __declspec(dllimport) long __stdcall RegQueryValueExA ( HKEY hKey, const char * lpValueName,
06697     int * lpReserved, unsigned long * lpType, unsigned char * lpData, unsigned long * lpcbData );
06698 STB_EXTERN __declspec(dllimport) long __stdcall RegSetValueExA ( HKEY hKey, const char * lpValueName,
06699     int  Reserved, int  dwType, const unsigned char* lpData, int  cbData );
06700 STB_EXTERN __declspec(dllimport) long __stdcall  RegOpenKeyExA ( HKEY hKey, const char * lpSubKey,
06701     int ulOptions, int samDesired, HKEY * phkResult );
06702 
06703 #endif // _WINDOWS_
06704 
06705 #define STB__REG_OPTION_NON_VOLATILE  0
06706 #define STB__REG_KEY_ALL_ACCESS       0x000f003f
06707 #define STB__REG_KEY_READ             0x00020019
06708 
06709 #ifdef _M_AMD64
06710 #define STB__HKEY_CURRENT_USER        0x80000001ull
06711 #define STB__HKEY_LOCAL_MACHINE       0x80000002ull
06712 #else
06713 #define STB__HKEY_CURRENT_USER        0x80000001
06714 #define STB__HKEY_LOCAL_MACHINE       0x80000002
06715 #endif
06716 
06717 void *stb_reg_open(const char *mode, const char *where)
06718 {
06719    long res;
06720    HKEY base;
06721    HKEY zreg;
06722    if (!stb_stricmp(mode+1, "cu") || !stb_stricmp(mode+1, "hkcu"))
06723       base = (HKEY) STB__HKEY_CURRENT_USER;
06724    else if (!stb_stricmp(mode+1, "lm") || !stb_stricmp(mode+1, "hklm"))
06725       base = (HKEY) STB__HKEY_LOCAL_MACHINE;
06726    else
06727       return NULL;
06728 
06729    if (mode[0] == 'r')
06730       res = RegOpenKeyExA(base, where, 0, STB__REG_KEY_READ, &zreg);
06731    else if (mode[0] == 'w')
06732       res = RegCreateKeyExA(base, where,  0, NULL, STB__REG_OPTION_NON_VOLATILE, STB__REG_KEY_ALL_ACCESS, NULL, &zreg, NULL);
06733    else
06734       return NULL;
06735 
06736    return res ? NULL : zreg;
06737 }
06738 
06739 void stb_reg_close(void *reg)
06740 {
06741    RegCloseKey((HKEY) reg);
06742 }
06743 
06744 #define STB__REG_SZ         1
06745 #define STB__REG_BINARY     3
06746 #define STB__REG_DWORD      4
06747 
06748 int stb_reg_read(void *zreg, const char *str, void *data, unsigned long len)
06749 {
06750    unsigned long type;
06751    unsigned long alen = len;
06752    if (0 == RegQueryValueExA((HKEY) zreg, str, 0, &type, (unsigned char *) data, &len))
06753       if (type == STB__REG_BINARY || type == STB__REG_SZ || type == STB__REG_DWORD) {
06754          if (len < alen)
06755             *((char *) data + len) = 0;
06756          return 1;
06757       }
06758    return 0;
06759 }
06760 
06761 void stb_reg_write(void *zreg, const char *str, const void *data, unsigned long len)
06762 {
06763    if (zreg)
06764       RegSetValueExA((HKEY) zreg, str, 0, STB__REG_BINARY, (const unsigned char *) data, len);
06765 }
06766 
06767 int stb_reg_read_string(void *zreg, const char *str, char *data, int len)
06768 {
06769    if (!stb_reg_read(zreg, str, data, len)) return 0;
06770    data[len-1] = 0; // force a 0 at the end of the string no matter what
06771    return 1;
06772 }
06773 
06774 void stb_reg_write_string(void *zreg, const char *str, const char *data)
06775 {
06776    if (zreg)
06777       RegSetValueExA((HKEY) zreg, str, 0, STB__REG_SZ, (const unsigned char *)  data, (int) strlen(data)+1);
06778 }
06779 #endif  // STB_DEFINE
06780 #endif  // _WIN32
06781 
06782 
06784 //
06785 //     stb_cfg - This is like the registry, but the config info
06786 //               is all stored in plain old files where we can
06787 //               backup and restore them easily. The LOCATION of
06788 //               the config files is gotten from... the registry!
06789 
06790 #ifndef STB_NO_STB_STRINGS
06791 typedef struct stb_cfg_st stb_cfg;
06792 
06793 STB_EXTERN stb_cfg * stb_cfg_open(char *config, const char *mode); // mode = "r", "w"
06794 STB_EXTERN void      stb_cfg_close(stb_cfg *cfg);
06795 STB_EXTERN int       stb_cfg_read(stb_cfg *cfg, char *key, void *value, int len);
06796 STB_EXTERN void      stb_cfg_write(stb_cfg *cfg, char *key, void *value, int len);
06797 STB_EXTERN int       stb_cfg_read_string(stb_cfg *cfg, char *key, char *value, int len);
06798 STB_EXTERN void      stb_cfg_write_string(stb_cfg *cfg, char *key, char *value);
06799 STB_EXTERN int       stb_cfg_delete(stb_cfg *cfg, char *key);
06800 STB_EXTERN void      stb_cfg_set_directory(char *dir);
06801 
06802 #ifdef STB_DEFINE
06803 
06804 typedef struct
06805 {
06806    char *key;
06807    void *value;
06808    int value_len;
06809 } stb__cfg_item;
06810 
06811 struct stb_cfg_st
06812 {
06813    stb__cfg_item *data;
06814    char *loaded_file;   // this needs to be freed
06815    FILE *f; // write the data to this file on close
06816 };
06817 
06818 static const char *stb__cfg_sig = "sTbCoNfIg!\0\0";
06819 static char stb__cfg_dir[512];
06820 STB_EXTERN void stb_cfg_set_directory(char *dir)
06821 {
06822    stb_p_strcpy_s(stb__cfg_dir, sizeof(stb__cfg_dir), dir);
06823 }
06824 
06825 STB_EXTERN stb_cfg * stb_cfg_open(char *config, const char *mode)
06826 {
06827    size_t len;
06828    stb_cfg *z;
06829    char file[512];
06830    if (mode[0] != 'r' && mode[0] != 'w') return NULL;
06831 
06832    if (!stb__cfg_dir[0]) {
06833       #ifdef _WIN32
06834       stb_p_strcpy_s(stb__cfg_dir, sizeof(stb__cfg_dir), "c:/stb");
06835       #else
06836       strcpy(stb__cfg_dir, "~/.stbconfig");
06837       #endif
06838 
06839       #ifdef STB_HAS_REGISTRY
06840       {
06841          void *reg = stb_reg_open("rHKLM", "Software\\SilverSpaceship\\stb");
06842          if (reg) {
06843             stb_reg_read_string(reg, "config_dir", stb__cfg_dir, sizeof(stb__cfg_dir));
06844             stb_reg_close(reg);
06845          }
06846       }
06847       #endif
06848    }
06849 
06850    stb_p_sprintf(file stb_p_size(sizeof(file)), "%s/%s.cfg", stb__cfg_dir, config);
06851 
06852    z = (stb_cfg *) stb_malloc(0, sizeof(*z));
06853    z->data = NULL;
06854 
06855    z->loaded_file = stb_filec(file, &len);
06856    if (z->loaded_file) {
06857       char *s = z->loaded_file;
06858       if (!memcmp(s, stb__cfg_sig, 12)) {
06859          char *s = z->loaded_file + 12;
06860          while (s < z->loaded_file + len) {
06861             stb__cfg_item a;
06862             int n = *(stb_int16 *) s;
06863             a.key = s+2;
06864             s = s+2 + n;
06865             a.value_len = *(int *) s;
06866             s += 4;
06867             a.value = s;
06868             s += a.value_len;
06869             stb_arr_push(z->data, a);
06870          }
06871          assert(s == z->loaded_file + len);
06872       }
06873    }
06874 
06875    if (mode[0] == 'w')
06876       z->f = stb_p_fopen(file, "wb");
06877    else
06878       z->f = NULL;
06879 
06880    return z;
06881 }
06882 
06883 void stb_cfg_close(stb_cfg *z)
06884 {
06885    if (z->f) {
06886       int i;
06887       // write the file out
06888       fwrite(stb__cfg_sig, 12, 1, z->f);
06889       for (i=0; i < stb_arr_len(z->data); ++i) {
06890          stb_int16 n = (stb_int16) strlen(z->data[i].key)+1;
06891          fwrite(&n, 2, 1, z->f);
06892          fwrite(z->data[i].key, n, 1, z->f);
06893          fwrite(&z->data[i].value_len, 4, 1, z->f);
06894          fwrite(z->data[i].value, z->data[i].value_len, 1, z->f);
06895       }
06896       fclose(z->f);
06897    }
06898    stb_arr_free(z->data);
06899    stb_free(z);
06900 }
06901 
06902 int stb_cfg_read(stb_cfg *z, char *key, void *value, int len)
06903 {
06904    int i;
06905    for (i=0; i < stb_arr_len(z->data); ++i) {
06906       if (!stb_stricmp(z->data[i].key, key)) {
06907          int n = stb_min(len, z->data[i].value_len);
06908          memcpy(value, z->data[i].value, n);
06909          if (n < len)
06910             *((char *) value + n) = 0;
06911          return 1;
06912       }
06913    }
06914    return 0;
06915 }
06916 
06917 void stb_cfg_write(stb_cfg *z, char *key, void *value, int len)
06918 {
06919    int i;
06920    for (i=0; i < stb_arr_len(z->data); ++i)
06921       if (!stb_stricmp(z->data[i].key, key))
06922          break;
06923    if (i == stb_arr_len(z->data)) {
06924       stb__cfg_item p;
06925       p.key = stb_strdup(key, z);
06926       p.value = NULL;
06927       p.value_len = 0;
06928       stb_arr_push(z->data, p);
06929    }
06930    z->data[i].value = stb_malloc(z, len);
06931    z->data[i].value_len = len;
06932    memcpy(z->data[i].value, value, len);
06933 }
06934 
06935 int stb_cfg_delete(stb_cfg *z, char *key)
06936 {
06937    int i;
06938    for (i=0; i < stb_arr_len(z->data); ++i)
06939       if (!stb_stricmp(z->data[i].key, key)) {
06940          stb_arr_fastdelete(z->data, i);
06941          return 1;
06942       }
06943    return 0;
06944 }
06945 
06946 int stb_cfg_read_string(stb_cfg *z, char *key, char *value, int len)
06947 {
06948    if (!stb_cfg_read(z, key, value, len)) return 0;
06949    value[len-1] = 0;
06950    return 1;
06951 }
06952 
06953 void stb_cfg_write_string(stb_cfg *z, char *key, char *value)
06954 {
06955    stb_cfg_write(z, key, value, (int) strlen(value)+1);
06956 }
06957 #endif
06958 
06960 //
06961 //     stb_dirtree  - load a description of a directory tree
06962 //                      uses a cache and stat()s the directories for changes
06963 //                      MUCH faster on NTFS, _wrong_ on FAT32, so should
06964 //                      ignore the db on FAT32
06965 
06966 #ifdef _WIN32
06967 
06968 typedef struct
06969 {
06970    char   * path;           // full path from passed-in root
06971    time_t   last_modified;
06972    int      num_files;
06973    int      flag;
06974 } stb_dirtree_dir;
06975 
06976 typedef struct
06977 {
06978    char *name;              // name relative to path
06979    int   dir;               // index into dirs[] array
06980    stb_int64 size;      // size, max 4GB
06981    time_t   last_modified;
06982    int      flag;
06983 } stb_dirtree_file;
06984 
06985 typedef struct
06986 {
06987    stb_dirtree_dir  *dirs;
06988    stb_dirtree_file *files;
06989 
06990    // internal use
06991    void             * string_pool;   // used to free data en masse
06992 } stb_dirtree;
06993 
06994 extern void         stb_dirtree_free          ( stb_dirtree *d );
06995 extern stb_dirtree *stb_dirtree_get           ( char *dir);
06996 extern stb_dirtree *stb_dirtree_get_dir       ( char *dir, char *cache_dir);
06997 extern stb_dirtree *stb_dirtree_get_with_file ( char *dir, char *cache_file);
06998 
06999 // get a list of all the files recursively underneath 'dir'
07000 //
07001 // cache_file is used to store a copy of the directory tree to speed up
07002 // later calls. It must be unique to 'dir' and the current working
07003 // directory! Otherwise who knows what will happen (a good solution
07004 // is to put it _in_ dir, but this API doesn't force that).
07005 //
07006 // Also, it might be possible to break this if you have two different processes
07007 // do a call to stb_dirtree_get() with the same cache file at about the same
07008 // time, but I _think_ it might just work.
07009 
07010 // i needed to build an identical data structure representing the state of
07011 // a mirrored copy WITHOUT bothering to rescan it (i.e. we're mirroring to
07012 // it WITHOUT scanning it, e.g. it's over the net), so this requires access
07013 // to all of the innards.
07014 extern void stb_dirtree_db_add_dir(stb_dirtree *active, char *path, time_t last);
07015 extern void stb_dirtree_db_add_file(stb_dirtree *active, char *name, int dir, stb_int64 size, time_t last);
07016 extern void stb_dirtree_db_read(stb_dirtree *target, char *filename, char *dir);
07017 extern void stb_dirtree_db_write(stb_dirtree *target, char *filename, char *dir);
07018 
07019 #ifdef STB_DEFINE
07020 static void stb__dirtree_add_dir(char *path, time_t last, stb_dirtree *active)
07021 {
07022    stb_dirtree_dir d;
07023    d.last_modified = last;
07024    d.num_files = 0;
07025    d.path = stb_strdup(path, active->string_pool);
07026    stb_arr_push(active->dirs, d);
07027 }
07028 
07029 static void stb__dirtree_add_file(char *name, int dir, stb_int64 size, time_t last, stb_dirtree *active)
07030 {
07031    stb_dirtree_file f;
07032    f.dir = dir;
07033    f.size = size;
07034    f.last_modified = last;
07035    f.name = stb_strdup(name, active->string_pool);
07036    ++active->dirs[dir].num_files;
07037    stb_arr_push(active->files, f);
07038 }
07039 
07040 // version 02 supports > 4GB files
07041 static char stb__signature[12] = { 's', 'T', 'b', 'D', 'i', 'R', 't', 'R', 'e', 'E', '0', '2' };
07042 
07043 static void stb__dirtree_save_db(char *filename, stb_dirtree *data, char *root)
07044 {
07045    int i, num_dirs_final=0, num_files_final;
07046    char *info = root ? root : (char*)"";
07047    int *remap;
07048    FILE *f = stb_p_fopen(filename, "wb");
07049    if (!f) return;
07050 
07051    fwrite(stb__signature, sizeof(stb__signature), 1, f);
07052    fwrite(info, strlen(info)+1, 1, f);
07053    // need to be slightly tricky and not write out NULLed directories, nor the root
07054 
07055    // build remapping table of all dirs we'll be writing out
07056    remap = (int *) malloc(sizeof(remap[0]) * stb_arr_len(data->dirs));
07057    for (i=0; i < stb_arr_len(data->dirs); ++i) {
07058       if (data->dirs[i].path == NULL || (root && 0==stb_stricmp(data->dirs[i].path, root))) {
07059          remap[i] = -1;
07060       } else {
07061          remap[i] = num_dirs_final++;
07062       }
07063    }
07064 
07065    fwrite(&num_dirs_final, 4, 1, f);
07066    for (i=0; i < stb_arr_len(data->dirs); ++i) {
07067       if (remap[i] >= 0) {
07068          fwrite(&data->dirs[i].last_modified, 4, 1, f);
07069          stb_fput_string(f, data->dirs[i].path);
07070       }
07071    }
07072 
07073    num_files_final = 0;
07074    for (i=0; i < stb_arr_len(data->files); ++i)
07075       if (remap[data->files[i].dir] >= 0 && data->files[i].name)
07076          ++num_files_final;
07077 
07078    fwrite(&num_files_final, 4, 1, f);
07079    for (i=0; i < stb_arr_len(data->files); ++i) {
07080       if (remap[data->files[i].dir] >= 0 && data->files[i].name) {
07081          stb_fput_ranged(f, remap[data->files[i].dir], 0, num_dirs_final);
07082          stb_fput_varlen64(f, data->files[i].size);
07083          fwrite(&data->files[i].last_modified, 4, 1, f);
07084          stb_fput_string(f, data->files[i].name);
07085       }
07086    }
07087 
07088    fclose(f);
07089 }
07090 
07091 // note: stomps any existing data, rather than appending
07092 static void stb__dirtree_load_db(char *filename, stb_dirtree *data, char *dir)
07093 {
07094    char sig[2048];
07095    int i,n;
07096    FILE *f = stb_p_fopen(filename, "rb");
07097 
07098    if (!f) return;
07099 
07100    data->string_pool = stb_malloc(0,1);
07101 
07102    fread(sig, sizeof(stb__signature), 1, f);
07103    if (memcmp(stb__signature, sig, sizeof(stb__signature))) { fclose(f); return; }
07104    if (!fread(sig, strlen(dir)+1, 1, f))                    { fclose(f); return; }
07105    if (stb_stricmp(sig,dir))                                { fclose(f); return; }
07106 
07107    // we can just read them straight in, because they're guaranteed to be valid
07108    fread(&n, 4, 1, f);
07109    stb_arr_setlen(data->dirs, n);
07110    for(i=0; i < stb_arr_len(data->dirs); ++i) {
07111       fread(&data->dirs[i].last_modified, 4, 1, f);
07112       data->dirs[i].path = stb_fget_string(f, data->string_pool);
07113       if (data->dirs[i].path == NULL) goto bail;
07114    }
07115    fread(&n, 4, 1, f);
07116    stb_arr_setlen(data->files, n);
07117    for (i=0; i < stb_arr_len(data->files); ++i) {
07118       data->files[i].dir  = stb_fget_ranged(f, 0, stb_arr_len(data->dirs));
07119       data->files[i].size = stb_fget_varlen64(f);
07120       fread(&data->files[i].last_modified, 4, 1, f);
07121       data->files[i].name = stb_fget_string(f, data->string_pool);
07122       if (data->files[i].name == NULL) goto bail;
07123    }
07124 
07125    if (0) {
07126       bail:
07127          stb_arr_free(data->dirs);
07128          stb_arr_free(data->files);
07129    }
07130    fclose(f);
07131 }
07132 
07133 FILE *hlog;
07134 
07135 static int stb__dircount, stb__dircount_mask, stb__showfile;
07136 static void stb__dirtree_scandir(char *path, time_t last_time, stb_dirtree *active)
07137 {
07138    // this is dumb depth first; theoretically it might be faster
07139    // to fully traverse each directory before visiting its children,
07140    // but it's complicated and didn't seem like a gain in the test app
07141 
07142    int n;
07143 
07144    struct _wfinddatai64_t c_file;
07145    long hFile;
07146    stb__wchar full_path[1024];
07147    int has_slash;
07148    if (stb__showfile) printf("<");
07149 
07150    has_slash = (path[0] && path[strlen(path)-1] == '/');
07151 
07152    // @TODO: do this concatenation without using swprintf to avoid this mess:
07153 #if (defined(_MSC_VER) && _MSC_VER < 1400) // || (defined(__clang__))
07154    // confusingly, Windows Kits\10 needs to go down this path?!?
07155    // except now it doesn't, I don't know what changed
07156    if (has_slash)
07157       swprintf(full_path, L"%s*", stb__from_utf8(path));
07158    else
07159       swprintf(full_path, L"%s/*", stb__from_utf8(path));
07160 #else
07161    if (has_slash)
07162       swprintf((wchar_t *) full_path, (size_t) 1024, L"%s*", (wchar_t *) stb__from_utf8(path));
07163    else
07164       swprintf((wchar_t *) full_path, (size_t) 1024, L"%s/*", (wchar_t *) stb__from_utf8(path));
07165 #endif
07166 
07167    // it's possible this directory is already present: that means it was in the
07168    // cache, but its parent wasn't... in that case, we're done with it
07169    if (stb__showfile) printf("C[%d]", stb_arr_len(active->dirs));
07170    for (n=0; n < stb_arr_len(active->dirs); ++n)
07171       if (0 == stb_stricmp(active->dirs[n].path, path)) {
07172          if (stb__showfile) printf("D");
07173          return;
07174       }
07175    if (stb__showfile) printf("E");
07176 
07177    // otherwise, we need to add it
07178    stb__dirtree_add_dir(path, last_time, active);
07179    n = stb_arr_lastn(active->dirs);
07180 
07181    if (stb__showfile) printf("[");
07182    if( (hFile = (long) _wfindfirsti64( (wchar_t *) full_path, &c_file )) != -1L ) {
07183       do {
07184          if (stb__showfile) printf(")");
07185          if (c_file.attrib & _A_SUBDIR) {
07186             // ignore subdirectories starting with '.', e.g. "." and ".."
07187             if (c_file.name[0] != '.') {
07188                char *new_path = (char *) full_path;
07189                char *temp = stb__to_utf8((stb__wchar *) c_file.name);
07190 
07191                if (has_slash)
07192                   stb_p_sprintf(new_path stb_p_size(sizeof(full_path)), "%s%s", path, temp);
07193                else
07194                   stb_p_sprintf(new_path stb_p_size(sizeof(full_path)), "%s/%s", path, temp);
07195 
07196                if (stb__dircount_mask) {
07197                   ++stb__dircount;
07198                   if (!(stb__dircount & stb__dircount_mask)) {
07199                      char dummy_path[128], *pad;
07200                      stb_strncpy(dummy_path, new_path, sizeof(dummy_path)-1);
07201                      if (strlen(dummy_path) > 96) {
07202                         stb_p_strcpy_s(dummy_path+96/2-1,128, "...");
07203                         stb_p_strcpy_s(dummy_path+96/2+2,128, new_path + strlen(new_path)-96/2+2);
07204                      }
07205                      pad = dummy_path + strlen(dummy_path);
07206                      while (pad < dummy_path+98)
07207                         *pad++ = ' ';
07208                      *pad = 0;
07209                      printf("%s\r", dummy_path);
07210                      #if 0
07211                      if (hlog == 0) {
07212                         hlog = stb_p_fopen("c:/x/temp.log", "w");
07213                         fprintf(hlog, "%s\n", dummy_path);
07214                      }
07215                      #endif
07216                   }
07217                }
07218 
07219                stb__dirtree_scandir(new_path, c_file.time_write, active);
07220             }
07221          } else {
07222             char *temp = stb__to_utf8((stb__wchar *) c_file.name);
07223             stb__dirtree_add_file(temp, n, c_file.size, c_file.time_write, active);
07224          }
07225          if (stb__showfile) printf("(");
07226       } while( _wfindnexti64( hFile, &c_file ) == 0 );
07227       if (stb__showfile) printf("]");
07228       _findclose( hFile );
07229    }
07230    if (stb__showfile) printf(">\n");
07231 }
07232 
07233 // scan the database and see if it's all valid
07234 static int stb__dirtree_update_db(stb_dirtree *db, stb_dirtree *active)
07235 {
07236    int changes_detected = STB_FALSE;
07237    int i;
07238    int *remap;
07239    int *rescan=NULL;
07240    remap = (int *) malloc(sizeof(remap[0]) * stb_arr_len(db->dirs));
07241    memset(remap, 0, sizeof(remap[0]) * stb_arr_len(db->dirs));
07242    rescan = NULL;
07243 
07244    for (i=0; i < stb_arr_len(db->dirs); ++i) {
07245       struct _stat info;
07246       if (stb__dircount_mask) {
07247          ++stb__dircount;
07248          if (!(stb__dircount & stb__dircount_mask)) {
07249             printf(".");
07250          }
07251       }
07252       if (0 == _stat(db->dirs[i].path, &info)) {
07253          if (info.st_mode & _S_IFDIR) {
07254             // it's still a directory, as expected
07255             int n = abs((int) (info.st_mtime - db->dirs[i].last_modified));
07256             if (n > 1 && n != 3600) {  // the 3600 is a hack because sometimes this jumps for no apparent reason, even when no time zone or DST issues are at play
07257                // it's changed! force a rescan
07258                // we don't want to scan it until we've stat()d its
07259                // subdirs, though, so we queue it
07260                if (stb__showfile) printf("Changed: %s - %08x:%08x\n", db->dirs[i].path, (unsigned int) db->dirs[i].last_modified, (unsigned int) info.st_mtime);
07261                stb_arr_push(rescan, i);
07262                // update the last_mod time
07263                db->dirs[i].last_modified = info.st_mtime;
07264                // ignore existing files in this dir
07265                remap[i] = -1;
07266                changes_detected = STB_TRUE;
07267             } else {
07268                // it hasn't changed, just copy it through unchanged
07269                stb__dirtree_add_dir(db->dirs[i].path, db->dirs[i].last_modified, active);
07270                remap[i] = stb_arr_lastn(active->dirs);
07271             }
07272          } else {
07273             // this path used to refer to a directory, but now it's a file!
07274             // assume that the parent directory is going to be forced to rescan anyway
07275             goto delete_entry;
07276          }
07277       } else {
07278         delete_entry:
07279          // directory no longer exists, so don't copy it
07280          // we don't free it because it's in the string pool now
07281          db->dirs[i].path = NULL;
07282          remap[i] = -1;
07283          changes_detected = STB_TRUE;
07284       }
07285    }
07286 
07287    // at this point, we have:
07288    //
07289    //   <rescan> holds a list of directory indices that need to be scanned due to being out of date
07290    //   <remap> holds the directory index in <active> for each dir in <db>, if it exists; -1 if not
07291    //           directories in <rescan> are not in <active> yet
07292 
07293    // so we can go ahead and remap all the known files right now
07294    for (i=0; i < stb_arr_len(db->files); ++i) {
07295       int dir = db->files[i].dir;
07296       if (remap[dir] >= 0) {
07297          stb__dirtree_add_file(db->files[i].name, remap[dir], db->files[i].size, db->files[i].last_modified, active);
07298       }
07299    }
07300 
07301    // at this point we're done with db->files, and done with remap
07302    free(remap);
07303 
07304    // now scan those directories using the standard scan
07305    for (i=0; i < stb_arr_len(rescan); ++i) {
07306       int z = rescan[i];
07307       stb__dirtree_scandir(db->dirs[z].path, db->dirs[z].last_modified, active);
07308    }
07309    stb_arr_free(rescan);
07310 
07311    return changes_detected;
07312 }
07313 
07314 static void stb__dirtree_free_raw(stb_dirtree *d)
07315 {
07316    stb_free(d->string_pool);
07317    stb_arr_free(d->dirs);
07318    stb_arr_free(d->files);
07319 }
07320 
07321 stb_dirtree *stb_dirtree_get_with_file(char *dir, char *cache_file)
07322 {
07323    stb_dirtree *output = (stb_dirtree *) malloc(sizeof(*output));
07324    stb_dirtree db,active;
07325    int prev_dir_count, cache_mismatch;
07326 
07327    char *stripped_dir; // store the directory name without a trailing '/' or '\\'
07328 
07329    // load the database of last-known state on disk
07330    db.string_pool = NULL;
07331    db.files = NULL;
07332    db.dirs = NULL;
07333 
07334    stripped_dir = stb_strip_final_slash(stb_p_strdup(dir));
07335 
07336    if (cache_file != NULL)
07337       stb__dirtree_load_db(cache_file, &db, stripped_dir);
07338    else if (stb__showfile)
07339       printf("No cache file\n");
07340 
07341    active.files = NULL;
07342    active.dirs = NULL;
07343    active.string_pool = stb_malloc(0,1); // @TODO: share string pools between both?
07344 
07345    // check all the directories in the database; make note if
07346    // anything we scanned had changed, and rescan those things
07347    cache_mismatch = stb__dirtree_update_db(&db, &active);
07348 
07349    // check the root tree
07350    prev_dir_count = stb_arr_len(active.dirs);  // record how many directories we've seen
07351 
07352    stb__dirtree_scandir(stripped_dir, 0, &active);  // no last_modified time available for root
07353 
07354    if (stb__dircount_mask)
07355       printf("                                                                              \r");
07356 
07357    // done with the DB; write it back out if any changes, i.e. either
07358    //      1. any inconsistency found between cached information and actual disk
07359    //   or 2. if scanning the root found any new directories--which we detect because
07360    //         more than one directory got added to the active db during that scan
07361    if (cache_mismatch || stb_arr_len(active.dirs) > prev_dir_count+1)
07362       stb__dirtree_save_db(cache_file, &active, stripped_dir);
07363 
07364    free(stripped_dir);
07365 
07366    stb__dirtree_free_raw(&db);
07367 
07368    *output = active;
07369    return output;
07370 }
07371 
07372 stb_dirtree *stb_dirtree_get_dir(char *dir, char *cache_dir)
07373 {
07374    int i;
07375    stb_uint8 sha[20];
07376    char dir_lower[1024];
07377    char cache_file[1024],*s;
07378    if (cache_dir == NULL)
07379       return stb_dirtree_get_with_file(dir, NULL);
07380    stb_p_strcpy_s(dir_lower, sizeof(dir_lower), dir);
07381    stb_tolower(dir_lower);
07382    stb_sha1(sha, (unsigned char *) dir_lower, (unsigned int) strlen(dir_lower));
07383    stb_p_strcpy_s(cache_file, sizeof(cache_file), cache_dir);
07384    s = cache_file + strlen(cache_file);
07385    if (s[-1] != '/' && s[-1] != '\\') *s++ = '/';
07386    stb_p_strcpy_s(s, sizeof(cache_file), "dirtree_");
07387    s += strlen(s);
07388    for (i=0; i < 8; ++i) {
07389       char *hex = (char*)"0123456789abcdef";
07390       stb_uint z = sha[i];
07391       *s++ = hex[z >> 4];
07392       *s++ = hex[z & 15];
07393    }
07394    stb_p_strcpy_s(s, sizeof(cache_file), ".bin");
07395    return stb_dirtree_get_with_file(dir, cache_file);
07396 }
07397 
07398 stb_dirtree *stb_dirtree_get(char *dir)
07399 {
07400    char cache_dir[256];
07401    stb_p_strcpy_s(cache_dir, sizeof(cache_dir), "c:/bindata");
07402    #ifdef STB_HAS_REGISTRY
07403    {
07404       void *reg = stb_reg_open("rHKLM", "Software\\SilverSpaceship\\stb");
07405       if (reg) {
07406          stb_reg_read(reg, "dirtree", cache_dir, sizeof(cache_dir));
07407          stb_reg_close(reg);
07408       }
07409    }
07410    #endif
07411    return stb_dirtree_get_dir(dir, cache_dir);
07412 }
07413 
07414 void stb_dirtree_free(stb_dirtree *d)
07415 {
07416    stb__dirtree_free_raw(d);
07417    free(d);
07418 }
07419 
07420 void stb_dirtree_db_add_dir(stb_dirtree *active, char *path, time_t last)
07421 {
07422    stb__dirtree_add_dir(path, last, active);
07423 }
07424 
07425 void stb_dirtree_db_add_file(stb_dirtree *active, char *name, int dir, stb_int64 size, time_t last)
07426 {
07427    stb__dirtree_add_file(name, dir, size, last, active);
07428 }
07429 
07430 void stb_dirtree_db_read(stb_dirtree *target, char *filename, char *dir)
07431 {
07432    char *s = stb_strip_final_slash(stb_p_strdup(dir));
07433    target->dirs = 0;
07434    target->files = 0;
07435    target->string_pool = 0;
07436    stb__dirtree_load_db(filename, target, s);
07437    free(s);
07438 }
07439 
07440 void stb_dirtree_db_write(stb_dirtree *target, char *filename, char *dir)
07441 {
07442    stb__dirtree_save_db(filename, target, 0); // don't strip out any directories
07443 }
07444 
07445 #endif // STB_DEFINE
07446 
07447 #endif // _WIN32
07448 #endif // STB_NO_STB_STRINGS
07449 
07451 //
07452 //  STB_MALLOC_WRAPPER
07453 //
07454 //    you can use the wrapper functions with your own malloc wrapper,
07455 //    or define STB_MALLOC_WRAPPER project-wide to have
07456 //    malloc/free/realloc/strdup all get vectored to it
07457 
07458 // this has too many very specific error messages you could google for and find in stb.h,
07459 // so don't use it if they don't want any stb.h-identifiable strings
07460 #if defined(STB_DEFINE) && !defined(STB_NO_STB_STRINGS)
07461 
07462 typedef struct
07463 {
07464    void *p;
07465    char *file;
07466    int  line;
07467    size_t size;
07468 } stb_malloc_record;
07469 
07470 #ifndef STB_MALLOC_HISTORY_COUNT
07471 #define STB_MALLOC_HISTORY_COUNT 50 // 800 bytes
07472 #endif
07473 
07474 stb_malloc_record *stb__allocations;
07475 static int stb__alloc_size, stb__alloc_limit, stb__alloc_mask;
07476 int stb__alloc_count;
07477 
07478 stb_malloc_record stb__alloc_history[STB_MALLOC_HISTORY_COUNT];
07479 int stb__history_pos;
07480 
07481 static int stb__hashfind(void *p)
07482 {
07483    stb_uint32 h = stb_hashptr(p);
07484    int s,n = h & stb__alloc_mask;
07485    if (stb__allocations[n].p == p)
07486       return n;
07487    s = stb_rehash(h)|1;
07488    for(;;) {
07489       if (stb__allocations[n].p == NULL)
07490          return -1;
07491       n = (n+s) & stb__alloc_mask;
07492       if (stb__allocations[n].p == p)
07493          return n;
07494    }
07495 }
07496 
07497 size_t stb_wrapper_allocsize(void *p)
07498 {
07499    int n = stb__hashfind(p);
07500    if (n < 0) return 0;
07501    return stb__allocations[n].size;
07502 }
07503 
07504 static int stb__historyfind(void *p)
07505 {
07506    int n = stb__history_pos;
07507    int i;
07508    for (i=0; i < STB_MALLOC_HISTORY_COUNT; ++i) {
07509       if (--n < 0) n = STB_MALLOC_HISTORY_COUNT-1;
07510       if (stb__alloc_history[n].p == p)
07511          return n;
07512    }
07513    return -1;
07514 }
07515 
07516 static void stb__add_alloc(void *p, size_t sz, char *file, int line);
07517 static void stb__grow_alloc(void)
07518 {
07519    int i,old_num = stb__alloc_size;
07520    stb_malloc_record *old = stb__allocations;
07521    if (stb__alloc_size == 0)
07522       stb__alloc_size = 64;
07523    else
07524       stb__alloc_size *= 2;
07525 
07526    stb__allocations = (stb_malloc_record *) stb__realloc_raw(NULL, stb__alloc_size * sizeof(stb__allocations[0]));
07527    if (stb__allocations == NULL)
07528       stb_fatal("Internal error: couldn't grow malloc wrapper table");
07529    memset(stb__allocations, 0, stb__alloc_size * sizeof(stb__allocations[0]));
07530    stb__alloc_limit = (stb__alloc_size*3)>>2;
07531    stb__alloc_mask = stb__alloc_size-1;
07532 
07533    stb__alloc_count = 0;
07534 
07535    for (i=0; i < old_num; ++i)
07536       if (old[i].p > STB_DEL) {
07537          stb__add_alloc(old[i].p, old[i].size, old[i].file, old[i].line);
07538          assert(stb__hashfind(old[i].p) >= 0);
07539       }
07540    for (i=0; i < old_num; ++i)
07541       if (old[i].p > STB_DEL)
07542          assert(stb__hashfind(old[i].p) >= 0);
07543    stb__realloc_raw(old, 0);
07544 }
07545 
07546 static void stb__add_alloc(void *p, size_t sz, char *file, int line)
07547 {
07548    stb_uint32 h;
07549    int n;
07550    if (stb__alloc_count >= stb__alloc_limit)
07551       stb__grow_alloc();
07552    h = stb_hashptr(p);
07553    n = h & stb__alloc_mask;
07554    if (stb__allocations[n].p > STB_DEL) {
07555       int s = stb_rehash(h)|1;
07556       do {
07557          n = (n+s) & stb__alloc_mask;
07558       } while (stb__allocations[n].p > STB_DEL);
07559    }
07560    assert(stb__allocations[n].p == NULL || stb__allocations[n].p == STB_DEL);
07561    stb__allocations[n].p = p;
07562    stb__allocations[n].size = sz;
07563    stb__allocations[n].line = line;
07564    stb__allocations[n].file = file;
07565    ++stb__alloc_count;
07566 }
07567 
07568 static void stb__remove_alloc(int n, char *file, int line)
07569 {
07570    stb__alloc_history[stb__history_pos] = stb__allocations[n];
07571    stb__alloc_history[stb__history_pos].file = file;
07572    stb__alloc_history[stb__history_pos].line = line;
07573    if (++stb__history_pos == STB_MALLOC_HISTORY_COUNT)
07574       stb__history_pos = 0;
07575    stb__allocations[n].p = STB_DEL;
07576    --stb__alloc_count;
07577 }
07578 
07579 void stb_wrapper_malloc(void *p, size_t sz, char *file, int line)
07580 {
07581    if (!p) return;
07582    stb__add_alloc(p,sz,file,line);
07583 }
07584 
07585 void stb_wrapper_free(void *p, char *file, int line)
07586 {
07587    int n;
07588 
07589    if (p == NULL) return;
07590 
07591    n = stb__hashfind(p);
07592 
07593    if (n >= 0)
07594       stb__remove_alloc(n, file, line);
07595    else {
07596       // tried to free something we hadn't allocated!
07597       n = stb__historyfind(p);
07598       assert(0); /* NOTREACHED */
07599       if (n >= 0)
07600          stb_fatal("Attempted to free %d-byte block %p at %s:%d previously freed/realloced at %s:%d",
07601                        stb__alloc_history[n].size, p,
07602                        file, line,
07603                        stb__alloc_history[n].file, stb__alloc_history[n].line);
07604       else
07605          stb_fatal("Attempted to free unknown block %p at %s:%d", p, file,line);
07606    }
07607 }
07608 
07609 void stb_wrapper_check(void *p)
07610 {
07611    int n;
07612 
07613    if (p == NULL) return;
07614 
07615    n = stb__hashfind(p);
07616 
07617    if (n >= 0) return;
07618 
07619    for (n=0; n < stb__alloc_size; ++n)
07620       if (stb__allocations[n].p == p)
07621          stb_fatal("Internal error: pointer %p was allocated, but hash search failed", p);
07622 
07623    // tried to free something that wasn't allocated!
07624    n = stb__historyfind(p);
07625    if (n >= 0)
07626       stb_fatal("Checked %d-byte block %p previously freed/realloced at %s:%d",
07627                     stb__alloc_history[n].size, p,
07628                     stb__alloc_history[n].file, stb__alloc_history[n].line);
07629    stb_fatal("Checked unknown block %p");
07630 }
07631 
07632 void stb_wrapper_realloc(void *p, void *q, size_t sz, char *file, int line)
07633 {
07634    int n;
07635    if (p == NULL) { stb_wrapper_malloc(q, sz, file, line); return; }
07636    if (q == NULL) return; // nothing happened
07637 
07638    n = stb__hashfind(p);
07639    if (n == -1) {
07640       // tried to free something we hadn't allocated!
07641       // this is weird, though, because we got past the realloc!
07642       n = stb__historyfind(p);
07643       assert(0); /* NOTREACHED */
07644       if (n >= 0)
07645          stb_fatal("Attempted to realloc %d-byte block %p at %s:%d previously freed/realloced at %s:%d",
07646                        stb__alloc_history[n].size, p,
07647                        file, line,
07648                        stb__alloc_history[n].file, stb__alloc_history[n].line);
07649       else
07650          stb_fatal("Attempted to realloc unknown block %p at %s:%d", p, file,line);
07651    } else {
07652       if (q == p) {
07653          stb__allocations[n].size = sz;
07654          stb__allocations[n].file = file;
07655          stb__allocations[n].line = line;
07656       } else {
07657          stb__remove_alloc(n, file, line);
07658          stb__add_alloc(q,sz,file,line);
07659       }
07660    }
07661 }
07662 
07663 void stb_wrapper_listall(void (*func)(void *ptr, size_t sz, char *file, int line))
07664 {
07665    int i;
07666    for (i=0; i < stb__alloc_size; ++i)
07667       if (stb__allocations[i].p > STB_DEL)
07668          func(stb__allocations[i].p   , stb__allocations[i].size,
07669               stb__allocations[i].file, stb__allocations[i].line);
07670 }
07671 
07672 void stb_wrapper_dump(char *filename)
07673 {
07674    int i;
07675    FILE *f = stb_p_fopen(filename, "w");
07676    if (!f) return;
07677    for (i=0; i < stb__alloc_size; ++i)
07678       if (stb__allocations[i].p > STB_DEL)
07679          fprintf(f, "%p %7d - %4d %s\n",
07680             stb__allocations[i].p   , (int) stb__allocations[i].size,
07681             stb__allocations[i].line, stb__allocations[i].file);
07682 }
07683 #endif // STB_DEFINE
07684 
07685 
07687 //
07688 //                  stb_pointer_set
07689 //
07690 //
07691 // For data structures that support querying by key, data structure
07692 // classes always hand-wave away the issue of what to do if two entries
07693 // have the same key: basically, store a linked list of all the nodes
07694 // which have the same key (a LISP-style list).
07695 //
07696 // The thing is, it's not that trivial. If you have an O(log n)
07697 // lookup data structure, but then n/4 items have the same value,
07698 // you don't want to spend O(n) time scanning that list when
07699 // deleting an item if you already have a pointer to the item.
07700 // (You have to spend O(n) time enumerating all the items with
07701 // a given key, sure, and you can't accelerate deleting a particular
07702 // item if you only have the key, not a pointer to the item.)
07703 //
07704 // I'm going to call this data structure, whatever it turns out to
07705 // be, a "pointer set", because we don't store any associated data for
07706 // items in this data structure, we just answer the question of
07707 // whether an item is in it or not (it's effectively one bit per pointer).
07708 // Technically they don't have to be pointers; you could cast ints
07709 // to (void *) if you want, but you can't store 0 or 1 because of the
07710 // hash table.
07711 //
07712 // Since the fastest data structure we might want to add support for
07713 // identical-keys to is a hash table with O(1)-ish lookup time,
07714 // that means that the conceptual "linked list of all items with
07715 // the same indexed value" that we build needs to have the same
07716 // performance; that way when we index a table we think is arbitrary
07717 // ints, but in fact half of them are 0, we don't get screwed.
07718 //
07719 // Therefore, it needs to be a hash table, at least when it gets
07720 // large. On the other hand, when the data has totally arbitrary ints
07721 // or floats, there won't be many collisions, and we'll have tons of
07722 // 1-item bitmaps. That will be grossly inefficient as hash tables;
07723 // trade-off; the hash table is reasonably efficient per-item when
07724 // it's large, but not when it's small. So we need to do something
07725 // Judy-like and use different strategies depending on the size.
07726 //
07727 // Like Judy, we'll use the bottom bit to encode the strategy:
07728 //
07729 //      bottom bits:
07730 //          00     -   direct pointer
07731 //          01     -   4-item bucket (16 bytes, no length, NULLs)
07732 //          10     -   N-item array
07733 //          11     -   hash table
07734 
07735 typedef struct stb_ps stb_ps;
07736 
07737 STB_EXTERN int      stb_ps_find  (stb_ps *ps, void *value);
07738 STB_EXTERN stb_ps * stb_ps_add   (stb_ps *ps, void *value);
07739 STB_EXTERN stb_ps * stb_ps_remove(stb_ps *ps, void *value);
07740 STB_EXTERN stb_ps * stb_ps_remove_any(stb_ps *ps, void **value);
07741 STB_EXTERN void     stb_ps_delete(stb_ps *ps);
07742 STB_EXTERN int      stb_ps_count (stb_ps *ps);
07743 
07744 STB_EXTERN stb_ps * stb_ps_copy  (stb_ps *ps);
07745 STB_EXTERN int      stb_ps_subset(stb_ps *bigger, stb_ps *smaller);
07746 STB_EXTERN int      stb_ps_eq    (stb_ps *p0, stb_ps *p1);
07747 
07748 STB_EXTERN void ** stb_ps_getlist  (stb_ps *ps, int *count);
07749 STB_EXTERN int     stb_ps_writelist(stb_ps *ps, void **list, int size );
07750 
07751 // enum and fastlist don't allocate storage, but you must consume the
07752 // list before there's any chance the data structure gets screwed up;
07753 STB_EXTERN int     stb_ps_enum     (stb_ps *ps, void *data,
07754                                        int (*func)(void *value, void*data) );
07755 STB_EXTERN void ** stb_ps_fastlist(stb_ps *ps, int *count);
07756 //  result:
07757 //     returns a list, *count is the length of that list,
07758 //     but some entries of the list may be invalid;
07759 //     test with 'stb_ps_fastlist_valid(x)'
07760 
07761 #define stb_ps_fastlist_valid(x)   ((stb_uinta) (x) > 1)
07762 
07763 #ifdef STB_DEFINE
07764 
07765 enum
07766 {
07767    STB_ps_direct = 0,
07768    STB_ps_bucket = 1,
07769    STB_ps_array  = 2,
07770    STB_ps_hash   = 3,
07771 };
07772 
07773 #define STB_BUCKET_SIZE  4
07774 
07775 typedef struct
07776 {
07777    void *p[STB_BUCKET_SIZE];
07778 } stb_ps_bucket;
07779 #define GetBucket(p)    ((stb_ps_bucket *) ((char *) (p) - STB_ps_bucket))
07780 #define EncodeBucket(p) ((stb_ps *) ((char *) (p) + STB_ps_bucket))
07781 
07782 static void stb_bucket_free(stb_ps_bucket *b)
07783 {
07784    free(b);
07785 }
07786 
07787 static stb_ps_bucket *stb_bucket_create2(void *v0, void *v1)
07788 {
07789    stb_ps_bucket *b = (stb_ps_bucket*) malloc(sizeof(*b));
07790    b->p[0] = v0;
07791    b->p[1] = v1;
07792    b->p[2] = NULL;
07793    b->p[3] = NULL;
07794    return b;
07795 }
07796 
07797 static stb_ps_bucket * stb_bucket_create3(void **v)
07798 {
07799    stb_ps_bucket *b = (stb_ps_bucket*) malloc(sizeof(*b));
07800    b->p[0] = v[0];
07801    b->p[1] = v[1];
07802    b->p[2] = v[2];
07803    b->p[3] = NULL;
07804    return b;
07805 }
07806 
07807 
07808 // could use stb_arr, but this will save us memory
07809 typedef struct
07810 {
07811    int count;
07812    void *p[1];
07813 } stb_ps_array;
07814 #define GetArray(p)     ((stb_ps_array *) ((char *) (p) - STB_ps_array))
07815 #define EncodeArray(p)  ((stb_ps *) ((char *) (p) + STB_ps_array))
07816 
07817 static int stb_ps_array_max = 13;
07818 
07819 typedef struct
07820 {
07821    int size, mask;
07822    int count, count_deletes;
07823    int grow_threshhold;
07824    int shrink_threshhold;
07825    int rehash_threshhold;
07826    int any_offset;
07827    void *table[1];
07828 } stb_ps_hash;
07829 #define GetHash(p)      ((stb_ps_hash *) ((char *) (p) - STB_ps_hash))
07830 #define EncodeHash(p)   ((stb_ps *) ((char *) (p) + STB_ps_hash))
07831 
07832 #define stb_ps_empty(v)   (((stb_uint32) v) <= 1)
07833 
07834 static stb_ps_hash *stb_ps_makehash(int size, int old_size, void **old_data)
07835 {
07836    int i;
07837    stb_ps_hash *h = (stb_ps_hash *) malloc(sizeof(*h) + (size-1) * sizeof(h->table[0]));
07838    assert(stb_is_pow2(size));
07839    h->size = size;
07840    h->mask = size-1;
07841    h->shrink_threshhold = (int) (0.3f * size);
07842    h->  grow_threshhold = (int) (0.8f * size);
07843    h->rehash_threshhold = (int) (0.9f * size);
07844    h->count = 0;
07845    h->count_deletes = 0;
07846    h->any_offset = 0;
07847    memset(h->table, 0, size * sizeof(h->table[0]));
07848    for (i=0; i < old_size; ++i)
07849         if (!stb_ps_empty((size_t)old_data[i]))
07850          stb_ps_add(EncodeHash(h), old_data[i]);
07851    return h;
07852 }
07853 
07854 void stb_ps_delete(stb_ps *ps)
07855 {
07856     switch (3 & (int)(size_t) ps) {
07857       case STB_ps_direct: break;
07858       case STB_ps_bucket: stb_bucket_free(GetBucket(ps)); break;
07859       case STB_ps_array : free(GetArray(ps)); break;
07860       case STB_ps_hash  : free(GetHash(ps)); break;
07861    }
07862 }
07863 
07864 stb_ps *stb_ps_copy(stb_ps *ps)
07865 {
07866    int i;
07867    // not a switch: order based on expected performance/power-law distribution
07868     switch (3 & (int)(size_t) ps) {
07869       case STB_ps_direct: return ps;
07870       case STB_ps_bucket: {
07871          stb_ps_bucket *n = (stb_ps_bucket *) malloc(sizeof(*n));
07872          *n = *GetBucket(ps);
07873          return EncodeBucket(n);
07874       }
07875       case STB_ps_array: {
07876          stb_ps_array *a = GetArray(ps);
07877          stb_ps_array *n = (stb_ps_array *) malloc(sizeof(*n) + stb_ps_array_max * sizeof(n->p[0]));
07878          n->count = a->count;
07879          for (i=0; i < a->count; ++i)
07880             n->p[i] = a->p[i];
07881          return EncodeArray(n);
07882       }
07883       case STB_ps_hash: {
07884          stb_ps_hash *h = GetHash(ps);
07885          stb_ps_hash *n = stb_ps_makehash(h->size, h->size, h->table);
07886          return EncodeHash(n);
07887       }
07888    }
07889    assert(0); /* NOTREACHED */
07890    return NULL;
07891 }
07892 
07893 int stb_ps_find(stb_ps *ps, void *value)
07894 {
07895     int i, code = 3 & (int)(size_t) ps;
07896     assert((3 & (int)(size_t) value) == STB_ps_direct);
07897    assert(stb_ps_fastlist_valid(value));
07898    // not a switch: order based on expected performance/power-law distribution
07899    if (code == STB_ps_direct)
07900       return value == ps;
07901    if (code == STB_ps_bucket) {
07902       stb_ps_bucket *b = GetBucket(ps);
07903       assert(STB_BUCKET_SIZE == 4);
07904       if (b->p[0] == value || b->p[1] == value ||
07905           b->p[2] == value || b->p[3] == value)
07906           return STB_TRUE;
07907       return STB_FALSE;
07908    }
07909    if (code == STB_ps_array) {
07910       stb_ps_array *a = GetArray(ps);
07911       for (i=0; i < a->count; ++i)
07912          if (a->p[i] == value)
07913             return STB_TRUE;
07914       return STB_FALSE;
07915    } else {
07916       stb_ps_hash *h = GetHash(ps);
07917       stb_uint32 hash = stb_hashptr(value);
07918       stb_uint32 s, n = hash & h->mask;
07919       void **t = h->table;
07920       if (t[n] == value) return STB_TRUE;
07921       if (t[n] == NULL) return STB_FALSE;
07922       s = stb_rehash(hash) | 1;
07923       do {
07924          n = (n + s) & h->mask;
07925          if (t[n] == value) return STB_TRUE;
07926       } while (t[n] != NULL);
07927       return STB_FALSE;
07928    }
07929 }
07930 
07931 stb_ps *  stb_ps_add   (stb_ps *ps, void *value)
07932 {
07933    #ifdef STB_DEBUG
07934    assert(!stb_ps_find(ps,value));
07935    #endif
07936    if (value == NULL) return ps; // ignore NULL adds to avoid bad breakage
07937     assert((3 & (int)(size_t) value) == STB_ps_direct);
07938    assert(stb_ps_fastlist_valid(value));
07939    assert(value != STB_DEL);     // STB_DEL is less likely
07940 
07941     switch (3 & (int)(size_t) ps) {
07942       case STB_ps_direct:
07943          if (ps == NULL) return (stb_ps *) value;
07944          return EncodeBucket(stb_bucket_create2(ps,value));
07945 
07946       case STB_ps_bucket: {
07947          stb_ps_bucket *b = GetBucket(ps);
07948          stb_ps_array  *a;
07949          assert(STB_BUCKET_SIZE == 4);
07950          if (b->p[0] == NULL) { b->p[0] = value; return ps; }
07951          if (b->p[1] == NULL) { b->p[1] = value; return ps; }
07952          if (b->p[2] == NULL) { b->p[2] = value; return ps; }
07953          if (b->p[3] == NULL) { b->p[3] = value; return ps; }
07954          a = (stb_ps_array *) malloc(sizeof(*a) + 7 * sizeof(a->p[0])); // 8 slots, must be 2^k
07955          memcpy(a->p, b, sizeof(*b));
07956          a->p[4] = value;
07957          a->count = 5;
07958          stb_bucket_free(b);
07959          return EncodeArray(a);
07960       }
07961 
07962       case STB_ps_array: {
07963          stb_ps_array *a = GetArray(ps);
07964          if (a->count == stb_ps_array_max) {
07965             // promote from array to hash
07966             stb_ps_hash *h = stb_ps_makehash(2 << stb_log2_ceil(a->count), a->count, a->p);
07967             free(a);
07968             return stb_ps_add(EncodeHash(h), value);
07969          }
07970          // do we need to resize the array? the array doubles in size when it
07971          // crosses a power-of-two
07972          if ((a->count & (a->count-1))==0) {
07973             int newsize = a->count*2;
07974             // clamp newsize to max if:
07975             //    1. it's larger than max
07976             //    2. newsize*1.5 is larger than max (to avoid extra resizing)
07977             if (newsize + a->count > stb_ps_array_max)
07978                newsize = stb_ps_array_max;
07979             a = (stb_ps_array *) realloc(a, sizeof(*a) + (newsize-1) * sizeof(a->p[0]));
07980          }
07981          a->p[a->count++] = value;
07982          return EncodeArray(a);
07983       }
07984       case STB_ps_hash: {
07985          stb_ps_hash *h = GetHash(ps);
07986          stb_uint32 hash = stb_hashptr(value);
07987          stb_uint32 n = hash & h->mask;
07988          void **t = h->table;
07989          // find first NULL or STB_DEL entry
07990           if (!stb_ps_empty((size_t)t[n])) {
07991             stb_uint32 s = stb_rehash(hash) | 1;
07992             do {
07993                n = (n + s) & h->mask;
07994             } while (!stb_ps_empty((size_t)t[n]));
07995          }
07996          if (t[n] == STB_DEL)
07997             -- h->count_deletes;
07998          t[n] = value;
07999          ++ h->count;
08000          if (h->count == h->grow_threshhold) {
08001             stb_ps_hash *h2 = stb_ps_makehash(h->size*2, h->size, t);
08002             free(h);
08003             return EncodeHash(h2);
08004          }
08005          if (h->count + h->count_deletes == h->rehash_threshhold) {
08006             stb_ps_hash *h2 = stb_ps_makehash(h->size, h->size, t);
08007             free(h);
08008             return EncodeHash(h2);
08009          }
08010          return ps;
08011       }
08012    }
08013    return NULL; /* NOTREACHED */
08014 }
08015 
08016 stb_ps *stb_ps_remove(stb_ps *ps, void *value)
08017 {
08018    #ifdef STB_DEBUG
08019    assert(stb_ps_find(ps, value));
08020    #endif
08021     assert((3 & (int)(size_t) value) == STB_ps_direct);
08022    if (value == NULL) return ps; // ignore NULL removes to avoid bad breakage
08023     switch (3 & (int)(size_t) ps) {
08024       case STB_ps_direct:
08025          return ps == value ? NULL : ps;
08026       case STB_ps_bucket: {
08027          stb_ps_bucket *b = GetBucket(ps);
08028          int count=0;
08029          assert(STB_BUCKET_SIZE == 4);
08030          if (b->p[0] == value) b->p[0] = NULL; else count += (b->p[0] != NULL);
08031          if (b->p[1] == value) b->p[1] = NULL; else count += (b->p[1] != NULL);
08032          if (b->p[2] == value) b->p[2] = NULL; else count += (b->p[2] != NULL);
08033          if (b->p[3] == value) b->p[3] = NULL; else count += (b->p[3] != NULL);
08034          if (count == 1) { // shrink bucket at size 1
08035             value = b->p[0];
08036             if (value == NULL) value = b->p[1];
08037             if (value == NULL) value = b->p[2];
08038             if (value == NULL) value = b->p[3];
08039             assert(value != NULL);
08040             stb_bucket_free(b);
08041             return (stb_ps *) value; // return STB_ps_direct of value
08042          }
08043          return ps;
08044       }
08045       case STB_ps_array: {
08046          stb_ps_array *a = GetArray(ps);
08047          int i;
08048          for (i=0; i < a->count; ++i) {
08049             if (a->p[i] == value) {
08050                a->p[i] = a->p[--a->count];
08051                if (a->count == 3) { // shrink to bucket!
08052                   stb_ps_bucket *b = stb_bucket_create3(a->p);
08053                   free(a);
08054                   return EncodeBucket(b);
08055                }
08056                return ps;
08057             }
08058          }
08059          return ps;
08060       }
08061       case STB_ps_hash: {
08062          stb_ps_hash *h = GetHash(ps);
08063          stb_uint32 hash = stb_hashptr(value);
08064          stb_uint32 s, n = hash & h->mask;
08065          void **t = h->table;
08066          if (t[n] != value) {
08067             s = stb_rehash(hash) | 1;
08068             do {
08069                n = (n + s) & h->mask;
08070             } while (t[n] != value);
08071          }
08072          t[n] = STB_DEL;
08073          -- h->count;
08074          ++ h->count_deletes;
08075          // should we shrink down to an array?
08076          if (h->count < stb_ps_array_max) {
08077             int n = 1 << stb_log2_floor(stb_ps_array_max);
08078             if (h->count < n) {
08079                stb_ps_array *a = (stb_ps_array *) malloc(sizeof(*a) + (n-1) * sizeof(a->p[0]));
08080                int i,j=0;
08081                for (i=0; i < h->size; ++i)
08082                     if (!stb_ps_empty((size_t)t[i]))
08083                      a->p[j++] = t[i];
08084                assert(j == h->count);
08085                a->count = j;
08086                free(h);
08087                return EncodeArray(a);
08088             }
08089          }
08090          if (h->count == h->shrink_threshhold) {
08091             stb_ps_hash *h2 = stb_ps_makehash(h->size >> 1, h->size, t);
08092             free(h);
08093             return EncodeHash(h2);
08094          }
08095          return ps;
08096       }
08097    }
08098    return ps; /* NOTREACHED */
08099 }
08100 
08101 stb_ps *stb_ps_remove_any(stb_ps *ps, void **value)
08102 {
08103    assert(ps != NULL);
08104     switch (3 & (int)(size_t) ps) {
08105       case STB_ps_direct:
08106          *value = ps;
08107          return NULL;
08108       case STB_ps_bucket: {
08109          stb_ps_bucket *b = GetBucket(ps);
08110          int count=0, slast=0, last=0;
08111          assert(STB_BUCKET_SIZE == 4);
08112          if (b->p[0]) { ++count;               last = 0; }
08113          if (b->p[1]) { ++count; slast = last; last = 1; }
08114          if (b->p[2]) { ++count; slast = last; last = 2; }
08115          if (b->p[3]) { ++count; slast = last; last = 3; }
08116          *value = b->p[last];
08117          b->p[last] = 0;
08118          if (count == 2) {
08119             void *leftover = b->p[slast]; // second to last
08120             stb_bucket_free(b);
08121             return (stb_ps *) leftover;
08122          }
08123          return ps;
08124       }
08125       case STB_ps_array: {
08126          stb_ps_array *a = GetArray(ps);
08127          *value = a->p[a->count-1];
08128          if (a->count == 4)
08129             return stb_ps_remove(ps, *value);
08130          --a->count;
08131          return ps;
08132       }
08133       case STB_ps_hash: {
08134          stb_ps_hash *h = GetHash(ps);
08135          void **t = h->table;
08136          stb_uint32 n = h->any_offset;
08137           while (stb_ps_empty((size_t)t[n]))
08138             n = (n + 1) & h->mask;
08139          *value = t[n];
08140          h->any_offset = (n+1) & h->mask;
08141          // check if we need to skip down to the previous type
08142          if (h->count-1 < stb_ps_array_max || h->count-1 == h->shrink_threshhold)
08143             return stb_ps_remove(ps, *value);
08144          t[n] = STB_DEL;
08145          -- h->count;
08146          ++ h->count_deletes;
08147          return ps;
08148       }
08149    }
08150    return ps; /* NOTREACHED */
08151 }
08152 
08153 
08154 void ** stb_ps_getlist(stb_ps *ps, int *count)
08155 {
08156    int i,n=0;
08157    void **p = NULL;
08158     switch (3 & (int)(size_t) ps) {
08159       case STB_ps_direct:
08160          if (ps == NULL) { *count = 0; return NULL; }
08161          p = (void **) malloc(sizeof(*p) * 1);
08162          p[0] = ps;
08163          *count = 1;
08164          return p;
08165       case STB_ps_bucket: {
08166          stb_ps_bucket *b = GetBucket(ps);
08167          p = (void **) malloc(sizeof(*p) * STB_BUCKET_SIZE);
08168          for (i=0; i < STB_BUCKET_SIZE; ++i)
08169             if (b->p[i] != NULL)
08170                p[n++] = b->p[i];
08171          break;
08172       }
08173       case STB_ps_array: {
08174          stb_ps_array *a = GetArray(ps);
08175          p = (void **) malloc(sizeof(*p) * a->count);
08176          memcpy(p, a->p, sizeof(*p) * a->count);
08177          *count = a->count;
08178          return p;
08179       }
08180       case STB_ps_hash: {
08181          stb_ps_hash *h = GetHash(ps);
08182          p = (void **) malloc(sizeof(*p) * h->count);
08183          for (i=0; i < h->size; ++i)
08184               if (!stb_ps_empty((size_t)h->table[i]))
08185                p[n++] = h->table[i];
08186          break;
08187       }
08188    }
08189    *count = n;
08190    return p;
08191 }
08192 
08193 int stb_ps_writelist(stb_ps *ps, void **list, int size )
08194 {
08195    int i,n=0;
08196     switch (3 & (int)(size_t) ps) {
08197       case STB_ps_direct:
08198          if (ps == NULL || size <= 0) return 0;
08199          list[0] = ps;
08200          return 1;
08201       case STB_ps_bucket: {
08202          stb_ps_bucket *b = GetBucket(ps);
08203          for (i=0; i < STB_BUCKET_SIZE; ++i)
08204             if (b->p[i] != NULL && n < size)
08205                list[n++] = b->p[i];
08206          return n;
08207       }
08208       case STB_ps_array: {
08209          stb_ps_array *a = GetArray(ps);
08210          n = stb_min(size, a->count);
08211          memcpy(list, a->p, sizeof(*list) * n);
08212          return n;
08213       }
08214       case STB_ps_hash: {
08215          stb_ps_hash *h = GetHash(ps);
08216          if (size <= 0) return 0;
08217          for (i=0; i < h->count; ++i) {
08218              if (!stb_ps_empty((size_t)h->table[i])) {
08219                list[n++] = h->table[i];
08220                if (n == size) break;
08221             }
08222          }
08223          return n;
08224       }
08225    }
08226    return 0; /* NOTREACHED */
08227 }
08228 
08229 int stb_ps_enum(stb_ps *ps, void *data, int (*func)(void *value, void *data))
08230 {
08231    int i;
08232     switch (3 & (int)(size_t) ps) {
08233       case STB_ps_direct:
08234          if (ps == NULL) return STB_TRUE;
08235          return func(ps, data);
08236       case STB_ps_bucket: {
08237          stb_ps_bucket *b = GetBucket(ps);
08238          for (i=0; i < STB_BUCKET_SIZE; ++i)
08239             if (b->p[i] != NULL)
08240                if (!func(b->p[i], data))
08241                   return STB_FALSE;
08242          return STB_TRUE;
08243       }
08244       case STB_ps_array: {
08245          stb_ps_array *a = GetArray(ps);
08246          for (i=0; i < a->count; ++i)
08247             if (!func(a->p[i], data))
08248                return STB_FALSE;
08249          return STB_TRUE;
08250       }
08251       case STB_ps_hash: {
08252          stb_ps_hash *h = GetHash(ps);
08253          for (i=0; i < h->count; ++i)
08254               if (!stb_ps_empty((size_t)h->table[i]))
08255                if (!func(h->table[i], data))
08256                   return STB_FALSE;
08257          return STB_TRUE;
08258       }
08259    }
08260    return STB_TRUE; /* NOTREACHED */
08261 }
08262 
08263 int stb_ps_count (stb_ps *ps)
08264 {
08265     switch (3 & (int)(size_t) ps) {
08266       case STB_ps_direct:
08267          return ps != NULL;
08268       case STB_ps_bucket: {
08269          stb_ps_bucket *b = GetBucket(ps);
08270          return (b->p[0] != NULL) + (b->p[1] != NULL) +
08271                 (b->p[2] != NULL) + (b->p[3] != NULL);
08272       }
08273       case STB_ps_array: {
08274          stb_ps_array *a = GetArray(ps);
08275          return a->count;
08276       }
08277       case STB_ps_hash: {
08278          stb_ps_hash *h = GetHash(ps);
08279          return h->count;
08280       }
08281    }
08282    return 0;
08283 }
08284 
08285 void ** stb_ps_fastlist(stb_ps *ps, int *count)
08286 {
08287    static void *storage;
08288 
08289     switch (3 & (int)(size_t) ps) {
08290       case STB_ps_direct:
08291          if (ps == NULL) { *count = 0; return NULL; }
08292          storage = ps;
08293          *count = 1;
08294          return &storage;
08295       case STB_ps_bucket: {
08296          stb_ps_bucket *b = GetBucket(ps);
08297          *count = STB_BUCKET_SIZE;
08298          return b->p;
08299       }
08300       case STB_ps_array: {
08301          stb_ps_array *a = GetArray(ps);
08302          *count = a->count;
08303          return a->p;
08304       }
08305       case STB_ps_hash: {
08306          stb_ps_hash *h = GetHash(ps);
08307          *count = h->size;
08308          return h->table;
08309       }
08310    }
08311    return NULL; /* NOTREACHED */
08312 }
08313 
08314 int stb_ps_subset(stb_ps *bigger, stb_ps *smaller)
08315 {
08316    int i, listlen;
08317    void **list = stb_ps_fastlist(smaller, &listlen);
08318    for(i=0; i < listlen; ++i)
08319       if (stb_ps_fastlist_valid(list[i]))
08320          if (!stb_ps_find(bigger, list[i]))
08321             return 0;
08322    return 1;
08323 }
08324 
08325 int stb_ps_eq(stb_ps *p0, stb_ps *p1)
08326 {
08327    if (stb_ps_count(p0) != stb_ps_count(p1))
08328       return 0;
08329    return stb_ps_subset(p0, p1);
08330 }
08331 
08332 #undef GetBucket
08333 #undef GetArray
08334 #undef GetHash
08335 
08336 #undef EncodeBucket
08337 #undef EncodeArray
08338 #undef EncodeHash
08339 
08340 #endif
08341 
08342 
08344 //
08345 //               Random Numbers via Meresenne Twister or LCG
08346 //
08347 
08348 STB_EXTERN unsigned int  stb_srandLCG(unsigned int seed);
08349 STB_EXTERN unsigned int  stb_randLCG(void);
08350 STB_EXTERN double        stb_frandLCG(void);
08351 
08352 STB_EXTERN void          stb_srand(unsigned int seed);
08353 STB_EXTERN unsigned int  stb_rand(void);
08354 STB_EXTERN double        stb_frand(void);
08355 STB_EXTERN void          stb_shuffle(void *p, size_t n, size_t sz,
08356                                         unsigned int seed);
08357 STB_EXTERN void stb_reverse(void *p, size_t n, size_t sz);
08358 
08359 STB_EXTERN unsigned int  stb_randLCG_explicit(unsigned int  seed);
08360 
08361 #define stb_rand_define(x,y)                                         \
08362                                                                      \
08363    unsigned int  x(void)                                             \
08364    {                                                                 \
08365       static unsigned int  stb__rand = y;                            \
08366       stb__rand = stb__rand * 2147001325 + 715136305; /* BCPL */     \
08367       return 0x31415926 ^ ((stb__rand >> 16) + (stb__rand << 16));   \
08368    }
08369 
08370 #ifdef STB_DEFINE
08371 unsigned int  stb_randLCG_explicit(unsigned int seed)
08372 {
08373    return seed * 2147001325 + 715136305;
08374 }
08375 
08376 static unsigned int  stb__rand_seed=0;
08377 
08378 unsigned int  stb_srandLCG(unsigned int seed)
08379 {
08380    unsigned int  previous = stb__rand_seed;
08381    stb__rand_seed = seed;
08382    return previous;
08383 }
08384 
08385 unsigned int  stb_randLCG(void)
08386 {
08387    stb__rand_seed = stb__rand_seed * 2147001325 + 715136305; // BCPL generator
08388    // shuffle non-random bits to the middle, and xor to decorrelate with seed
08389    return 0x31415926 ^ ((stb__rand_seed >> 16) + (stb__rand_seed << 16));
08390 }
08391 
08392 double stb_frandLCG(void)
08393 {
08394    return stb_randLCG() / ((double) (1 << 16) * (1 << 16));
08395 }
08396 
08397 void stb_shuffle(void *p, size_t n, size_t sz, unsigned int seed)
08398 {
08399    char *a;
08400    unsigned int old_seed;
08401    int i;
08402    if (seed)
08403       old_seed = stb_srandLCG(seed);
08404    a = (char *) p + (n-1) * sz;
08405 
08406    for (i=(int) n; i > 1; --i) {
08407       int j = stb_randLCG() % i;
08408       stb_swap(a, (char *) p + j * sz, sz);
08409       a -= sz;
08410    }
08411    if (seed)
08412       stb_srandLCG(old_seed);
08413 }
08414 
08415 void stb_reverse(void *p, size_t n, size_t sz)
08416 {
08417    size_t i,j = n-1;
08418    for (i=0; i < j; ++i,--j) {
08419       stb_swap((char *) p + i * sz, (char *) p + j * sz, sz);
08420    }
08421 }
08422 
08423 // public domain Mersenne Twister by Michael Brundage
08424 #define STB__MT_LEN       624
08425 
08426 int stb__mt_index = STB__MT_LEN*sizeof(int)+1;
08427 unsigned int stb__mt_buffer[STB__MT_LEN];
08428 
08429 void stb_srand(unsigned int seed)
08430 {
08431    int i;
08432    unsigned int old = stb_srandLCG(seed);
08433    for (i = 0; i < STB__MT_LEN; i++)
08434       stb__mt_buffer[i] = stb_randLCG();
08435    stb_srandLCG(old);
08436    stb__mt_index = STB__MT_LEN*sizeof(unsigned int);
08437 }
08438 
08439 #define STB__MT_IA           397
08440 #define STB__MT_IB           (STB__MT_LEN - STB__MT_IA)
08441 #define STB__UPPER_MASK      0x80000000
08442 #define STB__LOWER_MASK      0x7FFFFFFF
08443 #define STB__MATRIX_A        0x9908B0DF
08444 #define STB__TWIST(b,i,j)    ((b)[i] & STB__UPPER_MASK) | ((b)[j] & STB__LOWER_MASK)
08445 #define STB__MAGIC(s)        (((s)&1)*STB__MATRIX_A)
08446 
08447 unsigned int stb_rand()
08448 {
08449    unsigned int  * b = stb__mt_buffer;
08450    int idx = stb__mt_index;
08451    unsigned int  s,r;
08452    int i;
08453 
08454    if (idx >= STB__MT_LEN*sizeof(unsigned int)) {
08455       if (idx > STB__MT_LEN*sizeof(unsigned int))
08456          stb_srand(0);
08457       idx = 0;
08458       i = 0;
08459       for (; i < STB__MT_IB; i++) {
08460          s = STB__TWIST(b, i, i+1);
08461          b[i] = b[i + STB__MT_IA] ^ (s >> 1) ^ STB__MAGIC(s);
08462       }
08463       for (; i < STB__MT_LEN-1; i++) {
08464          s = STB__TWIST(b, i, i+1);
08465          b[i] = b[i - STB__MT_IB] ^ (s >> 1) ^ STB__MAGIC(s);
08466       }
08467 
08468       s = STB__TWIST(b, STB__MT_LEN-1, 0);
08469       b[STB__MT_LEN-1] = b[STB__MT_IA-1] ^ (s >> 1) ^ STB__MAGIC(s);
08470    }
08471    stb__mt_index = idx + sizeof(unsigned int);
08472 
08473    r = *(unsigned int *)((unsigned char *)b + idx);
08474 
08475    r ^= (r >> 11);
08476    r ^= (r << 7) & 0x9D2C5680;
08477    r ^= (r << 15) & 0xEFC60000;
08478    r ^= (r >> 18);
08479 
08480    return r;
08481 }
08482 
08483 double stb_frand(void)
08484 {
08485    return stb_rand() / ((double) (1 << 16) * (1 << 16));
08486 }
08487 
08488 #endif
08489 
08490 
08492 //
08493 //                        stb_dupe
08494 //
08495 // stb_dupe is a duplicate-finding system for very, very large data
08496 // structures--large enough that sorting is too slow, but not so large
08497 // that we can't keep all the data in memory. using it works as follows:
08498 //
08499 //     1. create an stb_dupe:
08500 //          provide a hash function
08501 //          provide an equality function
08502 //          provide an estimate for the size
08503 //          optionally provide a comparison function
08504 //
08505 //     2. traverse your data, 'adding' pointers to the stb_dupe
08506 //
08507 //     3. finish and ask for duplicates
08508 //
08509 //        the stb_dupe will discard its intermediate data and build
08510 //        a collection of sorted lists of duplicates, with non-duplicate
08511 //        entries omitted entirely
08512 //
08513 //
08514 //  Implementation strategy:
08515 //
08516 //     while collecting the N items, we keep a hash table of approximate
08517 //     size sqrt(N). (if you tell use the N up front, the hash table is
08518 //     just that size exactly)
08519 //
08520 //     each entry in the hash table is just an stb__arr of pointers (no need
08521 //     to use stb_ps, because we don't need to delete from these)
08522 //
08523 //     for step 3, for each entry in the hash table, we apply stb_dupe to it
08524 //     recursively. once the size gets small enough (or doesn't decrease
08525 //     significantly), we switch to either using qsort() on the comparison
08526 //     function, or else we just do the icky N^2 gather
08527 
08528 
08529 typedef struct stb_dupe stb_dupe;
08530 
08531 typedef int (*stb_compare_func)(void *a, void *b);
08532 typedef int (*stb_hash_func)(void *a, unsigned int seed);
08533 
08534 STB_EXTERN void stb_dupe_free(stb_dupe *sd);
08535 STB_EXTERN stb_dupe *stb_dupe_create(stb_hash_func hash,
08536                           stb_compare_func eq, int size, stb_compare_func ineq);
08537 STB_EXTERN void stb_dupe_add(stb_dupe *sd, void *item);
08538 STB_EXTERN void stb_dupe_finish(stb_dupe *sd);
08539 STB_EXTERN int stb_dupe_numsets(stb_dupe *sd);
08540 STB_EXTERN void **stb_dupe_set(stb_dupe *sd, int num);
08541 STB_EXTERN int stb_dupe_set_count(stb_dupe *sd, int num);
08542 
08543 struct stb_dupe
08544 {
08545    void ***hash_table;
08546    int hash_size;
08547    int size_log2;
08548    int population;
08549 
08550    int hash_shift;
08551    stb_hash_func     hash;
08552 
08553    stb_compare_func  eq;
08554    stb_compare_func  ineq;
08555 
08556    void ***dupes;
08557 };
08558 
08559 #ifdef STB_DEFINE
08560 
08561 int stb_dupe_numsets(stb_dupe *sd)
08562 {
08563    assert(sd->hash_table == NULL);
08564    return stb_arr_len(sd->dupes);
08565 }
08566 
08567 void **stb_dupe_set(stb_dupe *sd, int num)
08568 {
08569    assert(sd->hash_table == NULL);
08570    return sd->dupes[num];
08571 }
08572 
08573 int stb_dupe_set_count(stb_dupe *sd, int num)
08574 {
08575    assert(sd->hash_table == NULL);
08576    return stb_arr_len(sd->dupes[num]);
08577 }
08578 
08579 stb_dupe *stb_dupe_create(stb_hash_func hash, stb_compare_func eq, int size,
08580                                               stb_compare_func ineq)
08581 {
08582    int i, hsize;
08583    stb_dupe *sd = (stb_dupe *) malloc(sizeof(*sd));
08584 
08585    sd->size_log2 = 4;
08586    hsize = 1 << sd->size_log2;
08587    while (hsize * hsize < size) {
08588       ++sd->size_log2;
08589       hsize *= 2;
08590    }
08591 
08592    sd->hash = hash;
08593    sd->eq   = eq;
08594    sd->ineq = ineq;
08595    sd->hash_shift = 0;
08596 
08597    sd->population = 0;
08598    sd->hash_size = hsize;
08599    sd->hash_table = (void ***) malloc(sizeof(*sd->hash_table) * hsize);
08600    for (i=0; i < hsize; ++i)
08601       sd->hash_table[i] = NULL;
08602 
08603    sd->dupes = NULL;
08604 
08605    return sd;
08606 }
08607 
08608 void stb_dupe_add(stb_dupe *sd, void *item)
08609 {
08610    stb_uint32 hash = sd->hash(item, sd->hash_shift);
08611    int z = hash & (sd->hash_size-1);
08612    stb_arr_push(sd->hash_table[z], item);
08613    ++sd->population;
08614 }
08615 
08616 void stb_dupe_free(stb_dupe *sd)
08617 {
08618    int i;
08619    for (i=0; i < stb_arr_len(sd->dupes); ++i)
08620       if (sd->dupes[i])
08621          stb_arr_free(sd->dupes[i]);
08622    stb_arr_free(sd->dupes);
08623    free(sd);
08624 }
08625 
08626 static stb_compare_func stb__compare;
08627 
08628 static int stb__dupe_compare(const void *a, const void *b)
08629 {
08630    void *p = *(void **) a;
08631    void *q = *(void **) b;
08632 
08633    return stb__compare(p,q);
08634 }
08635 
08636 void stb_dupe_finish(stb_dupe *sd)
08637 {
08638    int i,j,k;
08639    assert(sd->dupes == NULL);
08640    for (i=0; i < sd->hash_size; ++i) {
08641       void ** list = sd->hash_table[i];
08642       if (list != NULL) {
08643          int n = stb_arr_len(list);
08644          // @TODO: measure to find good numbers instead of just making them up!
08645          int thresh = (sd->ineq ? 200 : 20);
08646          // if n is large enough to be worth it, and n is smaller than
08647          // before (so we can guarantee we'll use a smaller hash table);
08648          // and there are enough hash bits left, assuming full 32-bit hash
08649          if (n > thresh && n < (sd->population >> 3) && sd->hash_shift + sd->size_log2*2 < 32) {
08650 
08651             // recursively process this row using stb_dupe, O(N log log N)
08652 
08653             stb_dupe *d = stb_dupe_create(sd->hash, sd->eq, n, sd->ineq);
08654             d->hash_shift = stb_randLCG_explicit(sd->hash_shift);
08655             for (j=0; j < n; ++j)
08656                stb_dupe_add(d, list[j]);
08657             stb_arr_free(sd->hash_table[i]);
08658             stb_dupe_finish(d);
08659             for (j=0; j < stb_arr_len(d->dupes); ++j) {
08660                stb_arr_push(sd->dupes, d->dupes[j]);
08661                d->dupes[j] = NULL; // take over ownership
08662             }
08663             stb_dupe_free(d);
08664 
08665          } else if (sd->ineq) {
08666 
08667             // process this row using qsort(), O(N log N)
08668             stb__compare = sd->ineq;
08669             qsort(list, n, sizeof(list[0]), stb__dupe_compare);
08670 
08671             // find equal subsequences of the list
08672             for (j=0; j < n-1; ) {
08673                // find a subsequence from j..k
08674                for (k=j; k < n; ++k)
08675                   // only use ineq so eq can be left undefined
08676                   if (sd->ineq(list[j], list[k]))
08677                      break;
08678                // k is the first one not in the subsequence
08679                if (k-j > 1) {
08680                   void **mylist = NULL;
08681                   stb_arr_setlen(mylist, k-j);
08682                   memcpy(mylist, list+j, sizeof(list[j]) * (k-j));
08683                   stb_arr_push(sd->dupes, mylist);
08684                }
08685                j = k;
08686             }
08687             stb_arr_free(sd->hash_table[i]);
08688          } else {
08689 
08690             // process this row using eq(), O(N^2)
08691             for (j=0; j < n; ++j) {
08692                if (list[j] != NULL) {
08693                   void **output  = NULL;
08694                   for (k=j+1; k < n; ++k) {
08695                      if (sd->eq(list[j], list[k])) {
08696                         if (output == NULL)
08697                            stb_arr_push(output, list[j]);
08698                         stb_arr_push(output, list[k]);
08699                         list[k] = NULL;
08700                      }
08701                   }
08702                   list[j] = NULL;
08703                   if (output)
08704                      stb_arr_push(sd->dupes, output);
08705                }
08706             }
08707             stb_arr_free(sd->hash_table[i]);
08708          }
08709       }
08710    }
08711    free(sd->hash_table);
08712    sd->hash_table = NULL;
08713 }
08714 #endif
08715 
08717 //
08718 //                       templatized Sort routine
08719 //
08720 // This is an attempt to implement a templated sorting algorithm.
08721 // To use it, you have to explicitly instantiate it as a _function_,
08722 // then you call that function. This allows the comparison to be inlined,
08723 // giving the sort similar performance to C++ sorts.
08724 //
08725 // It implements quicksort with three-way-median partitioning (generally
08726 // well-behaved), with a final insertion sort pass.
08727 //
08728 // When you define the compare expression, you should assume you have
08729 // elements of your array pointed to by 'a' and 'b', and perform the comparison
08730 // on those. OR you can use one or more statements; first say '0;', then
08731 // write whatever code you want, and compute the result into a variable 'c'.
08732 
08733 #define stb_declare_sort(FUNCNAME, TYPE)    \
08734                        void FUNCNAME(TYPE *p, int n)
08735 #define stb_define_sort(FUNCNAME,TYPE,COMPARE) \
08736                        stb__define_sort(       void, FUNCNAME,TYPE,COMPARE)
08737 #define stb_define_sort_static(FUNCNAME,TYPE,COMPARE) \
08738                        stb__define_sort(static void, FUNCNAME,TYPE,COMPARE)
08739 
08740 #define stb__define_sort(MODE, FUNCNAME, TYPE, COMPARE)                       \
08741                                                                               \
08742 static void STB_(FUNCNAME,_ins_sort)(TYPE *p, int n)                          \
08743 {                                                                             \
08744    int i,j;                                                                   \
08745    for (i=1; i < n; ++i) {                                                    \
08746       TYPE t = p[i], *a = &t;                                                 \
08747       j = i;                                                                  \
08748       while (j > 0) {                                                         \
08749          TYPE *b = &p[j-1];                                                   \
08750          int c = COMPARE;                                                     \
08751          if (!c) break;                                                       \
08752          p[j] = p[j-1];                                                       \
08753          --j;                                                                 \
08754       }                                                                       \
08755       if (i != j)                                                             \
08756          p[j] = t;                                                            \
08757    }                                                                          \
08758 }                                                                             \
08759                                                                               \
08760 static void STB_(FUNCNAME,_quicksort)(TYPE *p, int n)                         \
08761 {                                                                             \
08762    /* threshold for transitioning to insertion sort */                       \
08763    while (n > 12) {                                                           \
08764       TYPE *a,*b,t;                                                           \
08765       int c01,c12,c,m,i,j;                                                    \
08766                                                                               \
08767       /* compute median of three */                                           \
08768       m = n >> 1;                                                             \
08769       a = &p[0];                                                              \
08770       b = &p[m];                                                              \
08771       c = COMPARE;                                                            \
08772       c01 = c;                                                                \
08773       a = &p[m];                                                              \
08774       b = &p[n-1];                                                            \
08775       c = COMPARE;                                                            \
08776       c12 = c;                                                                \
08777       /* if 0 >= mid >= end, or 0 < mid < end, then use mid */                \
08778       if (c01 != c12) {                                                       \
08779          /* otherwise, we'll need to swap something else to middle */         \
08780          int z;                                                               \
08781          a = &p[0];                                                           \
08782          b = &p[n-1];                                                         \
08783          c = COMPARE;                                                         \
08784          /* 0>mid && mid<n:  0>n => n; 0<n => 0 */                            \
08785          /* 0<mid && mid>n:  0>n => 0; 0<n => n */                            \
08786          z = (c == c12) ? 0 : n-1;                                            \
08787          t = p[z];                                                            \
08788          p[z] = p[m];                                                         \
08789          p[m] = t;                                                            \
08790       }                                                                       \
08791       /* now p[m] is the median-of-three */                                   \
08792       /* swap it to the beginning so it won't move around */                  \
08793       t = p[0];                                                               \
08794       p[0] = p[m];                                                            \
08795       p[m] = t;                                                               \
08796                                                                               \
08797       /* partition loop */                                                    \
08798       i=1;                                                                    \
08799       j=n-1;                                                                  \
08800       for(;;) {                                                               \
08801          /* handling of equality is crucial here */                           \
08802          /* for sentinels & efficiency with duplicates */                     \
08803          b = &p[0];                                                           \
08804          for (;;++i) {                                                        \
08805             a=&p[i];                                                          \
08806             c = COMPARE;                                                      \
08807             if (!c) break;                                                    \
08808          }                                                                    \
08809          a = &p[0];                                                           \
08810          for (;;--j) {                                                        \
08811             b=&p[j];                                                          \
08812             c = COMPARE;                                                      \
08813             if (!c) break;                                                    \
08814          }                                                                    \
08815          /* make sure we haven't crossed */                                   \
08816          if (i >= j) break;                                                   \
08817          t = p[i];                                                            \
08818          p[i] = p[j];                                                         \
08819          p[j] = t;                                                            \
08820                                                                               \
08821          ++i;                                                                 \
08822          --j;                                                                 \
08823       }                                                                       \
08824       /* recurse on smaller side, iterate on larger */                        \
08825       if (j < (n-i)) {                                                        \
08826          STB_(FUNCNAME,_quicksort)(p,j);                                       \
08827          p = p+i;                                                             \
08828          n = n-i;                                                             \
08829       } else {                                                                \
08830          STB_(FUNCNAME,_quicksort)(p+i, n-i);                                  \
08831          n = j;                                                               \
08832       }                                                                       \
08833    }                                                                          \
08834 }                                                                             \
08835                                                                               \
08836 MODE FUNCNAME(TYPE *p, int n)                                                 \
08837 {                                                                             \
08838    STB_(FUNCNAME, _quicksort)(p, n);                                           \
08839    STB_(FUNCNAME, _ins_sort)(p, n);                                            \
08840 }                                                                             \
08841 
08842 
08844 //
08845 //      stb_bitset   an array of booleans indexed by integers
08846 //
08847 
08848 typedef stb_uint32 stb_bitset;
08849 
08850 STB_EXTERN  stb_bitset *stb_bitset_new(int value, int len);
08851 
08852 #define stb_bitset_clearall(arr,len)     (memset(arr,   0, 4 * (len)))
08853 #define stb_bitset_setall(arr,len)       (memset(arr, 255, 4 * (len)))
08854 
08855 #define stb_bitset_setbit(arr,n)         ((arr)[(n) >> 5] |=  (1 << (n & 31)))
08856 #define stb_bitset_clearbit(arr,n)       ((arr)[(n) >> 5] &= ~(1 << (n & 31)))
08857 #define stb_bitset_testbit(arr,n)        ((arr)[(n) >> 5] &   (1 << (n & 31)))
08858 
08859 STB_EXTERN  stb_bitset *stb_bitset_union(stb_bitset *p0, stb_bitset *p1, int len);
08860 
08861 STB_EXTERN  int *stb_bitset_getlist(stb_bitset *out, int start, int end);
08862 
08863 STB_EXTERN  int  stb_bitset_eq(stb_bitset *p0, stb_bitset *p1, int len);
08864 STB_EXTERN  int  stb_bitset_disjoint(stb_bitset *p0, stb_bitset *p1, int len);
08865 STB_EXTERN  int  stb_bitset_disjoint_0(stb_bitset *p0, stb_bitset *p1, int len);
08866 STB_EXTERN  int  stb_bitset_subset(stb_bitset *bigger, stb_bitset *smaller, int len);
08867 STB_EXTERN  int  stb_bitset_unioneq_changed(stb_bitset *p0, stb_bitset *p1, int len);
08868 
08869 #ifdef STB_DEFINE
08870 int stb_bitset_eq(stb_bitset *p0, stb_bitset *p1, int len)
08871 {
08872    int i;
08873    for (i=0; i < len; ++i)
08874       if (p0[i] != p1[i]) return 0;
08875    return 1;
08876 }
08877 
08878 int stb_bitset_disjoint(stb_bitset *p0, stb_bitset *p1, int len)
08879 {
08880    int i;
08881    for (i=0; i < len; ++i)
08882       if (p0[i] & p1[i]) return 0;
08883    return 1;
08884 }
08885 
08886 int stb_bitset_disjoint_0(stb_bitset *p0, stb_bitset *p1, int len)
08887 {
08888    int i;
08889    for (i=0; i < len; ++i)
08890       if ((p0[i] | p1[i]) != 0xffffffff) return 0;
08891    return 1;
08892 }
08893 
08894 int stb_bitset_subset(stb_bitset *bigger, stb_bitset *smaller, int len)
08895 {
08896    int i;
08897    for (i=0; i < len; ++i)
08898       if ((bigger[i] & smaller[i]) != smaller[i]) return 0;
08899    return 1;
08900 }
08901 
08902 stb_bitset *stb_bitset_union(stb_bitset *p0, stb_bitset *p1, int len)
08903 {
08904    int i;
08905    stb_bitset *d = (stb_bitset *) malloc(sizeof(*d) * len);
08906    for (i=0; i < len; ++i) d[i] = p0[i] | p1[i];
08907    return d;
08908 }
08909 
08910 int stb_bitset_unioneq_changed(stb_bitset *p0, stb_bitset *p1, int len)
08911 {
08912    int i, changed=0;
08913    for (i=0; i < len; ++i) {
08914       stb_bitset d = p0[i] | p1[i];
08915       if (d != p0[i]) {
08916          p0[i] = d;
08917          changed = 1;
08918       }
08919    }
08920    return changed;
08921 }
08922 
08923 stb_bitset *stb_bitset_new(int value, int len)
08924 {
08925    int i;
08926    stb_bitset *d = (stb_bitset *) malloc(sizeof(*d) * len);
08927    if (value) value = 0xffffffff;
08928    for (i=0; i < len; ++i) d[i] = value;
08929    return d;
08930 }
08931 
08932 int *stb_bitset_getlist(stb_bitset *out, int start, int end)
08933 {
08934    int *list = NULL;
08935    int i;
08936    for (i=start; i < end; ++i)
08937       if (stb_bitset_testbit(out, i))
08938          stb_arr_push(list, i);
08939    return list;
08940 }
08941 #endif
08942 
08944 //
08945 //      stb_wordwrap    quality word-wrapping for fixed-width fonts
08946 //
08947 
08948 STB_EXTERN int stb_wordwrap(int *pairs, int pair_max, int count, char *str);
08949 STB_EXTERN int *stb_wordwrapalloc(int count, char *str);
08950 
08951 #ifdef STB_DEFINE
08952 
08953 int stb_wordwrap(int *pairs, int pair_max, int count, char *str)
08954 {
08955    int n=0,i=0, start=0,nonwhite=0;
08956    if (pairs == NULL) pair_max = 0x7ffffff0;
08957    else pair_max *= 2;
08958    // parse
08959    for(;;) {
08960       int s=i; // first whitespace char; last nonwhite+1
08961       int w;   // word start
08962       // accept whitespace
08963       while (isspace(str[i])) {
08964          if (str[i] == '\n' || str[i] == '\r') {
08965             if (str[i] + str[i+1] == '\n' + '\r') ++i;
08966             if (n >= pair_max) return -1;
08967             if (pairs) pairs[n] = start, pairs[n+1] = s-start;
08968             n += 2;
08969             nonwhite=0;
08970             start = i+1;
08971             s = start;
08972          }
08973          ++i;
08974       }
08975       if (i >= start+count) {
08976          // we've gone off the end using whitespace
08977          if (nonwhite) {
08978             if (n >= pair_max) return -1;
08979             if (pairs) pairs[n] = start, pairs[n+1] = s-start;
08980             n += 2;
08981             start = s = i;
08982             nonwhite=0;
08983          } else {
08984             // output all the whitespace
08985             while (i >= start+count) {
08986                if (n >= pair_max) return -1;
08987                if (pairs) pairs[n] = start, pairs[n+1] = count;
08988                n += 2;
08989                start += count;
08990             }
08991             s = start;
08992          }
08993       }
08994 
08995       if (str[i] == 0) break;
08996       // now scan out a word and see if it fits
08997       w = i;
08998       while (str[i] && !isspace(str[i])) {
08999          ++i;
09000       }
09001       // wrapped?
09002       if (i > start + count) {
09003          // huge?
09004          if (i-s <= count) {
09005             if (n >= pair_max) return -1;
09006             if (pairs) pairs[n] = start, pairs[n+1] = s-start;
09007             n += 2;
09008             start = w;
09009          } else {
09010             // This word is longer than one line. If we wrap it onto N lines
09011             // there are leftover chars. do those chars fit on the cur line?
09012             // But if we have leading whitespace, we force it to start here.
09013             if ((w-start) + ((i-w) % count) <= count || !nonwhite) {
09014                // output a full line
09015                if (n >= pair_max) return -1;
09016                if (pairs) pairs[n] = start, pairs[n+1] = count;
09017                n += 2;
09018                start += count;
09019                w = start;
09020             } else {
09021                // output a partial line, trimming trailing whitespace
09022                if (s != start) {
09023                   if (n >= pair_max) return -1;
09024                   if (pairs) pairs[n] = start, pairs[n+1] = s-start;
09025                   n += 2;
09026                   start = w;
09027                }
09028             }
09029             // now output full lines as needed
09030             while (start + count <= i) {
09031                if (n >= pair_max) return -1;
09032                if (pairs) pairs[n] = start, pairs[n+1] = count;
09033                n += 2;
09034                start += count;
09035             }
09036          }
09037       }
09038       nonwhite=1;
09039    }
09040    if (start < i) {
09041       if (n >= pair_max) return -1;
09042       if (pairs) pairs[n] = start, pairs[n+1] = i-start;
09043       n += 2;
09044    }
09045    return n>>1;
09046 }
09047 
09048 int *stb_wordwrapalloc(int count, char *str)
09049 {
09050    int n = stb_wordwrap(NULL,0,count,str);
09051    int *z = NULL;
09052    stb_arr_setlen(z, n*2);
09053    stb_wordwrap(z, n, count, str);
09054    return z;
09055 }
09056 #endif
09057 
09058 
09060 //
09061 //         stb_match:    wildcards and regexping
09062 //
09063 
09064 STB_EXTERN int stb_wildmatch (char *expr, char *candidate);
09065 STB_EXTERN int stb_wildmatchi(char *expr, char *candidate);
09066 STB_EXTERN int stb_wildfind  (char *expr, char *candidate);
09067 STB_EXTERN int stb_wildfindi (char *expr, char *candidate);
09068 
09069 STB_EXTERN int stb_regex(char *regex, char *candidate);
09070 
09071 typedef struct stb_matcher stb_matcher;
09072 
09073 STB_EXTERN stb_matcher *stb_regex_matcher(char *regex);
09074 STB_EXTERN int stb_matcher_match(stb_matcher *m, char *str);
09075 STB_EXTERN int stb_matcher_find(stb_matcher *m, char *str);
09076 STB_EXTERN void stb_matcher_free(stb_matcher *f);
09077 
09078 STB_EXTERN stb_matcher *stb_lex_matcher(void);
09079 STB_EXTERN int stb_lex_item(stb_matcher *m, const char *str, int result);
09080 STB_EXTERN int stb_lex_item_wild(stb_matcher *matcher, const char *regex, int result);
09081 STB_EXTERN int stb_lex(stb_matcher *m, char *str, int *len);
09082 
09083 
09084 
09085 #ifdef STB_DEFINE
09086 
09087 static int stb__match_qstring(char *candidate, char *qstring, int qlen, int insensitive)
09088 {
09089    int i;
09090    if (insensitive) {
09091       for (i=0; i < qlen; ++i)
09092          if (qstring[i] == '?') {
09093             if (!candidate[i]) return 0;
09094          } else
09095             if (tolower(qstring[i]) != tolower(candidate[i]))
09096                return 0;
09097    } else {
09098       for (i=0; i < qlen; ++i)
09099          if (qstring[i] == '?') {
09100             if (!candidate[i]) return 0;
09101          } else
09102             if (qstring[i] != candidate[i])
09103                return 0;
09104    }
09105    return 1;
09106 }
09107 
09108 static int stb__find_qstring(char *candidate, char *qstring, int qlen, int insensitive)
09109 {
09110    char c;
09111 
09112    int offset=0;
09113    while (*qstring == '?') {
09114       ++qstring;
09115       --qlen;
09116       ++candidate;
09117       if (qlen == 0) return 0;
09118       if (*candidate == 0) return -1;
09119    }
09120 
09121    c = *qstring++;
09122    --qlen;
09123    if (insensitive) c = tolower(c);
09124 
09125    while (candidate[offset]) {
09126       if (c == (insensitive ? tolower(candidate[offset]) : candidate[offset]))
09127          if (stb__match_qstring(candidate+offset+1, qstring, qlen, insensitive))
09128             return offset;
09129       ++offset;
09130    }
09131 
09132    return -1;
09133 }
09134 
09135 int stb__wildmatch_raw2(char *expr, char *candidate, int search, int insensitive)
09136 {
09137    int where=0;
09138    int start = -1;
09139 
09140    if (!search) {
09141       // parse to first '*'
09142       if (*expr != '*')
09143          start = 0;
09144       while (*expr != '*') {
09145          if (!*expr)
09146             return *candidate == 0 ? 0 : -1;
09147          if (*expr == '?') {
09148             if (!*candidate) return -1;
09149          } else {
09150             if (insensitive) {
09151                if (tolower(*candidate) != tolower(*expr))
09152                   return -1;
09153             } else
09154                if (*candidate != *expr)
09155                   return -1;
09156          }
09157          ++candidate, ++expr, ++where;
09158       }
09159    } else {
09160       // 0-length search string
09161       if (!*expr)
09162          return 0;
09163    }
09164 
09165    assert(search || *expr == '*');
09166    if (!search)
09167       ++expr;
09168 
09169    // implicit '*' at this point
09170 
09171    while (*expr) {
09172       int o=0;
09173       // combine redundant * characters
09174       while (expr[0] == '*') ++expr;
09175 
09176       // ok, at this point, expr[-1] == '*',
09177       // and expr[0] != '*'
09178 
09179       if (!expr[0]) return start >= 0 ? start : 0;
09180 
09181       // now find next '*'
09182       o = 0;
09183       while (expr[o] != '*') {
09184          if (expr[o] == 0)
09185             break;
09186          ++o;
09187       }
09188       // if no '*', scan to end, then match at end
09189       if (expr[o] == 0 && !search) {
09190          int z;
09191          for (z=0; z < o; ++z)
09192             if (candidate[z] == 0)
09193                return -1;
09194          while (candidate[z])
09195             ++z;
09196          // ok, now check if they match
09197          if (stb__match_qstring(candidate+z-o, expr, o, insensitive))
09198             return start >= 0 ? start : 0;
09199          return -1;
09200       } else {
09201          // if yes '*', then do stb__find_qmatch on the intervening chars
09202          int n = stb__find_qstring(candidate, expr, o, insensitive);
09203          if (n < 0)
09204             return -1;
09205          if (start < 0)
09206             start = where + n;
09207          expr += o;
09208          candidate += n+o;
09209       }
09210 
09211       if (*expr == 0) {
09212          assert(search);
09213          return start;
09214       }
09215 
09216       assert(*expr == '*');
09217       ++expr;
09218    }
09219 
09220    return start >= 0 ? start : 0;
09221 }
09222 
09223 int stb__wildmatch_raw(char *expr, char *candidate, int search, int insensitive)
09224 {
09225    char buffer[256];
09226    // handle multiple search strings
09227    char *s = strchr(expr, ';');
09228    char *last = expr;
09229    while (s) {
09230       int z;
09231       // need to allow for non-writeable strings... assume they're small
09232       if (s - last < 256) {
09233          stb_strncpy(buffer, last, (int) (s-last+1));
09234          z = stb__wildmatch_raw2(buffer, candidate, search, insensitive);
09235       } else {
09236          *s = 0;
09237          z = stb__wildmatch_raw2(last, candidate, search, insensitive);
09238          *s = ';';
09239       }
09240       if (z >= 0) return z;
09241       last = s+1;
09242       s = strchr(last, ';');
09243    }
09244    return stb__wildmatch_raw2(last, candidate, search, insensitive);
09245 }
09246 
09247 int stb_wildmatch(char *expr, char *candidate)
09248 {
09249    return stb__wildmatch_raw(expr, candidate, 0,0) >= 0;
09250 }
09251 
09252 int stb_wildmatchi(char *expr, char *candidate)
09253 {
09254    return stb__wildmatch_raw(expr, candidate, 0,1) >= 0;
09255 }
09256 
09257 int stb_wildfind(char *expr, char *candidate)
09258 {
09259    return stb__wildmatch_raw(expr, candidate, 1,0);
09260 }
09261 
09262 int stb_wildfindi(char *expr, char *candidate)
09263 {
09264    return stb__wildmatch_raw(expr, candidate, 1,1);
09265 }
09266 
09267 typedef struct
09268 {
09269    stb_int16 transition[256];
09270 } stb_dfa;
09271 
09272 // an NFA node represents a state you're in; it then has
09273 // an arbitrary number of edges dangling off of it
09274 // note this isn't utf8-y
09275 typedef struct
09276 {
09277    stb_int16  match; // character/set to match
09278    stb_uint16 node;  // output node to go to
09279 } stb_nfa_edge;
09280 
09281 typedef struct
09282 {
09283    stb_int16 goal;   // does reaching this win the prize?
09284    stb_uint8 active; // is this in the active list
09285    stb_nfa_edge *out;
09286    stb_uint16 *eps;  // list of epsilon closures
09287 } stb_nfa_node;
09288 
09289 #define STB__DFA_UNDEF  -1
09290 #define STB__DFA_GOAL   -2
09291 #define STB__DFA_END    -3
09292 #define STB__DFA_MGOAL  -4
09293 #define STB__DFA_VALID  0
09294 
09295 #define STB__NFA_STOP_GOAL -1
09296 
09297 // compiled regexp
09298 struct stb_matcher
09299 {
09300    stb_uint16 start_node;
09301    stb_int16 dfa_start;
09302    stb_uint32 *charset;
09303    int num_charset;
09304    int match_start;
09305    stb_nfa_node *nodes;
09306    int does_lex;
09307 
09308    // dfa matcher
09309    stb_dfa    * dfa;
09310    stb_uint32 * dfa_mapping;
09311    stb_int16  * dfa_result;
09312    int num_words_per_dfa;
09313 };
09314 
09315 static int stb__add_node(stb_matcher *matcher)
09316 {
09317    stb_nfa_node z;
09318    z.active = 0;
09319    z.eps    = 0;
09320    z.goal   = 0;
09321    z.out    = 0;
09322    stb_arr_push(matcher->nodes, z);
09323    return stb_arr_len(matcher->nodes)-1;
09324 }
09325 
09326 static void stb__add_epsilon(stb_matcher *matcher, int from, int to)
09327 {
09328    assert(from != to);
09329    if (matcher->nodes[from].eps == NULL)
09330       stb_arr_malloc((void **) &matcher->nodes[from].eps, matcher);
09331    stb_arr_push(matcher->nodes[from].eps, to);
09332 }
09333 
09334 static void stb__add_edge(stb_matcher *matcher, int from, int to, int type)
09335 {
09336     stb_nfa_edge z = { (stb_int16)type, (stb_uint16)to };
09337    if (matcher->nodes[from].out == NULL)
09338       stb_arr_malloc((void **) &matcher->nodes[from].out, matcher);
09339    stb_arr_push(matcher->nodes[from].out, z);
09340 }
09341 
09342 static char *stb__reg_parse_alt(stb_matcher *m, int s, char *r, stb_uint16 *e);
09343 static char *stb__reg_parse(stb_matcher *matcher, int start, char *regex, stb_uint16 *end)
09344 {
09345    int n;
09346    int last_start = -1;
09347    stb_uint16 last_end = start;
09348 
09349    while (*regex) {
09350       switch (*regex) {
09351          case '(':
09352             last_start = last_end;
09353             regex = stb__reg_parse_alt(matcher, last_end, regex+1, &last_end);
09354             if (regex == NULL || *regex != ')')
09355                return NULL;
09356             ++regex;
09357             break;
09358 
09359          case '|':
09360          case ')':
09361             *end = last_end;
09362             return regex;
09363 
09364          case '?':
09365             if (last_start < 0) return NULL;
09366             stb__add_epsilon(matcher, last_start, last_end);
09367             ++regex;
09368             break;
09369 
09370          case '*':
09371             if (last_start < 0) return NULL;
09372             stb__add_epsilon(matcher, last_start, last_end);
09373 
09374             // fall through
09375 
09376          case '+':
09377             if (last_start < 0) return NULL;
09378             stb__add_epsilon(matcher, last_end, last_start);
09379             // prevent links back to last_end from chaining to last_start
09380             n = stb__add_node(matcher);
09381             stb__add_epsilon(matcher, last_end, n);
09382             last_end = n;
09383             ++regex;
09384             break;
09385 
09386          case '{':   // not supported!
09387             // @TODO: given {n,m}, clone last_start to last_end m times,
09388             // and include epsilons from start to first m-n blocks
09389             return NULL;
09390 
09391          case '\\':
09392             ++regex;
09393             if (!*regex) return NULL;
09394 
09395             // fallthrough
09396          default: // match exactly this character
09397             n = stb__add_node(matcher);
09398             stb__add_edge(matcher, last_end, n, *regex);
09399             last_start = last_end;
09400             last_end = n;
09401             ++regex;
09402             break;
09403 
09404          case '$':
09405             n = stb__add_node(matcher);
09406             stb__add_edge(matcher, last_end, n, '\n');
09407             last_start = last_end;
09408             last_end = n;
09409             ++regex;
09410             break;
09411 
09412          case '.':
09413             n = stb__add_node(matcher);
09414             stb__add_edge(matcher, last_end, n, -1);
09415             last_start = last_end;
09416             last_end = n;
09417             ++regex;
09418             break;
09419 
09420          case '[': {
09421             stb_uint8 flags[256];
09422             int invert = 0,z;
09423             ++regex;
09424             if (matcher->num_charset == 0) {
09425                matcher->charset = (stb_uint *) stb_malloc(matcher, sizeof(*matcher->charset) * 256);
09426                memset(matcher->charset, 0, sizeof(*matcher->charset) * 256);
09427             }
09428 
09429             memset(flags,0,sizeof(flags));
09430 
09431             // leading ^ is special
09432             if (*regex == '^')
09433                ++regex, invert = 1;
09434 
09435             // leading ] is special
09436             if (*regex == ']') {
09437                flags[(int) ']'] = 1;
09438                ++regex;
09439             }
09440             while (*regex != ']') {
09441                stb_uint a;
09442                if (!*regex) return NULL;
09443                a = *regex++;
09444                if (regex[0] == '-' && regex[1] != ']') {
09445                   stb_uint i,b = regex[1];
09446                   regex += 2;
09447                   if (b == 0) return NULL;
09448                   if (a > b) return NULL;
09449                   for (i=a; i <= b; ++i)
09450                      flags[i] = 1;
09451                } else
09452                   flags[a] = 1;
09453             }
09454             ++regex;
09455             if (invert) {
09456                int i;
09457                for (i=0; i < 256; ++i)
09458                   flags[i] = 1-flags[i];
09459             }
09460 
09461             // now check if any existing charset matches
09462             for (z=0; z < matcher->num_charset; ++z) {
09463                int i, k[2] = { 0, 1 << z};
09464                for (i=0; i < 256; ++i) {
09465                   unsigned int f = k[flags[i]];
09466                   if ((matcher->charset[i] & k[1]) != f)
09467                      break;
09468                }
09469                if (i == 256) break;
09470             }
09471 
09472             if (z == matcher->num_charset) {
09473                int i;
09474                ++matcher->num_charset;
09475                if (matcher->num_charset > 32) {
09476                   assert(0); /* NOTREACHED */
09477                   return NULL; // too many charsets, oops
09478                }
09479                for (i=0; i < 256; ++i)
09480                   if (flags[i])
09481                      matcher->charset[i] |= (1 << z);
09482             }
09483 
09484             n = stb__add_node(matcher);
09485             stb__add_edge(matcher, last_end, n, -2 - z);
09486             last_start = last_end;
09487             last_end = n;
09488             break;
09489          }
09490       }
09491    }
09492    *end = last_end;
09493    return regex;
09494 }
09495 
09496 static char *stb__reg_parse_alt(stb_matcher *matcher, int start, char *regex, stb_uint16 *end)
09497 {
09498    stb_uint16 last_end = start;
09499    stb_uint16 main_end;
09500 
09501    int head, tail;
09502 
09503    head = stb__add_node(matcher);
09504    stb__add_epsilon(matcher, start, head);
09505 
09506    regex = stb__reg_parse(matcher, head, regex, &last_end);
09507    if (regex == NULL) return NULL;
09508    if (*regex == 0 || *regex == ')') {
09509       *end = last_end;
09510       return regex;
09511    }
09512 
09513    main_end = last_end;
09514    tail = stb__add_node(matcher);
09515 
09516    stb__add_epsilon(matcher, last_end, tail);
09517 
09518    // start alternatives from the same starting node; use epsilon
09519    // transitions to combine their endings
09520    while(*regex && *regex != ')') {
09521       assert(*regex == '|');
09522       head = stb__add_node(matcher);
09523       stb__add_epsilon(matcher, start, head);
09524       regex = stb__reg_parse(matcher, head, regex+1, &last_end);
09525       if (regex == NULL)
09526          return NULL;
09527       stb__add_epsilon(matcher, last_end, tail);
09528    }
09529 
09530    *end = tail;
09531    return regex;
09532 }
09533 
09534 static char *stb__wild_parse(stb_matcher *matcher, int start, char *str, stb_uint16 *end)
09535 {
09536    int n;
09537    stb_uint16 last_end;
09538 
09539    last_end = stb__add_node(matcher);
09540    stb__add_epsilon(matcher, start, last_end);
09541 
09542    while (*str) {
09543       switch (*str) {
09544             // fallthrough
09545          default: // match exactly this character
09546             n = stb__add_node(matcher);
09547             if (toupper(*str) == tolower(*str)) {
09548                stb__add_edge(matcher, last_end, n, *str);
09549             } else {
09550                stb__add_edge(matcher, last_end, n, tolower(*str));
09551                stb__add_edge(matcher, last_end, n, toupper(*str));
09552             }
09553             last_end = n;
09554             ++str;
09555             break;
09556 
09557          case '?':
09558             n = stb__add_node(matcher);
09559             stb__add_edge(matcher, last_end, n, -1);
09560             last_end = n;
09561             ++str;
09562             break;
09563 
09564          case '*':
09565             n = stb__add_node(matcher);
09566             stb__add_edge(matcher, last_end, n, -1);
09567             stb__add_epsilon(matcher, last_end, n);
09568             stb__add_epsilon(matcher, n, last_end);
09569             last_end = n;
09570             ++str;
09571             break;
09572       }
09573    }
09574 
09575    // now require end of string to match
09576    n = stb__add_node(matcher);
09577    stb__add_edge(matcher, last_end, n, 0);
09578    last_end = n;
09579 
09580    *end = last_end;
09581    return str;
09582 }
09583 
09584 static int stb__opt(stb_matcher *m, int n)
09585 {
09586    for(;;) {
09587       stb_nfa_node *p = &m->nodes[n];
09588       if (p->goal)                  return n;
09589       if (stb_arr_len(p->out))      return n;
09590       if (stb_arr_len(p->eps) != 1) return n;
09591       n = p->eps[0];
09592    }
09593 }
09594 
09595 static void stb__optimize(stb_matcher *m)
09596 {
09597    // if the target of any edge is a node with exactly
09598    // one out-epsilon, shorten it
09599    int i,j;
09600    for (i=0; i < stb_arr_len(m->nodes); ++i) {
09601       stb_nfa_node *p = &m->nodes[i];
09602       for (j=0; j < stb_arr_len(p->out); ++j)
09603          p->out[j].node = stb__opt(m,p->out[j].node);
09604       for (j=0; j < stb_arr_len(p->eps); ++j)
09605          p->eps[j]      = stb__opt(m,p->eps[j]     );
09606    }
09607    m->start_node = stb__opt(m,m->start_node);
09608 }
09609 
09610 void stb_matcher_free(stb_matcher *f)
09611 {
09612    stb_free(f);
09613 }
09614 
09615 static stb_matcher *stb__alloc_matcher(void)
09616 {
09617    stb_matcher *matcher = (stb_matcher *) stb_malloc(0,sizeof(*matcher));
09618 
09619    matcher->start_node  = 0;
09620    stb_arr_malloc((void **) &matcher->nodes, matcher);
09621    matcher->num_charset = 0;
09622    matcher->match_start = 0;
09623    matcher->does_lex    = 0;
09624 
09625    matcher->dfa_start   = STB__DFA_UNDEF;
09626    stb_arr_malloc((void **) &matcher->dfa, matcher);
09627    stb_arr_malloc((void **) &matcher->dfa_mapping, matcher);
09628    stb_arr_malloc((void **) &matcher->dfa_result, matcher);
09629 
09630    stb__add_node(matcher);
09631 
09632    return matcher;
09633 }
09634 
09635 static void stb__lex_reset(stb_matcher *matcher)
09636 {
09637    // flush cached dfa data
09638    stb_arr_setlen(matcher->dfa, 0);
09639    stb_arr_setlen(matcher->dfa_mapping, 0);
09640    stb_arr_setlen(matcher->dfa_result, 0);
09641    matcher->dfa_start = STB__DFA_UNDEF;
09642 }
09643 
09644 stb_matcher *stb_regex_matcher(char *regex)
09645 {
09646    char *z;
09647    stb_uint16 end;
09648    stb_matcher *matcher = stb__alloc_matcher();
09649    if (*regex == '^') {
09650       matcher->match_start = 1;
09651       ++regex;
09652    }
09653 
09654    z = stb__reg_parse_alt(matcher, matcher->start_node, regex, &end);
09655 
09656    if (!z || *z) {
09657       stb_free(matcher);
09658       return NULL;
09659    }
09660 
09661    ((matcher->nodes)[(int) end]).goal = STB__NFA_STOP_GOAL;
09662 
09663    return matcher;
09664 }
09665 
09666 stb_matcher *stb_lex_matcher(void)
09667 {
09668    stb_matcher *matcher = stb__alloc_matcher();
09669 
09670    matcher->match_start = 1;
09671    matcher->does_lex    = 1;
09672 
09673    return matcher;
09674 }
09675 
09676 int stb_lex_item(stb_matcher *matcher, const char *regex, int result)
09677 {
09678    char *z;
09679    stb_uint16 end;
09680 
09681    z = stb__reg_parse_alt(matcher, matcher->start_node, (char*) regex, &end);
09682 
09683    if (z == NULL)
09684       return 0;
09685 
09686    stb__lex_reset(matcher);
09687 
09688    matcher->nodes[(int) end].goal = result;
09689    return 1;
09690 }
09691 
09692 int stb_lex_item_wild(stb_matcher *matcher, const char *regex, int result)
09693 {
09694    char *z;
09695    stb_uint16 end;
09696 
09697    z = stb__wild_parse(matcher, matcher->start_node, (char*) regex, &end);
09698 
09699    if (z == NULL)
09700       return 0;
09701 
09702    stb__lex_reset(matcher);
09703 
09704    matcher->nodes[(int) end].goal = result;
09705    return 1;
09706 }
09707 
09708 static void stb__clear(stb_matcher *m, stb_uint16 *list)
09709 {
09710    int i;
09711    for (i=0; i < stb_arr_len(list); ++i)
09712       m->nodes[(int) list[i]].active = 0;
09713 }
09714 
09715 static int stb__clear_goalcheck(stb_matcher *m, stb_uint16 *list)
09716 {
09717    int i, t=0;
09718    for (i=0; i < stb_arr_len(list); ++i) {
09719       t += m->nodes[(int) list[i]].goal;
09720       m->nodes[(int) list[i]].active = 0;
09721    }
09722    return t;
09723 }
09724 
09725 static stb_uint16 * stb__add_if_inactive(stb_matcher *m, stb_uint16 *list, int n)
09726 {
09727    if (!m->nodes[n].active) {
09728       stb_arr_push(list, n);
09729       m->nodes[n].active = 1;
09730    }
09731    return list;
09732 }
09733 
09734 static stb_uint16 * stb__eps_closure(stb_matcher *m, stb_uint16 *list)
09735 {
09736    int i,n = stb_arr_len(list);
09737 
09738    for(i=0; i < n; ++i) {
09739       stb_uint16 *e = m->nodes[(int) list[i]].eps;
09740       if (e) {
09741          int j,k = stb_arr_len(e);
09742          for (j=0; j < k; ++j)
09743             list = stb__add_if_inactive(m, list, e[j]);
09744          n = stb_arr_len(list);
09745       }
09746    }
09747 
09748    return list;
09749 }
09750 
09751 int stb_matcher_match(stb_matcher *m, char *str)
09752 {
09753    int result = 0;
09754    int i,j,y,z;
09755    stb_uint16 *previous = NULL;
09756    stb_uint16 *current = NULL;
09757    stb_uint16 *temp;
09758 
09759    stb_arr_setsize(previous, 4);
09760    stb_arr_setsize(current, 4);
09761 
09762    previous = stb__add_if_inactive(m, previous, m->start_node);
09763    previous = stb__eps_closure(m,previous);
09764    stb__clear(m, previous);
09765 
09766    while (*str && stb_arr_len(previous)) {
09767       y = stb_arr_len(previous);
09768       for (i=0; i < y; ++i) {
09769          stb_nfa_node *n = &m->nodes[(int) previous[i]];
09770          z = stb_arr_len(n->out);
09771          for (j=0; j < z; ++j) {
09772             if (n->out[j].match >= 0) {
09773                if (n->out[j].match == *str)
09774                   current = stb__add_if_inactive(m, current, n->out[j].node);
09775             } else if (n->out[j].match == -1) {
09776                if (*str != '\n')
09777                   current = stb__add_if_inactive(m, current, n->out[j].node);
09778             } else if (n->out[j].match < -1) {
09779                int z = -n->out[j].match - 2;
09780                if (m->charset[(stb_uint8) *str] & (1 << z))
09781                   current = stb__add_if_inactive(m, current, n->out[j].node);
09782             }
09783          }
09784       }
09785       stb_arr_setlen(previous, 0);
09786 
09787       temp = previous;
09788       previous = current;
09789       current = temp;
09790 
09791       previous = stb__eps_closure(m,previous);
09792       stb__clear(m, previous);
09793 
09794       ++str;
09795    }
09796 
09797    // transition to pick up a '$' at the end
09798    y = stb_arr_len(previous);
09799    for (i=0; i < y; ++i)
09800       m->nodes[(int) previous[i]].active = 1;
09801 
09802    for (i=0; i < y; ++i) {
09803       stb_nfa_node *n = &m->nodes[(int) previous[i]];
09804       z = stb_arr_len(n->out);
09805       for (j=0; j < z; ++j) {
09806          if (n->out[j].match == '\n')
09807             current = stb__add_if_inactive(m, current, n->out[j].node);
09808       }
09809    }
09810 
09811    previous = stb__eps_closure(m,previous);
09812    stb__clear(m, previous);
09813 
09814    y = stb_arr_len(previous);
09815    for (i=0; i < y; ++i)
09816       if (m->nodes[(int) previous[i]].goal)
09817          result = 1;
09818 
09819    stb_arr_free(previous);
09820    stb_arr_free(current);
09821 
09822    return result && *str == 0;
09823 }
09824 
09825 stb_int16 stb__get_dfa_node(stb_matcher *m, stb_uint16 *list)
09826 {
09827    stb_uint16 node;
09828    stb_uint32 data[8], *state, *newstate;
09829    int i,j,n;
09830 
09831    state = (stb_uint32 *) stb_temp(data, m->num_words_per_dfa * 4);
09832    memset(state, 0, m->num_words_per_dfa*4);
09833 
09834    n = stb_arr_len(list);
09835    for (i=0; i < n; ++i) {
09836       int x = list[i];
09837       state[x >> 5] |= 1 << (x & 31);
09838    }
09839 
09840    // @TODO use a hash table
09841    n = stb_arr_len(m->dfa_mapping);
09842    i=j=0;
09843    for(; j < n; ++i, j += m->num_words_per_dfa) {
09844       // @TODO special case for <= 32
09845       if (!memcmp(state, m->dfa_mapping + j, m->num_words_per_dfa*4)) {
09846          node = i;
09847          goto done;
09848       }
09849    }
09850 
09851    assert(stb_arr_len(m->dfa) == i);
09852    node = i;
09853 
09854    newstate = stb_arr_addn(m->dfa_mapping, m->num_words_per_dfa);
09855    memcpy(newstate, state, m->num_words_per_dfa*4);
09856 
09857    // set all transitions to 'unknown'
09858    stb_arr_add(m->dfa);
09859    memset(m->dfa[i].transition, -1, sizeof(m->dfa[i].transition));
09860 
09861    if (m->does_lex) {
09862       int result = -1;
09863       n = stb_arr_len(list);
09864       for (i=0; i < n; ++i) {
09865          if (m->nodes[(int) list[i]].goal > result)
09866             result = m->nodes[(int) list[i]].goal;
09867       }
09868 
09869       stb_arr_push(m->dfa_result, result);
09870    }
09871 
09872 done:
09873    stb_tempfree(data, state);
09874    return node;
09875 }
09876 
09877 static int stb__matcher_dfa(stb_matcher *m, char *str_c, int *len)
09878 {
09879    stb_uint8 *str = (stb_uint8 *) str_c;
09880    stb_int16 node,prevnode;
09881    stb_dfa *trans;
09882    int match_length = 0;
09883    stb_int16 match_result=0;
09884 
09885    if (m->dfa_start == STB__DFA_UNDEF) {
09886       stb_uint16 *list;
09887 
09888       m->num_words_per_dfa = (stb_arr_len(m->nodes)+31) >> 5;
09889       stb__optimize(m);
09890 
09891       list = stb__add_if_inactive(m, NULL, m->start_node);
09892       list = stb__eps_closure(m,list);
09893       if (m->does_lex) {
09894          m->dfa_start = stb__get_dfa_node(m,list);
09895          stb__clear(m, list);
09896          // DON'T allow start state to be a goal state!
09897          // this allows people to specify regexes that can match 0
09898          // characters without them actually matching (also we don't
09899          // check _before_ advancing anyway
09900          if (m->dfa_start <= STB__DFA_MGOAL)
09901             m->dfa_start = -(m->dfa_start - STB__DFA_MGOAL);
09902       } else {
09903          if (stb__clear_goalcheck(m, list))
09904             m->dfa_start = STB__DFA_GOAL;
09905          else
09906             m->dfa_start = stb__get_dfa_node(m,list);
09907       }
09908       stb_arr_free(list);
09909    }
09910 
09911    prevnode = STB__DFA_UNDEF;
09912    node = m->dfa_start;
09913    trans = m->dfa;
09914 
09915    if (m->dfa_start == STB__DFA_GOAL)
09916       return 1;
09917 
09918    for(;;) {
09919       assert(node >= STB__DFA_VALID);
09920 
09921       // fast inner DFA loop; especially if STB__DFA_VALID is 0
09922 
09923       do {
09924          prevnode = node;
09925          node = trans[node].transition[*str++];
09926       } while (node >= STB__DFA_VALID);
09927 
09928       assert(node >= STB__DFA_MGOAL - stb_arr_len(m->dfa));
09929       assert(node < stb_arr_len(m->dfa));
09930 
09931       // special case for lex: need _longest_ match, so notice goal
09932       // state without stopping
09933       if (node <= STB__DFA_MGOAL) {
09934          match_length = (int) (str - (stb_uint8 *) str_c);
09935          node = -(node - STB__DFA_MGOAL);
09936          match_result = node;
09937          continue;
09938       }
09939 
09940       // slow NFA->DFA conversion
09941 
09942       // or we hit the goal or the end of the string, but those
09943       // can only happen once per search...
09944 
09945       if (node == STB__DFA_UNDEF) {
09946          // build a list  -- @TODO special case <= 32 states
09947          // heck, use a more compact data structure for <= 16 and <= 8 ?!
09948 
09949          // @TODO keep states/newstates around instead of reallocating them
09950          stb_uint16 *states = NULL;
09951          stb_uint16 *newstates = NULL;
09952          int i,j,y,z;
09953          stb_uint32 *flags = &m->dfa_mapping[prevnode * m->num_words_per_dfa];
09954          assert(prevnode != STB__DFA_UNDEF);
09955          stb_arr_setsize(states, 4);
09956          stb_arr_setsize(newstates,4);
09957          for (j=0; j < m->num_words_per_dfa; ++j) {
09958             for (i=0; i < 32; ++i) {
09959                if (*flags & (1 << i))
09960                   stb_arr_push(states, j*32+i);
09961             }
09962             ++flags;
09963          }
09964          // states is now the states we were in in the previous node;
09965          // so now we can compute what node it transitions to on str[-1]
09966 
09967          y = stb_arr_len(states);
09968          for (i=0; i < y; ++i) {
09969             stb_nfa_node *n = &m->nodes[(int) states[i]];
09970             z = stb_arr_len(n->out);
09971             for (j=0; j < z; ++j) {
09972                if (n->out[j].match >= 0) {
09973                   if (n->out[j].match == str[-1] || (str[-1] == 0 && n->out[j].match == '\n'))
09974                      newstates = stb__add_if_inactive(m, newstates, n->out[j].node);
09975                } else if (n->out[j].match == -1) {
09976                   if (str[-1] != '\n' && str[-1])
09977                      newstates = stb__add_if_inactive(m, newstates, n->out[j].node);
09978                } else if (n->out[j].match < -1) {
09979                   int z = -n->out[j].match - 2;
09980                   if (m->charset[str[-1]] & (1 << z))
09981                      newstates = stb__add_if_inactive(m, newstates, n->out[j].node);
09982                }
09983             }
09984          }
09985          // AND add in the start state!
09986          if (!m->match_start || (str[-1] == '\n' && !m->does_lex))
09987             newstates = stb__add_if_inactive(m, newstates, m->start_node);
09988          // AND epsilon close it
09989          newstates = stb__eps_closure(m, newstates);
09990          // if it's a goal state, then that's all there is to it
09991          if (stb__clear_goalcheck(m, newstates)) {
09992             if (m->does_lex) {
09993                match_length = (int) (str - (stb_uint8 *) str_c);
09994                node = stb__get_dfa_node(m,newstates);
09995                match_result = node;
09996                node = -node + STB__DFA_MGOAL;
09997                trans = m->dfa; // could have gotten realloc()ed
09998             } else
09999                node = STB__DFA_GOAL;
10000          } else if (str[-1] == 0 || stb_arr_len(newstates) == 0) {
10001             node = STB__DFA_END;
10002          } else {
10003             node = stb__get_dfa_node(m,newstates);
10004             trans = m->dfa; // could have gotten realloc()ed
10005          }
10006          trans[prevnode].transition[str[-1]] = node;
10007          if (node <= STB__DFA_MGOAL)
10008             node = -(node - STB__DFA_MGOAL);
10009          stb_arr_free(newstates);
10010          stb_arr_free(states);
10011       }
10012 
10013       if (node == STB__DFA_GOAL) {
10014          return 1;
10015       }
10016       if (node == STB__DFA_END) {
10017          if (m->does_lex) {
10018             if (match_result) {
10019                if (len) *len = match_length;
10020                return m->dfa_result[(int) match_result];
10021             }
10022          }
10023          return 0;
10024       }
10025 
10026       assert(node != STB__DFA_UNDEF);
10027    }
10028 }
10029 
10030 int stb_matcher_find(stb_matcher *m, char *str)
10031 {
10032    assert(m->does_lex == 0);
10033    return stb__matcher_dfa(m, str, NULL);
10034 }
10035 
10036 int stb_lex(stb_matcher *m, char *str, int *len)
10037 {
10038    assert(m->does_lex);
10039    return stb__matcher_dfa(m, str, len);
10040 }
10041 
10042 #ifdef STB_PERFECT_HASH
10043 int stb_regex(char *regex, char *str)
10044 {
10045    static stb_perfect p;
10046    static stb_matcher ** matchers;
10047    static char        ** regexps;
10048    static char        ** regexp_cache;
10049    static unsigned short *mapping;
10050     int z = stb_perfect_hash(&p, (int)(size_t) regex);
10051    if (z >= 0) {
10052       if (strcmp(regex, regexp_cache[(int) mapping[z]])) {
10053          int i = mapping[z];
10054          stb_matcher_free(matchers[i]);
10055          free(regexp_cache[i]);
10056          regexps[i] = regex;
10057          regexp_cache[i] = stb_p_strdup(regex);
10058          matchers[i] = stb_regex_matcher(regex);
10059       }
10060    } else {
10061       int i,n;
10062       if (regex == NULL) {
10063          for (i=0; i < stb_arr_len(matchers); ++i) {
10064             stb_matcher_free(matchers[i]);
10065             free(regexp_cache[i]);
10066          }
10067          stb_arr_free(matchers);
10068          stb_arr_free(regexps);
10069          stb_arr_free(regexp_cache);
10070          stb_perfect_destroy(&p);
10071          free(mapping); mapping = NULL;
10072          return -1;
10073       }
10074       stb_arr_push(regexps, regex);
10075       stb_arr_push(regexp_cache, stb_p_strdup(regex));
10076       stb_arr_push(matchers, stb_regex_matcher(regex));
10077       stb_perfect_destroy(&p);
10078       n = stb_perfect_create(&p, (unsigned int *) (char **) regexps, stb_arr_len(regexps));
10079       mapping = (unsigned short *) realloc(mapping, n * sizeof(*mapping));
10080       for (i=0; i < stb_arr_len(regexps); ++i)
10081           mapping[stb_perfect_hash(&p, (int)(size_t) regexps[i])] = i;
10082       z = stb_perfect_hash(&p, (int)(size_t) regex);
10083    }
10084    return stb_matcher_find(matchers[(int) mapping[z]], str);
10085 }
10086 #endif
10087 #endif // STB_DEFINE
10088 
10089 
10090 #if 0
10091 
10092 //
10093 //                      C source-code introspection
10094 //
10095 
10096 // runtime structure
10097 typedef struct
10098 {
10099    char *name;
10100    char *type;     // base type
10101    char *comment;  // content of comment field
10102    int   size;     // size of base type
10103    int   offset;   // field offset
10104    int   arrcount[8]; // array sizes; -1 = pointer indirection; 0 = end of list
10105 } stb_info_field;
10106 
10107 typedef struct
10108 {
10109    char *structname;
10110    int size;
10111    int num_fields;
10112    stb_info_field *fields;
10113 } stb_info_struct;
10114 
10115 extern stb_info_struct stb_introspect_output[];
10116 
10117 //
10118 
10119 STB_EXTERN void stb_introspect_precompiled(stb_info_struct *compiled);
10120 STB_EXTERN void stb__introspect(char *path, char *file);
10121 
10122 #define stb_introspect_ship()            stb__introspect(NULL, NULL, stb__introspect_output)
10123 
10124 #ifdef STB_SHIP
10125 #define stb_introspect()                 stb_introspect_ship()
10126 #define stb_introspect_path(p)           stb_introspect_ship()
10127 #else
10128 // bootstrapping: define stb_introspect() (or 'path') the first time
10129 #define stb_introspect()                 stb__introspect(NULL, __FILE__, NULL)
10130 #define stb_introspect_auto()            stb__introspect(NULL, __FILE__, stb__introspect_output)
10131 
10132 #define stb_introspect_path(p)           stb__introspect(p, __FILE__, NULL)
10133 #define stb_introspect_path(p)           stb__introspect(p, __FILE__, NULL)
10134 #endif
10135 
10136 #ifdef STB_DEFINE
10137 
10138 #ifndef STB_INTROSPECT_CPP
10139    #ifdef __cplusplus
10140    #define STB_INTROSPECT_CPP 1
10141    #else
10142    #define STB_INTROSPECT_CPP 0
10143    #endif
10144 #endif
10145 
10146 void stb_introspect_precompiled(stb_info_struct *compiled)
10147 {
10148 
10149 }
10150 
10151 
10152 static void stb__introspect_filename(char *buffer, char *path)
10153 {
10154    #if STB_INTROSPECT_CPP
10155    stb_p_sprintf(buffer stb_p_size(9999), "%s/stb_introspect.cpp", path);
10156    #else
10157    stb_p_sprintf(buffer stb_p_size(9999), "%s/stb_introspect.c", path);
10158    #endif
10159 }
10160 
10161 static void stb__introspect_compute(char *path, char *file)
10162 {
10163    int i;
10164    char ** include_list = NULL;
10165    char ** introspect_list = NULL;
10166    FILE *f;
10167    f = stb_p_fopen(file, "w");
10168    if (!f) return;
10169 
10170    fputs("// if you get compiler errors, change the following 0 to a 1:\n", f);
10171    fputs("#define STB_INTROSPECT_INVALID 0\n\n", f);
10172    fputs("// this will force the code to compile, and force the introspector\n", f);
10173    fputs("// to run and then exit, allowing you to recompile\n\n\n", f);
10174    fputs("#include \"stb.h\"\n\n",f );
10175    fputs("#if STB_INTROSPECT_INVALID\n", f);
10176    fputs("   stb_info_struct stb__introspect_output[] = { (void *) 1 }\n", f);
10177    fputs("#else\n\n", f);
10178    for (i=0; i < stb_arr_len(include_list); ++i)
10179       fprintf(f, " #include \"%s\"\n", include_list[i]);
10180 
10181    fputs(" stb_info_struct stb__introspect_output[] =\n{\n", f);
10182    for (i=0; i < stb_arr_len(introspect_list); ++i)
10183       fprintf(f, "  stb_introspect_%s,\n", introspect_list[i]);
10184    fputs(" };\n", f);
10185    fputs("#endif\n", f);
10186    fclose(f);
10187 }
10188 
10189 static stb_info_struct *stb__introspect_info;
10190 
10191 #ifndef STB_SHIP
10192 
10193 #endif
10194 
10195 void stb__introspect(char *path, char *file, stb_info_struct *compiled)
10196 {
10197    static int first=1;
10198    if (!first) return;
10199    first=0;
10200 
10201    stb__introspect_info = compiled;
10202 
10203    #ifndef STB_SHIP
10204    if (path || file) {
10205       int bail_flag = compiled && compiled[0].structname == (void *) 1;
10206       int needs_building = bail_flag;
10207       struct stb__stat st;
10208       char buffer[1024], buffer2[1024];
10209       if (!path) {
10210          stb_splitpath(buffer, file, STB_PATH);
10211          path = buffer;
10212       }
10213       // bail if the source path doesn't exist
10214       if (!stb_fexists(path)) return;
10215 
10216       stb__introspect_filename(buffer2, path);
10217 
10218       // get source/include files timestamps, compare to output-file timestamp;
10219       // if mismatched, regenerate
10220 
10221       if (stb__stat(buffer2, &st))
10222          needs_building = STB_TRUE;
10223 
10224       {
10225          // find any file that contains an introspection command and is newer
10226          // if needs_building is already true, we don't need to do this test,
10227          // but we still need these arrays, so go ahead and get them
10228          char **all[3];
10229          all[0] = stb_readdir_files_mask(path, "*.h");
10230          all[1] = stb_readdir_files_mask(path, "*.c");
10231          all[2] = stb_readdir_files_mask(path, "*.cpp");
10232          int i,j;
10233          if (needs_building) {
10234             for (j=0; j < 3; ++j) {
10235                for (i=0; i < stb_arr_len(all[j]); ++i) {
10236                   struct stb__stat st2;
10237                   if (!stb__stat(all[j][i], &st2)) {
10238                      if (st.st_mtime < st2.st_mtime) {
10239                         char *z = stb_filec(all[j][i], NULL);
10240                         int found=STB_FALSE;
10241                         while (y) {
10242                            y = strstr(y, "//si");
10243                            if (y && isspace(y[4])) {
10244                               found = STB_TRUE;
10245                               break;
10246                            }
10247                         }
10248                         needs_building = STB_TRUE;
10249                         goto done;
10250                      }
10251                   }
10252                }
10253             }
10254            done:;
10255          }
10256                char *z = stb_filec(all[i], NULL), *y = z;
10257                int found=STB_FALSE;
10258                while (y) {
10259                   y = strstr(y, "//si");
10260                   if (y && isspace(y[4])) {
10261                      found = STB_TRUE;
10262                      break;
10263                   }
10264                }
10265                if (found)
10266                   stb_arr_push(introspect_h, stb_p_strdup(all[i]));
10267                free(z);
10268             }
10269          }
10270          stb_readdir_free(all);
10271          if (!needs_building) {
10272             for (i=0; i < stb_arr_len(introspect_h); ++i) {
10273                struct stb__stat st2;
10274                if (!stb__stat(introspect_h[i], &st2))
10275                   if (st.st_mtime < st2.st_mtime)
10276                      needs_building = STB_TRUE;
10277             }
10278          }
10279 
10280          if (needs_building) {
10281             stb__introspect_compute(path, buffer2);
10282          }
10283       }
10284    }
10285    #endif
10286 }
10287 #endif
10288 #endif
10289 
10290 #ifdef STB_INTROSPECT
10291 // compile-time code-generator
10292 #define INTROSPECT(x)   int main(int argc, char **argv) { stb__introspect(__FILE__); return 0; }
10293 #define FILE(x)
10294 
10295 void stb__introspect(char *filename)
10296 {
10297    char *file = stb_file(filename, NULL);
10298    char *s = file, *t, **p;
10299    char *out_name = "stb_introspect.c";
10300    char *out_path;
10301    STB_ARR(char) filelist = NULL;
10302    int i,n;
10303    if (!file) stb_fatal("Couldn't open %s", filename);
10304 
10305    out_path = stb_splitpathdup(filename, STB_PATH);
10306 
10307    // search for the macros
10308    while (*s) {
10309       char buffer[256];
10310       while (*s && !isupper(*s)) ++s;
10311       s = stb_strtok_invert(buffer, s, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
10312       s = stb_skipwhite(s);
10313       if (*s == '(') {
10314          ++s;
10315          t = strchr(s, ')');
10316          if (t == NULL) stb_fatal("Error parsing %s", filename);
10317 
10318       }
10319    }
10320 }
10321 
10322 
10323 
10324 #endif
10325 
10326 
10328 //
10329 //             STB-C sliding-window dictionary compression
10330 //
10331 //  This uses a DEFLATE-style sliding window, but no bitwise entropy.
10332 //  Everything is on byte boundaries, so you could then apply a byte-wise
10333 //  entropy code, though that's nowhere near as effective.
10334 //
10335 //  An STB-C stream begins with a 16-byte header:
10336 //      4 bytes: 0x57 0xBC 0x00 0x00
10337 //      8 bytes: big-endian size of decompressed data, 64-bits
10338 //      4 bytes: big-endian size of window (how far back decompressor may need)
10339 //
10340 //  The following symbols appear in the stream (these were determined ad hoc,
10341 //  not by analysis):
10342 //
10343 //  [dict]      00000100 yyyyyyyy yyyyyyyy yyyyyyyy xxxxxxxx xxxxxxxx
10344 //  [END]       00000101 11111010 cccccccc cccccccc cccccccc cccccccc
10345 //  [dict]      00000110 yyyyyyyy yyyyyyyy yyyyyyyy xxxxxxxx
10346 //  [literals]  00000111 zzzzzzzz zzzzzzzz
10347 //  [literals]  00001zzz zzzzzzzz
10348 //  [dict]      00010yyy yyyyyyyy yyyyyyyy xxxxxxxx xxxxxxxx
10349 //  [dict]      00011yyy yyyyyyyy yyyyyyyy xxxxxxxx
10350 //  [literals]  001zzzzz
10351 //  [dict]      01yyyyyy yyyyyyyy xxxxxxxx
10352 //  [dict]      1xxxxxxx yyyyyyyy
10353 //
10354 //      xxxxxxxx: match length - 1
10355 //      yyyyyyyy: backwards distance - 1
10356 //      zzzzzzzz: num literals - 1
10357 //      cccccccc: adler32 checksum of decompressed data
10358 //   (all big-endian)
10359 
10360 
10361 STB_EXTERN stb_uint stb_decompress_length(stb_uchar *input);
10362 STB_EXTERN stb_uint stb_decompress(stb_uchar *out,stb_uchar *in,stb_uint len);
10363 STB_EXTERN stb_uint stb_compress  (stb_uchar *out,stb_uchar *in,stb_uint len);
10364 STB_EXTERN void stb_compress_window(int z);
10365 STB_EXTERN void stb_compress_hashsize(unsigned int z);
10366 
10367 STB_EXTERN int stb_compress_tofile(char *filename, char *in,  stb_uint  len);
10368 STB_EXTERN int stb_compress_intofile(FILE *f, char *input,    stb_uint  len);
10369 STB_EXTERN char *stb_decompress_fromfile(char *filename,      stb_uint *len);
10370 
10371 STB_EXTERN int stb_compress_stream_start(FILE *f);
10372 STB_EXTERN void stb_compress_stream_end(int close);
10373 STB_EXTERN void stb_write(char *data, int data_len);
10374 
10375 #ifdef STB_DEFINE
10376 
10377 stb_uint stb_decompress_length(stb_uchar *input)
10378 {
10379    return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11];
10380 }
10381 
10383 
10384 // simple implementation that just writes whole thing into big block
10385 
10386 static unsigned char *stb__barrier;
10387 static unsigned char *stb__barrier2;
10388 static unsigned char *stb__barrier3;
10389 static unsigned char *stb__barrier4;
10390 
10391 static stb_uchar *stb__dout;
10392 static void stb__match(stb_uchar *data, stb_uint length)
10393 {
10394    // INVERSE of memmove... write each byte before copying the next...
10395    assert (stb__dout + length <= stb__barrier);
10396    if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
10397    if (data < stb__barrier4) { stb__dout = stb__barrier+1; return; }
10398    while (length--) *stb__dout++ = *data++;
10399 }
10400 
10401 static void stb__lit(stb_uchar *data, stb_uint length)
10402 {
10403    assert (stb__dout + length <= stb__barrier);
10404    if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
10405    if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; }
10406    memcpy(stb__dout, data, length);
10407    stb__dout += length;
10408 }
10409 
10410 #define stb__in2(x)   ((i[x] << 8) + i[(x)+1])
10411 #define stb__in3(x)   ((i[x] << 16) + stb__in2((x)+1))
10412 #define stb__in4(x)   ((i[x] << 24) + stb__in3((x)+1))
10413 
10414 static stb_uchar *stb_decompress_token(stb_uchar *i)
10415 {
10416    if (*i >= 0x20) { // use fewer if's for cases that expand small
10417       if (*i >= 0x80)       stb__match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2;
10418       else if (*i >= 0x40)  stb__match(stb__dout-(stb__in2(0) - 0x4000 + 1), i[2]+1), i += 3;
10419       else /* *i >= 0x20 */ stb__lit(i+1, i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
10420    } else { // more ifs for cases that expand large, since overhead is amortized
10421       if (*i >= 0x18)       stb__match(stb__dout-(stb__in3(0) - 0x180000 + 1), i[3]+1), i += 4;
10422       else if (*i >= 0x10)  stb__match(stb__dout-(stb__in3(0) - 0x100000 + 1), stb__in2(3)+1), i += 5;
10423       else if (*i >= 0x08)  stb__lit(i+2, stb__in2(0) - 0x0800 + 1), i += 2 + (stb__in2(0) - 0x0800 + 1);
10424       else if (*i == 0x07)  stb__lit(i+3, stb__in2(1) + 1), i += 3 + (stb__in2(1) + 1);
10425       else if (*i == 0x06)  stb__match(stb__dout-(stb__in3(1)+1), i[4]+1), i += 5;
10426       else if (*i == 0x04)  stb__match(stb__dout-(stb__in3(1)+1), stb__in2(4)+1), i += 6;
10427    }
10428    return i;
10429 }
10430 
10431 stb_uint stb_decompress(stb_uchar *output, stb_uchar *i, stb_uint length)
10432 {
10433    stb_uint olen;
10434    if (stb__in4(0) != 0x57bC0000) return 0;
10435    if (stb__in4(4) != 0)          return 0; // error! stream is > 4GB
10436    olen = stb_decompress_length(i);
10437    stb__barrier2 = i;
10438    stb__barrier3 = i+length;
10439    stb__barrier = output + olen;
10440    stb__barrier4 = output;
10441    i += 16;
10442 
10443    stb__dout = output;
10444    while (1) {
10445       stb_uchar *old_i = i;
10446       i = stb_decompress_token(i);
10447       if (i == old_i) {
10448          if (*i == 0x05 && i[1] == 0xfa) {
10449             assert(stb__dout == output + olen);
10450             if (stb__dout != output + olen) return 0;
10451             if (stb_adler32(1, output, olen) != (stb_uint) stb__in4(2))
10452                return 0;
10453             return olen;
10454          } else {
10455             assert(0); /* NOTREACHED */
10456             return 0;
10457          }
10458       }
10459       assert(stb__dout <= output + olen);
10460       if (stb__dout > output + olen)
10461          return 0;
10462    }
10463 }
10464 
10465 char *stb_decompress_fromfile(char *filename, unsigned int *len)
10466 {
10467    unsigned int n;
10468    char *q;
10469    unsigned char *p;
10470    FILE *f = stb_p_fopen(filename, "rb");   if (f == NULL) return NULL;
10471    fseek(f, 0, SEEK_END);
10472    n = ftell(f);
10473    fseek(f, 0, SEEK_SET);
10474    p = (unsigned char * ) malloc(n); if (p == NULL) return NULL;
10475    fread(p, 1, n, f);
10476    fclose(f);
10477    if (p == NULL) return NULL;
10478    if (p[0] != 0x57 || p[1] != 0xBc || p[2] || p[3]) { free(p); return NULL; }
10479    q = (char *) malloc(stb_decompress_length(p)+1);
10480    if (!q) { free(p); return NULL; }
10481    *len = stb_decompress((unsigned char *) q, p, n);
10482    if (*len) q[*len] = 0;
10483    free(p);
10484    return q;
10485 }
10486 
10487 #if 0
10488 //  streaming decompressor
10489 
10490 static struct
10491 {
10492    stb__uchar *in_buffer;
10493    stb__uchar *match;
10494 
10495    stb__uint pending_literals;
10496    stb__uint pending_match;
10497 } xx;
10498 
10499 
10500 
10501 static void stb__match(stb_uchar *data, stb_uint length)
10502 {
10503    // INVERSE of memmove... write each byte before copying the next...
10504    assert (stb__dout + length <= stb__barrier);
10505    if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
10506    if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; }
10507    while (length--) *stb__dout++ = *data++;
10508 }
10509 
10510 static void stb__lit(stb_uchar *data, stb_uint length)
10511 {
10512    assert (stb__dout + length <= stb__barrier);
10513    if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
10514    if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; }
10515    memcpy(stb__dout, data, length);
10516    stb__dout += length;
10517 }
10518 
10519 static void sx_match(stb_uchar *data, stb_uint length)
10520 {
10521    xx.match = data;
10522    xx.pending_match = length;
10523 }
10524 
10525 static void sx_lit(stb_uchar *data, stb_uint length)
10526 {
10527    xx.pending_lit = length;
10528 }
10529 
10530 static int stb_decompress_token_state(void)
10531 {
10532    stb__uchar *i = xx.in_buffer;
10533 
10534    if (*i >= 0x20) { // use fewer if's for cases that expand small
10535       if (*i >= 0x80)       sx_match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2;
10536       else if (*i >= 0x40)  sx_match(stb__dout-(stb__in2(0) - 0x4000 + 1), i[2]+1), i += 3;
10537       else /* *i >= 0x20 */ sx_lit(i+1, i[0] - 0x20 + 1), i += 1;
10538    } else { // more ifs for cases that expand large, since overhead is amortized
10539       if (*i >= 0x18)       sx_match(stb__dout-(stb__in3(0) - 0x180000 + 1), i[3]+1), i += 4;
10540       else if (*i >= 0x10)  sx_match(stb__dout-(stb__in3(0) - 0x100000 + 1), stb__in2(3)+1), i += 5;
10541       else if (*i >= 0x08)  sx_lit(i+2, stb__in2(0) - 0x0800 + 1), i += 2;
10542       else if (*i == 0x07)  sx_lit(i+3, stb__in2(1) + 1), i += 3;
10543       else if (*i == 0x06)  sx_match(stb__dout-(stb__in3(1)+1), i[4]+1), i += 5;
10544       else if (*i == 0x04)  sx_match(stb__dout-(stb__in3(1)+1), stb__in2(4)+1), i += 6;
10545       else return 0;
10546    }
10547    xx.in_buffer = i;
10548    return 1;
10549 }
10550 #endif
10551 
10552 
10553 
10555 
10556 static unsigned int stb_matchlen(stb_uchar *m1, stb_uchar *m2, stb_uint maxlen)
10557 {
10558    stb_uint i;
10559    for (i=0; i < maxlen; ++i)
10560       if (m1[i] != m2[i]) return i;
10561    return i;
10562 }
10563 
10564 // simple implementation that just takes the source data in a big block
10565 
10566 static stb_uchar *stb__out;
10567 static FILE      *stb__outfile;
10568 static stb_uint   stb__outbytes;
10569 
10570 static void stb__write(unsigned char v)
10571 {
10572    fputc(v, stb__outfile);
10573    ++stb__outbytes;
10574 }
10575 
10576 #define stb_out(v)    (stb__out ? (void)(*stb__out++ = (stb_uchar) (v)) : stb__write((stb_uchar) (v)))
10577 
10578 static void stb_out2(stb_uint v)
10579 {
10580    stb_out(v >> 8);
10581    stb_out(v);
10582 }
10583 
10584 static void stb_out3(stb_uint v) { stb_out(v >> 16); stb_out(v >> 8); stb_out(v); }
10585 static void stb_out4(stb_uint v) { stb_out(v >> 24); stb_out(v >> 16);
10586                                    stb_out(v >> 8 ); stb_out(v);                  }
10587 
10588 static void outliterals(stb_uchar *in, ptrdiff_t numlit)
10589 {
10590    while (numlit > 65536) {
10591       outliterals(in,65536);
10592       in     += 65536;
10593       numlit -= 65536;
10594    }
10595 
10596    if      (numlit ==     0)    ;
10597    else if (numlit <=    32)    stb_out (0x000020 + (stb_uint) numlit-1);
10598    else if (numlit <=  2048)    stb_out2(0x000800 + (stb_uint) numlit-1);
10599    else /*  numlit <= 65536) */ stb_out3(0x070000 + (stb_uint) numlit-1);
10600 
10601    if (stb__out) {
10602       memcpy(stb__out,in,numlit);
10603       stb__out += numlit;
10604    } else
10605       fwrite(in, 1, numlit, stb__outfile);
10606 }
10607 
10608 static int stb__window = 0x40000; // 256K
10609 void stb_compress_window(int z)
10610 {
10611    if (z >= 0x1000000) z = 0x1000000; // limit of implementation
10612    if (z <      0x100) z = 0x100;   // insanely small
10613    stb__window = z;
10614 }
10615 
10616 static int stb_not_crap(int best, int dist)
10617 {
10618    return   ((best > 2  &&  dist <= 0x00100)
10619           || (best > 5  &&  dist <= 0x04000)
10620           || (best > 7  &&  dist <= 0x80000));
10621 }
10622 
10623 static  stb_uint stb__hashsize = 32768;
10624 void stb_compress_hashsize(unsigned int y)
10625 {
10626    unsigned int z = 1024;
10627    while (z < y) z <<= 1;
10628    stb__hashsize = z >> 2;   // pass in bytes, store #pointers
10629 }
10630 
10631 // note that you can play with the hashing functions all you
10632 // want without needing to change the decompressor
10633 #define stb__hc(q,h,c)      (((h) << 7) + ((h) >> 25) + q[c])
10634 #define stb__hc2(q,h,c,d)   (((h) << 14) + ((h) >> 18) + (q[c] << 7) + q[d])
10635 #define stb__hc3(q,c,d,e)   ((q[c] << 14) + (q[d] << 7) + q[e])
10636 
10637 static stb_uint32 stb__running_adler;
10638 
10639 static int stb_compress_chunk(stb_uchar *history,
10640                               stb_uchar *start,
10641                               stb_uchar *end,
10642                               int length,
10643                               int *pending_literals,
10644                               stb_uchar **chash,
10645                               stb_uint mask)
10646 {
10647    int window = stb__window;
10648    stb_uint match_max;
10649    stb_uchar *lit_start = start - *pending_literals;
10650    stb_uchar *q = start;
10651 
10652    #define STB__SCRAMBLE(h)   (((h) + ((h) >> 16)) & mask)
10653 
10654    // stop short of the end so we don't scan off the end doing
10655    // the hashing; this means we won't compress the last few bytes
10656    // unless they were part of something longer
10657    while (q < start+length && q+12 < end) {
10658       int m;
10659       stb_uint h1,h2,h3,h4, h;
10660       stb_uchar *t;
10661       int best = 2, dist=0;
10662 
10663       if (q+65536 > end)
10664          match_max = (stb_uint) (end-q);
10665       else
10666          match_max = 65536u;
10667 
10668       #define stb__nc(b,d)  ((d) <= window && ((b) > 9 || stb_not_crap(b,d)))
10669 
10670       #define STB__TRY(t,p)  /* avoid retrying a match we already tried */ \
10671                       if (p ? dist != (int) (q-t) : 1)                     \
10672                       if ((m = (int) stb_matchlen(t, q, match_max)) > best)\
10673                       if (stb__nc(m,(int) (q-(t))))                        \
10674                           best = m, dist = (int) (q - (t))
10675 
10676       // rather than search for all matches, only try 4 candidate locations,
10677       // chosen based on 4 different hash functions of different lengths.
10678       // this strategy is inspired by LZO; hashing is unrolled here using the
10679       // 'hc' macro
10680       h = stb__hc3(q,0, 1, 2); h1 = STB__SCRAMBLE(h);
10681                                       t = chash[h1]; if (t) STB__TRY(t,0);
10682       h = stb__hc2(q,h, 3, 4); h2 = STB__SCRAMBLE(h);
10683       h = stb__hc2(q,h, 5, 6);        t = chash[h2]; if (t) STB__TRY(t,1);
10684       h = stb__hc2(q,h, 7, 8); h3 = STB__SCRAMBLE(h);
10685       h = stb__hc2(q,h, 9,10);        t = chash[h3]; if (t) STB__TRY(t,1);
10686       h = stb__hc2(q,h,11,12); h4 = STB__SCRAMBLE(h);
10687                                       t = chash[h4]; if (t) STB__TRY(t,1);
10688 
10689       // because we use a shared hash table, can only update it
10690       // _after_ we've probed all of them
10691       chash[h1] = chash[h2] = chash[h3] = chash[h4] = q;
10692 
10693       if (best > 2)
10694          assert(dist > 0);
10695 
10696       // see if our best match qualifies
10697       if (best < 3) { // fast path literals
10698          ++q;
10699       } else if (best > 2  &&  best <= 0x80    &&  dist <= 0x100) {
10700          outliterals(lit_start, q-lit_start); lit_start = (q += best);
10701          stb_out(0x80 + best-1);
10702          stb_out(dist-1);
10703       } else if (best > 5  &&  best <= 0x100   &&  dist <= 0x4000) {
10704          outliterals(lit_start, q-lit_start); lit_start = (q += best);
10705          stb_out2(0x4000 + dist-1);
10706          stb_out(best-1);
10707       } else if (best > 7  &&  best <= 0x100   &&  dist <= 0x80000) {
10708          outliterals(lit_start, q-lit_start); lit_start = (q += best);
10709          stb_out3(0x180000 + dist-1);
10710          stb_out(best-1);
10711       } else if (best > 8  &&  best <= 0x10000 &&  dist <= 0x80000) {
10712          outliterals(lit_start, q-lit_start); lit_start = (q += best);
10713          stb_out3(0x100000 + dist-1);
10714          stb_out2(best-1);
10715       } else if (best > 9                      &&  dist <= 0x1000000) {
10716          if (best > 65536) best = 65536;
10717          outliterals(lit_start, q-lit_start); lit_start = (q += best);
10718          if (best <= 0x100) {
10719             stb_out(0x06);
10720             stb_out3(dist-1);
10721             stb_out(best-1);
10722          } else {
10723             stb_out(0x04);
10724             stb_out3(dist-1);
10725             stb_out2(best-1);
10726          }
10727       } else {  // fallback literals if no match was a balanced tradeoff
10728          ++q;
10729       }
10730    }
10731 
10732    // if we didn't get all the way, add the rest to literals
10733    if (q-start < length)
10734       q = start+length;
10735 
10736    // the literals are everything from lit_start to q
10737    *pending_literals = (int) (q - lit_start);
10738 
10739    stb__running_adler = stb_adler32(stb__running_adler, start, (int) (q - start));
10740    return (int) (q - start);
10741 }
10742 
10743 static int stb_compress_inner(stb_uchar *input, stb_uint length)
10744 {
10745    int literals = 0;
10746    stb_uint len,i;
10747 
10748    stb_uchar **chash;
10749    chash = (stb_uchar**) malloc(stb__hashsize * sizeof(stb_uchar*));
10750    if (chash == NULL) return 0; // failure
10751    for (i=0; i < stb__hashsize; ++i)
10752       chash[i] = NULL;
10753 
10754    // stream signature
10755    stb_out(0x57); stb_out(0xbc);
10756    stb_out2(0);
10757 
10758    stb_out4(0);       // 64-bit length requires 32-bit leading 0
10759    stb_out4(length);
10760    stb_out4(stb__window);
10761 
10762    stb__running_adler = 1;
10763 
10764    len = stb_compress_chunk(input, input, input+length, length, &literals, chash, stb__hashsize-1);
10765    assert(len == length);
10766 
10767    outliterals(input+length - literals, literals);
10768 
10769    free(chash);
10770 
10771    stb_out2(0x05fa); // end opcode
10772 
10773    stb_out4(stb__running_adler);
10774 
10775    return 1; // success
10776 }
10777 
10778 stb_uint stb_compress(stb_uchar *out, stb_uchar *input, stb_uint length)
10779 {
10780    stb__out = out;
10781    stb__outfile = NULL;
10782 
10783    stb_compress_inner(input, length);
10784 
10785    return (stb_uint) (stb__out - out);
10786 }
10787 
10788 int stb_compress_tofile(char *filename, char *input, unsigned int length)
10789 {
10790    //int maxlen = length + 512 + (length >> 2); // total guess
10791    //char *buffer = (char *) malloc(maxlen);
10792    //int blen = stb_compress((stb_uchar*)buffer, (stb_uchar*)input, length);
10793 
10794    stb__out = NULL;
10795    stb__outfile = stb_p_fopen(filename, "wb");
10796    if (!stb__outfile) return 0;
10797 
10798    stb__outbytes = 0;
10799 
10800    if (!stb_compress_inner((stb_uchar*)input, length))
10801       return 0;
10802 
10803    fclose(stb__outfile);
10804 
10805    return stb__outbytes;
10806 }
10807 
10808 int stb_compress_intofile(FILE *f, char *input, unsigned int length)
10809 {
10810    //int maxlen = length + 512 + (length >> 2); // total guess
10811    //char *buffer = (char*)malloc(maxlen);
10812    //int blen = stb_compress((stb_uchar*)buffer, (stb_uchar*)input, length);
10813 
10814    stb__out = NULL;
10815    stb__outfile = f;
10816    if (!stb__outfile) return 0;
10817 
10818    stb__outbytes = 0;
10819 
10820    if (!stb_compress_inner((stb_uchar*)input, length))
10821       return 0;
10822 
10823    return stb__outbytes;
10824 }
10825 
10827 
10828 
10829 static size_t stb_out_backpatch_id(void)
10830 {
10831    if (stb__out)
10832       return (size_t) stb__out;
10833    else
10834       return ftell(stb__outfile);
10835 }
10836 
10837 static void stb_out_backpatch(size_t id, stb_uint value)
10838 {
10839    stb_uchar data[4] = { (stb_uchar)(value >> 24), (stb_uchar)(value >> 16), (stb_uchar)(value >> 8), (stb_uchar)(value) };
10840    if (stb__out) {
10841       memcpy((void *) id, data, 4);
10842    } else {
10843       stb_uint where = ftell(stb__outfile);
10844       fseek(stb__outfile, (long) id, SEEK_SET);
10845       fwrite(data, 4, 1, stb__outfile);
10846       fseek(stb__outfile, where, SEEK_SET);
10847    }
10848 }
10849 
10850 // ok, the wraparound buffer was a total failure. let's instead
10851 // use a copying-in-place buffer, which lets us share the code.
10852 // This is way less efficient but it'll do for now.
10853 
10854 static struct
10855 {
10856    stb_uchar *buffer;
10857    int size;           // physical size of buffer in bytes
10858 
10859    int valid;          // amount of valid data in bytes
10860    int start;          // bytes of data already output
10861 
10862    int window;
10863    int fsize;
10864 
10865    int pending_literals; // bytes not-quite output but counted in start
10866    int length_id;
10867 
10868    stb_uint total_bytes;
10869 
10870    stb_uchar **chash;
10871    stb_uint    hashmask;
10872 } xtb;
10873 
10874 static int stb_compress_streaming_start(void)
10875 {
10876    stb_uint i;
10877    xtb.size = stb__window * 3;
10878    xtb.buffer = (stb_uchar*)malloc(xtb.size);
10879    if (!xtb.buffer) return 0;
10880 
10881    xtb.chash = (stb_uchar**)malloc(sizeof(*xtb.chash) * stb__hashsize);
10882    if (!xtb.chash) {
10883       free(xtb.buffer);
10884       return 0;
10885    }
10886 
10887    for (i=0; i < stb__hashsize; ++i)
10888       xtb.chash[i] = NULL;
10889 
10890    xtb.hashmask = stb__hashsize-1;
10891 
10892    xtb.valid        = 0;
10893    xtb.start        = 0;
10894    xtb.window       = stb__window;
10895    xtb.fsize        = stb__window;
10896    xtb.pending_literals = 0;
10897    xtb.total_bytes  = 0;
10898 
10899       // stream signature
10900    stb_out(0x57); stb_out(0xbc); stb_out2(0);
10901 
10902    stb_out4(0);       // 64-bit length requires 32-bit leading 0
10903 
10904    xtb.length_id = (int) stb_out_backpatch_id();
10905    stb_out4(0);       // we don't know the output length yet
10906 
10907    stb_out4(stb__window);
10908 
10909    stb__running_adler = 1;
10910 
10911    return 1;
10912 }
10913 
10914 static int stb_compress_streaming_end(void)
10915 {
10916    // flush out any remaining data
10917    stb_compress_chunk(xtb.buffer, xtb.buffer+xtb.start, xtb.buffer+xtb.valid,
10918                       xtb.valid-xtb.start, &xtb.pending_literals, xtb.chash, xtb.hashmask);
10919 
10920    // write out pending literals
10921    outliterals(xtb.buffer + xtb.valid - xtb.pending_literals, xtb.pending_literals);
10922 
10923    stb_out2(0x05fa); // end opcode
10924    stb_out4(stb__running_adler);
10925 
10926    stb_out_backpatch(xtb.length_id, xtb.total_bytes);
10927 
10928    free(xtb.buffer);
10929    free(xtb.chash);
10930    return 1;
10931 }
10932 
10933 void stb_write(char *data, int data_len)
10934 {
10935    stb_uint i;
10936 
10937    // @TODO: fast path for filling the buffer and doing nothing else
10938    //   if (xtb.valid + data_len < xtb.size)
10939 
10940    xtb.total_bytes += data_len;
10941 
10942    while (data_len) {
10943       // fill buffer
10944       if (xtb.valid < xtb.size) {
10945          int amt = xtb.size - xtb.valid;
10946          if (data_len < amt) amt = data_len;
10947          memcpy(xtb.buffer + xtb.valid, data, amt);
10948          data_len -= amt;
10949          data     += amt;
10950          xtb.valid += amt;
10951       }
10952       if (xtb.valid < xtb.size)
10953          return;
10954 
10955       // at this point, the buffer is full
10956 
10957       // if we can process some data, go for it; make sure
10958       // we leave an 'fsize's worth of data, though
10959       if (xtb.start + xtb.fsize < xtb.valid) {
10960          int amount = (xtb.valid - xtb.fsize) - xtb.start;
10961          int n;
10962          assert(amount > 0);
10963          n = stb_compress_chunk(xtb.buffer, xtb.buffer + xtb.start, xtb.buffer + xtb.valid,
10964                                 amount, &xtb.pending_literals, xtb.chash, xtb.hashmask);
10965          xtb.start += n;
10966       }
10967 
10968       assert(xtb.start + xtb.fsize >= xtb.valid);
10969       // at this point, our future size is too small, so we
10970       // need to flush some history. we, in fact, flush exactly
10971       // one window's worth of history
10972 
10973       {
10974          int flush = xtb.window;
10975          assert(xtb.start >= flush);
10976          assert(xtb.valid >= flush);
10977 
10978          // if 'pending literals' extends back into the shift region,
10979          // write them out
10980          if (xtb.start - xtb.pending_literals < flush) {
10981             outliterals(xtb.buffer + xtb.start - xtb.pending_literals, xtb.pending_literals);
10982             xtb.pending_literals = 0;
10983          }
10984 
10985          // now shift the window
10986          memmove(xtb.buffer, xtb.buffer + flush, xtb.valid - flush);
10987          xtb.start -= flush;
10988          xtb.valid -= flush;
10989 
10990          for (i=0; i <= xtb.hashmask; ++i)
10991             if (xtb.chash[i] < xtb.buffer + flush)
10992                xtb.chash[i] = NULL;
10993             else
10994                xtb.chash[i] -= flush;
10995       }
10996       // and now that we've made room for more data, go back to the top
10997    }
10998 }
10999 
11000 int stb_compress_stream_start(FILE *f)
11001 {
11002    stb__out = NULL;
11003    stb__outfile = f;
11004 
11005    if (f == NULL)
11006       return 0;
11007 
11008    if (!stb_compress_streaming_start())
11009       return 0;
11010 
11011    return 1;
11012 }
11013 
11014 void stb_compress_stream_end(int close)
11015 {
11016    stb_compress_streaming_end();
11017    if (close && stb__outfile) {
11018       fclose(stb__outfile);
11019    }
11020 }
11021 
11022 #endif // STB_DEFINE
11023 
11025 //
11026 //  File abstraction... tired of not having this... we can write
11027 //  compressors to be layers over these that auto-close their children.
11028 
11029 
11030 typedef struct stbfile
11031 {
11032    int (*getbyte)(struct stbfile *);  // -1 on EOF
11033    unsigned int (*getdata)(struct stbfile *, void *block, unsigned int len);
11034 
11035    int (*putbyte)(struct stbfile *, int byte);
11036    unsigned int (*putdata)(struct stbfile *, void *block, unsigned int len);
11037 
11038    unsigned int (*size)(struct stbfile *);
11039 
11040    unsigned int (*tell)(struct stbfile *);
11041    void (*backpatch)(struct stbfile *, unsigned int tell, void *block, unsigned int len);
11042 
11043    void (*close)(struct stbfile *);
11044 
11045    FILE *f;  // file to fread/fwrite
11046    unsigned char *buffer; // input/output buffer
11047    unsigned char *indata, *inend; // input buffer
11048    union {
11049       int various;
11050       void *ptr;
11051    };
11052 } stbfile;
11053 
11054 STB_EXTERN unsigned int stb_getc(stbfile *f); // read
11055 STB_EXTERN int stb_putc(stbfile *f, int ch); // write
11056 STB_EXTERN unsigned int stb_getdata(stbfile *f, void *buffer, unsigned int len); // read
11057 STB_EXTERN unsigned int stb_putdata(stbfile *f, void *buffer, unsigned int len); // write
11058 STB_EXTERN unsigned int stb_tell(stbfile *f); // read
11059 STB_EXTERN unsigned int stb_size(stbfile *f); // read/write
11060 STB_EXTERN void stb_backpatch(stbfile *f, unsigned int tell, void *buffer, unsigned int len); // write
11061 
11062 #ifdef STB_DEFINE
11063 
11064 unsigned int stb_getc(stbfile *f) { return f->getbyte(f); }
11065 int stb_putc(stbfile *f, int ch)  { return f->putbyte(f, ch); }
11066 
11067 unsigned int stb_getdata(stbfile *f, void *buffer, unsigned int len)
11068 {
11069    return f->getdata(f, buffer, len);
11070 }
11071 unsigned int stb_putdata(stbfile *f, void *buffer, unsigned int len)
11072 {
11073    return f->putdata(f, buffer, len);
11074 }
11075 void stb_close(stbfile *f)
11076 {
11077    f->close(f);
11078    free(f);
11079 }
11080 unsigned int stb_tell(stbfile *f) { return f->tell(f); }
11081 unsigned int stb_size(stbfile *f) { return f->size(f); }
11082 void stb_backpatch(stbfile *f, unsigned int tell, void *buffer, unsigned int len)
11083 {
11084    f->backpatch(f,tell,buffer,len);
11085 }
11086 
11087 // FILE * implementation
11088 static int stb__fgetbyte(stbfile *f) { return fgetc(f->f); }
11089 static int stb__fputbyte(stbfile *f, int ch) { return fputc(ch, f->f)==0; }
11090 static unsigned int stb__fgetdata(stbfile *f, void *buffer, unsigned int len) { return (unsigned int) fread(buffer,1,len,f->f); }
11091 static unsigned int stb__fputdata(stbfile *f, void *buffer, unsigned int len) { return (unsigned int) fwrite(buffer,1,len,f->f); }
11092 static unsigned int stb__fsize(stbfile *f) { return (unsigned int) stb_filelen(f->f); }
11093 static unsigned int stb__ftell(stbfile *f) { return (unsigned int) ftell(f->f); }
11094 static void stb__fbackpatch(stbfile *f, unsigned int where, void *buffer, unsigned int len)
11095 {
11096    fseek(f->f, where, SEEK_SET);
11097    fwrite(buffer, 1, len, f->f);
11098    fseek(f->f, 0, SEEK_END);
11099 }
11100 static void         stb__fclose(stbfile *f) { fclose(f->f); }
11101 
11102 stbfile *stb_openf(FILE *f)
11103 {
11104    stbfile m = { stb__fgetbyte, stb__fgetdata,
11105                  stb__fputbyte, stb__fputdata,
11106                  stb__fsize, stb__ftell, stb__fbackpatch, stb__fclose,
11107                  0,0,0, };
11108    stbfile *z = (stbfile *) malloc(sizeof(*z));
11109    if (z) {
11110       *z = m;
11111       z->f = f;
11112    }
11113    return z;
11114 }
11115 
11116 static int stb__nogetbyte(stbfile *f) { assert(0); return -1; }
11117 static unsigned int stb__nogetdata(stbfile *f, void *buffer, unsigned int len) { assert(0); return 0; }
11118 static int stb__noputbyte(stbfile *f, int ch) { assert(0); return 0; }
11119 static unsigned int stb__noputdata(stbfile *f, void *buffer, unsigned int len) { assert(0); return 0; }
11120 static void stb__nobackpatch(stbfile *f, unsigned int where, void *buffer, unsigned int len) { assert(0); }
11121 
11122 static int stb__bgetbyte(stbfile *s)
11123 {
11124    if (s->indata < s->inend)
11125       return *s->indata++;
11126    else
11127       return -1;
11128 }
11129 
11130 static unsigned int stb__bgetdata(stbfile *s, void *buffer, unsigned int len)
11131 {
11132    if (s->indata + len > s->inend)
11133       len = (unsigned int) (s->inend - s->indata);
11134    memcpy(buffer, s->indata, len);
11135    s->indata += len;
11136    return len;
11137 }
11138 static unsigned int stb__bsize(stbfile *s) { return (unsigned int) (s->inend  - s->buffer); }
11139 static unsigned int stb__btell(stbfile *s) { return (unsigned int) (s->indata - s->buffer); }
11140 
11141 static void stb__bclose(stbfile *s)
11142 {
11143    if (s->various)
11144       free(s->buffer);
11145 }
11146 
11147 stbfile *stb_open_inbuffer(void *buffer, unsigned int len)
11148 {
11149    stbfile m = { stb__bgetbyte, stb__bgetdata,
11150                  stb__noputbyte, stb__noputdata,
11151                  stb__bsize, stb__btell, stb__nobackpatch, stb__bclose };
11152    stbfile *z = (stbfile *) malloc(sizeof(*z));
11153    if (z) {
11154       *z = m;
11155       z->buffer = (unsigned char *) buffer;
11156       z->indata = z->buffer;
11157       z->inend = z->indata + len;
11158    }
11159    return z;
11160 }
11161 
11162 stbfile *stb_open_inbuffer_free(void *buffer, unsigned int len)
11163 {
11164    stbfile *z = stb_open_inbuffer(buffer, len);
11165    if (z)
11166       z->various = 1; // free
11167    return z;
11168 }
11169 
11170 #ifndef STB_VERSION
11171 // if we've been cut-and-pasted elsewhere, you get a limited
11172 // version of stb_open, without the 'k' flag and utf8 support
11173 static void stb__fclose2(stbfile *f)
11174 {
11175    fclose(f->f);
11176 }
11177 
11178 stbfile *stb_open(char *filename, char *mode)
11179 {
11180    FILE *f = stb_p_fopen(filename, mode);
11181    stbfile *s;
11182    if (f == NULL) return NULL;
11183    s = stb_openf(f);
11184    if (s)
11185       s->close = stb__fclose2;
11186    return s;
11187 }
11188 #else
11189 // the full version depends on some code in stb.h; this
11190 // also includes the memory buffer output format implemented with stb_arr
11191 static void stb__fclose2(stbfile *f)
11192 {
11193    stb_fclose(f->f, f->various);
11194 }
11195 
11196 stbfile *stb_open(char *filename, char *mode)
11197 {
11198    FILE *f = stb_fopen(filename, mode[0] == 'k' ? mode+1 : mode);
11199    stbfile *s;
11200    if (f == NULL) return NULL;
11201    s = stb_openf(f);
11202    if (s) {
11203       s->close = stb__fclose2;
11204       s->various = mode[0] == 'k' ? stb_keep_if_different : stb_keep_yes;
11205    }
11206    return s;
11207 }
11208 
11209 static int stb__aputbyte(stbfile *f, int ch)
11210 {
11211    stb_arr_push(f->buffer, ch);
11212    return 1;
11213 }
11214 static unsigned int stb__aputdata(stbfile *f, void *data, unsigned int len)
11215 {
11216    memcpy(stb_arr_addn(f->buffer, (int) len), data, len);
11217    return len;
11218 }
11219 static unsigned int stb__asize(stbfile *f) { return stb_arr_len(f->buffer); }
11220 static void stb__abackpatch(stbfile *f, unsigned int where, void *data, unsigned int len)
11221 {
11222    memcpy(f->buffer+where, data, len);
11223 }
11224 static void stb__aclose(stbfile *f)
11225 {
11226    *(unsigned char **) f->ptr = f->buffer;
11227 }
11228 
11229 stbfile *stb_open_outbuffer(unsigned char **update_on_close)
11230 {
11231    stbfile m = { stb__nogetbyte, stb__nogetdata,
11232                  stb__aputbyte, stb__aputdata,
11233                  stb__asize, stb__asize, stb__abackpatch, stb__aclose };
11234    stbfile *z = (stbfile *) malloc(sizeof(*z));
11235    if (z) {
11236       z->ptr = update_on_close;
11237       *z = m;
11238    }
11239    return z;
11240 }
11241 #endif
11242 #endif
11243 
11244 
11246 //
11247 //  Arithmetic coder... based on cbloom's notes on the subject, should be
11248 //  less code than a huffman code.
11249 
11250 typedef struct
11251 {
11252    unsigned int range_low;
11253    unsigned int range_high;
11254    unsigned int code, range; // decode
11255    int buffered_u8;
11256    int pending_ffs;
11257    stbfile *output;
11258 } stb_arith;
11259 
11260 STB_EXTERN void stb_arith_init_encode(stb_arith *a, stbfile *out);
11261 STB_EXTERN void stb_arith_init_decode(stb_arith *a, stbfile *in);
11262 STB_EXTERN stbfile *stb_arith_encode_close(stb_arith *a);
11263 STB_EXTERN stbfile *stb_arith_decode_close(stb_arith *a);
11264 
11265 STB_EXTERN void stb_arith_encode(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq);
11266 STB_EXTERN void stb_arith_encode_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq);
11267 STB_EXTERN unsigned int stb_arith_decode_value(stb_arith *a, unsigned int totalfreq);
11268 STB_EXTERN void stb_arith_decode_advance(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq);
11269 STB_EXTERN unsigned int stb_arith_decode_value_log2(stb_arith *a, unsigned int totalfreq2);
11270 STB_EXTERN void stb_arith_decode_advance_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq);
11271 
11272 STB_EXTERN void stb_arith_encode_byte(stb_arith *a, int byte);
11273 STB_EXTERN int  stb_arith_decode_byte(stb_arith *a);
11274 
11275 // this is a memory-inefficient way of doing things, but it's
11276 // fast(?) and simple
11277 typedef struct
11278 {
11279    unsigned short cumfreq;
11280    unsigned short samples;
11281 } stb_arith_symstate_item;
11282 
11283 typedef struct
11284 {
11285    int num_sym;
11286    unsigned int pow2;
11287    int countdown;
11288    stb_arith_symstate_item data[1];
11289 } stb_arith_symstate;
11290 
11291 #ifdef STB_DEFINE
11292 void stb_arith_init_encode(stb_arith *a, stbfile *out)
11293 {
11294    a->range_low = 0;
11295    a->range_high = 0xffffffff;
11296    a->pending_ffs = -1; // means no buffered character currently, to speed up normal case
11297    a->output = out;
11298 }
11299 
11300 static void stb__arith_carry(stb_arith *a)
11301 {
11302    int i;
11303    assert(a->pending_ffs != -1); // can't carry with no data
11304    stb_putc(a->output, a->buffered_u8);
11305    for (i=0; i < a->pending_ffs; ++i)
11306       stb_putc(a->output, 0);
11307 }
11308 
11309 static void stb__arith_putbyte(stb_arith *a, int byte)
11310 {
11311    if (a->pending_ffs) {
11312       if (a->pending_ffs == -1) { // means no buffered data; encoded for fast path efficiency
11313          if (byte == 0xff)
11314             stb_putc(a->output, byte); // just write it immediately
11315          else {
11316             a->buffered_u8 = byte;
11317             a->pending_ffs = 0;
11318          }
11319       } else if (byte == 0xff) {
11320          ++a->pending_ffs;
11321       } else {
11322          int i;
11323          stb_putc(a->output, a->buffered_u8);
11324          for (i=0; i < a->pending_ffs; ++i)
11325             stb_putc(a->output, 0xff);
11326       }
11327    } else if (byte == 0xff) {
11328       ++a->pending_ffs;
11329    } else {
11330       // fast path
11331       stb_putc(a->output, a->buffered_u8);
11332       a->buffered_u8 = byte;
11333    }
11334 }
11335 
11336 static void stb__arith_flush(stb_arith *a)
11337 {
11338    if (a->pending_ffs >= 0) {
11339       int i;
11340       stb_putc(a->output, a->buffered_u8);
11341       for (i=0; i < a->pending_ffs; ++i)
11342          stb_putc(a->output, 0xff);
11343    }
11344 }
11345 
11346 static void stb__renorm_encoder(stb_arith *a)
11347 {
11348    stb__arith_putbyte(a, a->range_low >> 24);
11349    a->range_low <<= 8;
11350    a->range_high = (a->range_high << 8) | 0xff;
11351 }
11352 
11353 static void stb__renorm_decoder(stb_arith *a)
11354 {
11355    int c = stb_getc(a->output);
11356    a->code = (a->code << 8) + (c >= 0 ? c : 0); // if EOF, insert 0
11357 }
11358 
11359 void stb_arith_encode(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq)
11360 {
11361    unsigned int range = a->range_high - a->range_low;
11362    unsigned int old = a->range_low;
11363    range /= totalfreq;
11364    a->range_low += range * cumfreq;
11365    a->range_high = a->range_low + range*freq;
11366    if (a->range_low < old)
11367       stb__arith_carry(a);
11368    while (a->range_high - a->range_low < 0x1000000)
11369       stb__renorm_encoder(a);
11370 }
11371 
11372 void stb_arith_encode_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq)
11373 {
11374    unsigned int range = a->range_high - a->range_low;
11375    unsigned int old = a->range_low;
11376    range >>= totalfreq2;
11377    a->range_low += range * cumfreq;
11378    a->range_high = a->range_low + range*freq;
11379    if (a->range_low < old)
11380       stb__arith_carry(a);
11381    while (a->range_high - a->range_low < 0x1000000)
11382       stb__renorm_encoder(a);
11383 }
11384 
11385 unsigned int stb_arith_decode_value(stb_arith *a, unsigned int totalfreq)
11386 {
11387    unsigned int freqsize = a->range / totalfreq;
11388    unsigned int z = a->code / freqsize;
11389    return z >= totalfreq ? totalfreq-1 : z;
11390 }
11391 
11392 void stb_arith_decode_advance(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq)
11393 {
11394    unsigned int freqsize = a->range / totalfreq; // @OPTIMIZE, share with above divide somehow?
11395    a->code -= freqsize * cumfreq;
11396    a->range = freqsize * freq;
11397    while (a->range < 0x1000000)
11398       stb__renorm_decoder(a);
11399 }
11400 
11401 unsigned int stb_arith_decode_value_log2(stb_arith *a, unsigned int totalfreq2)
11402 {
11403    unsigned int freqsize = a->range >> totalfreq2;
11404    unsigned int z = a->code / freqsize;
11405    return z >= (1U<<totalfreq2) ? (1U<<totalfreq2)-1 : z;
11406 }
11407 
11408 void stb_arith_decode_advance_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq)
11409 {
11410    unsigned int freqsize = a->range >> totalfreq2;
11411    a->code -= freqsize * cumfreq;
11412    a->range = freqsize * freq;
11413    while (a->range < 0x1000000)
11414       stb__renorm_decoder(a);
11415 }
11416 
11417 stbfile *stb_arith_encode_close(stb_arith *a)
11418 {
11419    // put exactly as many bytes as we'll read, so we can turn on/off arithmetic coding in a stream
11420    stb__arith_putbyte(a, a->range_low >> 24);
11421    stb__arith_putbyte(a, a->range_low >> 16);
11422    stb__arith_putbyte(a, a->range_low >>  8);
11423    stb__arith_putbyte(a, a->range_low >>  0);
11424    stb__arith_flush(a);
11425    return a->output;
11426 }
11427 
11428 stbfile *stb_arith_decode_close(stb_arith *a)
11429 {
11430    return a->output;
11431 }
11432 #endif
11433 
11435 //
11436 //                         Threads
11437 //
11438 
11439 #ifndef _WIN32
11440 #ifdef STB_THREADS
11441 #error "threads not implemented except for Windows"
11442 #endif
11443 #endif
11444 
11445 // call this function to free any global variables for memory testing
11446 STB_EXTERN void stb_thread_cleanup(void);
11447 
11448 typedef void * (*stb_thread_func)(void *);
11449 
11450 // do not rely on these types, this is an implementation detail.
11451 // compare against STB_THREAD_NULL and ST_SEMAPHORE_NULL
11452 typedef void *stb_thread;
11453 typedef void *stb_semaphore;
11454 typedef void *stb_mutex;
11455 typedef struct stb__sync *stb_sync;
11456 
11457 #define STB_SEMAPHORE_NULL    NULL
11458 #define STB_THREAD_NULL       NULL
11459 #define STB_MUTEX_NULL        NULL
11460 #define STB_SYNC_NULL         NULL
11461 
11462 // get the number of processors (limited to those in the affinity mask for this process).
11463 STB_EXTERN int stb_processor_count(void);
11464 // force to run on a single core -- needed for RDTSC to work, e.g. for iprof
11465 STB_EXTERN void stb_force_uniprocessor(void);
11466 
11467 // stb_work functions: queue up work to be done by some worker threads
11468 
11469 // set number of threads to serve the queue; you can change this on the fly,
11470 // but if you decrease it, it won't decrease until things currently on the
11471 // queue are finished
11472 STB_EXTERN void          stb_work_numthreads(int n);
11473 // set maximum number of units in the queue; you can only set this BEFORE running any work functions
11474 STB_EXTERN int           stb_work_maxunits(int n);
11475 // enqueue some work to be done (can do this from any thread, or even from a piece of work);
11476 // return value of f is stored in *return_code if non-NULL
11477 STB_EXTERN int           stb_work(stb_thread_func f, void *d, volatile void **return_code);
11478 // as above, but stb_sync_reach is called on 'rel' after work is complete
11479 STB_EXTERN int           stb_work_reach(stb_thread_func f, void *d, volatile void **return_code, stb_sync rel);
11480 
11481 
11482 // necessary to call this when using volatile to order writes/reads
11483 STB_EXTERN void          stb_barrier(void);
11484 
11485 // support for independent queues with their own threads
11486 
11487 typedef struct stb__workqueue stb_workqueue;
11488 
11489 STB_EXTERN stb_workqueue*stb_workq_new(int numthreads, int max_units);
11490 STB_EXTERN stb_workqueue*stb_workq_new_flags(int numthreads, int max_units, int no_add_mutex, int no_remove_mutex);
11491 STB_EXTERN void          stb_workq_delete(stb_workqueue *q);
11492 STB_EXTERN void          stb_workq_numthreads(stb_workqueue *q, int n);
11493 STB_EXTERN int           stb_workq(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code);
11494 STB_EXTERN int           stb_workq_reach(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code, stb_sync rel);
11495 STB_EXTERN int           stb_workq_length(stb_workqueue *q);
11496 
11497 STB_EXTERN stb_thread    stb_create_thread (stb_thread_func f, void *d);
11498 STB_EXTERN stb_thread    stb_create_thread2(stb_thread_func f, void *d, volatile void **return_code, stb_semaphore rel);
11499 STB_EXTERN void          stb_destroy_thread(stb_thread t);
11500 
11501 STB_EXTERN stb_semaphore stb_sem_new(int max_val);
11502 STB_EXTERN stb_semaphore stb_sem_new_extra(int max_val, int start_val);
11503 STB_EXTERN void          stb_sem_delete (stb_semaphore s);
11504 STB_EXTERN void          stb_sem_waitfor(stb_semaphore s);
11505 STB_EXTERN void          stb_sem_release(stb_semaphore s);
11506 
11507 STB_EXTERN stb_mutex     stb_mutex_new(void);
11508 STB_EXTERN void          stb_mutex_delete(stb_mutex m);
11509 STB_EXTERN void          stb_mutex_begin(stb_mutex m);
11510 STB_EXTERN void          stb_mutex_end(stb_mutex m);
11511 
11512 STB_EXTERN stb_sync      stb_sync_new(void);
11513 STB_EXTERN void          stb_sync_delete(stb_sync s);
11514 STB_EXTERN int           stb_sync_set_target(stb_sync s, int count);
11515 STB_EXTERN void          stb_sync_reach_and_wait(stb_sync s);    // wait for 'target' reachers
11516 STB_EXTERN int           stb_sync_reach(stb_sync s);
11517 
11518 typedef struct stb__threadqueue stb_threadqueue;
11519 #define STB_THREADQ_DYNAMIC   0
11520 STB_EXTERN stb_threadqueue *stb_threadq_new(int item_size, int num_items, int many_add, int many_remove);
11521 STB_EXTERN void             stb_threadq_delete(stb_threadqueue *tq);
11522 STB_EXTERN int              stb_threadq_get(stb_threadqueue *tq, void *output);
11523 STB_EXTERN void             stb_threadq_get_block(stb_threadqueue *tq, void *output);
11524 STB_EXTERN int              stb_threadq_add(stb_threadqueue *tq, void *input);
11525 // can return FALSE if STB_THREADQ_DYNAMIC and attempt to grow fails
11526 STB_EXTERN int              stb_threadq_add_block(stb_threadqueue *tq, void *input);
11527 
11528 #ifdef STB_THREADS
11529 #ifdef STB_DEFINE
11530 
11531 typedef struct
11532 {
11533    stb_thread_func f;
11534    void *d;
11535    volatile void **return_val;
11536    stb_semaphore sem;
11537 } stb__thread;
11538 
11539 // this is initialized along all possible paths to create threads, therefore
11540 // it's always initialized before any other threads are create, therefore
11541 // it's free of races AS LONG AS you only create threads through stb_*
11542 static stb_mutex stb__threadmutex, stb__workmutex;
11543 
11544 static void stb__threadmutex_init(void)
11545 {
11546    if (stb__threadmutex == STB_SEMAPHORE_NULL) {
11547       stb__threadmutex = stb_mutex_new();
11548       stb__workmutex = stb_mutex_new();
11549    }
11550 }
11551 
11552 #ifdef STB_THREAD_TEST
11553 volatile float stb__t1=1, stb__t2;
11554 
11555 static void stb__wait(int n)
11556 {
11557    float z = 0;
11558    int i;
11559    for (i=0; i < n; ++i)
11560       z += 1 / (stb__t1+i);
11561    stb__t2 = z;
11562 }
11563 #else
11564 #define stb__wait(x)
11565 #endif
11566 
11567 #ifdef _WIN32
11568 
11569 // avoid including windows.h -- note that our definitions aren't
11570 // exactly the same (we don't define the security descriptor struct)
11571 // so if you want to include windows.h, make sure you do it first.
11572 #include <process.h>
11573 
11574 #ifndef _WINDOWS_  // check windows.h guard
11575 #define STB__IMPORT   STB_EXTERN __declspec(dllimport)
11576 #define STB__DW       unsigned long
11577 
11578 STB__IMPORT int     __stdcall TerminateThread(void *, STB__DW);
11579 STB__IMPORT void *  __stdcall CreateSemaphoreA(void *sec, long,long,char*);
11580 STB__IMPORT int     __stdcall CloseHandle(void *);
11581 STB__IMPORT STB__DW __stdcall WaitForSingleObject(void *, STB__DW);
11582 STB__IMPORT int     __stdcall ReleaseSemaphore(void *, long, long *);
11583 STB__IMPORT void    __stdcall Sleep(STB__DW);
11584 #endif
11585 
11586 // necessary to call this when using volatile to order writes/reads
11587 void stb_barrier(void)
11588 {
11589    #ifdef MemoryBarrier
11590    MemoryBarrier();
11591    #else
11592    long temp;
11593    __asm xchg temp,eax;
11594    #endif
11595 }
11596 
11597 static void stb__thread_run(void *t)
11598 {
11599    void *res;
11600    stb__thread info = * (stb__thread *) t;
11601    free(t);
11602    res = info.f(info.d);
11603    if (info.return_val)
11604       *info.return_val = res;
11605    if (info.sem != STB_SEMAPHORE_NULL)
11606       stb_sem_release(info.sem);
11607 }
11608 
11609 static stb_thread stb_create_thread_raw(stb_thread_func f, void *d, volatile void **return_code, stb_semaphore rel)
11610 {
11611 #ifdef _MT
11612 #if defined(STB_FASTMALLOC) && !defined(STB_FASTMALLOC_ITS_OKAY_I_ONLY_MALLOC_IN_ONE_THREAD)
11613    stb_fatal("Error! Cannot use STB_FASTMALLOC with threads.\n");
11614    return STB_THREAD_NULL;
11615 #else
11616    unsigned long id;
11617    stb__thread *data = (stb__thread *) malloc(sizeof(*data));
11618    if (!data) return NULL;
11619    stb__threadmutex_init();
11620    data->f = f;
11621    data->d = d;
11622    data->return_val = return_code;
11623    data->sem = rel;
11624    id = _beginthread(stb__thread_run, 0, data);
11625    if (id == -1) return NULL;
11626    return (void *) id;
11627 #endif
11628 #else
11629 #ifdef STB_NO_STB_STRINGS
11630    stb_fatal("Invalid compilation");
11631 #else
11632    stb_fatal("Must compile mult-threaded to use stb_thread/stb_work.");
11633 #endif
11634    return NULL;
11635 #endif
11636 }
11637 
11638 // trivial win32 wrappers
11639 void          stb_destroy_thread(stb_thread t)   { TerminateThread(t,0); }
11640 stb_semaphore stb_sem_new(int maxv)                {return CreateSemaphoreA(NULL,0,maxv,NULL); }
11641 stb_semaphore stb_sem_new_extra(int maxv,int start){return CreateSemaphoreA(NULL,start,maxv,NULL); }
11642 void          stb_sem_delete(stb_semaphore s)    { if (s != NULL) CloseHandle(s); }
11643 void          stb_sem_waitfor(stb_semaphore s)   { WaitForSingleObject(s, 0xffffffff); } // INFINITE
11644 void          stb_sem_release(stb_semaphore s)   { ReleaseSemaphore(s,1,NULL); }
11645 static void   stb__thread_sleep(int ms)          { Sleep(ms); }
11646 
11647 #ifndef _WINDOWS_
11648 STB__IMPORT int __stdcall GetProcessAffinityMask(void *, STB__DW *, STB__DW *);
11649 STB__IMPORT void * __stdcall GetCurrentProcess(void);
11650 STB__IMPORT int __stdcall SetProcessAffinityMask(void *, STB__DW);
11651 #endif
11652 
11653 int stb_processor_count(void)
11654 {
11655    unsigned long proc,sys;
11656    GetProcessAffinityMask(GetCurrentProcess(), &proc, &sys);
11657    return stb_bitcount(proc);
11658 }
11659 
11660 void stb_force_uniprocessor(void)
11661 {
11662    unsigned long proc,sys;
11663    GetProcessAffinityMask(GetCurrentProcess(), &proc, &sys);
11664    if (stb_bitcount(proc) > 1) {
11665       int z;
11666       for (z=0; z < 32; ++z)
11667          if (proc & (1 << z))
11668             break;
11669       if (z < 32) {
11670          proc = 1 << z;
11671          SetProcessAffinityMask(GetCurrentProcess(), proc);
11672       }
11673    }
11674 }
11675 
11676 #ifdef _WINDOWS_
11677 #define STB_MUTEX_NATIVE
11678 void *stb_mutex_new(void)
11679 {
11680    CRITICAL_SECTION *p = (CRITICAL_SECTION *) malloc(sizeof(*p));
11681    if (p)
11682 #if _WIN32_WINNT >= 0x0500
11683       InitializeCriticalSectionAndSpinCount(p, 500);
11684 #else
11685       InitializeCriticalSection(p);
11686 #endif
11687    return p;
11688 }
11689 
11690 void stb_mutex_delete(void *p)
11691 {
11692    if (p) {
11693       DeleteCriticalSection((CRITICAL_SECTION *) p);
11694       free(p);
11695    }
11696 }
11697 
11698 void stb_mutex_begin(void *p)
11699 {
11700    stb__wait(500);
11701    if (p)
11702       EnterCriticalSection((CRITICAL_SECTION *) p);
11703 }
11704 
11705 void stb_mutex_end(void *p)
11706 {
11707    if (p)
11708       LeaveCriticalSection((CRITICAL_SECTION *) p);
11709    stb__wait(500);
11710 }
11711 #endif // _WINDOWS_
11712 
11713 #if 0
11714 // for future reference,
11715 // InterlockedCompareExchange for x86:
11716  int cas64_mp(void * dest, void * xcmp, void * xxchg) {
11717         __asm
11718         {
11719                 mov             esi, [xxchg]            ; exchange
11720                 mov             ebx, [esi + 0]
11721                 mov             ecx, [esi + 4]
11722 
11723                 mov             esi, [xcmp]                     ; comparand
11724                 mov             eax, [esi + 0]
11725                 mov             edx, [esi + 4]
11726 
11727                 mov             edi, [dest]                     ; destination
11728                 lock cmpxchg8b  [edi]
11729                 jz              yyyy;
11730 
11731                 mov             [esi + 0], eax;
11732                 mov             [esi + 4], edx;
11733 
11734 yyyy:
11735                 xor             eax, eax;
11736                 setz    al;
11737         };
11738 
11739 inline unsigned __int64 _InterlockedCompareExchange64(volatile unsigned __int64 *dest
11740                            ,unsigned __int64 exchange
11741                            ,unsigned __int64 comperand)
11742 {
11743     //value returned in eax::edx
11744     __asm {
11745         lea esi,comperand;
11746         lea edi,exchange;
11747 
11748         mov eax,[esi];
11749         mov edx,4[esi];
11750         mov ebx,[edi];
11751         mov ecx,4[edi];
11752         mov esi,dest;
11753         lock CMPXCHG8B [esi];
11754     }
11755 #endif // #if 0
11756 
11757 #endif // _WIN32
11758 
11759 stb_thread stb_create_thread2(stb_thread_func f, void *d, volatile void **return_code, stb_semaphore rel)
11760 {
11761    return stb_create_thread_raw(f,d,return_code,rel);
11762 }
11763 
11764 stb_thread stb_create_thread(stb_thread_func f, void *d)
11765 {
11766    return stb_create_thread2(f,d,NULL,STB_SEMAPHORE_NULL);
11767 }
11768 
11769 // mutex implemented by wrapping semaphore
11770 #ifndef STB_MUTEX_NATIVE
11771 stb_mutex stb_mutex_new(void)            { return stb_sem_new_extra(1,1); }
11772 void      stb_mutex_delete(stb_mutex m)  { stb_sem_delete (m);      }
11773 void      stb_mutex_begin(stb_mutex m)   { stb__wait(500); if (m) stb_sem_waitfor(m); }
11774 void      stb_mutex_end(stb_mutex m)     { if (m) stb_sem_release(m); stb__wait(500); }
11775 #endif
11776 
11777 // thread merge operation
11778 struct stb__sync
11779 {
11780    int target;  // target number of threads to hit it
11781    int sofar;   // total threads that hit it
11782    int waiting; // total threads waiting
11783 
11784    stb_mutex start;   // mutex to prevent starting again before finishing previous
11785    stb_mutex mutex;   // mutex while tweaking state
11786    stb_semaphore release; // semaphore wake up waiting threads
11787       // we have to wake them up one at a time, rather than using a single release
11788       // call, because win32 semaphores don't let you dynamically change the max count!
11789 };
11790 
11791 stb_sync stb_sync_new(void)
11792 {
11793    stb_sync s = (stb_sync) malloc(sizeof(*s));
11794    if (!s) return s;
11795 
11796    s->target = s->sofar = s->waiting = 0;
11797    s->mutex   = stb_mutex_new();
11798    s->start   = stb_mutex_new();
11799    s->release = stb_sem_new(1);
11800    if (s->mutex == STB_MUTEX_NULL || s->release == STB_SEMAPHORE_NULL || s->start == STB_MUTEX_NULL) {
11801       stb_mutex_delete(s->mutex);
11802       stb_mutex_delete(s->mutex);
11803       stb_sem_delete(s->release);
11804       free(s);
11805       return NULL;
11806    }
11807    return s;
11808 }
11809 
11810 void stb_sync_delete(stb_sync s)
11811 {
11812    if (s->waiting) {
11813       // it's bad to delete while there are threads waiting!
11814       // shall we wait for them to reach, or just bail? just bail
11815       assert(0);
11816    }
11817    stb_mutex_delete(s->mutex);
11818    stb_mutex_delete(s->release);
11819    free(s);
11820 }
11821 
11822 int stb_sync_set_target(stb_sync s, int count)
11823 {
11824    // don't allow setting a target until the last one is fully released;
11825    // note that this can lead to inefficient pipelining, and maybe we'd
11826    // be better off ping-ponging between two internal syncs?
11827    // I tried seeing how often this happened using TryEnterCriticalSection
11828    // and could _never_ get it to happen in imv(stb), even with more threads
11829    // than processors. So who knows!
11830    stb_mutex_begin(s->start);
11831 
11832    // this mutex is pointless, since it's not valid for threads
11833    // to call reach() before anyone calls set_target() anyway
11834    stb_mutex_begin(s->mutex);
11835 
11836    assert(s->target == 0); // enforced by start mutex
11837    s->target  = count;
11838    s->sofar   = 0;
11839    s->waiting = 0;
11840    stb_mutex_end(s->mutex);
11841    return STB_TRUE;
11842 }
11843 
11844 void stb__sync_release(stb_sync s)
11845 {
11846    if (s->waiting)
11847       stb_sem_release(s->release);
11848    else {
11849       s->target = 0;
11850       stb_mutex_end(s->start);
11851    }
11852 }
11853 
11854 int stb_sync_reach(stb_sync s)
11855 {
11856    int n;
11857    stb_mutex_begin(s->mutex);
11858    assert(s->sofar < s->target);
11859    n = ++s->sofar; // record this value to avoid possible race if we did 'return s->sofar';
11860    if (s->sofar == s->target)
11861       stb__sync_release(s);
11862    stb_mutex_end(s->mutex);
11863    return n;
11864 }
11865 
11866 void stb_sync_reach_and_wait(stb_sync s)
11867 {
11868    stb_mutex_begin(s->mutex);
11869    assert(s->sofar < s->target);
11870    ++s->sofar;
11871    if (s->sofar == s->target) {
11872       stb__sync_release(s);
11873       stb_mutex_end(s->mutex);
11874    } else {
11875       ++s->waiting; // we're waiting, so one more waiter
11876       stb_mutex_end(s->mutex); // release the mutex to other threads
11877 
11878       stb_sem_waitfor(s->release); // wait for merge completion
11879 
11880       stb_mutex_begin(s->mutex); // on merge completion, grab the mutex
11881       --s->waiting; // we're done waiting
11882       stb__sync_release(s);    // restart the next waiter
11883       stb_mutex_end(s->mutex); // and now we're done
11884       // this ends the same as the first case, but it's a lot
11885       // clearer to understand without sharing the code
11886    }
11887 }
11888 
11889 struct stb__threadqueue
11890 {
11891    stb_mutex add, remove;
11892    stb_semaphore nonempty, nonfull;
11893    int head_blockers;  // number of threads blocking--used to know whether to release(avail)
11894    int tail_blockers;
11895    int head, tail, array_size, growable;
11896    int item_size;
11897    char *data;
11898 };
11899 
11900 static int stb__tq_wrap(volatile stb_threadqueue *z, int p)
11901 {
11902    if (p == z->array_size)
11903       return p - z->array_size;
11904    else
11905       return p;
11906 }
11907 
11908 int stb__threadq_get_raw(stb_threadqueue *tq2, void *output, int block)
11909 {
11910    volatile stb_threadqueue *tq = (volatile stb_threadqueue *) tq2;
11911    if (tq->head == tq->tail && !block) return 0;
11912 
11913    stb_mutex_begin(tq->remove);
11914 
11915    while (tq->head == tq->tail) {
11916       if (!block) {
11917          stb_mutex_end(tq->remove);
11918          return 0;
11919       }
11920       ++tq->head_blockers;
11921       stb_mutex_end(tq->remove);
11922 
11923       stb_sem_waitfor(tq->nonempty);
11924 
11925       stb_mutex_begin(tq->remove);
11926       --tq->head_blockers;
11927    }
11928 
11929    memcpy(output, tq->data + tq->head*tq->item_size, tq->item_size);
11930    stb_barrier();
11931    tq->head = stb__tq_wrap(tq, tq->head+1);
11932 
11933    stb_sem_release(tq->nonfull);
11934    if (tq->head_blockers) // can't check if actually non-empty due to race?
11935       stb_sem_release(tq->nonempty); // if there are other blockers, wake one
11936 
11937    stb_mutex_end(tq->remove);
11938    return STB_TRUE;
11939 }
11940 
11941 int stb__threadq_grow(volatile stb_threadqueue *tq)
11942 {
11943    int n;
11944    char *p;
11945    assert(tq->remove != STB_MUTEX_NULL); // must have this to allow growth!
11946    stb_mutex_begin(tq->remove);
11947 
11948    n = tq->array_size * 2;
11949    p = (char *) realloc(tq->data, n * tq->item_size);
11950    if (p == NULL) {
11951       stb_mutex_end(tq->remove);
11952       stb_mutex_end(tq->add);
11953       return STB_FALSE;
11954    }
11955    if (tq->tail < tq->head) {
11956       memcpy(p + tq->array_size * tq->item_size, p, tq->tail * tq->item_size);
11957       tq->tail += tq->array_size;
11958    }
11959    tq->data = p;
11960    tq->array_size = n;
11961 
11962    stb_mutex_end(tq->remove);
11963    return STB_TRUE;
11964 }
11965 
11966 int stb__threadq_add_raw(stb_threadqueue *tq2, void *input, int block)
11967 {
11968    int tail,pos;
11969    volatile stb_threadqueue *tq = (volatile stb_threadqueue *) tq2;
11970    stb_mutex_begin(tq->add);
11971    for(;;) {
11972       pos = tq->tail;
11973       tail = stb__tq_wrap(tq, pos+1);
11974       if (tail != tq->head) break;
11975 
11976       // full
11977       if (tq->growable) {
11978          if (!stb__threadq_grow(tq)) {
11979             stb_mutex_end(tq->add);
11980             return STB_FALSE; // out of memory
11981          }
11982       } else if (!block) {
11983          stb_mutex_end(tq->add);
11984          return STB_FALSE;
11985       } else {
11986          ++tq->tail_blockers;
11987          stb_mutex_end(tq->add);
11988 
11989          stb_sem_waitfor(tq->nonfull);
11990 
11991          stb_mutex_begin(tq->add);
11992          --tq->tail_blockers;
11993       }
11994    }
11995    memcpy(tq->data + tq->item_size * pos, input, tq->item_size);
11996    stb_barrier();
11997    tq->tail = tail;
11998    stb_sem_release(tq->nonempty);
11999    if (tq->tail_blockers) // can't check if actually non-full due to race?
12000       stb_sem_release(tq->nonfull);
12001    stb_mutex_end(tq->add);
12002    return STB_TRUE;
12003 }
12004 
12005 int stb_threadq_length(stb_threadqueue *tq2)
12006 {
12007    int a,b,n;
12008    volatile stb_threadqueue *tq = (volatile stb_threadqueue *) tq2;
12009    stb_mutex_begin(tq->add);
12010    a = tq->head;
12011    b = tq->tail;
12012    n = tq->array_size;
12013    stb_mutex_end(tq->add);
12014    if (a > b) b += n;
12015    return b-a;
12016 }
12017 
12018 int stb_threadq_get(stb_threadqueue *tq, void *output)
12019 {
12020    return stb__threadq_get_raw(tq, output, STB_FALSE);
12021 }
12022 
12023 void stb_threadq_get_block(stb_threadqueue *tq, void *output)
12024 {
12025    stb__threadq_get_raw(tq, output, STB_TRUE);
12026 }
12027 
12028 int stb_threadq_add(stb_threadqueue *tq, void *input)
12029 {
12030    return stb__threadq_add_raw(tq, input, STB_FALSE);
12031 }
12032 
12033 int stb_threadq_add_block(stb_threadqueue *tq, void *input)
12034 {
12035    return stb__threadq_add_raw(tq, input, STB_TRUE);
12036 }
12037 
12038 void stb_threadq_delete(stb_threadqueue *tq)
12039 {
12040    if (tq) {
12041       free(tq->data);
12042       stb_mutex_delete(tq->add);
12043       stb_mutex_delete(tq->remove);
12044       stb_sem_delete(tq->nonempty);
12045       stb_sem_delete(tq->nonfull);
12046       free(tq);
12047    }
12048 }
12049 
12050 #define STB_THREADQUEUE_DYNAMIC   0
12051 stb_threadqueue *stb_threadq_new(int item_size, int num_items, int many_add, int many_remove)
12052 {
12053    int error=0;
12054    stb_threadqueue *tq = (stb_threadqueue *) malloc(sizeof(*tq));
12055    if (tq == NULL) return NULL;
12056 
12057    if (num_items == STB_THREADQUEUE_DYNAMIC) {
12058       tq->growable = STB_TRUE;
12059       num_items = 32;
12060    } else
12061       tq->growable = STB_FALSE;
12062 
12063    tq->item_size = item_size;
12064    tq->array_size = num_items+1;
12065 
12066    tq->add = tq->remove = STB_MUTEX_NULL;
12067    tq->nonempty = tq->nonfull = STB_SEMAPHORE_NULL;
12068    tq->data = NULL;
12069    if (many_add)
12070       { tq->add    = stb_mutex_new(); if (tq->add    == STB_MUTEX_NULL) goto error; }
12071    if (many_remove || tq->growable)
12072       { tq->remove = stb_mutex_new(); if (tq->remove == STB_MUTEX_NULL) goto error; }
12073    tq->nonempty = stb_sem_new(1); if (tq->nonempty == STB_SEMAPHORE_NULL) goto error;
12074    tq->nonfull  = stb_sem_new(1); if (tq->nonfull  == STB_SEMAPHORE_NULL) goto error;
12075    tq->data = (char *) malloc(tq->item_size * tq->array_size);
12076    if (tq->data == NULL) goto error;
12077 
12078    tq->head = tq->tail = 0;
12079    tq->head_blockers = tq->tail_blockers = 0;
12080 
12081    return tq;
12082 
12083 error:
12084    stb_threadq_delete(tq);
12085    return NULL;
12086 }
12087 
12088 typedef struct
12089 {
12090    stb_thread_func f;
12091    void *d;
12092    volatile void **retval;
12093    stb_sync sync;
12094 } stb__workinfo;
12095 
12096 //static volatile stb__workinfo *stb__work;
12097 
12098 struct stb__workqueue
12099 {
12100    int numthreads;
12101    stb_threadqueue *tq;
12102 };
12103 
12104 static stb_workqueue *stb__work_global;
12105 
12106 static void *stb__thread_workloop(void *p)
12107 {
12108    volatile stb_workqueue *q = (volatile stb_workqueue *) p;
12109    for(;;) {
12110       void *z;
12111       stb__workinfo w;
12112       stb_threadq_get_block(q->tq, &w);
12113       if (w.f == NULL) // null work is a signal to end the thread
12114          return NULL;
12115       z = w.f(w.d);
12116       if (w.retval) { stb_barrier(); *w.retval = z; }
12117       if (w.sync != STB_SYNC_NULL) stb_sync_reach(w.sync);
12118    }
12119 }
12120 
12121 stb_workqueue *stb_workq_new(int num_threads, int max_units)
12122 {
12123    return stb_workq_new_flags(num_threads, max_units, 0,0);
12124 }
12125 
12126 stb_workqueue *stb_workq_new_flags(int numthreads, int max_units, int no_add_mutex, int no_remove_mutex)
12127 {
12128    stb_workqueue *q = (stb_workqueue *) malloc(sizeof(*q));
12129    if (q == NULL) return NULL;
12130    q->tq = stb_threadq_new(sizeof(stb__workinfo), max_units, !no_add_mutex, !no_remove_mutex);
12131    if (q->tq == NULL) { free(q); return NULL; }
12132    q->numthreads = 0;
12133    stb_workq_numthreads(q, numthreads);
12134    return q;
12135 }
12136 
12137 void stb_workq_delete(stb_workqueue *q)
12138 {
12139    while (stb_workq_length(q) != 0)
12140       stb__thread_sleep(1);
12141    stb_threadq_delete(q->tq);
12142    free(q);
12143 }
12144 
12145 static int stb__work_maxitems = STB_THREADQUEUE_DYNAMIC;
12146 
12147 static void stb_work_init(int num_threads)
12148 {
12149    if (stb__work_global == NULL) {
12150       stb__threadmutex_init();
12151       stb_mutex_begin(stb__workmutex);
12152       stb_barrier();
12153       if (*(stb_workqueue * volatile *) &stb__work_global == NULL)
12154          stb__work_global = stb_workq_new(num_threads, stb__work_maxitems);
12155       stb_mutex_end(stb__workmutex);
12156    }
12157 }
12158 
12159 static int stb__work_raw(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code, stb_sync rel)
12160 {
12161    stb__workinfo w;
12162    if (q == NULL) {
12163       stb_work_init(1);
12164       q = stb__work_global;
12165    }
12166    w.f = f;
12167    w.d = d;
12168    w.retval = return_code;
12169    w.sync = rel;
12170    return stb_threadq_add(q->tq, &w);
12171 }
12172 
12173 int stb_workq_length(stb_workqueue *q)
12174 {
12175    return stb_threadq_length(q->tq);
12176 }
12177 
12178 int stb_workq(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code)
12179 {
12180    if (f == NULL) return 0;
12181    return stb_workq_reach(q, f, d, return_code, NULL);
12182 }
12183 
12184 int stb_workq_reach(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code, stb_sync rel)
12185 {
12186    if (f == NULL) return 0;
12187    return stb__work_raw(q, f, d, return_code, rel);
12188 }
12189 
12190 static void stb__workq_numthreads(stb_workqueue *q, int n)
12191 {
12192    while (q->numthreads < n) {
12193       stb_create_thread(stb__thread_workloop, q);
12194       ++q->numthreads;
12195    }
12196    while (q->numthreads > n) {
12197       stb__work_raw(q, NULL, NULL, NULL, NULL);
12198       --q->numthreads;
12199    }
12200 }
12201 
12202 void stb_workq_numthreads(stb_workqueue *q, int n)
12203 {
12204    stb_mutex_begin(stb__threadmutex);
12205    stb__workq_numthreads(q,n);
12206    stb_mutex_end(stb__threadmutex);
12207 }
12208 
12209 int stb_work_maxunits(int n)
12210 {
12211    if (stb__work_global == NULL) {
12212       stb__work_maxitems = n;
12213       stb_work_init(1);
12214    }
12215    return stb__work_maxitems;
12216 }
12217 
12218 int stb_work(stb_thread_func f, void *d, volatile void **return_code)
12219 {
12220    return stb_workq(stb__work_global, f,d,return_code);
12221 }
12222 
12223 int stb_work_reach(stb_thread_func f, void *d, volatile void **return_code, stb_sync rel)
12224 {
12225    return stb_workq_reach(stb__work_global, f,d,return_code,rel);
12226 }
12227 
12228 void stb_work_numthreads(int n)
12229 {
12230    if (stb__work_global == NULL)
12231       stb_work_init(n);
12232    else
12233       stb_workq_numthreads(stb__work_global, n);
12234 }
12235 #endif // STB_DEFINE
12236 
12237 
12239 //
12240 // Background disk I/O
12241 //
12242 //
12243 
12244 #define STB_BGIO_READ_ALL   (-1)
12245 STB_EXTERN int stb_bgio_read    (char *filename, int offset, int len, stb_uchar **result, int *olen);
12246 STB_EXTERN int stb_bgio_readf   (FILE *f       , int offset, int len, stb_uchar **result, int *olen);
12247 STB_EXTERN int stb_bgio_read_to (char *filename, int offset, int len, stb_uchar  *buffer, int *olen);
12248 STB_EXTERN int stb_bgio_readf_to(FILE *f       , int offset, int len, stb_uchar  *buffer, int *olen);
12249 
12250 typedef struct
12251 {
12252    int have_data;
12253    int is_valid;
12254    int is_dir;
12255    time_t filetime;
12256    stb_int64 filesize;
12257 } stb_bgstat;
12258 
12259 STB_EXTERN int stb_bgio_stat    (char *filename, stb_bgstat *result);
12260 
12261 #ifdef STB_DEFINE
12262 
12263 static stb_workqueue *stb__diskio;
12264 static stb_mutex stb__diskio_mutex;
12265 
12266 void stb_thread_cleanup(void)
12267 {
12268    if (stb__work_global) stb_workq_delete(stb__work_global); stb__work_global = NULL;
12269    if (stb__threadmutex) stb_mutex_delete(stb__threadmutex); stb__threadmutex = NULL;
12270    if (stb__workmutex)   stb_mutex_delete(stb__workmutex);   stb__workmutex   = NULL;
12271    if (stb__diskio)      stb_workq_delete(stb__diskio);      stb__diskio      = NULL;
12272    if (stb__diskio_mutex)stb_mutex_delete(stb__diskio_mutex);stb__diskio_mutex= NULL;
12273 }
12274 
12275 
12276 typedef struct
12277 {
12278    char *filename;
12279    FILE *f;
12280    int offset;
12281    int len;
12282 
12283    stb_bgstat *stat_out;
12284    stb_uchar *output;
12285    stb_uchar **result;
12286    int *len_output;
12287    int *flag;
12288 } stb__disk_command;
12289 
12290 #define STB__MAX_DISK_COMMAND 100
12291 static stb__disk_command stb__dc_queue[STB__MAX_DISK_COMMAND];
12292 static int stb__dc_offset;
12293 
12294 void stb__io_init(void)
12295 {
12296    if (!stb__diskio) {
12297       stb__threadmutex_init();
12298       stb_mutex_begin(stb__threadmutex);
12299       stb_barrier();
12300       if (*(stb_thread * volatile *) &stb__diskio == NULL) {
12301          stb__diskio_mutex = stb_mutex_new();
12302          // use many threads so OS can try to schedule seeks
12303          stb__diskio = stb_workq_new_flags(16,STB__MAX_DISK_COMMAND,STB_FALSE,STB_FALSE);
12304       }
12305       stb_mutex_end(stb__threadmutex);
12306    }
12307 }
12308 
12309 static void * stb__io_error(stb__disk_command *dc)
12310 {
12311    if (dc->len_output) *dc->len_output = 0;
12312    if (dc->result) *dc->result = NULL;
12313    if (dc->flag) *dc->flag = -1;
12314    return NULL;
12315 }
12316 
12317 static void * stb__io_task(void *p)
12318 {
12319    stb__disk_command *dc = (stb__disk_command *) p;
12320    int len;
12321    FILE *f;
12322    stb_uchar *buf;
12323 
12324    if (dc->stat_out) {
12325       struct _stati64 s;
12326       if (!_stati64(dc->filename, &s)) {
12327          dc->stat_out->filesize = s.st_size;
12328          dc->stat_out->filetime = s.st_mtime;
12329          dc->stat_out->is_dir = s.st_mode & _S_IFDIR;
12330          dc->stat_out->is_valid = (s.st_mode & _S_IFREG) || dc->stat_out->is_dir;
12331       } else
12332          dc->stat_out->is_valid = 0;
12333       stb_barrier();
12334       dc->stat_out->have_data = 1;
12335       free(dc->filename);
12336       return 0;
12337    }
12338    if (dc->f) {
12339       #ifdef WIN32
12340       f = _fdopen(_dup(_fileno(dc->f)), "rb");
12341       #else
12342       f = fdopen(dup(fileno(dc->f)), "rb");
12343       #endif
12344       if (!f)
12345          return stb__io_error(dc);
12346    } else {
12347       f = fopen(dc->filename, "rb");
12348       free(dc->filename);
12349       if (!f)
12350          return stb__io_error(dc);
12351    }
12352 
12353    len = dc->len;
12354    if (len < 0) {
12355       fseek(f, 0, SEEK_END);
12356       len = ftell(f) - dc->offset;
12357    }
12358 
12359    if (fseek(f, dc->offset, SEEK_SET)) {
12360       fclose(f);
12361       return stb__io_error(dc);
12362    }
12363 
12364    if (dc->output)
12365       buf = dc->output;
12366    else {
12367       buf = (stb_uchar *) malloc(len);
12368       if (buf == NULL) {
12369          fclose(f);
12370          return stb__io_error(dc);
12371       }
12372    }
12373 
12374    len = fread(buf, 1, len, f);
12375    fclose(f);
12376    if (dc->len_output) *dc->len_output = len;
12377    if (dc->result) *dc->result = buf;
12378    if (dc->flag) *dc->flag = 1;
12379 
12380    return NULL;
12381 }
12382 
12383 int stb__io_add(char *fname, FILE *f, int off, int len, stb_uchar *out, stb_uchar **result, int *olen, int *flag, stb_bgstat *stat)
12384 {
12385    int res;
12386    stb__io_init();
12387    // do memory allocation outside of mutex
12388    if (fname) fname = stb_p_strdup(fname);
12389    stb_mutex_begin(stb__diskio_mutex);
12390    {
12391       stb__disk_command *dc = &stb__dc_queue[stb__dc_offset];
12392       dc->filename = fname;
12393       dc->f = f;
12394       dc->offset = off;
12395       dc->len = len;
12396       dc->output = out;
12397       dc->result = result;
12398       dc->len_output = olen;
12399       dc->flag = flag;
12400       dc->stat_out = stat;
12401       res = stb_workq(stb__diskio, stb__io_task, dc, NULL);
12402       if (res)
12403          stb__dc_offset = (stb__dc_offset + 1 == STB__MAX_DISK_COMMAND ? 0 : stb__dc_offset+1);
12404    }
12405    stb_mutex_end(stb__diskio_mutex);
12406    return res;
12407 }
12408 
12409 int stb_bgio_read(char *filename, int offset, int len, stb_uchar **result, int *olen)
12410 {
12411    return stb__io_add(filename,NULL,offset,len,NULL,result,olen,NULL,NULL);
12412 }
12413 
12414 int stb_bgio_readf(FILE *f, int offset, int len, stb_uchar **result, int *olen)
12415 {
12416    return stb__io_add(NULL,f,offset,len,NULL,result,olen,NULL,NULL);
12417 }
12418 
12419 int stb_bgio_read_to(char *filename, int offset, int len, stb_uchar *buffer, int *olen)
12420 {
12421    return stb__io_add(filename,NULL,offset,len,buffer,NULL,olen,NULL,NULL);
12422 }
12423 
12424 int stb_bgio_readf_to(FILE *f, int offset, int len, stb_uchar *buffer, int *olen)
12425 {
12426    return stb__io_add(NULL,f,offset,len,buffer,NULL,olen,NULL,NULL);
12427 }
12428 
12429 STB_EXTERN int stb_bgio_stat    (char *filename, stb_bgstat *result)
12430 {
12431    result->have_data = 0;
12432    return stb__io_add(filename,NULL,0,0,0,NULL,0,NULL, result);
12433 }
12434 #endif
12435 #endif
12436 
12437 
12438 
12440 //
12441 //                         Fast malloc implementation
12442 //
12443 //   This is a clone of TCMalloc, but without the thread support.
12444 //      1. large objects are allocated directly, page-aligned
12445 //      2. small objects are allocated in homogeonous heaps, 0 overhead
12446 //
12447 //   We keep an allocation table for pages a la TCMalloc. This would
12448 //   require 4MB for the entire address space, but we only allocate
12449 //   the parts that are in use. The overhead from using homogenous heaps
12450 //   everywhere is 3MB. (That is, if you allocate 1 object of each size,
12451 //   you'll use 3MB.)
12452 
12453 #if defined(STB_DEFINE) && ((defined(_WIN32) && !defined(_M_AMD64)) || defined(STB_FASTMALLOC))
12454 
12455 #ifdef _WIN32
12456    #ifndef _WINDOWS_
12457    #ifndef STB__IMPORT
12458    #define STB__IMPORT   STB_EXTERN __declspec(dllimport)
12459    #define STB__DW       unsigned long
12460    #endif
12461    STB__IMPORT void * __stdcall VirtualAlloc(void *p, unsigned long size, unsigned long type, unsigned long protect);
12462    STB__IMPORT int   __stdcall VirtualFree(void *p, unsigned long size, unsigned long freetype);
12463    #endif
12464    #define stb__alloc_pages_raw(x)     (stb_uint32) VirtualAlloc(NULL, (x), 0x3000, 0x04)
12465    #define stb__dealloc_pages_raw(p)   VirtualFree((void *) p, 0, 0x8000)
12466 #else
12467    #error "Platform not currently supported"
12468 #endif
12469 
12470 typedef struct stb__span
12471 {
12472    int                start, len;
12473    struct stb__span  *next, *prev;
12474    void              *first_free;
12475    unsigned short     list; // 1..256 free; 257..511 sizeclass; 0=large block
12476    short              allocations; // # outstanding allocations for sizeclass
12477 } stb__span;  // 24
12478 
12479 static stb__span **stb__span_for_page;
12480 static int stb__firstpage, stb__lastpage;
12481 static void stb__update_page_range(int first, int last)
12482 {
12483    stb__span **sfp;
12484    int i, f,l;
12485    if (first >= stb__firstpage && last <= stb__lastpage) return;
12486    if (stb__span_for_page == NULL) {
12487       f = first;
12488       l = f+stb_max(last-f, 16384);
12489       l = stb_min(l, 1<<20);
12490    } else if (last > stb__lastpage) {
12491       f = stb__firstpage;
12492       l = f + (stb__lastpage - f) * 2;
12493       l = stb_clamp(last, l,1<<20);
12494    } else {
12495       l = stb__lastpage;
12496       f = l - (l - stb__firstpage) * 2;
12497       f = stb_clamp(f, 0,first);
12498    }
12499    sfp = (stb__span **) stb__alloc_pages_raw(sizeof(void *) * (l-f));
12500    for (i=f; i < stb__firstpage; ++i) sfp[i - f] = NULL;
12501    for (   ; i < stb__lastpage ; ++i) sfp[i - f] = stb__span_for_page[i - stb__firstpage];
12502    for (   ; i < l             ; ++i) sfp[i - f] = NULL;
12503    if (stb__span_for_page) stb__dealloc_pages_raw(stb__span_for_page);
12504    stb__firstpage = f;
12505    stb__lastpage  = l;
12506    stb__span_for_page = sfp;
12507 }
12508 
12509 static stb__span *stb__span_free=NULL;
12510 static stb__span *stb__span_first, *stb__span_end;
12511 static stb__span *stb__span_alloc(void)
12512 {
12513    stb__span *s = stb__span_free;
12514    if (s)
12515       stb__span_free = s->next;
12516    else {
12517       if (!stb__span_first) {
12518          stb__span_first = (stb__span *) stb__alloc_pages_raw(65536);
12519          if (stb__span_first == NULL) return NULL;
12520          stb__span_end = stb__span_first + (65536 / sizeof(stb__span));
12521       }
12522       s = stb__span_first++;
12523       if (stb__span_first == stb__span_end) stb__span_first = NULL;
12524    }
12525    return s;
12526 }
12527 
12528 static stb__span *stb__spanlist[512];
12529 
12530 static void stb__spanlist_unlink(stb__span *s)
12531 {
12532    if (s->prev)
12533       s->prev->next = s->next;
12534    else {
12535       int n = s->list;
12536       assert(stb__spanlist[n] == s);
12537       stb__spanlist[n] = s->next;
12538    }
12539    if (s->next)
12540       s->next->prev = s->prev;
12541    s->next = s->prev = NULL;
12542    s->list = 0;
12543 }
12544 
12545 static void stb__spanlist_add(int n, stb__span *s)
12546 {
12547    s->list = n;
12548    s->next = stb__spanlist[n];
12549    s->prev = NULL;
12550    stb__spanlist[n] = s;
12551    if (s->next) s->next->prev = s;
12552 }
12553 
12554 #define stb__page_shift       12
12555 #define stb__page_size        (1 << stb__page_shift)
12556 #define stb__page_number(x)   ((x) >> stb__page_shift)
12557 #define stb__page_address(x)  ((x) << stb__page_shift)
12558 
12559 static void stb__set_span_for_page(stb__span *s)
12560 {
12561    int i;
12562    for (i=0; i < s->len; ++i)
12563       stb__span_for_page[s->start + i - stb__firstpage] = s;
12564 }
12565 
12566 static stb__span *stb__coalesce(stb__span *a, stb__span *b)
12567 {
12568    assert(a->start + a->len == b->start);
12569    if (a->list) stb__spanlist_unlink(a);
12570    if (b->list) stb__spanlist_unlink(b);
12571    a->len += b->len;
12572    b->len = 0;
12573    b->next = stb__span_free;
12574    stb__span_free = b;
12575    stb__set_span_for_page(a);
12576    return a;
12577 }
12578 
12579 static void stb__free_span(stb__span *s)
12580 {
12581    stb__span *n = NULL;
12582    if (s->start > stb__firstpage) {
12583       n = stb__span_for_page[s->start-1 - stb__firstpage];
12584       if (n && n->allocations == -2 && n->start + n->len == s->start) s = stb__coalesce(n,s);
12585    }
12586    if (s->start + s->len < stb__lastpage) {
12587       n = stb__span_for_page[s->start + s->len - stb__firstpage];
12588       if (n && n->allocations == -2 && s->start + s->len == n->start) s = stb__coalesce(s,n);
12589    }
12590    s->allocations = -2;
12591    stb__spanlist_add(s->len > 256 ? 256 : s->len, s);
12592 }
12593 
12594 static stb__span *stb__alloc_pages(int num)
12595 {
12596    stb__span *s = stb__span_alloc();
12597    int p;
12598    if (!s) return NULL;
12599    p = stb__alloc_pages_raw(num << stb__page_shift);
12600    if (p == 0) { s->next = stb__span_free; stb__span_free = s; return 0; }
12601    assert(stb__page_address(stb__page_number(p)) == p);
12602    p = stb__page_number(p);
12603    stb__update_page_range(p, p+num);
12604    s->start = p;
12605    s->len   = num;
12606    s->next  = NULL;
12607    s->prev  = NULL;
12608    stb__set_span_for_page(s);
12609    return s;
12610 }
12611 
12612 static stb__span *stb__alloc_span(int pagecount)
12613 {
12614    int i;
12615    stb__span *p = NULL;
12616    for(i=pagecount; i < 256; ++i)
12617       if (stb__spanlist[i]) {
12618          p = stb__spanlist[i];
12619          break;
12620       }
12621    if (!p) {
12622       p = stb__spanlist[256];
12623       while (p && p->len < pagecount)
12624          p = p->next;
12625    }
12626    if (!p) {
12627       p = stb__alloc_pages(pagecount < 16 ? 16 : pagecount);
12628       if (p == NULL) return 0;
12629    } else
12630       stb__spanlist_unlink(p);
12631 
12632    if (p->len > pagecount) {
12633       stb__span *q = stb__span_alloc();
12634       if (q) {
12635          q->start = p->start + pagecount;
12636          q->len   = p->len   - pagecount;
12637          p->len   = pagecount;
12638          for (i=0; i < q->len; ++i)
12639             stb__span_for_page[q->start+i - stb__firstpage] = q;
12640          stb__spanlist_add(q->len > 256 ? 256 : q->len, q);
12641       }
12642    }
12643    return p;
12644 }
12645 
12646 #define STB__MAX_SMALL_SIZE     32768
12647 #define STB__MAX_SIZE_CLASSES   256
12648 
12649 static unsigned char stb__class_base[32];
12650 static unsigned char stb__class_shift[32];
12651 static unsigned char stb__pages_for_class[STB__MAX_SIZE_CLASSES];
12652 static           int stb__size_for_class[STB__MAX_SIZE_CLASSES];
12653 
12654 stb__span *stb__get_nonempty_sizeclass(int c)
12655 {
12656    int s = c + 256, i, size, tsize; // remap to span-list index
12657    char *z;
12658    void *q;
12659    stb__span *p = stb__spanlist[s];
12660    if (p) {
12661       if (p->first_free) return p; // fast path: it's in the first one in list
12662       for (p=p->next; p; p=p->next)
12663          if (p->first_free) {
12664             // move to front for future queries
12665             stb__spanlist_unlink(p);
12666             stb__spanlist_add(s, p);
12667             return p;
12668          }
12669    }
12670    // no non-empty ones, so allocate a new one
12671    p = stb__alloc_span(stb__pages_for_class[c]);
12672    if (!p) return NULL;
12673    // create the free list up front
12674    size = stb__size_for_class[c];
12675    tsize = stb__pages_for_class[c] << stb__page_shift;
12676    i = 0;
12677    z = (char *) stb__page_address(p->start);
12678    q = NULL;
12679    while (i + size <= tsize) {
12680       * (void **) z = q; q = z;
12681       z += size;
12682       i += size;
12683    }
12684    p->first_free = q;
12685    p->allocations = 0;
12686    stb__spanlist_add(s,p);
12687    return p;
12688 }
12689 
12690 static int stb__sizeclass(size_t sz)
12691 {
12692    int z = stb_log2_floor(sz); // -1 below to group e.g. 13,14,15,16 correctly
12693    return stb__class_base[z] + ((sz-1) >> stb__class_shift[z]);
12694 }
12695 
12696 static void stb__init_sizeclass(void)
12697 {
12698    int i, size, overhead;
12699    int align_shift = 2;  // allow 4-byte and 12-byte blocks as well, vs. TCMalloc
12700    int next_class = 1;
12701    int last_log = 0;
12702 
12703    for (i = 0; i < align_shift; i++) {
12704       stb__class_base [i] = next_class;
12705       stb__class_shift[i] = align_shift;
12706    }
12707 
12708    for (size = 1 << align_shift; size <= STB__MAX_SMALL_SIZE; size += 1 << align_shift) {
12709       i = stb_log2_floor(size);
12710       if (i > last_log) {
12711          if (size == 16) ++align_shift; // switch from 4-byte to 8-byte alignment
12712          else if (size >= 128 && align_shift < 8) ++align_shift;
12713          stb__class_base[i]  = next_class - ((size-1) >> align_shift);
12714          stb__class_shift[i] = align_shift;
12715          last_log = i;
12716       }
12717       stb__size_for_class[next_class++] = size;
12718    }
12719 
12720    for (i=1; i <= STB__MAX_SMALL_SIZE; ++i)
12721       assert(i <= stb__size_for_class[stb__sizeclass(i)]);
12722 
12723    overhead = 0;
12724    for (i = 1; i < next_class; i++) {
12725       int s = stb__size_for_class[i];
12726       size = stb__page_size;
12727       while (size % s > size >> 3)
12728          size += stb__page_size;
12729       stb__pages_for_class[i] = (unsigned char) (size >> stb__page_shift);
12730       overhead += size;
12731    }
12732    assert(overhead < (4 << 20)); // make sure it's under 4MB of overhead
12733 }
12734 
12735 #ifdef STB_DEBUG
12736 #define stb__smemset(a,b,c)  memset((void *) a, b, c)
12737 #elif defined(STB_FASTMALLOC_INIT)
12738 #define stb__smemset(a,b,c)  memset((void *) a, b, c)
12739 #else
12740 #define stb__smemset(a,b,c)
12741 #endif
12742 void *stb_smalloc(size_t sz)
12743 {
12744    stb__span *s;
12745    if (sz == 0) return NULL;
12746    if (stb__size_for_class[1] == 0) stb__init_sizeclass();
12747    if (sz > STB__MAX_SMALL_SIZE) {
12748       s = stb__alloc_span((sz + stb__page_size - 1) >> stb__page_shift);
12749       if (s == NULL) return NULL;
12750       s->list = 0;
12751       s->next = s->prev = NULL;
12752       s->allocations = -32767;
12753       stb__smemset(stb__page_address(s->start), 0xcd, (sz+3)&~3);
12754       return (void *) stb__page_address(s->start);
12755    } else {
12756       void *p;
12757       int c = stb__sizeclass(sz);
12758       s = stb__spanlist[256+c];
12759       if (!s || !s->first_free)
12760          s = stb__get_nonempty_sizeclass(c);
12761       if (s == NULL) return NULL;
12762       p = s->first_free;
12763       s->first_free = * (void **) p;
12764       ++s->allocations;
12765       stb__smemset(p,0xcd, sz);
12766       return p;
12767    }
12768 }
12769 
12770 int stb_ssize(void *p)
12771 {
12772    stb__span *s;
12773    if (p == NULL) return 0;
12774    s = stb__span_for_page[stb__page_number((stb_uint) p) - stb__firstpage];
12775    if (s->list >= 256) {
12776       return stb__size_for_class[s->list - 256];
12777    } else {
12778       assert(s->list == 0);
12779       return s->len << stb__page_shift;
12780    }
12781 }
12782 
12783 void stb_sfree(void *p)
12784 {
12785    stb__span *s;
12786    if (p == NULL) return;
12787    s = stb__span_for_page[stb__page_number((stb_uint) p) - stb__firstpage];
12788    if (s->list >= 256) {
12789       stb__smemset(p, 0xfe, stb__size_for_class[s->list-256]);
12790       * (void **) p = s->first_free;
12791       s->first_free = p;
12792       if (--s->allocations == 0) {
12793          stb__spanlist_unlink(s);
12794          stb__free_span(s);
12795       }
12796    } else {
12797       assert(s->list == 0);
12798       stb__smemset(p, 0xfe, stb_ssize(p));
12799       stb__free_span(s);
12800    }
12801 }
12802 
12803 void *stb_srealloc(void *p, size_t sz)
12804 {
12805    size_t cur_size;
12806    if (p == NULL) return stb_smalloc(sz);
12807    if (sz == 0) { stb_sfree(p); return NULL; }
12808    cur_size = stb_ssize(p);
12809    if (sz > cur_size || sz <= (cur_size >> 1)) {
12810       void *q;
12811       if (sz > cur_size && sz < (cur_size << 1)) sz = cur_size << 1;
12812       q = stb_smalloc(sz); if (q == NULL) return NULL;
12813       memcpy(q, p, sz < cur_size ? sz : cur_size);
12814       stb_sfree(p);
12815       return q;
12816    }
12817    return p;
12818 }
12819 
12820 void *stb_scalloc(size_t n, size_t sz)
12821 {
12822    void *p;
12823    if (n == 0 || sz == 0) return NULL;
12824    if (stb_log2_ceil(n) + stb_log2_ceil(n) >= 32) return NULL;
12825    p = stb_smalloc(n*sz);
12826    if (p) memset(p, 0, n*sz);
12827    return p;
12828 }
12829 
12830 char *stb_sstrdup(char *s)
12831 {
12832    int n = strlen(s);
12833    char *p = (char *) stb_smalloc(n+1);
12834    if (p) stb_p_strcpy_s(p,n+1,s);
12835    return p;
12836 }
12837 #endif // STB_DEFINE
12838 
12839 
12840 
12842 //
12843 //                         Source code constants
12844 //
12845 // This is a trivial system to let you specify constants in source code,
12846 // then while running you can change the constants.
12847 //
12848 // Note that you can't wrap the #defines, because we need to know their
12849 // names. So we provide a pre-wrapped version without 'STB_' for convenience;
12850 // to request it, #define STB_CONVENIENT_H, yielding:
12851 //       KI -- integer
12852 //       KU -- unsigned integer
12853 //       KF -- float
12854 //       KD -- double
12855 //       KS -- string constant
12856 //
12857 // Defaults to functioning in debug build, not in release builds.
12858 // To force on, define STB_ALWAYS_H
12859 
12860 #ifdef STB_CONVENIENT_H
12861 #define KI(x) STB_I(x)
12862 #define KU(x) STB_UI(x)
12863 #define KF(x) STB_F(x)
12864 #define KD(x) STB_D(x)
12865 #define KS(x) STB_S(x)
12866 #endif
12867 
12868 STB_EXTERN void stb_source_path(char *str);
12869 #ifdef STB_DEFINE
12870 char *stb__source_path;
12871 void stb_source_path(char *path)
12872 {
12873    stb__source_path = path;
12874 }
12875 
12876 char *stb__get_sourcefile_path(char *file)
12877 {
12878    static char filebuf[512];
12879    if (stb__source_path) {
12880       stb_p_sprintf(filebuf stb_p_size(sizeof(filebuf)), "%s/%s", stb__source_path, file);
12881       if (stb_fexists(filebuf)) return filebuf;
12882    }
12883 
12884    if (stb_fexists(file)) return file;
12885 
12886    stb_p_sprintf(filebuf stb_p_size(sizeof(filebuf)), "../%s", file);
12887    if (!stb_fexists(filebuf)) return filebuf;
12888 
12889    return file;
12890 }
12891 #endif
12892 
12893 #define STB_F(x)   ((float) STB_H(x))
12894 #define STB_UI(x)  ((unsigned int) STB_I(x))
12895 
12896 #if !defined(STB_DEBUG) && !defined(STB_ALWAYS_H)
12897 #define STB_D(x)   ((double) (x))
12898 #define STB_I(x)   ((int) (x))
12899 #define STB_S(x)   ((char *) (x))
12900 #else
12901 #define STB_D(x)   stb__double_constant(__FILE__, __LINE__-1, (x))
12902 #define STB_I(x)   stb__int_constant(__FILE__, __LINE__-1, (x))
12903 #define STB_S(x)   stb__string_constant(__FILE__, __LINE__-1, (x))
12904 
12905 STB_EXTERN double stb__double_constant(char *file, int line, double x);
12906 STB_EXTERN int    stb__int_constant(char *file, int line, int x);
12907 STB_EXTERN char * stb__string_constant(char *file, int line, char *str);
12908 
12909 #ifdef STB_DEFINE
12910 
12911 enum
12912 {
12913    STB__CTYPE_int,
12914    STB__CTYPE_uint,
12915    STB__CTYPE_float,
12916    STB__CTYPE_double,
12917    STB__CTYPE_string,
12918 };
12919 
12920 typedef struct
12921 {
12922    int line;
12923    int type;
12924    union {
12925       int ival;
12926       double dval;
12927       char *sval;
12928    };
12929 } stb__Entry;
12930 
12931 typedef struct
12932 {
12933    stb__Entry *entries;
12934    char *filename;
12935    time_t timestamp;
12936    char **file_data;
12937    int file_len;
12938    unsigned short *line_index;
12939 } stb__FileEntry;
12940 
12941 static void stb__constant_parse(stb__FileEntry *f, int i)
12942 {
12943    char *s;
12944    int n;
12945    if (!stb_arr_valid(f->entries, i)) return;
12946    n = f->entries[i].line;
12947    if (n >= f->file_len) return;
12948    s = f->file_data[n];
12949    switch (f->entries[i].type) {
12950       case STB__CTYPE_float:
12951          while (*s) {
12952             if (!strncmp(s, "STB_D(", 6)) { s+=6; goto matched_float; }
12953             if (!strncmp(s, "STB_F(", 6)) { s+=6; goto matched_float; }
12954             if (!strncmp(s, "KD(", 3)) { s+=3; goto matched_float; }
12955             if (!strncmp(s, "KF(", 3)) { s+=3; goto matched_float; }
12956             ++s;
12957          }
12958          break;
12959       matched_float:
12960          f->entries[i].dval = strtod(s, NULL);
12961          break;
12962       case STB__CTYPE_int:
12963          while (*s) {
12964             if (!strncmp(s, "STB_I(", 6)) { s+=6; goto matched_int; }
12965             if (!strncmp(s, "STB_UI(", 7)) { s+=7; goto matched_int; }
12966             if (!strncmp(s, "KI(", 3)) { s+=3; goto matched_int; }
12967             if (!strncmp(s, "KU(", 3)) { s+=3; goto matched_int; }
12968             ++s;
12969          }
12970          break;
12971       matched_int: {
12972          int neg=0;
12973          s = stb_skipwhite(s);
12974          while (*s == '-') { neg = !neg; s = stb_skipwhite(s+1); } // handle '- - 5', pointlessly
12975          if (s[0] == '0' && tolower(s[1]) == 'x')
12976             f->entries[i].ival = strtol(s, NULL, 16);
12977          else if (s[0] == '0')
12978             f->entries[i].ival = strtol(s, NULL, 8);
12979          else
12980             f->entries[i].ival = strtol(s, NULL, 10);
12981          if (neg) f->entries[i].ival = -f->entries[i].ival;
12982          break;
12983       }
12984       case STB__CTYPE_string:
12985          // @TODO
12986          break;
12987    }
12988 }
12989 
12990 static stb_sdict *stb__constant_file_hash;
12991 
12992 stb__Entry *stb__constant_get_entry(char *filename, int line, int type)
12993 {
12994    int i;
12995    stb__FileEntry *f;
12996    if (stb__constant_file_hash == NULL)
12997       stb__constant_file_hash = stb_sdict_new(STB_TRUE);
12998    f = (stb__FileEntry*) stb_sdict_get(stb__constant_file_hash, filename);
12999    if (f == NULL) {
13000       char *s = stb__get_sourcefile_path(filename);
13001       if (s == NULL || !stb_fexists(s)) return 0;
13002       f = (stb__FileEntry *) malloc(sizeof(*f));
13003       f->timestamp = stb_ftimestamp(s);
13004       f->file_data = stb_stringfile(s, &f->file_len);
13005       f->filename = stb_p_strdup(s); // cache the full path
13006       f->entries = NULL;
13007       f->line_index = 0;
13008       stb_arr_setlen(f->line_index, f->file_len);
13009       memset(f->line_index, 0xff, stb_arr_storage(f->line_index));
13010    } else {
13011       time_t t = stb_ftimestamp(f->filename);
13012       if (f->timestamp != t) {
13013          f->timestamp = t;
13014          free(f->file_data);
13015          f->file_data = stb_stringfile(f->filename, &f->file_len);
13016          stb_arr_setlen(f->line_index, f->file_len);
13017          for (i=0; i < stb_arr_len(f->entries); ++i)
13018             stb__constant_parse(f, i);
13019       }
13020    }
13021 
13022    if (line >= f->file_len) return 0;
13023 
13024    if (f->line_index[line] >= stb_arr_len(f->entries)) {
13025       // need a new entry
13026       int n = stb_arr_len(f->entries);
13027       stb__Entry e;
13028       e.line = line;
13029       if (line < f->file_len)
13030          f->line_index[line] = n;
13031       e.type = type;
13032       stb_arr_push(f->entries, e);
13033       stb__constant_parse(f, n);
13034    }
13035    return f->entries + f->line_index[line];
13036 }
13037 
13038 double stb__double_constant(char *file, int line, double x)
13039 {
13040    stb__Entry *e = stb__constant_get_entry(file, line, STB__CTYPE_float);
13041    if (!e) return x;
13042    return e->dval;
13043 }
13044 
13045 int    stb__int_constant(char *file, int line, int x)
13046 {
13047    stb__Entry *e = stb__constant_get_entry(file, line, STB__CTYPE_int);
13048    if (!e) return x;
13049    return e->ival;
13050 }
13051 
13052 char * stb__string_constant(char *file, int line, char *x)
13053 {
13054    stb__Entry *e = stb__constant_get_entry(file, line, STB__CTYPE_string);
13055    if (!e) return x;
13056    return e->sval;
13057 }
13058 
13059 #endif // STB_DEFINE
13060 #endif // !STB_DEBUG && !STB_ALWAYS_H
13061 
13062 
13063 #ifdef STB_STUA
13064 #error "STUA is no longer supported"
13065 
13066 //
13067 //  stua: little scripting language
13068 //
13069 //     define STB_STUA to compile it
13070 //
13071 //     see http://nothings.org/stb/stb_stua.html for documentation
13072 //
13073 //  basic parsing model:
13074 //
13075 //   lexical analysis
13076 //      use stb_lex() to parse tokens; keywords get their own tokens
13077 //
13078 //   parsing:
13079 //      recursive descent parser. too much of a hassle to make an unambiguous
13080 //      LR(1) grammar, and one-pass generation is clumsier (recursive descent
13081 //      makes it easier to e.g. compile nested functions). on the other hand,
13082 //      dictionary syntax required hackery to get extra lookahead.
13083 //
13084 //   codegen:
13085 //      output into an evaluation tree, using array indices as 'pointers'
13086 //
13087 //   run:
13088 //      traverse the tree; support for 'break/continue/return' is tricky
13089 //
13090 //   garbage collection:
13091 //      stu__mark and sweep; explicit stack with non-stu__compile_global_scope roots
13092 
13093 typedef stb_int32 stua_obj;
13094 
13095 typedef stb_idict stua_dict;
13096 
13097 STB_EXTERN void stua_run_script(char *s);
13098 STB_EXTERN void stua_uninit(void);
13099 
13100 extern stua_obj stua_globals;
13101 
13102 STB_EXTERN double   stua_number(stua_obj z);
13103 
13104 STB_EXTERN stua_obj stua_getnil(void);
13105 STB_EXTERN stua_obj stua_getfalse(void);
13106 STB_EXTERN stua_obj stua_gettrue(void);
13107 STB_EXTERN stua_obj stua_string(char *z);
13108 STB_EXTERN stua_obj stua_make_number(double d);
13109 STB_EXTERN stua_obj stua_box(int type, void *data, int size);
13110 
13111 enum
13112 {
13113    STUA_op_negate=129,
13114    STUA_op_shl,   STUA_op_ge,
13115    STUA_op_shr,   STUA_op_le,
13116    STUA_op_shru,
13117    STUA_op_last
13118 };
13119 
13120 #define STUA_NO_VALUE   2     // equivalent to a tagged NULL
13121 STB_EXTERN stua_obj (*stua_overload)(int op, stua_obj a, stua_obj b, stua_obj c);
13122 
13123 STB_EXTERN stua_obj stua_error(char *err, ...);
13124 
13125 STB_EXTERN stua_obj stua_pushroot(stua_obj o);
13126 STB_EXTERN void     stua_poproot (   void   );
13127 
13128 
13129 #ifdef STB_DEFINE
13130 // INTERPRETER
13131 
13132 // 31-bit floating point implementation
13133 //   force the (1 << 30) bit (2nd highest bit) to be zero by re-biasing the exponent;
13134 //   then shift and set the bottom bit
13135 
13136 static stua_obj stu__floatp(float *f)
13137 {
13138    unsigned int n = *(unsigned int *) f;
13139    unsigned int e = n & (0xff << 23);
13140 
13141    assert(sizeof(int) == 4 && sizeof(float) == 4);
13142 
13143    if (!e)                    // zero?
13144       n = n;                  //   no change
13145    else if (e < (64 << 23))   // underflow of the packed encoding?
13146       n = (n & 0x80000000);   //   signed 0
13147    else if (e > (190 << 23))  // overflow of the encoding? (or INF or NAN)
13148       n = (n & 0x80000000) + (127 << 23); // new INF encoding
13149    else
13150       n -= 0x20000000;
13151 
13152    // now we need to shuffle the bits so that the spare bit is at the bottom
13153    assert((n & 0x40000000) == 0);
13154    return (n & 0x80000000) + (n << 1) + 1;
13155 }
13156 
13157 static unsigned char stu__getfloat_addend[256];
13158 static float stu__getfloat(stua_obj v)
13159 {
13160    unsigned int n;
13161    unsigned int e = ((unsigned int) v) >> 24;
13162 
13163    n = (int) v >> 1;  // preserve high bit
13164    n += stu__getfloat_addend[e] << 24;
13165    return *(float *) &n;
13166 }
13167 
13168 stua_obj stua_float(float f)
13169 {
13170    return stu__floatp(&f);
13171 }
13172 
13173 static void stu__float_init(void)
13174 {
13175    int i;
13176    stu__getfloat_addend[0]    = 0;   // do nothing to biased exponent of 0
13177    for (i=1; i < 127; ++i)
13178       stu__getfloat_addend[i] = 32;  // undo the -0x20000000
13179    stu__getfloat_addend[127]  = 64;  // convert packed INF to INF (0x3f -> 0x7f)
13180 
13181    for (i=0; i < 128; ++i) // for signed floats, remove the bit we just shifted down
13182       stu__getfloat_addend[128+i] = stu__getfloat_addend[i] - 64;
13183 }
13184 
13185 // Tagged data type implementation
13186 
13187                                                  // TAGS:
13188 #define stu__int_tag          0  // of 2 bits    //   00   int
13189 #define stu__float_tag        1  // of 1 bit     //   01   float
13190 #define stu__ptr_tag          2  // of 2 bits    //   10   boxed
13191                                                  //   11   float
13192 
13193 #define stu__tag(x)           ((x) & 3)
13194 #define stu__number(x)        (stu__tag(x) != stu__ptr_tag)
13195 #define stu__isint(x)         (stu__tag(x) == stu__int_tag)
13196 
13197 #define stu__int(x)           ((x) >> 2)
13198 #define stu__float(x)         (stu__getfloat(x))
13199 
13200 #define stu__makeint(v)       ((v)*4+stu__int_tag)
13201 
13202 // boxed data, and tag support for boxed data
13203 
13204 enum
13205 {
13206    STU___float    = 1,   STU___int      = 2,
13207    STU___number   = 3,   STU___string   = 4,
13208    STU___function = 5,   STU___dict     = 6,
13209    STU___boolean  = 7,   STU___error    = 8,
13210 };
13211 
13212 // boxed data
13213 #define STU__BOX  short type, stua_gc
13214 typedef struct stu__box { STU__BOX; } stu__box;
13215 
13216 stu__box stu__nil   = { 0, 1 };
13217 stu__box stu__true  = { STU___boolean, 1, };
13218 stu__box stu__false = { STU___boolean, 1, };
13219 
13220 #define stu__makeptr(v)  ((stua_obj)     (v) + stu__ptr_tag)
13221 
13222 #define stua_nil    stu__makeptr(&stu__nil)
13223 #define stua_true   stu__makeptr(&stu__true)
13224 #define stua_false  stu__makeptr(&stu__false)
13225 
13226 stua_obj stua_getnil(void)   { return stua_nil; }
13227 stua_obj stua_getfalse(void) { return stua_false; }
13228 stua_obj stua_gettrue(void)  { return stua_true; }
13229 
13230 #define stu__ptr(x)      ((stu__box *) ((x) - stu__ptr_tag))
13231 
13232 #define stu__checkt(t,x) ((t) == STU___float  ? ((x) & 1) == stu__float_tag : \
13233                           (t) == STU___int    ? stu__isint(x)               : \
13234                           (t) == STU___number ? stu__number(x)              : \
13235                           stu__tag(x) == stu__ptr_tag && stu__ptr(x)->type == (t))
13236 
13237 typedef struct
13238 {
13239    STU__BOX;
13240    void *ptr;
13241 } stu__wrapper;
13242 
13243 // implementation of a 'function' or function + closure
13244 
13245 typedef struct stu__func
13246 {
13247    STU__BOX;
13248    stua_obj closure_source;  // 0 - regular function; 4 - C function
13249                              // if closure, pointer to source function
13250    union {
13251       stua_obj closure_data; // partial-application data
13252       void *store;           // pointer to free that holds 'code'
13253       stua_obj (*func)(stua_dict *context);
13254    } f;
13255    // closure ends here
13256    short *code;
13257    int num_param;
13258    stua_obj *param;  // list of parameter strings
13259 } stu__func;
13260 
13261 // apply this to 'short *code' to get at data
13262 #define stu__const(f)  ((stua_obj *) (f))
13263 
13264 static void stu__free_func(stu__func *f)
13265 {
13266    if (f->closure_source == 0)          free(f->f.store);
13267    if ((stb_uint) f->closure_source <= 4)   free(f->param);
13268    free(f);
13269 }
13270 
13271 #define stu__pd(x)       ((stua_dict *)    stu__ptr(x))
13272 #define stu__pw(x)       ((stu__wrapper *) stu__ptr(x))
13273 #define stu__pf(x)       ((stu__func *)    stu__ptr(x))
13274 
13275 
13276 // garbage-collection
13277 
13278 
13279 static stu__box ** stu__gc_ptrlist;
13280 static stua_obj * stu__gc_root_stack;
13281 
13282 stua_obj stua_pushroot(stua_obj o) { stb_arr_push(stu__gc_root_stack, o); return o; }
13283 void     stua_poproot (   void   ) { stb_arr_pop(stu__gc_root_stack); }
13284 
13285 static stb_sdict *stu__strings;
13286 static void stu__mark(stua_obj z)
13287 {
13288    int i;
13289    stu__box *p = stu__ptr(z);
13290    if (p->stua_gc == 1) return; // already marked
13291    assert(p->stua_gc == 0);
13292    p->stua_gc = 1;
13293    switch(p->type) {
13294       case STU___function: {
13295          stu__func *f = (stu__func *) p;
13296          if ((stb_uint) f->closure_source <= 4) {
13297             if (f->closure_source == 0) {
13298                for (i=1; i <= f->code[0]; ++i)
13299                   if (!stu__number(((stua_obj *) f->code)[-i]))
13300                      stu__mark(((stua_obj *) f->code)[-i]);
13301             }
13302             for (i=0; i < f->num_param; ++i)
13303                stu__mark(f->param[i]);
13304          } else {
13305             stu__mark(f->closure_source);
13306             stu__mark(f->f.closure_data);
13307          }
13308          break;
13309       }
13310       case STU___dict: {
13311          stua_dict *e = (stua_dict *) p;
13312          for (i=0; i < e->limit; ++i)
13313             if (e->table[i].k != STB_IEMPTY && e->table[i].k != STB_IDEL) {
13314                if (!stu__number(e->table[i].k)) stu__mark((int) e->table[i].k);
13315                if (!stu__number(e->table[i].v)) stu__mark((int) e->table[i].v);
13316             }
13317          break;
13318       }
13319    }
13320 }
13321 
13322 static int stu__num_allocs, stu__size_allocs;
13323 static stua_obj stu__flow_val = stua_nil; // used for break & return
13324 
13325 static void stua_gc(int force)
13326 {
13327    int i;
13328    if (!force && stu__num_allocs == 0 && stu__size_allocs == 0) return;
13329    stu__num_allocs = stu__size_allocs = 0;
13330    //printf("[gc]\n");
13331 
13332    // clear marks
13333    for (i=0; i < stb_arr_len(stu__gc_ptrlist); ++i)
13334        stu__gc_ptrlist[i]->stua_gc = 0;
13335 
13336    // stu__mark everything reachable
13337    stu__nil.stua_gc = stu__true.stua_gc = stu__false.stua_gc = 1;
13338    stu__mark(stua_globals);
13339    if (!stu__number(stu__flow_val))
13340       stu__mark(stu__flow_val);
13341    for (i=0; i < stb_arr_len(stu__gc_root_stack); ++i)
13342       if (!stu__number(stu__gc_root_stack[i]))
13343          stu__mark(stu__gc_root_stack[i]);
13344 
13345    // sweep unreachables
13346    for (i=0; i < stb_arr_len(stu__gc_ptrlist);) {
13347       stu__box *z = stu__gc_ptrlist[i];
13348       if (!z->stua_gc) {
13349          switch (z->type) {
13350             case STU___dict:        stb_idict_destroy((stua_dict *) z); break;
13351             case STU___error:       free(((stu__wrapper *) z)->ptr); break;
13352             case STU___string:      stb_sdict_remove(stu__strings, (char*) ((stu__wrapper *) z)->ptr, NULL); free(z); break;
13353             case STU___function:    stu__free_func((stu__func *) z); break;
13354          }
13355          // swap in the last item over this, and repeat
13356          z = stb_arr_pop(stu__gc_ptrlist);
13357          stu__gc_ptrlist[i] = z;
13358       } else
13359          ++i;
13360    }
13361 }
13362 
13363 static void stu__consider_gc(stua_obj x)
13364 {
13365    if (stu__size_allocs < 100000) return;
13366    if (stu__num_allocs < 10 && stu__size_allocs < 1000000) return;
13367    stb_arr_push(stu__gc_root_stack, x);
13368    stua_gc(0);
13369    stb_arr_pop(stu__gc_root_stack);
13370 }
13371 
13372 static stua_obj stu__makeobj(int type, void *data, int size, int safe_to_gc)
13373 {
13374    stua_obj x = stu__makeptr(data);
13375    ((stu__box *) data)->type = type;
13376    stb_arr_push(stu__gc_ptrlist, (stu__box *) data);
13377    stu__num_allocs  += 1;
13378    stu__size_allocs += size;
13379    if (safe_to_gc) stu__consider_gc(x);
13380    return x;
13381 }
13382 
13383 stua_obj stua_box(int type, void *data, int size)
13384 {
13385    stu__wrapper *p = (stu__wrapper *) malloc(sizeof(*p));
13386    p->ptr = data;
13387    return stu__makeobj(type, p, size, 0);
13388 }
13389 
13390 // a stu string can be directly compared for equality, because
13391 // they go into a hash table
13392 stua_obj stua_string(char *z)
13393 {
13394    stu__wrapper *b = (stu__wrapper *) stb_sdict_get(stu__strings, z);
13395    if (b == NULL) {
13396       int o = stua_box(STU___string, NULL, strlen(z) + sizeof(*b));
13397       b = stu__pw(o);
13398       stb_sdict_add(stu__strings, z, b);
13399       stb_sdict_getkey(stu__strings, z, (char **) &b->ptr);
13400    }
13401    return stu__makeptr(b);
13402 }
13403 
13404 // stb_obj dictionary is just an stb_idict
13405 static void     stu__set(stua_dict *d, stua_obj k, stua_obj v)
13406 { if (stb_idict_set(d, k, v)) stu__size_allocs += 8; }
13407 
13408 static stua_obj stu__get(stua_dict *d, stua_obj k, stua_obj res)
13409 {
13410    stb_idict_get_flag(d, k, &res);
13411    return res;
13412 }
13413 
13414 static stua_obj make_string(char *z, int len)
13415 {
13416    stua_obj s;
13417    char temp[256], *q = (char *) stb_temp(temp, len+1), *p = q;
13418    while (len > 0) {
13419       if (*z == '\\') {
13420               if (z[1] == 'n') *p = '\n';
13421          else if (z[1] == 'r') *p = '\r';
13422          else if (z[1] == 't') *p = '\t';
13423          else                  *p = z[1];
13424          p += 1; z += 2; len -= 2;
13425       } else {
13426          *p++ = *z++; len -= 1;
13427       }
13428    }
13429    *p = 0;
13430    s = stua_string(q);
13431    stb_tempfree(temp, q);
13432    return s;
13433 }
13434 
13435 enum token_names
13436 {
13437    T__none=128,
13438    ST_shl = STUA_op_shl,    ST_ge  = STUA_op_ge,
13439    ST_shr = STUA_op_shr,    ST_le = STUA_op_le,
13440    ST_shru = STUA_op_shru,  STU__negate = STUA_op_negate,
13441    ST__reset_numbering = STUA_op_last,
13442    ST_white,
13443    ST_id, ST_float, ST_decimal, ST_hex, ST_char,ST_string, ST_number,
13444    // make sure the keywords come _AFTER_ ST_id, so stb_lex prefer them
13445    ST_if,      ST_while,    ST_for,     ST_eq,  ST_nil,
13446    ST_then,    ST_do,       ST_in,      ST_ne,  ST_true,
13447    ST_else,    ST_break,    ST_let,     ST_and, ST_false,
13448    ST_elseif,  ST_continue, ST_into,    ST_or,  ST_repeat,
13449    ST_end,     ST_as,       ST_return,  ST_var, ST_func,
13450    ST_catch,   ST__frame,
13451    ST__max_terminals,
13452 
13453    STU__defaultparm, STU__seq,
13454 };
13455 
13456 static stua_dict  * stu__globaldict;
13457        stua_obj     stua_globals;
13458 
13459 static enum
13460 {
13461    FLOW_normal,  FLOW_continue,   FLOW_break,  FLOW_return,  FLOW_error,
13462 } stu__flow;
13463 
13464 stua_obj stua_error(char *z, ...)
13465 {
13466    stua_obj a;
13467    char temp[4096], *x;
13468    va_list v; va_start(v,z); vsprintf(temp, z, v); va_end(v);
13469    x = stb_p_strdup(temp);
13470    a = stua_box(STU___error, x, strlen(x));
13471    stu__flow = FLOW_error;
13472    stu__flow_val = a;
13473    return stua_nil;
13474 }
13475 
13476 double stua_number(stua_obj z)
13477 {
13478    return stu__tag(z) == stu__int_tag ? stu__int(z) : stu__float(z);
13479 }
13480 
13481 stua_obj stua_make_number(double d)
13482 {
13483    double e = floor(d);
13484    if (e == d && e < (1 << 29) && e >= -(1 << 29))
13485       return stu__makeint((int) e);
13486    else
13487       return stua_float((float) d);
13488 }
13489 
13490 stua_obj (*stua_overload)(int op, stua_obj a, stua_obj b, stua_obj c) = NULL;
13491 
13492 static stua_obj stu__op(int op, stua_obj a, stua_obj b, stua_obj c)
13493 {
13494    stua_obj r = STUA_NO_VALUE;
13495    if (op == '+') {
13496       if (stu__checkt(STU___string, a) && stu__checkt(STU___string, b)) {
13497          ;// @TODO: string concatenation
13498       } else if (stu__checkt(STU___function, a) && stu__checkt(STU___dict, b)) {
13499          stu__func *f = (stu__func *) malloc(12);
13500          assert(offsetof(stu__func, code)==12);
13501          f->closure_source = a;
13502          f->f.closure_data = b;
13503          return stu__makeobj(STU___function, f, 16, 1);
13504       }
13505    }
13506    if (stua_overload) r = stua_overload(op,a,b,c);
13507    if (stu__flow != FLOW_error && r == STUA_NO_VALUE)
13508       stua_error("Typecheck for operator %d", op), r=stua_nil;
13509    return r;
13510 }
13511 
13512 #define STU__EVAL2(a,b)             \
13513           a = stu__eval(stu__f[n+1]);  if (stu__flow) break; stua_pushroot(a); \
13514           b = stu__eval(stu__f[n+2]);  stua_poproot(); if (stu__flow) break;
13515 
13516 #define STU__FB(op)              \
13517           STU__EVAL2(a,b)           \
13518           if (stu__tag(a) == stu__int_tag && stu__tag(b) == stu__int_tag) \
13519              return ((a) op (b));                 \
13520           if (stu__number(a) && stu__number(b)) \
13521              return stua_make_number(stua_number(a) op stua_number(b)); \
13522           return stu__op(stu__f[n], a,b, stua_nil)
13523 
13524 #define STU__F(op)              \
13525           STU__EVAL2(a,b)           \
13526           if (stu__number(a) && stu__number(b)) \
13527              return stua_make_number(stua_number(a) op stua_number(b)); \
13528           return stu__op(stu__f[n], a,b, stua_nil)
13529 
13530 #define STU__I(op)               \
13531           STU__EVAL2(a,b)           \
13532           if (stu__tag(a) == stu__int_tag && stu__tag(b) == stu__int_tag) \
13533              return stu__makeint(stu__int(a) op stu__int(b));                 \
13534           return stu__op(stu__f[n], a,b, stua_nil)
13535 
13536 #define STU__C(op)               \
13537           STU__EVAL2(a,b)           \
13538           if (stu__number(a) && stu__number(b)) \
13539              return (stua_number(a) op stua_number(b)) ? stua_true : stua_false; \
13540           return stu__op(stu__f[n], a,b, stua_nil)
13541 
13542 #define STU__CE(op)              \
13543           STU__EVAL2(a,b)           \
13544           return (a op b) ? stua_true : stua_false
13545 
13546 static short *stu__f;
13547 static stua_obj  stu__f_obj;
13548 static stua_dict       *stu__c;
13549 static stua_obj stu__funceval(stua_obj fo, stua_obj co);
13550 
13551 static int stu__cond(stua_obj x)
13552 {
13553    if (stu__flow) return 0;
13554    if (!stu__checkt(STU___boolean, x))
13555       x = stu__op('!', x, stua_nil, stua_nil);
13556    if (x == stua_true ) return 1;
13557    if (x == stua_false) return 0;
13558    stu__flow = FLOW_error;
13559    return 0;
13560 }
13561 
13562 // had to manually eliminate tailcall recursion for debugging complex stuff
13563 #define TAILCALL(x)   n = (x); goto top;
13564 static stua_obj stu__eval(int n)
13565 {
13566 top:
13567    if (stu__flow >= FLOW_return) return stua_nil; // is this needed?
13568    if (n < 0) return stu__const(stu__f)[n];
13569    assert(n != 0 && n != 1);
13570    switch (stu__f[n]) {
13571       stua_obj a,b,c;
13572       case ST_catch:   a = stu__eval(stu__f[n+1]);
13573                        if (stu__flow == FLOW_error) { a=stu__flow_val; stu__flow = FLOW_normal; }
13574                        return a;
13575       case ST_var:     b = stu__eval(stu__f[n+2]); if (stu__flow) break;
13576                        stu__set(stu__c, stu__const(stu__f)[stu__f[n+1]], b);
13577                        return b;
13578       case STU__seq:   stu__eval(stu__f[n+1]); if (stu__flow) break;
13579                        TAILCALL(stu__f[n+2]);
13580       case ST_if:      if (!stu__cond(stu__eval(stu__f[n+1]))) return stua_nil;
13581                        TAILCALL(stu__f[n+2]);
13582       case ST_else:    a = stu__cond(stu__eval(stu__f[n+1]));
13583                        TAILCALL(stu__f[n + 2 + !a]);
13584                        #define STU__HANDLE_BREAK            \
13585                           if (stu__flow >= FLOW_break) {    \
13586                              if (stu__flow == FLOW_break) { \
13587                                 a = stu__flow_val;          \
13588                                 stu__flow = FLOW_normal;    \
13589                                 stu__flow_val = stua_nil;   \
13590                                 return a;                   \
13591                              }                              \
13592                              return stua_nil;               \
13593                           }
13594       case ST_as:      stu__eval(stu__f[n+3]);
13595                        STU__HANDLE_BREAK
13596                        // fallthrough!
13597       case ST_while:   a = stua_nil; stua_pushroot(a);
13598                        while (stu__cond(stu__eval(stu__f[n+1]))) {
13599                           stua_poproot();
13600                           a = stu__eval(stu__f[n+2]);
13601                           STU__HANDLE_BREAK
13602                           stu__flow = FLOW_normal;  // clear 'continue' flag
13603                           stua_pushroot(a);
13604                           if (stu__f[n+3]) stu__eval(stu__f[n+3]);
13605                           STU__HANDLE_BREAK
13606                           stu__flow = FLOW_normal;  // clear 'continue' flag
13607                        }
13608                        stua_poproot();
13609                        return a;
13610       case ST_break:   stu__flow = FLOW_break;  stu__flow_val = stu__eval(stu__f[n+1]); break;
13611       case ST_continue:stu__flow = FLOW_continue; break;
13612       case ST_return:  stu__flow = FLOW_return; stu__flow_val = stu__eval(stu__f[n+1]); break;
13613       case ST__frame:  return stu__f_obj;
13614       case '[':        STU__EVAL2(a,b);
13615                        if (stu__checkt(STU___dict, a))
13616                           return stu__get(stu__pd(a), b, stua_nil);
13617                        return stu__op(stu__f[n], a, b, stua_nil);
13618       case '=':        a = stu__eval(stu__f[n+2]); if (stu__flow) break;
13619                        n = stu__f[n+1];
13620                        if (stu__f[n] == ST_id) {
13621                           if (!stb_idict_update(stu__c, stu__const(stu__f)[stu__f[n+1]], a))
13622                              if (!stb_idict_update(stu__globaldict, stu__const(stu__f)[stu__f[n+1]], a))
13623                                 return stua_error("Assignment to undefined variable");
13624                        } else if (stu__f[n] == '[') {
13625                           stua_pushroot(a);
13626                           b = stu__eval(stu__f[n+1]); if (stu__flow) { stua_poproot(); break; }
13627                           stua_pushroot(b);
13628                           c = stu__eval(stu__f[n+2]); stua_poproot(); stua_poproot();
13629                           if (stu__flow) break;
13630                           if (!stu__checkt(STU___dict, b)) return stua_nil;
13631                           stu__set(stu__pd(b), c, a);
13632                        } else {
13633                           return stu__op(stu__f[n], stu__eval(n), a, stua_nil);
13634                        }
13635                        return a;
13636       case STU__defaultparm:
13637                        a = stu__eval(stu__f[n+2]);
13638                        stu__flow = FLOW_normal;
13639                        if (stb_idict_add(stu__c, stu__const(stu__f)[stu__f[n+1]], a))
13640                           stu__size_allocs += 8;
13641                        return stua_nil;
13642       case ST_id:      a = stu__get(stu__c, stu__const(stu__f)[stu__f[n+1]], STUA_NO_VALUE); // try local variable
13643                        return a != STUA_NO_VALUE       // else try stu__compile_global_scope variable
13644                             ? a : stu__get(stu__globaldict, stu__const(stu__f)[stu__f[n+1]], stua_nil);
13645       case STU__negate:a = stu__eval(stu__f[n+1]); if (stu__flow) break;
13646                        return stu__isint(a) ? -a : stu__op(stu__f[n], a, stua_nil, stua_nil);
13647       case '~':        a = stu__eval(stu__f[n+1]); if (stu__flow) break;
13648                        return stu__isint(a) ? (~a)&~3 : stu__op(stu__f[n], a, stua_nil, stua_nil);
13649       case '!':        a = stu__eval(stu__f[n+1]); if (stu__flow) break;
13650                        a = stu__cond(a); if (stu__flow) break;
13651                        return a ? stua_true : stua_false;
13652       case ST_eq: STU__CE(==); case ST_le: STU__C(<=); case '<': STU__C(<);
13653       case ST_ne: STU__CE(!=); case ST_ge: STU__C(>=); case '>': STU__C(>);
13654       case '+' : STU__FB(+);  case '*': STU__F(*);  case '&': STU__I(&); case ST_shl: STU__I(<<);
13655       case '-' : STU__FB(-);  case '/': STU__F(/);  case '|': STU__I(|); case ST_shr: STU__I(>>);
13656                              case '%': STU__I(%);  case '^': STU__I(^);
13657       case ST_shru:    STU__EVAL2(a,b);
13658                        if (stu__tag(a) == stu__int_tag && stu__tag(b) == stu__int_tag)
13659                           return stu__makeint((unsigned) stu__int(a) >> stu__int(b));
13660                        return stu__op(stu__f[n], a,b, stua_nil);
13661       case ST_and:      a = stu__eval(stu__f[n+1]); b = stu__cond(a); if (stu__flow) break;
13662                        return a ? stu__eval(stu__f[n+2]) : a;
13663       case ST_or :      a = stu__eval(stu__f[n+1]); b = stu__cond(a); if (stu__flow) break;
13664                        return a ? b : stu__eval(stu__f[n+2]);
13665       case'(':case':': STU__EVAL2(a,b);
13666                        if (!stu__checkt(STU___function, a))
13667                            return stu__op(stu__f[n], a,b, stua_nil);
13668                        if (!stu__checkt(STU___dict, b))
13669                            return stua_nil;
13670                        if (stu__f[n] == ':')
13671                           b = stu__makeobj(STU___dict, stb_idict_copy(stu__pd(b)), stb_idict_memory_usage(stu__pd(b)), 0);
13672                        a = stu__funceval(a,b);
13673                        return a;
13674       case '{' :    {
13675                        stua_dict *d;
13676                        d = stb_idict_new_size(stu__f[n+1] > 40 ? 64 : 16);
13677                        if (d == NULL)
13678                           return stua_nil; // breakpoint fodder
13679                        c = stu__makeobj(STU___dict, d, 32, 1);
13680                        stua_pushroot(c);
13681                        a = stu__f[n+1];
13682                        for (b=0; b < a; ++b) {
13683                           stua_obj x = stua_pushroot(stu__eval(stu__f[n+2 + b*2 + 0]));
13684                           stua_obj y = stu__eval(stu__f[n+2 + b*2 + 1]);
13685                           stua_poproot();
13686                           if (stu__flow) { stua_poproot(); return stua_nil; }
13687                           stu__set(d, x, y);
13688                        }
13689                        stua_poproot();
13690                        return c;
13691                     }
13692       default:         if (stu__f[n] < 0) return stu__const(stu__f)[stu__f[n]];
13693                        assert(0); /* NOTREACHED */ // internal error!
13694    }
13695    return stua_nil;
13696 }
13697 
13698 int stb__stua_nesting;
13699 static stua_obj stu__funceval(stua_obj fo, stua_obj co)
13700 {
13701    stu__func *f = stu__pf(fo);
13702    stua_dict *context = stu__pd(co);
13703    int i,j;
13704    stua_obj p;
13705    short *tf = stu__f;     // save previous function
13706    stua_dict *tc = stu__c;
13707 
13708    if (stu__flow == FLOW_error) return stua_nil;
13709    assert(stu__flow == FLOW_normal);
13710 
13711    stua_pushroot(fo);
13712    stua_pushroot(co);
13713    stu__consider_gc(stua_nil);
13714 
13715    while ((stb_uint) f->closure_source > 4) {
13716       // add data from closure to context
13717       stua_dict *e = (stua_dict *) stu__pd(f->f.closure_data);
13718       for (i=0; i < e->limit; ++i)
13719          if (e->table[i].k != STB_IEMPTY && e->table[i].k != STB_IDEL)
13720             if (stb_idict_add(context, e->table[i].k, e->table[i].v))
13721                stu__size_allocs += 8;
13722             // use add so if it's already defined, we don't override it; that way
13723             // explicit parameters win over applied ones, and most recent applications
13724             // win over previous ones
13725       f = stu__pf(f->closure_source);
13726    }
13727 
13728    for (j=0, i=0; i < f->num_param; ++i)
13729       // if it doesn't already exist, add it from the numbered parameters
13730       if (stb_idict_add(context, f->param[i], stu__get(context, stu__int(j), stua_nil)))
13731          ++j;
13732 
13733    // @TODO: if (stu__get(context, stu__int(f->num_param+1)) != STUA_NO_VALUE) // error: too many parameters
13734    // @TODO: ditto too few parameters
13735 
13736    if (f->closure_source == 4)
13737       p = f->f.func(context);
13738    else {
13739       stu__f = f->code, stu__c = context;
13740       stu__f_obj = co;
13741       ++stb__stua_nesting;
13742       if (stu__f[1])
13743          p = stu__eval(stu__f[1]);
13744       else
13745          p = stua_nil;
13746       --stb__stua_nesting;
13747       stu__f = tf, stu__c = tc;  // restore previous function
13748       if (stu__flow == FLOW_return) {
13749          stu__flow = FLOW_normal;
13750          p = stu__flow_val;
13751          stu__flow_val = stua_nil;
13752       }
13753    }
13754 
13755    stua_poproot();
13756    stua_poproot();
13757 
13758    return p;
13759 }
13760 
13761 // Parser
13762 
13763 static int stu__tok;
13764 static stua_obj stu__tokval;
13765 
13766 static char *stu__curbuf, *stu__bufstart;
13767 
13768 static stb_matcher *stu__lex_matcher;
13769 
13770 static unsigned char stu__prec[ST__max_terminals], stu__end[ST__max_terminals];
13771 
13772 static void stu__nexttoken(void)
13773 {
13774    int len;
13775 
13776 retry:
13777    stu__tok = stb_lex(stu__lex_matcher, stu__curbuf, &len);
13778    if (stu__tok == 0)
13779       return;
13780    switch(stu__tok) {
13781       case ST_white  : stu__curbuf += len; goto retry;
13782       case T__none  : stu__tok = *stu__curbuf; break;
13783       case ST_string:  stu__tokval = make_string(stu__curbuf+1, len-2); break;
13784       case ST_id    :  stu__tokval = make_string(stu__curbuf, len); break;
13785       case ST_hex    : stu__tokval = stu__makeint(strtol(stu__curbuf+2,NULL,16)); stu__tok = ST_number; break;
13786       case ST_decimal: stu__tokval = stu__makeint(strtol(stu__curbuf  ,NULL,10)); stu__tok = ST_number; break;
13787       case ST_float  : stu__tokval = stua_float((float) atof(stu__curbuf))       ; stu__tok = ST_number; break;
13788       case ST_char   : stu__tokval = stu__curbuf[2] == '\\' ? stu__curbuf[3] : stu__curbuf[2];
13789                       if (stu__curbuf[3] == 't') stu__tokval = '\t';
13790                       if (stu__curbuf[3] == 'n') stu__tokval = '\n';
13791                       if (stu__curbuf[3] == 'r') stu__tokval = '\r';
13792                       stu__tokval = stu__makeint(stu__tokval);
13793                       stu__tok  = ST_number;
13794                       break;
13795    }
13796    stu__curbuf += len;
13797 }
13798 
13799 static struct { int stu__tok; char *regex; } stu__lexemes[] =
13800 {
13801    ST_white  , "([ \t\n\r]|/\\*(.|\n)*\\*/|//[^\r\n]*([\r\n]|$))+",
13802    ST_id     , "[_a-zA-Z][_a-zA-Z0-9]*",
13803    ST_hex    , "0x[0-9a-fA-F]+",
13804    ST_decimal, "[0-9]+[0-9]*",
13805    ST_float  , "[0-9]+\\.?[0-9]*([eE][-+]?[0-9]+)?",
13806    ST_float  , "\\.[0-9]+([eE][-+]?[0-9]+)?",
13807    ST_char   , "c'(\\\\.|[^\\'])'",
13808    ST_string , "\"(\\\\.|[^\\\"\n\r])*\"",
13809    ST_string , "\'(\\\\.|[^\\\'\n\r])*\'",
13810 
13811    #define stua_key4(a,b,c,d)  ST_##a, #a, ST_##b, #b, ST_##c, #c, ST_##d, #d,
13812    stua_key4(if,then,else,elseif)    stua_key4(while,do,for,in)
13813    stua_key4(func,var,let,break)     stua_key4(nil,true,false,end)
13814    stua_key4(return,continue,as,repeat) stua_key4(_frame,catch,catch,catch)
13815 
13816    ST_shl, "<<",   ST_and, "&&",  ST_eq,  "==",  ST_ge, ">=",
13817    ST_shr, ">>",   ST_or , "||",  ST_ne,  "!=",  ST_le, "<=",
13818    ST_shru,">>>",  ST_into, "=>",
13819    T__none, ".",
13820 };
13821 
13822 typedef struct
13823 {
13824    stua_obj  *data;    // constants being compiled
13825    short     *code;    // code being compiled
13826    stua_dict *locals;
13827    short     *non_local_refs;
13828 } stu__comp_func;
13829 
13830 static stu__comp_func stu__pfunc;
13831 static stu__comp_func *func_stack = NULL;
13832 static void stu__push_func_comp(void)
13833 {
13834    stb_arr_push(func_stack, stu__pfunc);
13835    stu__pfunc.data = NULL;
13836    stu__pfunc.code = NULL;
13837    stu__pfunc.locals = stb_idict_new_size(16);
13838    stu__pfunc.non_local_refs = NULL;
13839    stb_arr_push(stu__pfunc.code, 0); // number of data items
13840    stb_arr_push(stu__pfunc.code, 1); // starting execution address
13841 }
13842 
13843 static void stu__pop_func_comp(void)
13844 {
13845    stb_arr_free(stu__pfunc.code);
13846    stb_arr_free(stu__pfunc.data);
13847    stb_idict_destroy(stu__pfunc.locals);
13848    stb_arr_free(stu__pfunc.non_local_refs);
13849    stu__pfunc = stb_arr_pop(func_stack);
13850 }
13851 
13852 // if an id is a reference to an outer lexical scope, this
13853 // function returns the "name" of it, and updates the stack
13854 // structures to make sure the names are propagated in.
13855 static int stu__nonlocal_id(stua_obj var_obj)
13856 {
13857    stua_obj dummy, var = var_obj;
13858    int i, n = stb_arr_len(func_stack), j,k;
13859    if (stb_idict_get_flag(stu__pfunc.locals, var, &dummy)) return 0;
13860    for (i=n-1; i > 1; --i) {
13861       if (stb_idict_get_flag(func_stack[i].locals, var, &dummy))
13862          break;
13863    }
13864    if (i <= 1) return 0; // stu__compile_global_scope
13865    j = i; // need to access variable from j'th frame
13866    for (i=0; i < stb_arr_len(stu__pfunc.non_local_refs); ++i)
13867       if (stu__pfunc.non_local_refs[i] == j) return j-n;
13868    stb_arr_push(stu__pfunc.non_local_refs, j-n);
13869    // now make sure all the parents propagate it down
13870    for (k=n-1; k > 1; --k) {
13871       if (j-k >= 0) return j-n; // comes direct from this parent
13872       for(i=0; i < stb_arr_len(func_stack[k].non_local_refs); ++i)
13873          if (func_stack[k].non_local_refs[i] == j-k)
13874             return j-n;
13875       stb_arr_push(func_stack[k].non_local_refs, j-k);
13876    }
13877    assert (k != 1);
13878 
13879    return j-n;
13880 }
13881 
13882 static int stu__off(void)                { return stb_arr_len(stu__pfunc.code); }
13883 static void stu__cc(int a)
13884 {
13885    assert(a >= -2000 && a < 5000);
13886    stb_arr_push(stu__pfunc.code, a);
13887 }
13888 static int stu__cc1(int a)                      { stu__cc(a); return stu__off()-1; }
13889 static int stu__cc2(int a, int b)               { stu__cc(a); stu__cc(b); return stu__off()-2; }
13890 static int stu__cc3(int a, int b, int c)        {
13891  if (a == '=') assert(c != 0);
13892  stu__cc(a); stu__cc(b); stu__cc(c); return stu__off()-3; }
13893 static int stu__cc4(int a, int b, int c, int d) { stu__cc(a); stu__cc(b); stu__cc(c); stu__cc(d); return stu__off()-4; }
13894 
13895 static int stu__cdv(stua_obj p)
13896 {
13897    int i;
13898    assert(p != STUA_NO_VALUE);
13899    for (i=0; i < stb_arr_len(stu__pfunc.data); ++i)
13900       if (stu__pfunc.data[i] == p)
13901          break;
13902    if (i == stb_arr_len(stu__pfunc.data))
13903       stb_arr_push(stu__pfunc.data, p);
13904    return ~i;
13905 }
13906 
13907 static int stu__cdt(void)
13908 {
13909    int z = stu__cdv(stu__tokval);
13910    stu__nexttoken();
13911    return z;
13912 }
13913 
13914 static int stu__seq(int a, int b)
13915 {
13916    return !a ? b : !b ? a : stu__cc3(STU__seq, a,b);
13917 }
13918 
13919 static char stu__comp_err_str[1024];
13920 static int stu__comp_err_line;
13921 static int stu__err(char *str, ...)
13922 {
13923    va_list v;
13924    char *s = stu__bufstart;
13925    stu__comp_err_line = 1;
13926    while (s < stu__curbuf) {
13927       if (s[0] == '\n' || s[0] == '\r') {
13928          if (s[0]+s[1] == '\n' + '\r') ++s;
13929          ++stu__comp_err_line;
13930       }
13931       ++s;
13932    }
13933    va_start(v, str);
13934    vsprintf(stu__comp_err_str, str, v);
13935    va_end(v);
13936    return 0;
13937 }
13938 
13939 static int stu__accept(int p)
13940 {
13941    if (stu__tok != p) return 0;
13942    stu__nexttoken();
13943    return 1;
13944 }
13945 
13946 static int stu__demand(int p)
13947 {
13948    if (stu__accept(p)) return 1;
13949    return stu__err("Didn't find expected stu__tok");
13950 }
13951 
13952 static int stu__demandv(int p, stua_obj *val)
13953 {
13954    if (stu__tok == p || p==0) {
13955       *val = stu__tokval;
13956       stu__nexttoken();
13957       return 1;
13958    } else
13959       return 0;
13960 }
13961 
13962 static int stu__expr(int p);
13963 int stu__nexpr(int p) { stu__nexttoken(); return stu__expr(p); }
13964 static int stu__statements(int once, int as);
13965 
13966 static int stu__parse_if(void)      // parse both ST_if and ST_elseif
13967 {
13968    int b,c,a;
13969    a = stu__nexpr(1);               if (!a) return 0;
13970    if (!stu__demand(ST_then))       return stu__err("expecting THEN");
13971    b = stu__statements(0,0);        if (!b) return 0;
13972    if (b == 1) b = -1;
13973 
13974    if (stu__tok == ST_elseif) {
13975       return stu__parse_if();
13976    } else if (stu__accept(ST_else)) {
13977       c = stu__statements(0,0); if (!c) return 0;
13978       if (!stu__demand(ST_end)) return stu__err("expecting END after else clause");
13979       return stu__cc4(ST_else, a, b, c);
13980    } else {
13981       if (!stu__demand(ST_end)) return stu__err("expecting END in if statement");
13982       return stu__cc3(ST_if, a, b);
13983    }
13984 }
13985 
13986 int stu__varinit(int z, int in_globals)
13987 {
13988    int a,b;
13989    stu__nexttoken();
13990    while (stu__demandv(ST_id, &b)) {
13991       if (!stb_idict_add(stu__pfunc.locals, b, 1))
13992          if (!in_globals) return stu__err("Redefined variable %s.", stu__pw(b)->ptr);
13993       if (stu__accept('=')) {
13994          a = stu__expr(1);       if (!a) return 0;
13995       } else
13996          a = stu__cdv(stua_nil);
13997       z = stu__seq(z, stu__cc3(ST_var, stu__cdv(b), a));
13998       if (!stu__accept(',')) break;
13999    }
14000    return z;
14001 }
14002 
14003 static int stu__compile_unary(int z, int outparm, int require_inparm)
14004 {
14005    int op = stu__tok, a, b;
14006    stu__nexttoken();
14007    if (outparm) {
14008       if (require_inparm || (stu__tok && stu__tok != ST_end && stu__tok != ST_else && stu__tok != ST_elseif && stu__tok !=';')) {
14009          a = stu__expr(1); if (!a) return 0;
14010       } else
14011          a = stu__cdv(stua_nil);
14012       b = stu__cc2(op, a);
14013    } else
14014       b = stu__cc1(op);
14015    return stu__seq(z,b);
14016 }
14017 
14018 static int stu__assign(void)
14019 {
14020    int z;
14021    stu__accept(ST_let);
14022    z = stu__expr(1); if (!z) return 0;
14023    if (stu__accept('=')) {
14024       int y,p = (z >= 0 ? stu__pfunc.code[z] : 0);
14025       if (z < 0 || (p != ST_id && p != '[')) return stu__err("Invalid lvalue in assignment");
14026       y = stu__assign();         if (!y) return 0;
14027       z = stu__cc3('=', z, y);
14028    }
14029    return z;
14030 }
14031 
14032 static int stu__statements(int once, int stop_while)
14033 {
14034    int a,b, c, z=0;
14035    for(;;) {
14036       switch (stu__tok) {
14037          case ST_if     : a = stu__parse_if(); if (!a) return 0;
14038                           z = stu__seq(z, a);
14039                           break;
14040          case ST_while  : if (stop_while) return (z ? z:1);
14041                           a = stu__nexpr(1); if (!a) return 0;
14042                           if (stu__accept(ST_as)) c = stu__statements(0,0); else c = 0;
14043                           if (!stu__demand(ST_do)) return stu__err("expecting DO");
14044                           b = stu__statements(0,0); if (!b) return 0;
14045                           if (!stu__demand(ST_end)) return stu__err("expecting END");
14046                           if (b == 1) b = -1;
14047                           z = stu__seq(z, stu__cc4(ST_while, a, b, c));
14048                           break;
14049          case ST_repeat : stu__nexttoken();
14050                           c = stu__statements(0,1); if (!c) return 0;
14051                           if (!stu__demand(ST_while)) return stu__err("expecting WHILE");
14052                           a = stu__expr(1); if (!a) return 0;
14053                           if (!stu__demand(ST_do)) return stu__err("expecting DO");
14054                           b = stu__statements(0,0); if (!b) return 0;
14055                           if (!stu__demand(ST_end)) return stu__err("expecting END");
14056                           if (b == 1) b = -1;
14057                           z = stu__seq(z, stu__cc4(ST_as, a, b, c));
14058                           break;
14059          case ST_catch  : a = stu__nexpr(1); if (!a) return 0;
14060                           z = stu__seq(z, stu__cc2(ST_catch, a));
14061                           break;
14062          case ST_var    : z = stu__varinit(z,0); break;
14063          case ST_return : z = stu__compile_unary(z,1,1); break;
14064          case ST_continue:z = stu__compile_unary(z,0,0); break;
14065          case ST_break  : z = stu__compile_unary(z,1,0); break;
14066          case ST_into   : if (z == 0 && !once) return stu__err("=> cannot be first statement in block");
14067                           a = stu__nexpr(99);
14068                           b = (a >= 0? stu__pfunc.code[a] : 0);
14069                           if (a < 0 || (b != ST_id && b != '[')) return stu__err("Invalid lvalue on right side of =>");
14070                           z = stu__cc3('=', a, z);
14071                           break;
14072          default        : if (stu__end[stu__tok]) return once ? 0 : (z ? z:1);
14073                           a = stu__assign(); if (!a) return 0;
14074                           stu__accept(';');
14075                           if (stu__tok && !stu__end[stu__tok]) {
14076                              if (a < 0)
14077                                 return stu__err("Constant has no effect");
14078                              if (stu__pfunc.code[a] != '(' && stu__pfunc.code[a] != '=')
14079                                 return stu__err("Expression has no effect");
14080                           }
14081                           z = stu__seq(z, a);
14082                           break;
14083       }
14084       if (!z) return 0;
14085       stu__accept(';');
14086       if (once && stu__tok != ST_into) return z;
14087    }
14088 }
14089 
14090 static int stu__postexpr(int z, int p);
14091 static int stu__dictdef(int end, int *count)
14092 {
14093    int z,n=0,i,flags=0;
14094    short *dict=NULL;
14095    stu__nexttoken();
14096    while (stu__tok != end) {
14097       if (stu__tok == ST_id) {
14098          stua_obj id = stu__tokval;
14099          stu__nexttoken();
14100          if (stu__tok == '=') {
14101             flags |= 1;
14102             stb_arr_push(dict, stu__cdv(id));
14103             z = stu__nexpr(1); if (!z) return 0;
14104          } else {
14105             z = stu__cc2(ST_id, stu__cdv(id));
14106             z = stu__postexpr(z,1); if (!z) return 0;
14107             flags |= 2;
14108             stb_arr_push(dict, stu__cdv(stu__makeint(n++)));
14109          }
14110       } else {
14111          z = stu__expr(1); if (!z) return 0;
14112          flags |= 2;
14113          stb_arr_push(dict, stu__cdv(stu__makeint(n++)));
14114       }
14115       if (end != ')' && flags == 3) { z=stu__err("can't mix initialized and uninitialized defs"); goto done;}
14116       stb_arr_push(dict, z);
14117       if (!stu__accept(',')) break;
14118    }
14119    if (!stu__demand(end))
14120       return stu__err(end == ')' ? "Expecting ) at end of function call"
14121                                  : "Expecting } at end of dictionary definition");
14122    z = stu__cc2('{', stb_arr_len(dict)/2);
14123    for (i=0; i < stb_arr_len(dict); ++i)
14124       stu__cc(dict[i]);
14125    if (count) *count = n;
14126 done:
14127    stb_arr_free(dict);
14128    return z;
14129 }
14130 
14131 static int stu__comp_id(void)
14132 {
14133    int z,d;
14134    d = stu__nonlocal_id(stu__tokval);
14135    if (d == 0)
14136       return z = stu__cc2(ST_id, stu__cdt());
14137    // access a non-local frame by naming it with the appropriate int
14138    assert(d < 0);
14139    z = stu__cdv(d);            // relative frame # is the 'variable' in our local frame
14140    z = stu__cc2(ST_id, z);     // now access that dictionary
14141    return stu__cc3('[', z, stu__cdt()); // now access the variable from that dir
14142 }
14143 
14144 static stua_obj stu__funcdef(stua_obj *id, stua_obj *func);
14145 static int stu__expr(int p)
14146 {
14147    int z;
14148    // unary
14149    switch (stu__tok) {
14150       case ST_number: z = stu__cdt(); break;
14151       case ST_string: z = stu__cdt(); break;  // @TODO - string concatenation like C
14152       case ST_id    : z = stu__comp_id(); break;
14153       case ST__frame: z = stu__cc1(ST__frame); stu__nexttoken(); break;
14154       case ST_func  : z = stu__funcdef(NULL,NULL); break;
14155       case ST_if    : z = stu__parse_if(); break;
14156       case ST_nil   : z = stu__cdv(stua_nil); stu__nexttoken(); break;
14157       case ST_true  : z = stu__cdv(stua_true); stu__nexttoken(); break;
14158       case ST_false : z = stu__cdv(stua_false); stu__nexttoken(); break;
14159       case '-'      : z = stu__nexpr(99); if (z) z=stu__cc2(STU__negate,z); else return z; break;
14160       case '!'      : z = stu__nexpr(99); if (z) z=stu__cc2('!',z); else return z; break;
14161       case '~'      : z = stu__nexpr(99); if (z) z=stu__cc2('~',z); else return z; break;
14162       case '{'      : z = stu__dictdef('}', NULL); break;
14163       default       : return stu__err("Unexpected token");
14164       case '('      : stu__nexttoken(); z = stu__statements(0,0); if (!stu__demand(')')) return stu__err("Expecting )");
14165    }
14166    return stu__postexpr(z,p);
14167 }
14168 
14169 static int stu__postexpr(int z, int p)
14170 {
14171    int q;
14172    // postfix
14173    while (stu__tok == '(' || stu__tok == '[' || stu__tok == '.') {
14174       if (stu__accept('.')) {
14175          // MUST be followed by a plain identifier! use [] for other stuff
14176          if (stu__tok != ST_id) return stu__err("Must follow . with plain name; try [] instead");
14177          z = stu__cc3('[', z, stu__cdv(stu__tokval));
14178          stu__nexttoken();
14179       } else if (stu__accept('[')) {
14180          while (stu__tok != ']') {
14181             int r = stu__expr(1); if (!r) return 0;
14182             z = stu__cc3('[', z, r);
14183             if (!stu__accept(',')) break;
14184          }
14185          if (!stu__demand(']')) return stu__err("Expecting ]");
14186       } else {
14187          int n, p = stu__dictdef(')', &n); if (!p) return 0;
14188          #if 0 // this is incorrect!
14189          if (z > 0 && stu__pfunc.code[z] == ST_id) {
14190             stua_obj q = stu__get(stu__globaldict, stu__pfunc.data[-stu__pfunc.code[z+1]-1], stua_nil);
14191             if (stu__checkt(STU___function, q))
14192                if ((stu__pf(q))->num_param != n)
14193                   return stu__err("Incorrect number of parameters");
14194          }
14195          #endif
14196          z = stu__cc3('(', z, p);
14197       }
14198    }
14199    // binop - this implementation taken from lcc
14200    for (q=stu__prec[stu__tok]; q >= p; --q) {
14201       while (stu__prec[stu__tok] == q) {
14202          int o = stu__tok, y = stu__nexpr(p+1); if (!y) return 0;
14203          z = stu__cc3(o,z,y);
14204       }
14205    }
14206    return z;
14207 }
14208 
14209 static stua_obj stu__finish_func(stua_obj *param, int start)
14210 {
14211    int n, size;
14212    stu__func *f = (stu__func *) malloc(sizeof(*f));
14213    f->closure_source = 0;
14214    f->num_param = stb_arr_len(param);
14215    f->param = (int *) stb_copy(param, f->num_param * sizeof(*f->param));
14216    size = stb_arr_storage(stu__pfunc.code) + stb_arr_storage(stu__pfunc.data) + sizeof(*f) + 8;
14217    f->f.store = malloc(stb_arr_storage(stu__pfunc.code) + stb_arr_storage(stu__pfunc.data));
14218    f->code = (short *) ((char *) f->f.store + stb_arr_storage(stu__pfunc.data));
14219    memcpy(f->code, stu__pfunc.code, stb_arr_storage(stu__pfunc.code));
14220    f->code[1] = start;
14221    f->code[0] = stb_arr_len(stu__pfunc.data);
14222    for (n=0; n < f->code[0]; ++n)
14223       ((stua_obj *) f->code)[-1-n] = stu__pfunc.data[n];
14224    return stu__makeobj(STU___function, f, size, 0);
14225 }
14226 
14227 static int stu__funcdef(stua_obj *id, stua_obj *result)
14228 {
14229    int n,z=0,i,q;
14230    stua_obj *param = NULL;
14231    short *nonlocal;
14232    stua_obj v,f=stua_nil;
14233    assert(stu__tok == ST_func);
14234    stu__nexttoken();
14235    if (id) {
14236       if (!stu__demandv(ST_id, id)) return stu__err("Expecting function name");
14237    } else
14238       stu__accept(ST_id);
14239    if (!stu__demand('(')) return stu__err("Expecting ( for function parameter");
14240    stu__push_func_comp();
14241    while (stu__tok != ')') {
14242       if (!stu__demandv(ST_id, &v)) { z=stu__err("Expecting parameter name"); goto done; }
14243       stb_idict_add(stu__pfunc.locals, v, 1);
14244       if (stu__tok == '=') {
14245          n = stu__nexpr(1); if (!n) { z=0; goto done; }
14246          z = stu__seq(z, stu__cc3(STU__defaultparm, stu__cdv(v), n));
14247       } else
14248          stb_arr_push(param, v);
14249       if (!stu__accept(',')) break;
14250    }
14251    if (!stu__demand(')'))   { z=stu__err("Expecting ) at end of parameter list"); goto done; }
14252    n = stu__statements(0,0);   if (!n) { z=0; goto done; }
14253    if (!stu__demand(ST_end)) { z=stu__err("Expecting END at end of function"); goto done; }
14254    if (n == 1) n = 0;
14255    n = stu__seq(z,n);
14256    f = stu__finish_func(param, n);
14257    if (result) { *result = f; z=1; stu__pop_func_comp(); }
14258    else {
14259       nonlocal = stu__pfunc.non_local_refs;
14260       stu__pfunc.non_local_refs = NULL;
14261       stu__pop_func_comp();
14262       z = stu__cdv(f);
14263       if (nonlocal) {  // build a closure with references to the needed frames
14264          short *initcode = NULL;
14265          for (i=0; i < stb_arr_len(nonlocal); ++i) {
14266             int k = nonlocal[i], p;
14267             stb_arr_push(initcode, stu__cdv(k));
14268             if (k == -1) p = stu__cc1(ST__frame);
14269             else { p = stu__cdv(stu__makeint(k+1)); p = stu__cc2(ST_id, p); }
14270             stb_arr_push(initcode, p);
14271          }
14272          q = stu__cc2('{', stb_arr_len(nonlocal));
14273          for (i=0; i < stb_arr_len(initcode); ++i)
14274             stu__cc(initcode[i]);
14275          z = stu__cc3('+', z, q);
14276          stb_arr_free(initcode);
14277       }
14278       stb_arr_free(nonlocal);
14279    }
14280 done:
14281    stb_arr_free(param);
14282    if (!z) stu__pop_func_comp();
14283    return z;
14284 }
14285 
14286 static int stu__compile_global_scope(void)
14287 {
14288    stua_obj o;
14289    int z=0;
14290 
14291    stu__push_func_comp();
14292    while (stu__tok != 0) {
14293       if (stu__tok == ST_func) {
14294          stua_obj id, f;
14295          if (!stu__funcdef(&id,&f))
14296             goto error;
14297          stu__set(stu__globaldict, id, f);
14298       } else if (stu__tok == ST_var) {
14299          z = stu__varinit(z,1); if (!z) goto error;
14300       } else {
14301          int y = stu__statements(1,0); if (!y) goto error;
14302          z = stu__seq(z,y);
14303       }
14304       stu__accept(';');
14305    }
14306    o = stu__finish_func(NULL, z);
14307    stu__pop_func_comp();
14308 
14309    o = stu__funceval(o, stua_globals); // initialize stu__globaldict
14310    if (stu__flow == FLOW_error)
14311       printf("Error: %s\n", ((stu__wrapper *) stu__ptr(stu__flow_val))->ptr);
14312    return 1;
14313 error:
14314    stu__pop_func_comp();
14315    return 0;
14316 }
14317 
14318 stua_obj stu__myprint(stua_dict *context)
14319 {
14320    stua_obj x = stu__get(context, stua_string("x"), stua_nil);
14321    if ((x & 1) == stu__float_tag) printf("%f", stu__getfloat(x));
14322    else if (stu__tag(x) == stu__int_tag) printf("%d", stu__int(x));
14323    else {
14324        stu__wrapper *s = stu__pw(x);
14325        if (s->type == STU___string || s->type == STU___error)
14326           printf("%s", s->ptr);
14327        else if (s->type == STU___dict) printf("{{dictionary}}");
14328        else if (s->type == STU___function) printf("[[function]]");
14329        else
14330           printf("[[ERROR:%s]]", s->ptr);
14331    }
14332    return x;
14333 }
14334 
14335 void stua_init(void)
14336 {
14337    if (!stu__globaldict) {
14338       int i;
14339       stua_obj s;
14340       stu__func *f;
14341 
14342       stu__prec[ST_and] = stu__prec[ST_or] =                     1;
14343       stu__prec[ST_eq ] = stu__prec[ST_ne] = stu__prec[ST_le] =
14344        stu__prec[ST_ge] = stu__prec['>' ]  = stu__prec['<'] =    2;
14345       stu__prec[':']    =                                        3;
14346       stu__prec['&']    = stu__prec['|']   = stu__prec['^'] =    4;
14347       stu__prec['+']    = stu__prec['-']   =                     5;
14348       stu__prec['*']    = stu__prec['/']   = stu__prec['%'] =
14349        stu__prec[ST_shl]= stu__prec[ST_shr]= stu__prec[ST_shru]= 6;
14350 
14351       stu__end[')']   = stu__end[ST_end] = stu__end[ST_else] = 1;
14352       stu__end[ST_do] = stu__end[ST_elseif] = 1;
14353 
14354       stu__float_init();
14355       stu__lex_matcher = stb_lex_matcher();
14356       for (i=0; i < sizeof(stu__lexemes)/sizeof(stu__lexemes[0]); ++i)
14357          stb_lex_item(stu__lex_matcher, stu__lexemes[i].regex, stu__lexemes[i].stu__tok);
14358 
14359       stu__globaldict = stb_idict_new_size(64);
14360       stua_globals    = stu__makeobj(STU___dict, stu__globaldict, 0,0);
14361       stu__strings    = stb_sdict_new(0);
14362 
14363       stu__curbuf = stu__bufstart = "func _print(x) end\n"
14364       "func print()\n  var x=0 while _frame[x] != nil as x=x+1 do _print(_frame[x]) end end\n";
14365       stu__nexttoken();
14366       if (!stu__compile_global_scope())
14367          printf("Compile error in line %d: %s\n", stu__comp_err_line, stu__comp_err_str);
14368 
14369       s = stu__get(stu__globaldict, stua_string("_print"), stua_nil);
14370       if (stu__tag(s) == stu__ptr_tag && stu__ptr(s)->type == STU___function) {
14371          f = stu__pf(s);
14372          free(f->f.store);
14373          f->closure_source = 4;
14374          f->f.func = stu__myprint;
14375          f->code = NULL;
14376       }
14377    }
14378 }
14379 
14380 void stua_uninit(void)
14381 {
14382    if (stu__globaldict) {
14383       stb_idict_remove_all(stu__globaldict);
14384       stb_arr_setlen(stu__gc_root_stack, 0);
14385       stua_gc(1);
14386       stb_idict_destroy(stu__globaldict);
14387       stb_sdict_delete(stu__strings);
14388       stb_matcher_free(stu__lex_matcher);
14389       stb_arr_free(stu__gc_ptrlist);
14390       stb_arr_free(func_stack);
14391       stb_arr_free(stu__gc_root_stack);
14392       stu__globaldict = NULL;
14393    }
14394 }
14395 
14396 void stua_run_script(char *s)
14397 {
14398    stua_init();
14399 
14400    stu__curbuf = stu__bufstart = s;
14401    stu__nexttoken();
14402 
14403    stu__flow = FLOW_normal;
14404 
14405    if (!stu__compile_global_scope())
14406       printf("Compile error in line %d: %s\n", stu__comp_err_line, stu__comp_err_str);
14407    stua_gc(1);
14408 }
14409 #endif // STB_DEFINE
14410 #endif // STB_STUA
14411 
14412 #undef STB_EXTERN
14413 #endif // STB_INCLUDE_STB_H
14414 
14415 /*
14416 ------------------------------------------------------------------------------
14417 This software is available under 2 licenses -- choose whichever you prefer.
14418 ------------------------------------------------------------------------------
14419 ALTERNATIVE A - MIT License
14420 Copyright (c) 2017 Sean Barrett
14421 Permission is hereby granted, free of charge, to any person obtaining a copy of
14422 this software and associated documentation files (the "Software"), to deal in
14423 the Software without restriction, including without limitation the rights to
14424 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
14425 of the Software, and to permit persons to whom the Software is furnished to do
14426 so, subject to the following conditions:
14427 The above copyright notice and this permission notice shall be included in all
14428 copies or substantial portions of the Software.
14429 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14430 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14431 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14432 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14433 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
14434 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
14435 SOFTWARE.
14436 ------------------------------------------------------------------------------
14437 ALTERNATIVE B - Public Domain (www.unlicense.org)
14438 This is free and unencumbered software released into the public domain.
14439 Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
14440 software, either in source code form or as a compiled binary, for any purpose,
14441 commercial or non-commercial, and by any means.
14442 In jurisdictions that recognize copyright laws, the author or authors of this
14443 software dedicate any and all copyright interest in the software to the public
14444 domain. We make this dedication for the benefit of the public at large and to
14445 the detriment of our heirs and successors. We intend this dedication to be an
14446 overt act of relinquishment in perpetuity of all present and future rights to
14447 this software under copyright law.
14448 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14449 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14450 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14451 AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
14452 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
14453 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
14454 ------------------------------------------------------------------------------
14455 */