Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

14405 lines
452 KiB

  1. /* stb.h - v2.31 - Sean's Tool Box -- public domain -- http://nothings.org/stb.h
  2. no warranty is offered or implied; use this code at your own risk
  3. This is a single header file with a bunch of useful utilities
  4. for getting stuff done in C/C++.
  5. Documentation: http://nothings.org/stb/stb_h.html
  6. Unit tests: http://nothings.org/stb/stb.c
  7. ============================================================================
  8. You MUST
  9. #define STB_DEFINE
  10. in EXACTLY _one_ C or C++ file that includes this header, BEFORE the
  11. include, like this:
  12. #define STB_DEFINE
  13. #include "stb.h"
  14. All other files should just #include "stb.h" without the #define.
  15. ============================================================================
  16. Version History
  17. 2.31 stb_ucharcmp
  18. 2.30 MinGW fix
  19. 2.29 attempt to fix use of swprintf()
  20. 2.28 various new functionality
  21. 2.27 test _WIN32 not WIN32 in STB_THREADS
  22. 2.26 various warning & bugfixes
  23. 2.25 various warning & bugfixes
  24. 2.24 various warning & bugfixes
  25. 2.23 fix 2.22
  26. 2.22 64-bit fixes from '!='; fix stb_sdict_copy() to have preferred name
  27. 2.21 utf-8 decoder rejects "overlong" encodings; attempted 64-bit improvements
  28. 2.20 fix to hash "copy" function--reported by someone with handle "!="
  29. 2.19 ???
  30. 2.18 stb_readdir_subdirs_mask
  31. 2.17 stb_cfg_dir
  32. 2.16 fix stb_bgio_, add stb_bgio_stat(); begin a streaming wrapper
  33. 2.15 upgraded hash table template to allow:
  34. - aggregate keys (explicit comparison func for EMPTY and DEL keys)
  35. - "static" implementations (so they can be culled if unused)
  36. 2.14 stb_mprintf
  37. 2.13 reduce identifiable strings in STB_NO_STB_STRINGS
  38. 2.12 fix STB_ONLY -- lots of uint32s, TRUE/FALSE things had crept in
  39. 2.11 fix bug in stb_dirtree_get() which caused "c://path" sorts of stuff
  40. 2.10 STB_F(), STB_I() inline constants (also KI,KU,KF,KD)
  41. 2.09 stb_box_face_vertex_axis_side
  42. 2.08 bugfix stb_trimwhite()
  43. 2.07 colored printing in windows (why are we in 1985?)
  44. 2.06 comparison functions are now functions-that-return-functions and
  45. accept a struct-offset as a parameter (not thread-safe)
  46. 2.05 compile and pass tests under Linux (but no threads); thread cleanup
  47. 2.04 stb_cubic_bezier_1d, smoothstep, avoid dependency on registry
  48. 2.03 ?
  49. 2.02 remove integrated documentation
  50. 2.01 integrate various fixes; stb_force_uniprocessor
  51. 2.00 revised stb_dupe to use multiple hashes
  52. 1.99 stb_charcmp
  53. 1.98 stb_arr_deleten, stb_arr_insertn
  54. 1.97 fix stb_newell_normal()
  55. 1.96 stb_hash_number()
  56. 1.95 hack stb__rec_max; clean up recursion code to use new functions
  57. 1.94 stb_dirtree; rename stb_extra to stb_ptrmap
  58. 1.93 stb_sem_new() API cleanup (no blockflag-starts blocked; use 'extra')
  59. 1.92 stb_threadqueue--multi reader/writer queue, fixed size or resizeable
  60. 1.91 stb_bgio_* for reading disk asynchronously
  61. 1.90 stb_mutex uses CRITICAL_REGION; new stb_sync primitive for thread
  62. joining; workqueue supports stb_sync instead of stb_semaphore
  63. 1.89 support ';' in constant-string wildcards; stb_mutex wrapper (can
  64. implement with EnterCriticalRegion eventually)
  65. 1.88 portable threading API (only for win32 so far); worker thread queue
  66. 1.87 fix wildcard handling in stb_readdir_recursive
  67. 1.86 support ';' in wildcards
  68. 1.85 make stb_regex work with non-constant strings;
  69. beginnings of stb_introspect()
  70. 1.84 (forgot to make notes)
  71. 1.83 whoops, stb_keep_if_different wasn't deleting the temp file
  72. 1.82 bring back stb_compress from stb_file.h for cmirror
  73. 1.81 various bugfixes, STB_FASTMALLOC_INIT inits FASTMALLOC in release
  74. 1.80 stb_readdir returns utf8; write own utf8-utf16 because lib was wrong
  75. 1.79 stb_write
  76. 1.78 calloc() support for malloc wrapper, STB_FASTMALLOC
  77. 1.77 STB_FASTMALLOC
  78. 1.76 STB_STUA - Lua-like language; (stb_image, stb_csample, stb_bilinear)
  79. 1.75 alloc/free array of blocks; stb_hheap bug; a few stb_ps_ funcs;
  80. hash*getkey, hash*copy; stb_bitset; stb_strnicmp; bugfix stb_bst
  81. 1.74 stb_replaceinplace; use stdlib C function to convert utf8 to UTF-16
  82. 1.73 fix performance bug & leak in stb_ischar (C++ port lost a 'static')
  83. 1.72 remove stb_block, stb_block_manager, stb_decompress (to stb_file.h)
  84. 1.71 stb_trimwhite, stb_tokens_nested, etc.
  85. 1.70 back out 1.69 because it might problemize mixed builds; stb_filec()
  86. 1.69 (stb_file returns 'char *' in C++)
  87. 1.68 add a special 'tree root' data type for stb_bst; stb_arr_end
  88. 1.67 full C++ port. (stb_block_manager)
  89. 1.66 stb_newell_normal
  90. 1.65 stb_lex_item_wild -- allow wildcard items which MUST match entirely
  91. 1.64 stb_data
  92. 1.63 stb_log_name
  93. 1.62 stb_define_sort; C++ cleanup
  94. 1.61 stb_hash_fast -- Paul Hsieh's hash function (beats Bob Jenkins'?)
  95. 1.60 stb_delete_directory_recursive
  96. 1.59 stb_readdir_recursive
  97. 1.58 stb_bst variant with parent pointer for O(1) iteration, not O(log N)
  98. 1.57 replace LCG random with Mersenne Twister (found a public domain one)
  99. 1.56 stb_perfect_hash, stb_ischar, stb_regex
  100. 1.55 new stb_bst API allows multiple BSTs per node (e.g. secondary keys)
  101. 1.54 bugfix: stb_define_hash, stb_wildmatch, regexp
  102. 1.53 stb_define_hash; recoded stb_extra, stb_sdict use it
  103. 1.52 stb_rand_define, stb_bst, stb_reverse
  104. 1.51 fix 'stb_arr_setlen(NULL, 0)'
  105. 1.50 stb_wordwrap
  106. 1.49 minor improvements to enable the scripting language
  107. 1.48 better approach for stb_arr using stb_malloc; more invasive, clearer
  108. 1.47 stb_lex (lexes stb.h at 1.5ML/s on 3Ghz P4; 60/70% of optimal/flex)
  109. 1.46 stb_wrapper_*, STB_MALLOC_WRAPPER
  110. 1.45 lightly tested DFA acceleration of regexp searching
  111. 1.44 wildcard matching & searching; regexp matching & searching
  112. 1.43 stb_temp
  113. 1.42 allow stb_arr to use stb_malloc/realloc; note this is global
  114. 1.41 make it compile in C++; (disable stb_arr in C++)
  115. 1.40 stb_dupe tweak; stb_swap; stb_substr
  116. 1.39 stb_dupe; improve stb_file_max to be less stupid
  117. 1.38 stb_sha1_file: generate sha1 for file, even > 4GB
  118. 1.37 stb_file_max; partial support for utf8 filenames in Windows
  119. 1.36 remove STB__NO_PREFIX - poor interaction with IDE, not worth it
  120. streamline stb_arr to make it separately publishable
  121. 1.35 bugfixes for stb_sdict, stb_malloc(0), stristr
  122. 1.34 (streaming interfaces for stb_compress)
  123. 1.33 stb_alloc; bug in stb_getopt; remove stb_overflow
  124. 1.32 (stb_compress returns, smaller&faster; encode window & 64-bit len)
  125. 1.31 stb_prefix_count
  126. 1.30 (STB__NO_PREFIX - remove stb_ prefixes for personal projects)
  127. 1.29 stb_fput_varlen64, etc.
  128. 1.28 stb_sha1
  129. 1.27 ?
  130. 1.26 stb_extra
  131. 1.25 ?
  132. 1.24 stb_copyfile
  133. 1.23 stb_readdir
  134. 1.22 ?
  135. 1.21 ?
  136. 1.20 ?
  137. 1.19 ?
  138. 1.18 ?
  139. 1.17 ?
  140. 1.16 ?
  141. 1.15 stb_fixpath, stb_splitpath, stb_strchr2
  142. 1.14 stb_arr
  143. 1.13 ?stb, stb_log, stb_fatal
  144. 1.12 ?stb_hash2
  145. 1.11 miniML
  146. 1.10 stb_crc32, stb_adler32
  147. 1.09 stb_sdict
  148. 1.08 stb_bitreverse, stb_ispow2, stb_big32
  149. stb_fopen, stb_fput_varlen, stb_fput_ranged
  150. stb_fcmp, stb_feq
  151. 1.07 (stb_encompress)
  152. 1.06 stb_compress
  153. 1.05 stb_tokens, (stb_hheap)
  154. 1.04 stb_rand
  155. 1.03 ?(s-strings)
  156. 1.02 ?stb_filelen, stb_tokens
  157. 1.01 stb_tolower
  158. 1.00 stb_hash, stb_intcmp
  159. stb_file, stb_stringfile, stb_fgets
  160. stb_prefix, stb_strlower, stb_strtok
  161. stb_image
  162. (stb_array), (stb_arena)
  163. Parenthesized items have since been removed.
  164. LICENSE
  165. See end of file for license information.
  166. CREDITS
  167. Written by Sean Barrett.
  168. Fixes:
  169. Philipp Wiesemann
  170. Robert Nix
  171. r-lyeh
  172. blackpawn
  173. github:Mojofreem
  174. Ryan Whitworth
  175. Vincent Isambart
  176. Mike Sartain
  177. Eugene Opalev
  178. Tim Sjostrand
  179. github:infatum
  180. Dave Butler (Croepha)
  181. */
  182. #include <stdarg.h>
  183. #ifndef STB__INCLUDE_STB_H
  184. #define STB__INCLUDE_STB_H
  185. #define STB_VERSION 1
  186. #ifdef STB_INTROSPECT
  187. #define STB_DEFINE
  188. #endif
  189. #ifdef STB_DEFINE_THREADS
  190. #ifndef STB_DEFINE
  191. #define STB_DEFINE
  192. #endif
  193. #ifndef STB_THREADS
  194. #define STB_THREADS
  195. #endif
  196. #endif
  197. #if defined(_WIN32) && !defined(__MINGW32__)
  198. #ifndef _CRT_SECURE_NO_WARNINGS
  199. #define _CRT_SECURE_NO_WARNINGS
  200. #endif
  201. #ifndef _CRT_NONSTDC_NO_DEPRECATE
  202. #define _CRT_NONSTDC_NO_DEPRECATE
  203. #endif
  204. #ifndef _CRT_NON_CONFORMING_SWPRINTFS
  205. #define _CRT_NON_CONFORMING_SWPRINTFS
  206. #endif
  207. #if !defined(_MSC_VER) || _MSC_VER > 1700
  208. #include <intrin.h> // _BitScanReverse
  209. #endif
  210. #endif
  211. #include <stdlib.h> // stdlib could have min/max
  212. #include <stdio.h> // need FILE
  213. #include <string.h> // stb_define_hash needs memcpy/memset
  214. #include <time.h> // stb_dirtree
  215. #ifdef __MINGW32__
  216. #include <fcntl.h> // O_RDWR
  217. #endif
  218. #ifdef STB_PERSONAL
  219. typedef int Bool;
  220. #define False 0
  221. #define True 1
  222. #endif
  223. #ifdef STB_MALLOC_WRAPPER_PAGED
  224. #define STB_MALLOC_WRAPPER_DEBUG
  225. #endif
  226. #ifdef STB_MALLOC_WRAPPER_DEBUG
  227. #define STB_MALLOC_WRAPPER
  228. #endif
  229. #ifdef STB_MALLOC_WRAPPER_FASTMALLOC
  230. #define STB_FASTMALLOC
  231. #define STB_MALLOC_WRAPPER
  232. #endif
  233. #ifdef STB_FASTMALLOC
  234. #ifndef _WIN32
  235. #undef STB_FASTMALLOC
  236. #endif
  237. #endif
  238. #ifdef STB_DEFINE
  239. #include <assert.h>
  240. #include <stdarg.h>
  241. #include <stddef.h>
  242. #include <ctype.h>
  243. #include <math.h>
  244. #ifndef _WIN32
  245. #include <unistd.h>
  246. #else
  247. #include <io.h> // _mktemp
  248. #include <direct.h> // _rmdir
  249. #endif
  250. #include <sys/types.h> // stat()/_stat()
  251. #include <sys/stat.h> // stat()/_stat()
  252. #endif
  253. #define stb_min(a,b) ((a) < (b) ? (a) : (b))
  254. #define stb_max(a,b) ((a) > (b) ? (a) : (b))
  255. #ifndef STB_ONLY
  256. #if !defined(__cplusplus) && !defined(min) && !defined(max)
  257. #define min(x,y) stb_min(x,y)
  258. #define max(x,y) stb_max(x,y)
  259. #endif
  260. #ifndef M_PI
  261. #define M_PI 3.14159265358979323846f
  262. #endif
  263. #ifndef TRUE
  264. #define TRUE 1
  265. #define FALSE 0
  266. #endif
  267. #ifndef deg2rad
  268. #define deg2rad(a) ((a)*(M_PI/180))
  269. #endif
  270. #ifndef rad2deg
  271. #define rad2deg(a) ((a)*(180/M_PI))
  272. #endif
  273. #ifndef swap
  274. #ifndef __cplusplus
  275. #define swap(TYPE,a,b) \
  276. do { TYPE stb__t; stb__t = (a); (a) = (b); (b) = stb__t; } while (0)
  277. #endif
  278. #endif
  279. typedef unsigned char uint8 ;
  280. typedef signed char int8 ;
  281. typedef unsigned short uint16;
  282. typedef signed short int16;
  283. #if defined(STB_USE_LONG_FOR_32_BIT_INT) || defined(STB_LONG32)
  284. typedef unsigned long uint32;
  285. typedef signed long int32;
  286. #else
  287. typedef unsigned int uint32;
  288. typedef signed int int32;
  289. #endif
  290. typedef unsigned char uchar ;
  291. typedef unsigned short ushort;
  292. typedef unsigned int uint ;
  293. typedef unsigned long ulong ;
  294. // produce compile errors if the sizes aren't right
  295. typedef char stb__testsize16[sizeof(int16)==2];
  296. typedef char stb__testsize32[sizeof(int32)==4];
  297. #endif
  298. #ifndef STB_TRUE
  299. #define STB_TRUE 1
  300. #define STB_FALSE 0
  301. #endif
  302. // if we're STB_ONLY, can't rely on uint32 or even uint, so all the
  303. // variables we'll use herein need typenames prefixed with 'stb':
  304. typedef unsigned char stb_uchar;
  305. typedef unsigned char stb_uint8;
  306. typedef unsigned int stb_uint;
  307. typedef unsigned short stb_uint16;
  308. typedef short stb_int16;
  309. typedef signed char stb_int8;
  310. #if defined(STB_USE_LONG_FOR_32_BIT_INT) || defined(STB_LONG32)
  311. typedef unsigned long stb_uint32;
  312. typedef long stb_int32;
  313. #else
  314. typedef unsigned int stb_uint32;
  315. typedef int stb_int32;
  316. #endif
  317. typedef char stb__testsize2_16[sizeof(stb_uint16)==2 ? 1 : -1];
  318. typedef char stb__testsize2_32[sizeof(stb_uint32)==4 ? 1 : -1];
  319. #ifdef _MSC_VER
  320. typedef unsigned __int64 stb_uint64;
  321. typedef __int64 stb_int64;
  322. #define STB_IMM_UINT64(literalui64) (literalui64##ui64)
  323. #define STB_IMM_INT64(literali64) (literali64##i64)
  324. #else
  325. // ??
  326. typedef unsigned long long stb_uint64;
  327. typedef long long stb_int64;
  328. #define STB_IMM_UINT64(literalui64) (literalui64##ULL)
  329. #define STB_IMM_INT64(literali64) (literali64##LL)
  330. #endif
  331. typedef char stb__testsize2_64[sizeof(stb_uint64)==8 ? 1 : -1];
  332. // add platform-specific ways of checking for sizeof(char*) == 8,
  333. // and make those define STB_PTR64
  334. #if defined(_WIN64) || defined(__x86_64__) || defined(__ia64__) || defined(__LP64__)
  335. #define STB_PTR64
  336. #endif
  337. #ifdef STB_PTR64
  338. typedef char stb__testsize2_ptr[sizeof(char *) == 8];
  339. typedef stb_uint64 stb_uinta;
  340. typedef stb_int64 stb_inta;
  341. #else
  342. typedef char stb__testsize2_ptr[sizeof(char *) == 4];
  343. typedef stb_uint32 stb_uinta;
  344. typedef stb_int32 stb_inta;
  345. #endif
  346. typedef char stb__testsize2_uinta[sizeof(stb_uinta)==sizeof(char*) ? 1 : -1];
  347. // if so, we should define an int type that is the pointer size. until then,
  348. // we'll have to make do with this (which is not the same at all!)
  349. typedef union
  350. {
  351. unsigned int i;
  352. void * p;
  353. } stb_uintptr;
  354. #ifdef __cplusplus
  355. #define STB_EXTERN extern "C"
  356. #else
  357. #define STB_EXTERN extern
  358. #endif
  359. // check for well-known debug defines
  360. #if defined(DEBUG) || defined(_DEBUG) || defined(DBG)
  361. #ifndef NDEBUG
  362. #define STB_DEBUG
  363. #endif
  364. #endif
  365. #ifdef STB_DEBUG
  366. #include <assert.h>
  367. #endif
  368. STB_EXTERN void stb_wrapper_malloc(void *newp, int sz, char *file, int line);
  369. STB_EXTERN void stb_wrapper_free(void *oldp, char *file, int line);
  370. STB_EXTERN void stb_wrapper_realloc(void *oldp, void *newp, int sz, char *file, int line);
  371. STB_EXTERN void stb_wrapper_calloc(size_t num, size_t sz, char *file, int line);
  372. STB_EXTERN void stb_wrapper_listall(void (*func)(void *ptr, int sz, char *file, int line));
  373. STB_EXTERN void stb_wrapper_dump(char *filename);
  374. STB_EXTERN int stb_wrapper_allocsize(void *oldp);
  375. STB_EXTERN void stb_wrapper_check(void *oldp);
  376. #ifdef STB_DEFINE
  377. // this is a special function used inside malloc wrapper
  378. // to do allocations that aren't tracked (to avoid
  379. // reentrancy). Of course if someone _else_ wraps realloc,
  380. // this breaks, but if they're doing that AND the malloc
  381. // wrapper they need to explicitly check for reentrancy.
  382. //
  383. // only define realloc_raw() and we do realloc(NULL,sz)
  384. // for malloc() and realloc(p,0) for free().
  385. static void * stb__realloc_raw(void *p, int sz)
  386. {
  387. if (p == NULL) return malloc(sz);
  388. if (sz == 0) { free(p); return NULL; }
  389. return realloc(p,sz);
  390. }
  391. #endif
  392. #ifdef _WIN32
  393. STB_EXTERN void * stb_smalloc(size_t sz);
  394. STB_EXTERN void stb_sfree(void *p);
  395. STB_EXTERN void * stb_srealloc(void *p, size_t sz);
  396. STB_EXTERN void * stb_scalloc(size_t n, size_t sz);
  397. STB_EXTERN char * stb_sstrdup(char *s);
  398. #endif
  399. #ifdef STB_FASTMALLOC
  400. #define malloc stb_smalloc
  401. #define free stb_sfree
  402. #define realloc stb_srealloc
  403. #define strdup stb_sstrdup
  404. #define calloc stb_scalloc
  405. #endif
  406. #ifndef STB_MALLOC_ALLCHECK
  407. #define stb__check(p) 1
  408. #else
  409. #ifndef STB_MALLOC_WRAPPER
  410. #error STB_MALLOC_ALLCHECK requires STB_MALLOC_WRAPPER
  411. #else
  412. #define stb__check(p) stb_mcheck(p)
  413. #endif
  414. #endif
  415. #ifdef STB_MALLOC_WRAPPER
  416. STB_EXTERN void * stb__malloc(int, char *, int);
  417. STB_EXTERN void * stb__realloc(void *, int, char *, int);
  418. STB_EXTERN void * stb__calloc(size_t n, size_t s, char *, int);
  419. STB_EXTERN void stb__free(void *, char *file, int);
  420. STB_EXTERN char * stb__strdup(char *s, char *file, int);
  421. STB_EXTERN void stb_malloc_checkall(void);
  422. STB_EXTERN void stb_malloc_check_counter(int init_delay, int rep_delay);
  423. #ifndef STB_MALLOC_WRAPPER_DEBUG
  424. #define stb_mcheck(p) 1
  425. #else
  426. STB_EXTERN int stb_mcheck(void *);
  427. #endif
  428. #ifdef STB_DEFINE
  429. #ifdef STB_MALLOC_WRAPPER_DEBUG
  430. #define STB__PAD 32
  431. #define STB__BIAS 16
  432. #define STB__SIG 0x51b01234
  433. #define STB__FIXSIZE(sz) (((sz+3) & ~3) + STB__PAD)
  434. #define STB__ptr(x,y) ((char *) (x) + (y))
  435. #else
  436. #define STB__ptr(x,y) (x)
  437. #define STB__FIXSIZE(sz) (sz)
  438. #endif
  439. #ifdef STB_MALLOC_WRAPPER_DEBUG
  440. int stb_mcheck(void *p)
  441. {
  442. unsigned int sz;
  443. if (p == NULL) return 1;
  444. p = ((char *) p) - STB__BIAS;
  445. sz = * (unsigned int *) p;
  446. assert(* (unsigned int *) STB__ptr(p,4) == STB__SIG);
  447. assert(* (unsigned int *) STB__ptr(p,8) == STB__SIG);
  448. assert(* (unsigned int *) STB__ptr(p,12) == STB__SIG);
  449. assert(* (unsigned int *) STB__ptr(p,sz-4) == STB__SIG+1);
  450. assert(* (unsigned int *) STB__ptr(p,sz-8) == STB__SIG+1);
  451. assert(* (unsigned int *) STB__ptr(p,sz-12) == STB__SIG+1);
  452. assert(* (unsigned int *) STB__ptr(p,sz-16) == STB__SIG+1);
  453. stb_wrapper_check(STB__ptr(p, STB__BIAS));
  454. return 1;
  455. }
  456. static void stb__check2(void *p, int sz, char *file, int line)
  457. {
  458. stb_mcheck(p);
  459. }
  460. void stb_malloc_checkall(void)
  461. {
  462. stb_wrapper_listall(stb__check2);
  463. }
  464. #else
  465. void stb_malloc_checkall(void) { }
  466. #endif
  467. static int stb__malloc_wait=(1 << 30), stb__malloc_next_wait = (1 << 30), stb__malloc_iter;
  468. void stb_malloc_check_counter(int init_delay, int rep_delay)
  469. {
  470. stb__malloc_wait = init_delay;
  471. stb__malloc_next_wait = rep_delay;
  472. }
  473. void stb_mcheck_all(void)
  474. {
  475. #ifdef STB_MALLOC_WRAPPER_DEBUG
  476. ++stb__malloc_iter;
  477. if (--stb__malloc_wait <= 0) {
  478. stb_malloc_checkall();
  479. stb__malloc_wait = stb__malloc_next_wait;
  480. }
  481. #endif
  482. }
  483. #ifdef STB_MALLOC_WRAPPER_PAGED
  484. #define STB__WINDOWS_PAGE (1 << 12)
  485. #ifndef _WINDOWS_
  486. STB_EXTERN __declspec(dllimport) void * __stdcall VirtualAlloc(void *p, unsigned long size, unsigned long type, unsigned long protect);
  487. STB_EXTERN __declspec(dllimport) int __stdcall VirtualFree(void *p, unsigned long size, unsigned long freetype);
  488. #endif
  489. #endif
  490. static void *stb__malloc_final(int sz)
  491. {
  492. #ifdef STB_MALLOC_WRAPPER_PAGED
  493. int aligned = (sz + STB__WINDOWS_PAGE - 1) & ~(STB__WINDOWS_PAGE-1);
  494. char *p = VirtualAlloc(NULL, aligned + STB__WINDOWS_PAGE, 0x2000, 0x04); // RESERVE, READWRITE
  495. if (p == NULL) return p;
  496. VirtualAlloc(p, aligned, 0x1000, 0x04); // COMMIT, READWRITE
  497. return p;
  498. #else
  499. return malloc(sz);
  500. #endif
  501. }
  502. static void stb__free_final(void *p)
  503. {
  504. #ifdef STB_MALLOC_WRAPPER_PAGED
  505. VirtualFree(p, 0, 0x8000); // RELEASE
  506. #else
  507. free(p);
  508. #endif
  509. }
  510. int stb__malloc_failure;
  511. static void *stb__realloc_final(void *p, int sz, int old_sz)
  512. {
  513. #ifdef STB_MALLOC_WRAPPER_PAGED
  514. void *q = stb__malloc_final(sz);
  515. if (q == NULL)
  516. return ++stb__malloc_failure, q;
  517. // @TODO: deal with p being smaller!
  518. memcpy(q, p, sz < old_sz ? sz : old_sz);
  519. stb__free_final(p);
  520. return q;
  521. #else
  522. return realloc(p,sz);
  523. #endif
  524. }
  525. void stb__free(void *p, char *file, int line)
  526. {
  527. stb_mcheck_all();
  528. if (!p) return;
  529. #ifdef STB_MALLOC_WRAPPER_DEBUG
  530. stb_mcheck(p);
  531. #endif
  532. stb_wrapper_free(p,file,line);
  533. #ifdef STB_MALLOC_WRAPPER_DEBUG
  534. p = STB__ptr(p,-STB__BIAS);
  535. * (unsigned int *) STB__ptr(p,0) = 0xdeadbeef;
  536. * (unsigned int *) STB__ptr(p,4) = 0xdeadbeef;
  537. * (unsigned int *) STB__ptr(p,8) = 0xdeadbeef;
  538. * (unsigned int *) STB__ptr(p,12) = 0xdeadbeef;
  539. #endif
  540. stb__free_final(p);
  541. }
  542. void * stb__malloc(int sz, char *file, int line)
  543. {
  544. void *p;
  545. stb_mcheck_all();
  546. if (sz == 0) return NULL;
  547. p = stb__malloc_final(STB__FIXSIZE(sz));
  548. if (p == NULL) p = stb__malloc_final(STB__FIXSIZE(sz));
  549. if (p == NULL) p = stb__malloc_final(STB__FIXSIZE(sz));
  550. if (p == NULL) {
  551. ++stb__malloc_failure;
  552. #ifdef STB_MALLOC_WRAPPER_DEBUG
  553. stb_malloc_checkall();
  554. #endif
  555. return p;
  556. }
  557. #ifdef STB_MALLOC_WRAPPER_DEBUG
  558. * (int *) STB__ptr(p,0) = STB__FIXSIZE(sz);
  559. * (unsigned int *) STB__ptr(p,4) = STB__SIG;
  560. * (unsigned int *) STB__ptr(p,8) = STB__SIG;
  561. * (unsigned int *) STB__ptr(p,12) = STB__SIG;
  562. * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-4) = STB__SIG+1;
  563. * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-8) = STB__SIG+1;
  564. * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-12) = STB__SIG+1;
  565. * (unsigned int *) STB__ptr(p,STB__FIXSIZE(sz)-16) = STB__SIG+1;
  566. p = STB__ptr(p, STB__BIAS);
  567. #endif
  568. stb_wrapper_malloc(p,sz,file,line);
  569. return p;
  570. }
  571. void * stb__realloc(void *p, int sz, char *file, int line)
  572. {
  573. void *q;
  574. stb_mcheck_all();
  575. if (p == NULL) return stb__malloc(sz,file,line);
  576. if (sz == 0 ) { stb__free(p,file,line); return NULL; }
  577. #ifdef STB_MALLOC_WRAPPER_DEBUG
  578. stb_mcheck(p);
  579. p = STB__ptr(p,-STB__BIAS);
  580. #endif
  581. #ifdef STB_MALLOC_WRAPPER_PAGED
  582. {
  583. int n = stb_wrapper_allocsize(STB__ptr(p,STB__BIAS));
  584. if (!n)
  585. stb_wrapper_check(STB__ptr(p,STB__BIAS));
  586. q = stb__realloc_final(p, STB__FIXSIZE(sz), STB__FIXSIZE(n));
  587. }
  588. #else
  589. q = realloc(p, STB__FIXSIZE(sz));
  590. #endif
  591. if (q == NULL)
  592. return ++stb__malloc_failure, q;
  593. #ifdef STB_MALLOC_WRAPPER_DEBUG
  594. * (int *) STB__ptr(q,0) = STB__FIXSIZE(sz);
  595. * (unsigned int *) STB__ptr(q,4) = STB__SIG;
  596. * (unsigned int *) STB__ptr(q,8) = STB__SIG;
  597. * (unsigned int *) STB__ptr(q,12) = STB__SIG;
  598. * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-4) = STB__SIG+1;
  599. * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-8) = STB__SIG+1;
  600. * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-12) = STB__SIG+1;
  601. * (unsigned int *) STB__ptr(q,STB__FIXSIZE(sz)-16) = STB__SIG+1;
  602. q = STB__ptr(q, STB__BIAS);
  603. p = STB__ptr(p, STB__BIAS);
  604. #endif
  605. stb_wrapper_realloc(p,q,sz,file,line);
  606. return q;
  607. }
  608. STB_EXTERN int stb_log2_ceil(unsigned int);
  609. static void *stb__calloc(size_t n, size_t sz, char *file, int line)
  610. {
  611. void *q;
  612. stb_mcheck_all();
  613. if (n == 0 || sz == 0) return NULL;
  614. if (stb_log2_ceil(n) + stb_log2_ceil(sz) >= 32) return NULL;
  615. q = stb__malloc(n*sz, file, line);
  616. if (q) memset(q, 0, n*sz);
  617. return q;
  618. }
  619. char * stb__strdup(char *s, char *file, int line)
  620. {
  621. char *p;
  622. stb_mcheck_all();
  623. p = stb__malloc(strlen(s)+1, file, line);
  624. if (!p) return p;
  625. strcpy(p, s);
  626. return p;
  627. }
  628. #endif // STB_DEFINE
  629. #ifdef STB_FASTMALLOC
  630. #undef malloc
  631. #undef realloc
  632. #undef free
  633. #undef strdup
  634. #undef calloc
  635. #endif
  636. // include everything that might define these, BEFORE making macros
  637. #include <stdlib.h>
  638. #include <string.h>
  639. #include <malloc.h>
  640. #define malloc(s) stb__malloc ( s, __FILE__, __LINE__)
  641. #define realloc(p,s) stb__realloc(p,s, __FILE__, __LINE__)
  642. #define calloc(n,s) stb__calloc (n,s, __FILE__, __LINE__)
  643. #define free(p) stb__free (p, __FILE__, __LINE__)
  644. #define strdup(p) stb__strdup (p, __FILE__, __LINE__)
  645. #endif
  646. //////////////////////////////////////////////////////////////////////////////
  647. //
  648. // Windows pretty display
  649. //
  650. STB_EXTERN void stbprint(const char *fmt, ...);
  651. STB_EXTERN char *stb_sprintf(const char *fmt, ...);
  652. STB_EXTERN char *stb_mprintf(const char *fmt, ...);
  653. STB_EXTERN int stb_snprintf(char *s, size_t n, const char *fmt, ...);
  654. STB_EXTERN int stb_vsnprintf(char *s, size_t n, const char *fmt, va_list v);
  655. #ifdef STB_DEFINE
  656. int stb_vsnprintf(char *s, size_t n, const char *fmt, va_list v)
  657. {
  658. int res;
  659. #ifdef _WIN32
  660. // Could use "_vsnprintf_s(s, n, _TRUNCATE, fmt, v)" ?
  661. res = _vsnprintf(s,n,fmt,v);
  662. #else
  663. res = vsnprintf(s,n,fmt,v);
  664. #endif
  665. if (n) s[n-1] = 0;
  666. // Unix returns length output would require, Windows returns negative when truncated.
  667. return (res >= (int) n || res < 0) ? -1 : res;
  668. }
  669. int stb_snprintf(char *s, size_t n, const char *fmt, ...)
  670. {
  671. int res;
  672. va_list v;
  673. va_start(v,fmt);
  674. res = stb_vsnprintf(s, n, fmt, v);
  675. va_end(v);
  676. return res;
  677. }
  678. char *stb_sprintf(const char *fmt, ...)
  679. {
  680. static char buffer[1024];
  681. va_list v;
  682. va_start(v,fmt);
  683. stb_vsnprintf(buffer,1024,fmt,v);
  684. va_end(v);
  685. return buffer;
  686. }
  687. char *stb_mprintf(const char *fmt, ...)
  688. {
  689. static char buffer[1024];
  690. va_list v;
  691. va_start(v,fmt);
  692. stb_vsnprintf(buffer,1024,fmt,v);
  693. va_end(v);
  694. return strdup(buffer);
  695. }
  696. #ifdef _WIN32
  697. #ifndef _WINDOWS_
  698. STB_EXTERN __declspec(dllimport) int __stdcall WriteConsoleA(void *, const void *, unsigned int, unsigned int *, void *);
  699. STB_EXTERN __declspec(dllimport) void * __stdcall GetStdHandle(unsigned int);
  700. STB_EXTERN __declspec(dllimport) int __stdcall SetConsoleTextAttribute(void *, unsigned short);
  701. #endif
  702. static void stb__print_one(void *handle, char *s, int len)
  703. {
  704. if (len)
  705. if (WriteConsoleA(handle, s, len, NULL,NULL))
  706. fwrite(s, 1, len, stdout); // if it fails, maybe redirected, so do normal
  707. }
  708. static void stb__print(char *s)
  709. {
  710. void *handle = GetStdHandle((unsigned int) -11); // STD_OUTPUT_HANDLE
  711. int pad=0; // number of padding characters to add
  712. char *t = s;
  713. while (*s) {
  714. int lpad;
  715. while (*s && *s != '{') {
  716. if (pad) {
  717. if (*s == '\r' || *s == '\n')
  718. pad = 0;
  719. else if (s[0] == ' ' && s[1] == ' ') {
  720. stb__print_one(handle, t, s-t);
  721. t = s;
  722. while (pad) {
  723. stb__print_one(handle, t, 1);
  724. --pad;
  725. }
  726. }
  727. }
  728. ++s;
  729. }
  730. if (!*s) break;
  731. stb__print_one(handle, t, s-t);
  732. if (s[1] == '{') {
  733. ++s;
  734. continue;
  735. }
  736. if (s[1] == '#') {
  737. t = s+3;
  738. if (isxdigit(s[2]))
  739. if (isdigit(s[2]))
  740. SetConsoleTextAttribute(handle, s[2] - '0');
  741. else
  742. SetConsoleTextAttribute(handle, tolower(s[2]) - 'a' + 10);
  743. else {
  744. SetConsoleTextAttribute(handle, 0x0f);
  745. t=s+2;
  746. }
  747. } else if (s[1] == '!') {
  748. SetConsoleTextAttribute(handle, 0x0c);
  749. t = s+2;
  750. } else if (s[1] == '@') {
  751. SetConsoleTextAttribute(handle, 0x09);
  752. t = s+2;
  753. } else if (s[1] == '$') {
  754. SetConsoleTextAttribute(handle, 0x0a);
  755. t = s+2;
  756. } else {
  757. SetConsoleTextAttribute(handle, 0x08); // 0,7,8,15 => shades of grey
  758. t = s+1;
  759. }
  760. lpad = (t-s);
  761. s = t;
  762. while (*s && *s != '}') ++s;
  763. if (!*s) break;
  764. stb__print_one(handle, t, s-t);
  765. if (s[1] == '}') {
  766. t = s+2;
  767. } else {
  768. pad += 1+lpad;
  769. t = s+1;
  770. }
  771. s=t;
  772. SetConsoleTextAttribute(handle, 0x07);
  773. }
  774. stb__print_one(handle, t, s-t);
  775. SetConsoleTextAttribute(handle, 0x07);
  776. }
  777. void stbprint(const char *fmt, ...)
  778. {
  779. int res;
  780. char buffer[1024];
  781. char *tbuf = buffer;
  782. va_list v;
  783. va_start(v,fmt);
  784. res = stb_vsnprintf(buffer, sizeof(buffer), fmt, v);
  785. va_end(v);
  786. if (res < 0) {
  787. tbuf = (char *) malloc(16384);
  788. va_start(v,fmt);
  789. res = _vsnprintf(tbuf,16384, fmt, v);
  790. va_end(v);
  791. tbuf[16383] = 0;
  792. }
  793. stb__print(tbuf);
  794. if (tbuf != buffer)
  795. free(tbuf);
  796. }
  797. #else // _WIN32
  798. void stbprint(const char *fmt, ...)
  799. {
  800. va_list v;
  801. va_start(v,fmt);
  802. vprintf(fmt,v);
  803. va_end(v);
  804. }
  805. #endif // _WIN32
  806. #endif // STB_DEFINE
  807. //////////////////////////////////////////////////////////////////////////////
  808. //
  809. // Windows UTF8 filename handling
  810. //
  811. // Windows stupidly treats 8-bit filenames as some dopey code page,
  812. // rather than utf-8. If we want to use utf8 filenames, we have to
  813. // convert them to WCHAR explicitly and call WCHAR versions of the
  814. // file functions. So, ok, we do.
  815. #ifdef _WIN32
  816. #define stb__fopen(x,y) _wfopen((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y))
  817. #define stb__windows(x,y) x
  818. #else
  819. #define stb__fopen(x,y) fopen(x,y)
  820. #define stb__windows(x,y) y
  821. #endif
  822. typedef unsigned short stb__wchar;
  823. STB_EXTERN stb__wchar * stb_from_utf8(stb__wchar *buffer, char *str, int n);
  824. STB_EXTERN char * stb_to_utf8 (char *buffer, stb__wchar *str, int n);
  825. STB_EXTERN stb__wchar *stb__from_utf8(char *str);
  826. STB_EXTERN stb__wchar *stb__from_utf8_alt(char *str);
  827. STB_EXTERN char *stb__to_utf8(stb__wchar *str);
  828. #ifdef STB_DEFINE
  829. stb__wchar * stb_from_utf8(stb__wchar *buffer, char *ostr, int n)
  830. {
  831. unsigned char *str = (unsigned char *) ostr;
  832. stb_uint32 c;
  833. int i=0;
  834. --n;
  835. while (*str) {
  836. if (i >= n)
  837. return NULL;
  838. if (!(*str & 0x80))
  839. buffer[i++] = *str++;
  840. else if ((*str & 0xe0) == 0xc0) {
  841. if (*str < 0xc2) return NULL;
  842. c = (*str++ & 0x1f) << 6;
  843. if ((*str & 0xc0) != 0x80) return NULL;
  844. buffer[i++] = c + (*str++ & 0x3f);
  845. } else if ((*str & 0xf0) == 0xe0) {
  846. if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return NULL;
  847. if (*str == 0xed && str[1] > 0x9f) return NULL; // str[1] < 0x80 is checked below
  848. c = (*str++ & 0x0f) << 12;
  849. if ((*str & 0xc0) != 0x80) return NULL;
  850. c += (*str++ & 0x3f) << 6;
  851. if ((*str & 0xc0) != 0x80) return NULL;
  852. buffer[i++] = c + (*str++ & 0x3f);
  853. } else if ((*str & 0xf8) == 0xf0) {
  854. if (*str > 0xf4) return NULL;
  855. if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return NULL;
  856. if (*str == 0xf4 && str[1] > 0x8f) return NULL; // str[1] < 0x80 is checked below
  857. c = (*str++ & 0x07) << 18;
  858. if ((*str & 0xc0) != 0x80) return NULL;
  859. c += (*str++ & 0x3f) << 12;
  860. if ((*str & 0xc0) != 0x80) return NULL;
  861. c += (*str++ & 0x3f) << 6;
  862. if ((*str & 0xc0) != 0x80) return NULL;
  863. c += (*str++ & 0x3f);
  864. // utf-8 encodings of values used in surrogate pairs are invalid
  865. if ((c & 0xFFFFF800) == 0xD800) return NULL;
  866. if (c >= 0x10000) {
  867. c -= 0x10000;
  868. if (i + 2 > n) return NULL;
  869. buffer[i++] = 0xD800 | (0x3ff & (c >> 10));
  870. buffer[i++] = 0xDC00 | (0x3ff & (c ));
  871. }
  872. } else
  873. return NULL;
  874. }
  875. buffer[i] = 0;
  876. return buffer;
  877. }
  878. char * stb_to_utf8(char *buffer, stb__wchar *str, int n)
  879. {
  880. int i=0;
  881. --n;
  882. while (*str) {
  883. if (*str < 0x80) {
  884. if (i+1 > n) return NULL;
  885. buffer[i++] = (char) *str++;
  886. } else if (*str < 0x800) {
  887. if (i+2 > n) return NULL;
  888. buffer[i++] = 0xc0 + (*str >> 6);
  889. buffer[i++] = 0x80 + (*str & 0x3f);
  890. str += 1;
  891. } else if (*str >= 0xd800 && *str < 0xdc00) {
  892. stb_uint32 c;
  893. if (i+4 > n) return NULL;
  894. c = ((str[0] - 0xd800) << 10) + ((str[1]) - 0xdc00) + 0x10000;
  895. buffer[i++] = 0xf0 + (c >> 18);
  896. buffer[i++] = 0x80 + ((c >> 12) & 0x3f);
  897. buffer[i++] = 0x80 + ((c >> 6) & 0x3f);
  898. buffer[i++] = 0x80 + ((c ) & 0x3f);
  899. str += 2;
  900. } else if (*str >= 0xdc00 && *str < 0xe000) {
  901. return NULL;
  902. } else {
  903. if (i+3 > n) return NULL;
  904. buffer[i++] = 0xe0 + (*str >> 12);
  905. buffer[i++] = 0x80 + ((*str >> 6) & 0x3f);
  906. buffer[i++] = 0x80 + ((*str ) & 0x3f);
  907. str += 1;
  908. }
  909. }
  910. buffer[i] = 0;
  911. return buffer;
  912. }
  913. stb__wchar *stb__from_utf8(char *str)
  914. {
  915. static stb__wchar buffer[4096];
  916. return stb_from_utf8(buffer, str, 4096);
  917. }
  918. stb__wchar *stb__from_utf8_alt(char *str)
  919. {
  920. static stb__wchar buffer[4096];
  921. return stb_from_utf8(buffer, str, 4096);
  922. }
  923. char *stb__to_utf8(stb__wchar *str)
  924. {
  925. static char buffer[4096];
  926. return stb_to_utf8(buffer, str, 4096);
  927. }
  928. #endif
  929. //////////////////////////////////////////////////////////////////////////////
  930. //
  931. // Miscellany
  932. //
  933. STB_EXTERN void stb_fatal(char *fmt, ...);
  934. STB_EXTERN void stb_(char *fmt, ...);
  935. STB_EXTERN void stb_append_to_file(char *file, char *fmt, ...);
  936. STB_EXTERN void stb_log(int active);
  937. STB_EXTERN void stb_log_fileline(int active);
  938. STB_EXTERN void stb_log_name(char *filename);
  939. STB_EXTERN void stb_swap(void *p, void *q, size_t sz);
  940. STB_EXTERN void *stb_copy(void *p, size_t sz);
  941. STB_EXTERN void stb_pointer_array_free(void *p, int len);
  942. STB_EXTERN void **stb_array_block_alloc(int count, int blocksize);
  943. #define stb_arrcount(x) (sizeof(x)/sizeof((x)[0]))
  944. STB_EXTERN int stb__record_fileline(char *f, int n);
  945. #ifdef STB_DEFINE
  946. static char *stb__file;
  947. static int stb__line;
  948. int stb__record_fileline(char *f, int n)
  949. {
  950. stb__file = f;
  951. stb__line = n;
  952. return 0;
  953. }
  954. void stb_fatal(char *s, ...)
  955. {
  956. va_list a;
  957. if (stb__file)
  958. fprintf(stderr, "[%s:%d] ", stb__file, stb__line);
  959. va_start(a,s);
  960. fputs("Fatal error: ", stderr);
  961. vfprintf(stderr, s, a);
  962. va_end(a);
  963. fputs("\n", stderr);
  964. #ifdef STB_DEBUG
  965. #ifdef _MSC_VER
  966. #ifndef STB_PTR64
  967. __asm int 3; // trap to debugger!
  968. #else
  969. __debugbreak();
  970. #endif
  971. #else
  972. __builtin_trap();
  973. #endif
  974. #endif
  975. exit(1);
  976. }
  977. static int stb__log_active=1, stb__log_fileline=1;
  978. void stb_log(int active)
  979. {
  980. stb__log_active = active;
  981. }
  982. void stb_log_fileline(int active)
  983. {
  984. stb__log_fileline = active;
  985. }
  986. #ifdef STB_NO_STB_STRINGS
  987. char *stb__log_filename = "temp.log";
  988. #else
  989. char *stb__log_filename = "stb.log";
  990. #endif
  991. void stb_log_name(char *s)
  992. {
  993. stb__log_filename = s;
  994. }
  995. void stb_(char *s, ...)
  996. {
  997. if (stb__log_active) {
  998. FILE *f = fopen(stb__log_filename, "a");
  999. if (f) {
  1000. va_list a;
  1001. if (stb__log_fileline && stb__file)
  1002. fprintf(f, "[%s:%4d] ", stb__file, stb__line);
  1003. va_start(a,s);
  1004. vfprintf(f, s, a);
  1005. va_end(a);
  1006. fputs("\n", f);
  1007. fclose(f);
  1008. }
  1009. }
  1010. }
  1011. void stb_append_to_file(char *filename, char *s, ...)
  1012. {
  1013. FILE *f = fopen(filename, "a");
  1014. if (f) {
  1015. va_list a;
  1016. va_start(a,s);
  1017. vfprintf(f, s, a);
  1018. va_end(a);
  1019. fputs("\n", f);
  1020. fclose(f);
  1021. }
  1022. }
  1023. typedef struct { char d[4]; } stb__4;
  1024. typedef struct { char d[8]; } stb__8;
  1025. // optimize the small cases, though you shouldn't be calling this for those!
  1026. void stb_swap(void *p, void *q, size_t sz)
  1027. {
  1028. char buffer[256];
  1029. if (p == q) return;
  1030. if (sz == 4) {
  1031. stb__4 temp = * ( stb__4 *) p;
  1032. * (stb__4 *) p = * ( stb__4 *) q;
  1033. * (stb__4 *) q = temp;
  1034. return;
  1035. } else if (sz == 8) {
  1036. stb__8 temp = * ( stb__8 *) p;
  1037. * (stb__8 *) p = * ( stb__8 *) q;
  1038. * (stb__8 *) q = temp;
  1039. return;
  1040. }
  1041. while (sz > sizeof(buffer)) {
  1042. stb_swap(p, q, sizeof(buffer));
  1043. p = (char *) p + sizeof(buffer);
  1044. q = (char *) q + sizeof(buffer);
  1045. sz -= sizeof(buffer);
  1046. }
  1047. memcpy(buffer, p , sz);
  1048. memcpy(p , q , sz);
  1049. memcpy(q , buffer, sz);
  1050. }
  1051. void *stb_copy(void *p, size_t sz)
  1052. {
  1053. void *q = malloc(sz);
  1054. memcpy(q, p, sz);
  1055. return q;
  1056. }
  1057. void stb_pointer_array_free(void *q, int len)
  1058. {
  1059. void **p = (void **) q;
  1060. int i;
  1061. for (i=0; i < len; ++i)
  1062. free(p[i]);
  1063. }
  1064. void **stb_array_block_alloc(int count, int blocksize)
  1065. {
  1066. int i;
  1067. char *p = (char *) malloc(sizeof(void *) * count + count * blocksize);
  1068. void **q;
  1069. if (p == NULL) return NULL;
  1070. q = (void **) p;
  1071. p += sizeof(void *) * count;
  1072. for (i=0; i < count; ++i)
  1073. q[i] = p + i * blocksize;
  1074. return q;
  1075. }
  1076. #endif
  1077. #ifdef STB_DEBUG
  1078. // tricky hack to allow recording FILE,LINE even in varargs functions
  1079. #define STB__RECORD_FILE(x) (stb__record_fileline(__FILE__, __LINE__),(x))
  1080. #define stb_log STB__RECORD_FILE(stb_log)
  1081. #define stb_ STB__RECORD_FILE(stb_)
  1082. #ifndef STB_FATAL_CLEAN
  1083. #define stb_fatal STB__RECORD_FILE(stb_fatal)
  1084. #endif
  1085. #define STB__DEBUG(x) x
  1086. #else
  1087. #define STB__DEBUG(x)
  1088. #endif
  1089. //////////////////////////////////////////////////////////////////////////////
  1090. //
  1091. // stb_temp
  1092. //
  1093. #define stb_temp(block, sz) stb__temp(block, sizeof(block), (sz))
  1094. STB_EXTERN void * stb__temp(void *b, int b_sz, int want_sz);
  1095. STB_EXTERN void stb_tempfree(void *block, void *ptr);
  1096. #ifdef STB_DEFINE
  1097. void * stb__temp(void *b, int b_sz, int want_sz)
  1098. {
  1099. if (b_sz >= want_sz)
  1100. return b;
  1101. else
  1102. return malloc(want_sz);
  1103. }
  1104. void stb_tempfree(void *b, void *p)
  1105. {
  1106. if (p != b)
  1107. free(p);
  1108. }
  1109. #endif
  1110. //////////////////////////////////////////////////////////////////////////////
  1111. //
  1112. // math/sampling operations
  1113. //
  1114. #define stb_lerp(t,a,b) ( (a) + (t) * (float) ((b)-(a)) )
  1115. #define stb_unlerp(t,a,b) ( ((t) - (a)) / (float) ((b) - (a)) )
  1116. #define stb_clamp(x,xmin,xmax) ((x) < (xmin) ? (xmin) : (x) > (xmax) ? (xmax) : (x))
  1117. STB_EXTERN void stb_newell_normal(float *normal, int num_vert, float **vert, int normalize);
  1118. STB_EXTERN int stb_box_face_vertex_axis_side(int face_number, int vertex_number, int axis);
  1119. STB_EXTERN void stb_linear_controller(float *curpos, float target_pos, float acc, float deacc, float dt);
  1120. STB_EXTERN int stb_float_eq(float x, float y, float delta, int max_ulps);
  1121. STB_EXTERN int stb_is_prime(unsigned int m);
  1122. STB_EXTERN unsigned int stb_power_of_two_nearest_prime(int n);
  1123. STB_EXTERN float stb_smoothstep(float t);
  1124. STB_EXTERN float stb_cubic_bezier_1d(float t, float p0, float p1, float p2, float p3);
  1125. STB_EXTERN double stb_linear_remap(double x, double a, double b,
  1126. double c, double d);
  1127. #ifdef STB_DEFINE
  1128. float stb_smoothstep(float t)
  1129. {
  1130. return (3 - 2*t)*(t*t);
  1131. }
  1132. float stb_cubic_bezier_1d(float t, float p0, float p1, float p2, float p3)
  1133. {
  1134. float it = 1-t;
  1135. return it*it*it*p0 + 3*it*it*t*p1 + 3*it*t*t*p2 + t*t*t*p3;
  1136. }
  1137. void stb_newell_normal(float *normal, int num_vert, float **vert, int normalize)
  1138. {
  1139. int i,j;
  1140. float p;
  1141. normal[0] = normal[1] = normal[2] = 0;
  1142. for (i=num_vert-1,j=0; j < num_vert; i=j++) {
  1143. float *u = vert[i];
  1144. float *v = vert[j];
  1145. normal[0] += (u[1] - v[1]) * (u[2] + v[2]);
  1146. normal[1] += (u[2] - v[2]) * (u[0] + v[0]);
  1147. normal[2] += (u[0] - v[0]) * (u[1] + v[1]);
  1148. }
  1149. if (normalize) {
  1150. p = normal[0]*normal[0] + normal[1]*normal[1] + normal[2]*normal[2];
  1151. p = (float) (1.0 / sqrt(p));
  1152. normal[0] *= p;
  1153. normal[1] *= p;
  1154. normal[2] *= p;
  1155. }
  1156. }
  1157. int stb_box_face_vertex_axis_side(int face_number, int vertex_number, int axis)
  1158. {
  1159. static int box_vertices[6][4][3] =
  1160. {
  1161. { { 1,1,1 }, { 1,0,1 }, { 1,0,0 }, { 1,1,0 } },
  1162. { { 0,0,0 }, { 0,0,1 }, { 0,1,1 }, { 0,1,0 } },
  1163. { { 0,0,0 }, { 0,1,0 }, { 1,1,0 }, { 1,0,0 } },
  1164. { { 0,0,0 }, { 1,0,0 }, { 1,0,1 }, { 0,0,1 } },
  1165. { { 1,1,1 }, { 0,1,1 }, { 0,0,1 }, { 1,0,1 } },
  1166. { { 1,1,1 }, { 1,1,0 }, { 0,1,0 }, { 0,1,1 } },
  1167. };
  1168. assert(face_number >= 0 && face_number < 6);
  1169. assert(vertex_number >= 0 && vertex_number < 4);
  1170. assert(axis >= 0 && axis < 3);
  1171. return box_vertices[face_number][vertex_number][axis];
  1172. }
  1173. void stb_linear_controller(float *curpos, float target_pos, float acc, float deacc, float dt)
  1174. {
  1175. float sign = 1, p, cp = *curpos;
  1176. if (cp == target_pos) return;
  1177. if (target_pos < cp) {
  1178. target_pos = -target_pos;
  1179. cp = -cp;
  1180. sign = -1;
  1181. }
  1182. // first decelerate
  1183. if (cp < 0) {
  1184. p = cp + deacc * dt;
  1185. if (p > 0) {
  1186. p = 0;
  1187. dt = dt - cp / deacc;
  1188. if (dt < 0) dt = 0;
  1189. } else {
  1190. dt = 0;
  1191. }
  1192. cp = p;
  1193. }
  1194. // now accelerate
  1195. p = cp + acc*dt;
  1196. if (p > target_pos) p = target_pos;
  1197. *curpos = p * sign;
  1198. // @TODO: testing
  1199. }
  1200. float stb_quadratic_controller(float target_pos, float curpos, float maxvel, float maxacc, float dt, float *curvel)
  1201. {
  1202. return 0; // @TODO
  1203. }
  1204. int stb_float_eq(float x, float y, float delta, int max_ulps)
  1205. {
  1206. if (fabs(x-y) <= delta) return 1;
  1207. if (abs(*(int *)&x - *(int *)&y) <= max_ulps) return 1;
  1208. return 0;
  1209. }
  1210. int stb_is_prime(unsigned int m)
  1211. {
  1212. unsigned int i,j;
  1213. if (m < 2) return 0;
  1214. if (m == 2) return 1;
  1215. if (!(m & 1)) return 0;
  1216. if (m % 3 == 0) return (m == 3);
  1217. for (i=5; (j=i*i), j <= m && j > i; i += 6) {
  1218. if (m % i == 0) return 0;
  1219. if (m % (i+2) == 0) return 0;
  1220. }
  1221. return 1;
  1222. }
  1223. unsigned int stb_power_of_two_nearest_prime(int n)
  1224. {
  1225. static signed char tab[32] = { 0,0,0,0,1,0,-1,0,1,-1,-1,3,-1,0,-1,2,1,
  1226. 0,2,0,-1,-4,-1,5,-1,18,-2,15,2,-1,2,0 };
  1227. if (!tab[0]) {
  1228. int i;
  1229. for (i=0; i < 32; ++i)
  1230. tab[i] = (1 << i) + 2*tab[i] - 1;
  1231. tab[1] = 2;
  1232. tab[0] = 1;
  1233. }
  1234. if (n >= 32) return 0xfffffffb;
  1235. return tab[n];
  1236. }
  1237. double stb_linear_remap(double x, double x_min, double x_max,
  1238. double out_min, double out_max)
  1239. {
  1240. return stb_lerp(stb_unlerp(x,x_min,x_max),out_min,out_max);
  1241. }
  1242. #endif
  1243. // create a macro so it's faster, but you can get at the function pointer
  1244. #define stb_linear_remap(t,a,b,c,d) stb_lerp(stb_unlerp(t,a,b),c,d)
  1245. //////////////////////////////////////////////////////////////////////////////
  1246. //
  1247. // bit operations
  1248. //
  1249. #define stb_big32(c) (((c)[0]<<24) + (c)[1]*65536 + (c)[2]*256 + (c)[3])
  1250. #define stb_little32(c) (((c)[3]<<24) + (c)[2]*65536 + (c)[1]*256 + (c)[0])
  1251. #define stb_big16(c) ((c)[0]*256 + (c)[1])
  1252. #define stb_little16(c) ((c)[1]*256 + (c)[0])
  1253. STB_EXTERN int stb_bitcount(unsigned int a);
  1254. STB_EXTERN unsigned int stb_bitreverse8(unsigned char n);
  1255. STB_EXTERN unsigned int stb_bitreverse(unsigned int n);
  1256. STB_EXTERN int stb_is_pow2(unsigned int n);
  1257. STB_EXTERN int stb_log2_ceil(unsigned int n);
  1258. STB_EXTERN int stb_log2_floor(unsigned int n);
  1259. STB_EXTERN int stb_lowbit8(unsigned int n);
  1260. STB_EXTERN int stb_highbit8(unsigned int n);
  1261. #ifdef STB_DEFINE
  1262. int stb_bitcount(unsigned int a)
  1263. {
  1264. a = (a & 0x55555555) + ((a >> 1) & 0x55555555); // max 2
  1265. a = (a & 0x33333333) + ((a >> 2) & 0x33333333); // max 4
  1266. a = (a + (a >> 4)) & 0x0f0f0f0f; // max 8 per 4, now 8 bits
  1267. a = (a + (a >> 8)); // max 16 per 8 bits
  1268. a = (a + (a >> 16)); // max 32 per 8 bits
  1269. return a & 0xff;
  1270. }
  1271. unsigned int stb_bitreverse8(unsigned char n)
  1272. {
  1273. n = ((n & 0xAA) >> 1) + ((n & 0x55) << 1);
  1274. n = ((n & 0xCC) >> 2) + ((n & 0x33) << 2);
  1275. return (unsigned char) ((n >> 4) + (n << 4));
  1276. }
  1277. unsigned int stb_bitreverse(unsigned int n)
  1278. {
  1279. n = ((n & 0xAAAAAAAA) >> 1) | ((n & 0x55555555) << 1);
  1280. n = ((n & 0xCCCCCCCC) >> 2) | ((n & 0x33333333) << 2);
  1281. n = ((n & 0xF0F0F0F0) >> 4) | ((n & 0x0F0F0F0F) << 4);
  1282. n = ((n & 0xFF00FF00) >> 8) | ((n & 0x00FF00FF) << 8);
  1283. return (n >> 16) | (n << 16);
  1284. }
  1285. int stb_is_pow2(unsigned int n)
  1286. {
  1287. return (n & (n-1)) == 0;
  1288. }
  1289. // tricky use of 4-bit table to identify 5 bit positions (note the '-1')
  1290. // 3-bit table would require another tree level; 5-bit table wouldn't save one
  1291. #if defined(_WIN32) && !defined(__MINGW32__)
  1292. #pragma warning(push)
  1293. #pragma warning(disable: 4035) // disable warning about no return value
  1294. int stb_log2_floor(unsigned int n)
  1295. {
  1296. #if _MSC_VER > 1700
  1297. unsigned long i;
  1298. _BitScanReverse(&i, n);
  1299. return i != 0 ? i : -1;
  1300. #else
  1301. __asm {
  1302. bsr eax,n
  1303. jnz done
  1304. mov eax,-1
  1305. }
  1306. done:;
  1307. #endif
  1308. }
  1309. #pragma warning(pop)
  1310. #else
  1311. int stb_log2_floor(unsigned int n)
  1312. {
  1313. static signed char log2_4[16] = { -1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3 };
  1314. // 2 compares if n < 16, 3 compares otherwise
  1315. if (n < (1U << 14))
  1316. if (n < (1U << 4)) return 0 + log2_4[n ];
  1317. else if (n < (1U << 9)) return 5 + log2_4[n >> 5];
  1318. else return 10 + log2_4[n >> 10];
  1319. else if (n < (1U << 24))
  1320. if (n < (1U << 19)) return 15 + log2_4[n >> 15];
  1321. else return 20 + log2_4[n >> 20];
  1322. else if (n < (1U << 29)) return 25 + log2_4[n >> 25];
  1323. else return 30 + log2_4[n >> 30];
  1324. }
  1325. #endif
  1326. // define ceil from floor
  1327. int stb_log2_ceil(unsigned int n)
  1328. {
  1329. if (stb_is_pow2(n)) return stb_log2_floor(n);
  1330. else return 1 + stb_log2_floor(n);
  1331. }
  1332. int stb_highbit8(unsigned int n)
  1333. {
  1334. return stb_log2_ceil(n&255);
  1335. }
  1336. int stb_lowbit8(unsigned int n)
  1337. {
  1338. static signed char lowbit4[16] = { -1,0,1,0, 2,0,1,0, 3,0,1,0, 2,0,1,0 };
  1339. int k = lowbit4[n & 15];
  1340. if (k >= 0) return k;
  1341. k = lowbit4[(n >> 4) & 15];
  1342. if (k >= 0) return k+4;
  1343. return k;
  1344. }
  1345. #endif
  1346. //////////////////////////////////////////////////////////////////////////////
  1347. //
  1348. // qsort Compare Routines
  1349. //
  1350. #ifdef _WIN32
  1351. #define stb_stricmp(a,b) stricmp(a,b)
  1352. #define stb_strnicmp(a,b,n) strnicmp(a,b,n)
  1353. #else
  1354. #define stb_stricmp(a,b) strcasecmp(a,b)
  1355. #define stb_strnicmp(a,b,n) strncasecmp(a,b,n)
  1356. #endif
  1357. STB_EXTERN int (*stb_intcmp(int offset))(const void *a, const void *b);
  1358. STB_EXTERN int (*stb_qsort_strcmp(int offset))(const void *a, const void *b);
  1359. STB_EXTERN int (*stb_qsort_stricmp(int offset))(const void *a, const void *b);
  1360. STB_EXTERN int (*stb_floatcmp(int offset))(const void *a, const void *b);
  1361. STB_EXTERN int (*stb_doublecmp(int offset))(const void *a, const void *b);
  1362. STB_EXTERN int (*stb_charcmp(int offset))(const void *a, const void *b);
  1363. #ifdef STB_DEFINE
  1364. static int stb__intcmpoffset, stb__ucharcmpoffset, stb__strcmpoffset;
  1365. static int stb__floatcmpoffset, stb__doublecmpoffset;
  1366. int stb__intcmp(const void *a, const void *b)
  1367. {
  1368. const int p = *(const int *) ((const char *) a + stb__intcmpoffset);
  1369. const int q = *(const int *) ((const char *) b + stb__intcmpoffset);
  1370. return p < q ? -1 : p > q;
  1371. }
  1372. int stb__ucharcmp(const void *a, const void *b)
  1373. {
  1374. const int p = *(const unsigned char *) ((const char *) a + stb__ucharcmpoffset);
  1375. const int q = *(const unsigned char *) ((const char *) b + stb__ucharcmpoffset);
  1376. return p < q ? -1 : p > q;
  1377. }
  1378. int stb__floatcmp(const void *a, const void *b)
  1379. {
  1380. const float p = *(const float *) ((const char *) a + stb__floatcmpoffset);
  1381. const float q = *(const float *) ((const char *) b + stb__floatcmpoffset);
  1382. return p < q ? -1 : p > q;
  1383. }
  1384. int stb__doublecmp(const void *a, const void *b)
  1385. {
  1386. const double p = *(const double *) ((const char *) a + stb__doublecmpoffset);
  1387. const double q = *(const double *) ((const char *) b + stb__doublecmpoffset);
  1388. return p < q ? -1 : p > q;
  1389. }
  1390. int stb__qsort_strcmp(const void *a, const void *b)
  1391. {
  1392. const char *p = *(const char **) ((const char *) a + stb__strcmpoffset);
  1393. const char *q = *(const char **) ((const char *) b + stb__strcmpoffset);
  1394. return strcmp(p,q);
  1395. }
  1396. int stb__qsort_stricmp(const void *a, const void *b)
  1397. {
  1398. const char *p = *(const char **) ((const char *) a + stb__strcmpoffset);
  1399. const char *q = *(const char **) ((const char *) b + stb__strcmpoffset);
  1400. return stb_stricmp(p,q);
  1401. }
  1402. int (*stb_intcmp(int offset))(const void *, const void *)
  1403. {
  1404. stb__intcmpoffset = offset;
  1405. return &stb__intcmp;
  1406. }
  1407. int (*stb_ucharcmp(int offset))(const void *, const void *)
  1408. {
  1409. stb__ucharcmpoffset = offset;
  1410. return &stb__ucharcmp;
  1411. }
  1412. int (*stb_qsort_strcmp(int offset))(const void *, const void *)
  1413. {
  1414. stb__strcmpoffset = offset;
  1415. return &stb__qsort_strcmp;
  1416. }
  1417. int (*stb_qsort_stricmp(int offset))(const void *, const void *)
  1418. {
  1419. stb__strcmpoffset = offset;
  1420. return &stb__qsort_stricmp;
  1421. }
  1422. int (*stb_floatcmp(int offset))(const void *, const void *)
  1423. {
  1424. stb__floatcmpoffset = offset;
  1425. return &stb__floatcmp;
  1426. }
  1427. int (*stb_doublecmp(int offset))(const void *, const void *)
  1428. {
  1429. stb__doublecmpoffset = offset;
  1430. return &stb__doublecmp;
  1431. }
  1432. #endif
  1433. //////////////////////////////////////////////////////////////////////////////
  1434. //
  1435. // Binary Search Toolkit
  1436. //
  1437. typedef struct
  1438. {
  1439. int minval, maxval, guess;
  1440. int mode, step;
  1441. } stb_search;
  1442. STB_EXTERN int stb_search_binary(stb_search *s, int minv, int maxv, int find_smallest);
  1443. STB_EXTERN int stb_search_open(stb_search *s, int minv, int find_smallest);
  1444. STB_EXTERN int stb_probe(stb_search *s, int compare, int *result); // return 0 when done
  1445. #ifdef STB_DEFINE
  1446. enum
  1447. {
  1448. STB_probe_binary_smallest,
  1449. STB_probe_binary_largest,
  1450. STB_probe_open_smallest,
  1451. STB_probe_open_largest,
  1452. };
  1453. static int stb_probe_guess(stb_search *s, int *result)
  1454. {
  1455. switch(s->mode) {
  1456. case STB_probe_binary_largest:
  1457. if (s->minval == s->maxval) {
  1458. *result = s->minval;
  1459. return 0;
  1460. }
  1461. assert(s->minval < s->maxval);
  1462. // if a < b, then a < p <= b
  1463. s->guess = s->minval + (((unsigned) s->maxval - s->minval + 1) >> 1);
  1464. break;
  1465. case STB_probe_binary_smallest:
  1466. if (s->minval == s->maxval) {
  1467. *result = s->minval;
  1468. return 0;
  1469. }
  1470. assert(s->minval < s->maxval);
  1471. // if a < b, then a <= p < b
  1472. s->guess = s->minval + (((unsigned) s->maxval - s->minval) >> 1);
  1473. break;
  1474. case STB_probe_open_smallest:
  1475. case STB_probe_open_largest:
  1476. s->guess = s->maxval; // guess the current maxval
  1477. break;
  1478. }
  1479. *result = s->guess;
  1480. return 1;
  1481. }
  1482. int stb_probe(stb_search *s, int compare, int *result)
  1483. {
  1484. switch(s->mode) {
  1485. case STB_probe_open_smallest:
  1486. case STB_probe_open_largest: {
  1487. if (compare <= 0) {
  1488. // then it lies within minval & maxval
  1489. if (s->mode == STB_probe_open_smallest)
  1490. s->mode = STB_probe_binary_smallest;
  1491. else
  1492. s->mode = STB_probe_binary_largest;
  1493. } else {
  1494. // otherwise, we need to probe larger
  1495. s->minval = s->maxval + 1;
  1496. s->maxval = s->minval + s->step;
  1497. s->step += s->step;
  1498. }
  1499. break;
  1500. }
  1501. case STB_probe_binary_smallest: {
  1502. // if compare < 0, then s->minval <= a < p
  1503. // if compare = 0, then s->minval <= a <= p
  1504. // if compare > 0, then p < a <= s->maxval
  1505. if (compare <= 0)
  1506. s->maxval = s->guess;
  1507. else
  1508. s->minval = s->guess+1;
  1509. break;
  1510. }
  1511. case STB_probe_binary_largest: {
  1512. // if compare < 0, then s->minval <= a < p
  1513. // if compare = 0, then p <= a <= s->maxval
  1514. // if compare > 0, then p < a <= s->maxval
  1515. if (compare < 0)
  1516. s->maxval = s->guess-1;
  1517. else
  1518. s->minval = s->guess;
  1519. break;
  1520. }
  1521. }
  1522. return stb_probe_guess(s, result);
  1523. }
  1524. int stb_search_binary(stb_search *s, int minv, int maxv, int find_smallest)
  1525. {
  1526. int r;
  1527. if (maxv < minv) return minv-1;
  1528. s->minval = minv;
  1529. s->maxval = maxv;
  1530. s->mode = find_smallest ? STB_probe_binary_smallest : STB_probe_binary_largest;
  1531. stb_probe_guess(s, &r);
  1532. return r;
  1533. }
  1534. int stb_search_open(stb_search *s, int minv, int find_smallest)
  1535. {
  1536. int r;
  1537. s->step = 4;
  1538. s->minval = minv;
  1539. s->maxval = minv+s->step;
  1540. s->mode = find_smallest ? STB_probe_open_smallest : STB_probe_open_largest;
  1541. stb_probe_guess(s, &r);
  1542. return r;
  1543. }
  1544. #endif
  1545. //////////////////////////////////////////////////////////////////////////////
  1546. //
  1547. // String Processing
  1548. //
  1549. #define stb_prefixi(s,t) (0==stb_strnicmp((s),(t),strlen(t)))
  1550. enum stb_splitpath_flag
  1551. {
  1552. STB_PATH = 1,
  1553. STB_FILE = 2,
  1554. STB_EXT = 4,
  1555. STB_PATH_FILE = STB_PATH + STB_FILE,
  1556. STB_FILE_EXT = STB_FILE + STB_EXT,
  1557. STB_EXT_NO_PERIOD = 8,
  1558. };
  1559. STB_EXTERN char * stb_skipwhite(char *s);
  1560. STB_EXTERN char * stb_trimwhite(char *s);
  1561. STB_EXTERN char * stb_skipnewline(char *s);
  1562. STB_EXTERN char * stb_strncpy(char *s, char *t, int n);
  1563. STB_EXTERN char * stb_substr(char *t, int n);
  1564. STB_EXTERN char * stb_duplower(char *s);
  1565. STB_EXTERN void stb_tolower (char *s);
  1566. STB_EXTERN char * stb_strchr2 (char *s, char p1, char p2);
  1567. STB_EXTERN char * stb_strrchr2(char *s, char p1, char p2);
  1568. STB_EXTERN char * stb_strtok(char *output, char *src, char *delimit);
  1569. STB_EXTERN char * stb_strtok_keep(char *output, char *src, char *delimit);
  1570. STB_EXTERN char * stb_strtok_invert(char *output, char *src, char *allowed);
  1571. STB_EXTERN char * stb_dupreplace(char *s, char *find, char *replace);
  1572. STB_EXTERN void stb_replaceinplace(char *s, char *find, char *replace);
  1573. STB_EXTERN char * stb_splitpath(char *output, char *src, int flag);
  1574. STB_EXTERN char * stb_splitpathdup(char *src, int flag);
  1575. STB_EXTERN char * stb_replacedir(char *output, char *src, char *dir);
  1576. STB_EXTERN char * stb_replaceext(char *output, char *src, char *ext);
  1577. STB_EXTERN void stb_fixpath(char *path);
  1578. STB_EXTERN char * stb_shorten_path_readable(char *path, int max_len);
  1579. STB_EXTERN int stb_suffix (char *s, char *t);
  1580. STB_EXTERN int stb_suffixi(char *s, char *t);
  1581. STB_EXTERN int stb_prefix (char *s, char *t);
  1582. STB_EXTERN char * stb_strichr(char *s, char t);
  1583. STB_EXTERN char * stb_stristr(char *s, char *t);
  1584. STB_EXTERN int stb_prefix_count(char *s, char *t);
  1585. STB_EXTERN const char * stb_plural(int n); // "s" or ""
  1586. STB_EXTERN size_t stb_strscpy(char *d, const char *s, size_t n);
  1587. STB_EXTERN char **stb_tokens(char *src, char *delimit, int *count);
  1588. STB_EXTERN char **stb_tokens_nested(char *src, char *delimit, int *count, char *nest_in, char *nest_out);
  1589. STB_EXTERN char **stb_tokens_nested_empty(char *src, char *delimit, int *count, char *nest_in, char *nest_out);
  1590. STB_EXTERN char **stb_tokens_allowempty(char *src, char *delimit, int *count);
  1591. STB_EXTERN char **stb_tokens_stripwhite(char *src, char *delimit, int *count);
  1592. STB_EXTERN char **stb_tokens_withdelim(char *src, char *delimit, int *count);
  1593. STB_EXTERN char **stb_tokens_quoted(char *src, char *delimit, int *count);
  1594. // with 'quoted', allow delimiters to appear inside quotation marks, and don't
  1595. // strip whitespace inside them (and we delete the quotation marks unless they
  1596. // appear back to back, in which case they're considered escaped)
  1597. #ifdef STB_DEFINE
  1598. size_t stb_strscpy(char *d, const char *s, size_t n)
  1599. {
  1600. size_t len = strlen(s);
  1601. if (len >= n) {
  1602. if (n) d[0] = 0;
  1603. return 0;
  1604. }
  1605. strcpy(d,s);
  1606. return len + 1;
  1607. }
  1608. const char *stb_plural(int n)
  1609. {
  1610. return n == 1 ? "" : "s";
  1611. }
  1612. int stb_prefix(char *s, char *t)
  1613. {
  1614. while (*t)
  1615. if (*s++ != *t++)
  1616. return STB_FALSE;
  1617. return STB_TRUE;
  1618. }
  1619. int stb_prefix_count(char *s, char *t)
  1620. {
  1621. int c=0;
  1622. while (*t) {
  1623. if (*s++ != *t++)
  1624. break;
  1625. ++c;
  1626. }
  1627. return c;
  1628. }
  1629. int stb_suffix(char *s, char *t)
  1630. {
  1631. size_t n = strlen(s);
  1632. size_t m = strlen(t);
  1633. if (m <= n)
  1634. return 0 == strcmp(s+n-m, t);
  1635. else
  1636. return 0;
  1637. }
  1638. int stb_suffixi(char *s, char *t)
  1639. {
  1640. size_t n = strlen(s);
  1641. size_t m = strlen(t);
  1642. if (m <= n)
  1643. return 0 == stb_stricmp(s+n-m, t);
  1644. else
  1645. return 0;
  1646. }
  1647. // originally I was using this table so that I could create known sentinel
  1648. // values--e.g. change whitetable[0] to be true if I was scanning for whitespace,
  1649. // and false if I was scanning for nonwhite. I don't appear to be using that
  1650. // functionality anymore (I do for tokentable, though), so just replace it
  1651. // with isspace()
  1652. char *stb_skipwhite(char *s)
  1653. {
  1654. while (isspace((unsigned char) *s)) ++s;
  1655. return s;
  1656. }
  1657. char *stb_skipnewline(char *s)
  1658. {
  1659. if (s[0] == '\r' || s[0] == '\n') {
  1660. if (s[0]+s[1] == '\r' + '\n') ++s;
  1661. ++s;
  1662. }
  1663. return s;
  1664. }
  1665. char *stb_trimwhite(char *s)
  1666. {
  1667. int i,n;
  1668. s = stb_skipwhite(s);
  1669. n = (int) strlen(s);
  1670. for (i=n-1; i >= 0; --i)
  1671. if (!isspace(s[i]))
  1672. break;
  1673. s[i+1] = 0;
  1674. return s;
  1675. }
  1676. char *stb_strncpy(char *s, char *t, int n)
  1677. {
  1678. strncpy(s,t,n);
  1679. s[n-1] = 0;
  1680. return s;
  1681. }
  1682. char *stb_substr(char *t, int n)
  1683. {
  1684. char *a;
  1685. int z = (int) strlen(t);
  1686. if (z < n) n = z;
  1687. a = (char *) malloc(n+1);
  1688. strncpy(a,t,n);
  1689. a[n] = 0;
  1690. return a;
  1691. }
  1692. char *stb_duplower(char *s)
  1693. {
  1694. char *p = strdup(s), *q = p;
  1695. while (*q) {
  1696. *q = tolower(*q);
  1697. ++q;
  1698. }
  1699. return p;
  1700. }
  1701. void stb_tolower(char *s)
  1702. {
  1703. while (*s) {
  1704. *s = tolower(*s);
  1705. ++s;
  1706. }
  1707. }
  1708. char *stb_strchr2(char *s, char x, char y)
  1709. {
  1710. for(; *s; ++s)
  1711. if (*s == x || *s == y)
  1712. return s;
  1713. return NULL;
  1714. }
  1715. char *stb_strrchr2(char *s, char x, char y)
  1716. {
  1717. char *r = NULL;
  1718. for(; *s; ++s)
  1719. if (*s == x || *s == y)
  1720. r = s;
  1721. return r;
  1722. }
  1723. char *stb_strichr(char *s, char t)
  1724. {
  1725. if (tolower(t) == toupper(t))
  1726. return strchr(s,t);
  1727. return stb_strchr2(s, (char) tolower(t), (char) toupper(t));
  1728. }
  1729. char *stb_stristr(char *s, char *t)
  1730. {
  1731. size_t n = strlen(t);
  1732. char *z;
  1733. if (n==0) return s;
  1734. while ((z = stb_strichr(s, *t)) != NULL) {
  1735. if (0==stb_strnicmp(z, t, n))
  1736. return z;
  1737. s = z+1;
  1738. }
  1739. return NULL;
  1740. }
  1741. static char *stb_strtok_raw(char *output, char *src, char *delimit, int keep, int invert)
  1742. {
  1743. if (invert) {
  1744. while (*src && strchr(delimit, *src) != NULL) {
  1745. *output++ = *src++;
  1746. }
  1747. } else {
  1748. while (*src && strchr(delimit, *src) == NULL) {
  1749. *output++ = *src++;
  1750. }
  1751. }
  1752. *output = 0;
  1753. if (keep)
  1754. return src;
  1755. else
  1756. return *src ? src+1 : src;
  1757. }
  1758. char *stb_strtok(char *output, char *src, char *delimit)
  1759. {
  1760. return stb_strtok_raw(output, src, delimit, 0, 0);
  1761. }
  1762. char *stb_strtok_keep(char *output, char *src, char *delimit)
  1763. {
  1764. return stb_strtok_raw(output, src, delimit, 1, 0);
  1765. }
  1766. char *stb_strtok_invert(char *output, char *src, char *delimit)
  1767. {
  1768. return stb_strtok_raw(output, src, delimit, 1,1);
  1769. }
  1770. static char **stb_tokens_raw(char *src_, char *delimit, int *count,
  1771. int stripwhite, int allow_empty, char *start, char *end)
  1772. {
  1773. int nested = 0;
  1774. unsigned char *src = (unsigned char *) src_;
  1775. static char stb_tokentable[256]; // rely on static initializion to 0
  1776. static char stable[256],etable[256];
  1777. char *out;
  1778. char **result;
  1779. int num=0;
  1780. unsigned char *s;
  1781. s = (unsigned char *) delimit; while (*s) stb_tokentable[*s++] = 1;
  1782. if (start) {
  1783. s = (unsigned char *) start; while (*s) stable[*s++] = 1;
  1784. s = (unsigned char *) end; if (s) while (*s) stable[*s++] = 1;
  1785. s = (unsigned char *) end; if (s) while (*s) etable[*s++] = 1;
  1786. }
  1787. stable[0] = 1;
  1788. // two passes through: the first time, counting how many
  1789. s = (unsigned char *) src;
  1790. while (*s) {
  1791. // state: just found delimiter
  1792. // skip further delimiters
  1793. if (!allow_empty) {
  1794. stb_tokentable[0] = 0;
  1795. while (stb_tokentable[*s])
  1796. ++s;
  1797. if (!*s) break;
  1798. }
  1799. ++num;
  1800. // skip further non-delimiters
  1801. stb_tokentable[0] = 1;
  1802. if (stripwhite == 2) { // quoted strings
  1803. while (!stb_tokentable[*s]) {
  1804. if (*s != '"')
  1805. ++s;
  1806. else {
  1807. ++s;
  1808. if (*s == '"')
  1809. ++s; // "" -> ", not start a string
  1810. else {
  1811. // begin a string
  1812. while (*s) {
  1813. if (s[0] == '"') {
  1814. if (s[1] == '"') s += 2; // "" -> "
  1815. else { ++s; break; } // terminating "
  1816. } else
  1817. ++s;
  1818. }
  1819. }
  1820. }
  1821. }
  1822. } else
  1823. while (nested || !stb_tokentable[*s]) {
  1824. if (stable[*s]) {
  1825. if (!*s) break;
  1826. if (end ? etable[*s] : nested)
  1827. --nested;
  1828. else
  1829. ++nested;
  1830. }
  1831. ++s;
  1832. }
  1833. if (allow_empty) {
  1834. if (*s) ++s;
  1835. }
  1836. }
  1837. // now num has the actual count... malloc our output structure
  1838. // need space for all the strings: strings won't be any longer than
  1839. // original input, since for every '\0' there's at least one delimiter
  1840. result = (char **) malloc(sizeof(*result) * (num+1) + (s-src+1));
  1841. if (result == NULL) return result;
  1842. out = (char *) (result + (num+1));
  1843. // second pass: copy out the data
  1844. s = (unsigned char *) src;
  1845. num = 0;
  1846. nested = 0;
  1847. while (*s) {
  1848. char *last_nonwhite;
  1849. // state: just found delimiter
  1850. // skip further delimiters
  1851. if (!allow_empty) {
  1852. stb_tokentable[0] = 0;
  1853. if (stripwhite)
  1854. while (stb_tokentable[*s] || isspace(*s))
  1855. ++s;
  1856. else
  1857. while (stb_tokentable[*s])
  1858. ++s;
  1859. } else if (stripwhite) {
  1860. while (isspace(*s)) ++s;
  1861. }
  1862. if (!*s) break;
  1863. // we're past any leading delimiters and whitespace
  1864. result[num] = out;
  1865. ++num;
  1866. // copy non-delimiters
  1867. stb_tokentable[0] = 1;
  1868. last_nonwhite = out-1;
  1869. if (stripwhite == 2) {
  1870. while (!stb_tokentable[*s]) {
  1871. if (*s != '"') {
  1872. if (!isspace(*s)) last_nonwhite = out;
  1873. *out++ = *s++;
  1874. } else {
  1875. ++s;
  1876. if (*s == '"') {
  1877. if (!isspace(*s)) last_nonwhite = out;
  1878. *out++ = *s++; // "" -> ", not start string
  1879. } else {
  1880. // begin a quoted string
  1881. while (*s) {
  1882. if (s[0] == '"') {
  1883. if (s[1] == '"') { *out++ = *s; s += 2; }
  1884. else { ++s; break; } // terminating "
  1885. } else
  1886. *out++ = *s++;
  1887. }
  1888. last_nonwhite = out-1; // all in quotes counts as non-white
  1889. }
  1890. }
  1891. }
  1892. } else {
  1893. while (nested || !stb_tokentable[*s]) {
  1894. if (!isspace(*s)) last_nonwhite = out;
  1895. if (stable[*s]) {
  1896. if (!*s) break;
  1897. if (end ? etable[*s] : nested)
  1898. --nested;
  1899. else
  1900. ++nested;
  1901. }
  1902. *out++ = *s++;
  1903. }
  1904. }
  1905. if (stripwhite) // rewind to last non-whitespace char
  1906. out = last_nonwhite+1;
  1907. *out++ = '\0';
  1908. if (*s) ++s; // skip delimiter
  1909. }
  1910. s = (unsigned char *) delimit; while (*s) stb_tokentable[*s++] = 0;
  1911. if (start) {
  1912. s = (unsigned char *) start; while (*s) stable[*s++] = 1;
  1913. s = (unsigned char *) end; if (s) while (*s) stable[*s++] = 1;
  1914. s = (unsigned char *) end; if (s) while (*s) etable[*s++] = 1;
  1915. }
  1916. if (count != NULL) *count = num;
  1917. result[num] = 0;
  1918. return result;
  1919. }
  1920. char **stb_tokens(char *src, char *delimit, int *count)
  1921. {
  1922. return stb_tokens_raw(src,delimit,count,0,0,0,0);
  1923. }
  1924. char **stb_tokens_nested(char *src, char *delimit, int *count, char *nest_in, char *nest_out)
  1925. {
  1926. return stb_tokens_raw(src,delimit,count,0,0,nest_in,nest_out);
  1927. }
  1928. char **stb_tokens_nested_empty(char *src, char *delimit, int *count, char *nest_in, char *nest_out)
  1929. {
  1930. return stb_tokens_raw(src,delimit,count,0,1,nest_in,nest_out);
  1931. }
  1932. char **stb_tokens_allowempty(char *src, char *delimit, int *count)
  1933. {
  1934. return stb_tokens_raw(src,delimit,count,0,1,0,0);
  1935. }
  1936. char **stb_tokens_stripwhite(char *src, char *delimit, int *count)
  1937. {
  1938. return stb_tokens_raw(src,delimit,count,1,1,0,0);
  1939. }
  1940. char **stb_tokens_quoted(char *src, char *delimit, int *count)
  1941. {
  1942. return stb_tokens_raw(src,delimit,count,2,1,0,0);
  1943. }
  1944. char *stb_dupreplace(char *src, char *find, char *replace)
  1945. {
  1946. size_t len_find = strlen(find);
  1947. size_t len_replace = strlen(replace);
  1948. int count = 0;
  1949. char *s,*p,*q;
  1950. s = strstr(src, find);
  1951. if (s == NULL) return strdup(src);
  1952. do {
  1953. ++count;
  1954. s = strstr(s + len_find, find);
  1955. } while (s != NULL);
  1956. p = (char *) malloc(strlen(src) + count * (len_replace - len_find) + 1);
  1957. if (p == NULL) return p;
  1958. q = p;
  1959. s = src;
  1960. for (;;) {
  1961. char *t = strstr(s, find);
  1962. if (t == NULL) {
  1963. strcpy(q,s);
  1964. assert(strlen(p) == strlen(src) + count*(len_replace-len_find));
  1965. return p;
  1966. }
  1967. memcpy(q, s, t-s);
  1968. q += t-s;
  1969. memcpy(q, replace, len_replace);
  1970. q += len_replace;
  1971. s = t + len_find;
  1972. }
  1973. }
  1974. void stb_replaceinplace(char *src, char *find, char *replace)
  1975. {
  1976. size_t len_find = strlen(find);
  1977. size_t len_replace = strlen(replace);
  1978. int delta;
  1979. char *s,*p,*q;
  1980. delta = len_replace - len_find;
  1981. assert(delta <= 0);
  1982. if (delta > 0) return;
  1983. p = strstr(src, find);
  1984. if (p == NULL) return;
  1985. s = q = p;
  1986. while (*s) {
  1987. memcpy(q, replace, len_replace);
  1988. p += len_find;
  1989. q += len_replace;
  1990. s = strstr(p, find);
  1991. if (s == NULL) s = p + strlen(p);
  1992. memmove(q, p, s-p);
  1993. q += s-p;
  1994. p = s;
  1995. }
  1996. *q = 0;
  1997. }
  1998. void stb_fixpath(char *path)
  1999. {
  2000. for(; *path; ++path)
  2001. if (*path == '\\')
  2002. *path = '/';
  2003. }
  2004. void stb__add_section(char *buffer, char *data, int curlen, int newlen)
  2005. {
  2006. if (newlen < curlen) {
  2007. int z1 = newlen >> 1, z2 = newlen-z1;
  2008. memcpy(buffer, data, z1-1);
  2009. buffer[z1-1] = '.';
  2010. buffer[z1-0] = '.';
  2011. memcpy(buffer+z1+1, data+curlen-z2+1, z2-1);
  2012. } else
  2013. memcpy(buffer, data, curlen);
  2014. }
  2015. char * stb_shorten_path_readable(char *path, int len)
  2016. {
  2017. static char buffer[1024];
  2018. int n = strlen(path),n1,n2,r1,r2;
  2019. char *s;
  2020. if (n <= len) return path;
  2021. if (len > 1024) return path;
  2022. s = stb_strrchr2(path, '/', '\\');
  2023. if (s) {
  2024. n1 = s - path + 1;
  2025. n2 = n - n1;
  2026. ++s;
  2027. } else {
  2028. n1 = 0;
  2029. n2 = n;
  2030. s = path;
  2031. }
  2032. // now we need to reduce r1 and r2 so that they fit in len
  2033. if (n1 < len>>1) {
  2034. r1 = n1;
  2035. r2 = len - r1;
  2036. } else if (n2 < len >> 1) {
  2037. r2 = n2;
  2038. r1 = len - r2;
  2039. } else {
  2040. r1 = n1 * len / n;
  2041. r2 = n2 * len / n;
  2042. if (r1 < len>>2) r1 = len>>2, r2 = len-r1;
  2043. if (r2 < len>>2) r2 = len>>2, r1 = len-r2;
  2044. }
  2045. assert(r1 <= n1 && r2 <= n2);
  2046. if (n1)
  2047. stb__add_section(buffer, path, n1, r1);
  2048. stb__add_section(buffer+r1, s, n2, r2);
  2049. buffer[len] = 0;
  2050. return buffer;
  2051. }
  2052. static char *stb__splitpath_raw(char *buffer, char *path, int flag)
  2053. {
  2054. int len=0,x,y, n = (int) strlen(path), f1,f2;
  2055. char *s = stb_strrchr2(path, '/', '\\');
  2056. char *t = strrchr(path, '.');
  2057. if (s && t && t < s) t = NULL;
  2058. if (s) ++s;
  2059. if (flag == STB_EXT_NO_PERIOD)
  2060. flag |= STB_EXT;
  2061. if (!(flag & (STB_PATH | STB_FILE | STB_EXT))) return NULL;
  2062. f1 = s == NULL ? 0 : s-path; // start of filename
  2063. f2 = t == NULL ? n : t-path; // just past end of filename
  2064. if (flag & STB_PATH) {
  2065. x = 0; if (f1 == 0 && flag == STB_PATH) len=2;
  2066. } else if (flag & STB_FILE) {
  2067. x = f1;
  2068. } else {
  2069. x = f2;
  2070. if (flag & STB_EXT_NO_PERIOD)
  2071. if (buffer[x] == '.')
  2072. ++x;
  2073. }
  2074. if (flag & STB_EXT)
  2075. y = n;
  2076. else if (flag & STB_FILE)
  2077. y = f2;
  2078. else
  2079. y = f1;
  2080. if (buffer == NULL) {
  2081. buffer = (char *) malloc(y-x + len + 1);
  2082. if (!buffer) return NULL;
  2083. }
  2084. if (len) { strcpy(buffer, "./"); return buffer; }
  2085. strncpy(buffer, path+x, y-x);
  2086. buffer[y-x] = 0;
  2087. return buffer;
  2088. }
  2089. char *stb_splitpath(char *output, char *src, int flag)
  2090. {
  2091. return stb__splitpath_raw(output, src, flag);
  2092. }
  2093. char *stb_splitpathdup(char *src, int flag)
  2094. {
  2095. return stb__splitpath_raw(NULL, src, flag);
  2096. }
  2097. char *stb_replacedir(char *output, char *src, char *dir)
  2098. {
  2099. char buffer[4096];
  2100. stb_splitpath(buffer, src, STB_FILE | STB_EXT);
  2101. if (dir)
  2102. sprintf(output, "%s/%s", dir, buffer);
  2103. else
  2104. strcpy(output, buffer);
  2105. return output;
  2106. }
  2107. char *stb_replaceext(char *output, char *src, char *ext)
  2108. {
  2109. char buffer[4096];
  2110. stb_splitpath(buffer, src, STB_PATH | STB_FILE);
  2111. if (ext)
  2112. sprintf(output, "%s.%s", buffer, ext[0] == '.' ? ext+1 : ext);
  2113. else
  2114. strcpy(output, buffer);
  2115. return output;
  2116. }
  2117. #endif
  2118. //////////////////////////////////////////////////////////////////////////////
  2119. //
  2120. // stb_alloc - hierarchical allocator
  2121. //
  2122. // inspired by http://swapped.cc/halloc
  2123. //
  2124. //
  2125. // When you alloc a given block through stb_alloc, you have these choices:
  2126. //
  2127. // 1. does it have a parent?
  2128. // 2. can it have children?
  2129. // 3. can it be freed directly?
  2130. // 4. is it transferrable?
  2131. // 5. what is its alignment?
  2132. //
  2133. // Here are interesting combinations of those:
  2134. //
  2135. // children free transfer alignment
  2136. // arena Y Y N n/a
  2137. // no-overhead, chunked N N N normal
  2138. // string pool alloc N N N 1
  2139. // parent-ptr, chunked Y N N normal
  2140. // low-overhead, unchunked N Y Y normal
  2141. // general purpose alloc Y Y Y normal
  2142. //
  2143. // Unchunked allocations will probably return 16-aligned pointers. If
  2144. // we 16-align the results, we have room for 4 pointers. For smaller
  2145. // allocations that allow finer alignment, we can reduce the pointers.
  2146. //
  2147. // The strategy is that given a pointer, assuming it has a header (only
  2148. // the no-overhead allocations have no header), we can determine the
  2149. // type of the header fields, and the number of them, by stepping backwards
  2150. // through memory and looking at the tags in the bottom bits.
  2151. //
  2152. // Implementation strategy:
  2153. // chunked allocations come from the middle of chunks, and can't
  2154. // be freed. thefore they do not need to be on a sibling chain.
  2155. // they may need child pointers if they have children.
  2156. //
  2157. // chunked, with-children
  2158. // void *parent;
  2159. //
  2160. // unchunked, no-children -- reduced storage
  2161. // void *next_sibling;
  2162. // void *prev_sibling_nextp;
  2163. //
  2164. // unchunked, general
  2165. // void *first_child;
  2166. // void *next_sibling;
  2167. // void *prev_sibling_nextp;
  2168. // void *chunks;
  2169. //
  2170. // so, if we code each of these fields with different bit patterns
  2171. // (actually same one for next/prev/child), then we can identify which
  2172. // each one is from the last field.
  2173. STB_EXTERN void stb_free(void *p);
  2174. STB_EXTERN void *stb_malloc_global(size_t size);
  2175. STB_EXTERN void *stb_malloc(void *context, size_t size);
  2176. STB_EXTERN void *stb_malloc_nofree(void *context, size_t size);
  2177. STB_EXTERN void *stb_malloc_leaf(void *context, size_t size);
  2178. STB_EXTERN void *stb_malloc_raw(void *context, size_t size);
  2179. STB_EXTERN void *stb_realloc(void *ptr, size_t newsize);
  2180. STB_EXTERN void stb_reassign(void *new_context, void *ptr);
  2181. STB_EXTERN void stb_malloc_validate(void *p, void *parent);
  2182. extern int stb_alloc_chunk_size ;
  2183. extern int stb_alloc_count_free ;
  2184. extern int stb_alloc_count_alloc;
  2185. extern int stb_alloc_alignment ;
  2186. #ifdef STB_DEFINE
  2187. int stb_alloc_chunk_size = 65536;
  2188. int stb_alloc_count_free = 0;
  2189. int stb_alloc_count_alloc = 0;
  2190. int stb_alloc_alignment = -16;
  2191. typedef struct stb__chunk
  2192. {
  2193. struct stb__chunk *next;
  2194. int data_left;
  2195. int alloc;
  2196. } stb__chunk;
  2197. typedef struct
  2198. {
  2199. void * next;
  2200. void ** prevn;
  2201. } stb__nochildren;
  2202. typedef struct
  2203. {
  2204. void ** prevn;
  2205. void * child;
  2206. void * next;
  2207. stb__chunk *chunks;
  2208. } stb__alloc;
  2209. typedef struct
  2210. {
  2211. stb__alloc *parent;
  2212. } stb__chunked;
  2213. #define STB__PARENT 1
  2214. #define STB__CHUNKS 2
  2215. typedef enum
  2216. {
  2217. STB__nochildren = 0,
  2218. STB__chunked = STB__PARENT,
  2219. STB__alloc = STB__CHUNKS,
  2220. STB__chunk_raw = 4,
  2221. } stb__alloc_type;
  2222. // these functions set the bottom bits of a pointer efficiently
  2223. #define STB__DECODE(x,v) ((void *) ((char *) (x) - (v)))
  2224. #define STB__ENCODE(x,v) ((void *) ((char *) (x) + (v)))
  2225. #define stb__parent(z) (stb__alloc *) STB__DECODE((z)->parent, STB__PARENT)
  2226. #define stb__chunks(z) (stb__chunk *) STB__DECODE((z)->chunks, STB__CHUNKS)
  2227. #define stb__setparent(z,p) (z)->parent = (stb__alloc *) STB__ENCODE((p), STB__PARENT)
  2228. #define stb__setchunks(z,c) (z)->chunks = (stb__chunk *) STB__ENCODE((c), STB__CHUNKS)
  2229. static stb__alloc stb__alloc_global =
  2230. {
  2231. NULL,
  2232. NULL,
  2233. NULL,
  2234. (stb__chunk *) STB__ENCODE(NULL, STB__CHUNKS)
  2235. };
  2236. static stb__alloc_type stb__identify(void *p)
  2237. {
  2238. void **q = (void **) p;
  2239. return (stb__alloc_type) ((stb_uinta) q[-1] & 3);
  2240. }
  2241. static void *** stb__prevn(void *p)
  2242. {
  2243. if (stb__identify(p) == STB__alloc) {
  2244. stb__alloc *s = (stb__alloc *) p - 1;
  2245. return &s->prevn;
  2246. } else {
  2247. stb__nochildren *s = (stb__nochildren *) p - 1;
  2248. return &s->prevn;
  2249. }
  2250. }
  2251. void stb_free(void *p)
  2252. {
  2253. if (p == NULL) return;
  2254. // count frees so that unit tests can see what's happening
  2255. ++stb_alloc_count_free;
  2256. switch(stb__identify(p)) {
  2257. case STB__chunked:
  2258. // freeing a chunked-block with children does nothing;
  2259. // they only get freed when the parent does
  2260. // surely this is wrong, and it should free them immediately?
  2261. // otherwise how are they getting put on the right chain?
  2262. return;
  2263. case STB__nochildren: {
  2264. stb__nochildren *s = (stb__nochildren *) p - 1;
  2265. // unlink from sibling chain
  2266. *(s->prevn) = s->next;
  2267. if (s->next)
  2268. *stb__prevn(s->next) = s->prevn;
  2269. free(s);
  2270. return;
  2271. }
  2272. case STB__alloc: {
  2273. stb__alloc *s = (stb__alloc *) p - 1;
  2274. stb__chunk *c, *n;
  2275. void *q;
  2276. // unlink from sibling chain, if any
  2277. *(s->prevn) = s->next;
  2278. if (s->next)
  2279. *stb__prevn(s->next) = s->prevn;
  2280. // first free chunks
  2281. c = (stb__chunk *) stb__chunks(s);
  2282. while (c != NULL) {
  2283. n = c->next;
  2284. stb_alloc_count_free += c->alloc;
  2285. free(c);
  2286. c = n;
  2287. }
  2288. // validating
  2289. stb__setchunks(s,NULL);
  2290. s->prevn = NULL;
  2291. s->next = NULL;
  2292. // now free children
  2293. while ((q = s->child) != NULL) {
  2294. stb_free(q);
  2295. }
  2296. // now free self
  2297. free(s);
  2298. return;
  2299. }
  2300. default:
  2301. assert(0); /* NOTREACHED */
  2302. }
  2303. }
  2304. void stb_malloc_validate(void *p, void *parent)
  2305. {
  2306. if (p == NULL) return;
  2307. switch(stb__identify(p)) {
  2308. case STB__chunked:
  2309. return;
  2310. case STB__nochildren: {
  2311. stb__nochildren *n = (stb__nochildren *) p - 1;
  2312. if (n->prevn)
  2313. assert(*n->prevn == p);
  2314. if (n->next) {
  2315. assert(*stb__prevn(n->next) == &n->next);
  2316. stb_malloc_validate(n, parent);
  2317. }
  2318. return;
  2319. }
  2320. case STB__alloc: {
  2321. stb__alloc *s = (stb__alloc *) p - 1;
  2322. if (s->prevn)
  2323. assert(*s->prevn == p);
  2324. if (s->child) {
  2325. assert(*stb__prevn(s->child) == &s->child);
  2326. stb_malloc_validate(s->child, p);
  2327. }
  2328. if (s->next) {
  2329. assert(*stb__prevn(s->next) == &s->next);
  2330. stb_malloc_validate(s->next, parent);
  2331. }
  2332. return;
  2333. }
  2334. default:
  2335. assert(0); /* NOTREACHED */
  2336. }
  2337. }
  2338. static void * stb__try_chunk(stb__chunk *c, int size, int align, int pre_align)
  2339. {
  2340. char *memblock = (char *) (c+1), *q;
  2341. stb_inta iq;
  2342. int start_offset;
  2343. // we going to allocate at the end of the chunk, not the start. confusing,
  2344. // but it means we don't need both a 'limit' and a 'cur', just a 'cur'.
  2345. // the block ends at: p + c->data_left
  2346. // then we move back by size
  2347. start_offset = c->data_left - size;
  2348. // now we need to check the alignment of that
  2349. q = memblock + start_offset;
  2350. iq = (stb_inta) q;
  2351. assert(sizeof(q) == sizeof(iq));
  2352. // suppose align = 2
  2353. // then we need to retreat iq far enough that (iq & (2-1)) == 0
  2354. // to get (iq & (align-1)) = 0 requires subtracting (iq & (align-1))
  2355. start_offset -= iq & (align-1);
  2356. assert(((stb_uinta) (memblock+start_offset) & (align-1)) == 0);
  2357. // now, if that + pre_align works, go for it!
  2358. start_offset -= pre_align;
  2359. if (start_offset >= 0) {
  2360. c->data_left = start_offset;
  2361. return memblock + start_offset;
  2362. }
  2363. return NULL;
  2364. }
  2365. static void stb__sort_chunks(stb__alloc *src)
  2366. {
  2367. // of the first two chunks, put the chunk with more data left in it first
  2368. stb__chunk *c = stb__chunks(src), *d;
  2369. if (c == NULL) return;
  2370. d = c->next;
  2371. if (d == NULL) return;
  2372. if (c->data_left > d->data_left) return;
  2373. c->next = d->next;
  2374. d->next = c;
  2375. stb__setchunks(src, d);
  2376. }
  2377. static void * stb__alloc_chunk(stb__alloc *src, int size, int align, int pre_align)
  2378. {
  2379. void *p;
  2380. stb__chunk *c = stb__chunks(src);
  2381. if (c && size <= stb_alloc_chunk_size) {
  2382. p = stb__try_chunk(c, size, align, pre_align);
  2383. if (p) { ++c->alloc; return p; }
  2384. // try a second chunk to reduce wastage
  2385. if (c->next) {
  2386. p = stb__try_chunk(c->next, size, align, pre_align);
  2387. if (p) { ++c->alloc; return p; }
  2388. // put the bigger chunk first, since the second will get buried
  2389. // the upshot of this is that, until it gets allocated from, chunk #2
  2390. // is always the largest remaining chunk. (could formalize
  2391. // this with a heap!)
  2392. stb__sort_chunks(src);
  2393. c = stb__chunks(src);
  2394. }
  2395. }
  2396. // allocate a new chunk
  2397. {
  2398. stb__chunk *n;
  2399. int chunk_size = stb_alloc_chunk_size;
  2400. // we're going to allocate a new chunk to put this in
  2401. if (size > chunk_size)
  2402. chunk_size = size;
  2403. assert(sizeof(*n) + pre_align <= 16);
  2404. // loop trying to allocate a large enough chunk
  2405. // the loop is because the alignment may cause problems if it's big...
  2406. // and we don't know what our chunk alignment is going to be
  2407. while (1) {
  2408. n = (stb__chunk *) malloc(16 + chunk_size);
  2409. if (n == NULL) return NULL;
  2410. n->data_left = chunk_size - sizeof(*n);
  2411. p = stb__try_chunk(n, size, align, pre_align);
  2412. if (p != NULL) {
  2413. n->next = c;
  2414. stb__setchunks(src, n);
  2415. // if we just used up the whole block immediately,
  2416. // move the following chunk up
  2417. n->alloc = 1;
  2418. if (size == chunk_size)
  2419. stb__sort_chunks(src);
  2420. return p;
  2421. }
  2422. free(n);
  2423. chunk_size += 16+align;
  2424. }
  2425. }
  2426. }
  2427. static stb__alloc * stb__get_context(void *context)
  2428. {
  2429. if (context == NULL) {
  2430. return &stb__alloc_global;
  2431. } else {
  2432. int u = stb__identify(context);
  2433. // if context is chunked, grab parent
  2434. if (u == STB__chunked) {
  2435. stb__chunked *s = (stb__chunked *) context - 1;
  2436. return stb__parent(s);
  2437. } else {
  2438. return (stb__alloc *) context - 1;
  2439. }
  2440. }
  2441. }
  2442. static void stb__insert_alloc(stb__alloc *src, stb__alloc *s)
  2443. {
  2444. s->prevn = &src->child;
  2445. s->next = src->child;
  2446. src->child = s+1;
  2447. if (s->next)
  2448. *stb__prevn(s->next) = &s->next;
  2449. }
  2450. static void stb__insert_nochild(stb__alloc *src, stb__nochildren *s)
  2451. {
  2452. s->prevn = &src->child;
  2453. s->next = src->child;
  2454. src->child = s+1;
  2455. if (s->next)
  2456. *stb__prevn(s->next) = &s->next;
  2457. }
  2458. static void * malloc_base(void *context, size_t size, stb__alloc_type t, int align)
  2459. {
  2460. void *p;
  2461. stb__alloc *src = stb__get_context(context);
  2462. if (align <= 0) {
  2463. // compute worst-case C packed alignment
  2464. // e.g. a 24-byte struct is 8-aligned
  2465. int align_proposed = 1 << stb_lowbit8(size);
  2466. if (align_proposed < 0)
  2467. align_proposed = 4;
  2468. if (align_proposed == 0) {
  2469. if (size == 0)
  2470. align_proposed = 1;
  2471. else
  2472. align_proposed = 256;
  2473. }
  2474. // a negative alignment means 'don't align any larger
  2475. // than this'; so -16 means we align 1,2,4,8, or 16
  2476. if (align < 0) {
  2477. if (align_proposed > -align)
  2478. align_proposed = -align;
  2479. }
  2480. align = align_proposed;
  2481. }
  2482. assert(stb_is_pow2(align));
  2483. // don't cause misalignment when allocating nochildren
  2484. if (t == STB__nochildren && align > 8)
  2485. t = STB__alloc;
  2486. switch (t) {
  2487. case STB__alloc: {
  2488. stb__alloc *s = (stb__alloc *) malloc(size + sizeof(*s));
  2489. if (s == NULL) return NULL;
  2490. p = s+1;
  2491. s->child = NULL;
  2492. stb__insert_alloc(src, s);
  2493. stb__setchunks(s,NULL);
  2494. break;
  2495. }
  2496. case STB__nochildren: {
  2497. stb__nochildren *s = (stb__nochildren *) malloc(size + sizeof(*s));
  2498. if (s == NULL) return NULL;
  2499. p = s+1;
  2500. stb__insert_nochild(src, s);
  2501. break;
  2502. }
  2503. case STB__chunk_raw: {
  2504. p = stb__alloc_chunk(src, size, align, 0);
  2505. if (p == NULL) return NULL;
  2506. break;
  2507. }
  2508. case STB__chunked: {
  2509. stb__chunked *s;
  2510. if (align < sizeof(stb_uintptr)) align = sizeof(stb_uintptr);
  2511. s = (stb__chunked *) stb__alloc_chunk(src, size, align, sizeof(*s));
  2512. if (s == NULL) return NULL;
  2513. stb__setparent(s, src);
  2514. p = s+1;
  2515. break;
  2516. }
  2517. default: p = NULL; assert(0); /* NOTREACHED */
  2518. }
  2519. ++stb_alloc_count_alloc;
  2520. return p;
  2521. }
  2522. void *stb_malloc_global(size_t size)
  2523. {
  2524. return malloc_base(NULL, size, STB__alloc, stb_alloc_alignment);
  2525. }
  2526. void *stb_malloc(void *context, size_t size)
  2527. {
  2528. return malloc_base(context, size, STB__alloc, stb_alloc_alignment);
  2529. }
  2530. void *stb_malloc_nofree(void *context, size_t size)
  2531. {
  2532. return malloc_base(context, size, STB__chunked, stb_alloc_alignment);
  2533. }
  2534. void *stb_malloc_leaf(void *context, size_t size)
  2535. {
  2536. return malloc_base(context, size, STB__nochildren, stb_alloc_alignment);
  2537. }
  2538. void *stb_malloc_raw(void *context, size_t size)
  2539. {
  2540. return malloc_base(context, size, STB__chunk_raw, stb_alloc_alignment);
  2541. }
  2542. char *stb_malloc_string(void *context, size_t size)
  2543. {
  2544. return (char *) malloc_base(context, size, STB__chunk_raw, 1);
  2545. }
  2546. void *stb_realloc(void *ptr, size_t newsize)
  2547. {
  2548. stb__alloc_type t;
  2549. if (ptr == NULL) return stb_malloc(NULL, newsize);
  2550. if (newsize == 0) { stb_free(ptr); return NULL; }
  2551. t = stb__identify(ptr);
  2552. assert(t == STB__alloc || t == STB__nochildren);
  2553. if (t == STB__alloc) {
  2554. stb__alloc *s = (stb__alloc *) ptr - 1;
  2555. s = (stb__alloc *) realloc(s, newsize + sizeof(*s));
  2556. if (s == NULL) return NULL;
  2557. ptr = s+1;
  2558. // update pointers
  2559. (*s->prevn) = ptr;
  2560. if (s->next)
  2561. *stb__prevn(s->next) = &s->next;
  2562. if (s->child)
  2563. *stb__prevn(s->child) = &s->child;
  2564. return ptr;
  2565. } else {
  2566. stb__nochildren *s = (stb__nochildren *) ptr - 1;
  2567. s = (stb__nochildren *) realloc(ptr, newsize + sizeof(s));
  2568. if (s == NULL) return NULL;
  2569. // update pointers
  2570. (*s->prevn) = s+1;
  2571. if (s->next)
  2572. *stb__prevn(s->next) = &s->next;
  2573. return s+1;
  2574. }
  2575. }
  2576. void *stb_realloc_c(void *context, void *ptr, size_t newsize)
  2577. {
  2578. if (ptr == NULL) return stb_malloc(context, newsize);
  2579. if (newsize == 0) { stb_free(ptr); return NULL; }
  2580. // @TODO: verify you haven't changed contexts
  2581. return stb_realloc(ptr, newsize);
  2582. }
  2583. void stb_reassign(void *new_context, void *ptr)
  2584. {
  2585. stb__alloc *src = stb__get_context(new_context);
  2586. stb__alloc_type t = stb__identify(ptr);
  2587. assert(t == STB__alloc || t == STB__nochildren);
  2588. if (t == STB__alloc) {
  2589. stb__alloc *s = (stb__alloc *) ptr - 1;
  2590. // unlink from old
  2591. *(s->prevn) = s->next;
  2592. if (s->next)
  2593. *stb__prevn(s->next) = s->prevn;
  2594. stb__insert_alloc(src, s);
  2595. } else {
  2596. stb__nochildren *s = (stb__nochildren *) ptr - 1;
  2597. // unlink from old
  2598. *(s->prevn) = s->next;
  2599. if (s->next)
  2600. *stb__prevn(s->next) = s->prevn;
  2601. stb__insert_nochild(src, s);
  2602. }
  2603. }
  2604. #endif
  2605. //////////////////////////////////////////////////////////////////////////////
  2606. //
  2607. // stb_arr
  2608. //
  2609. // An stb_arr is directly useable as a pointer (use the actual type in your
  2610. // definition), but when it resizes, it returns a new pointer and you can't
  2611. // use the old one, so you have to be careful to copy-in-out as necessary.
  2612. //
  2613. // Use a NULL pointer as a 0-length array.
  2614. //
  2615. // float *my_array = NULL, *temp;
  2616. //
  2617. // // add elements on the end one at a time
  2618. // stb_arr_push(my_array, 0.0f);
  2619. // stb_arr_push(my_array, 1.0f);
  2620. // stb_arr_push(my_array, 2.0f);
  2621. //
  2622. // assert(my_array[1] == 2.0f);
  2623. //
  2624. // // add an uninitialized element at the end, then assign it
  2625. // *stb_arr_add(my_array) = 3.0f;
  2626. //
  2627. // // add three uninitialized elements at the end
  2628. // temp = stb_arr_addn(my_array,3);
  2629. // temp[0] = 4.0f;
  2630. // temp[1] = 5.0f;
  2631. // temp[2] = 6.0f;
  2632. //
  2633. // assert(my_array[5] == 5.0f);
  2634. //
  2635. // // remove the last one
  2636. // stb_arr_pop(my_array);
  2637. //
  2638. // assert(stb_arr_len(my_array) == 6);
  2639. #ifdef STB_MALLOC_WRAPPER
  2640. #define STB__PARAMS , char *file, int line
  2641. #define STB__ARGS , file, line
  2642. #else
  2643. #define STB__PARAMS
  2644. #define STB__ARGS
  2645. #endif
  2646. // calling this function allocates an empty stb_arr attached to p
  2647. // (whereas NULL isn't attached to anything)
  2648. STB_EXTERN void stb_arr_malloc(void **target, void *context);
  2649. // call this function with a non-NULL value to have all successive
  2650. // stbs that are created be attached to the associated parent. Note
  2651. // that once a given stb_arr is non-empty, it stays attached to its
  2652. // current parent, even if you call this function again.
  2653. // it turns the previous value, so you can restore it
  2654. STB_EXTERN void* stb_arr_malloc_parent(void *p);
  2655. // simple functions written on top of other functions
  2656. #define stb_arr_empty(a) ( stb_arr_len(a) == 0 )
  2657. #define stb_arr_add(a) ( stb_arr_addn((a),1) )
  2658. #define stb_arr_push(a,v) ( *stb_arr_add(a)=(v) )
  2659. typedef struct
  2660. {
  2661. int len, limit;
  2662. int stb_malloc;
  2663. unsigned int signature;
  2664. } stb__arr;
  2665. #define stb_arr_signature 0x51bada7b // ends with 0123 in decimal
  2666. // access the header block stored before the data
  2667. #define stb_arrhead(a) /*lint --e(826)*/ (((stb__arr *) (a)) - 1)
  2668. #define stb_arrhead2(a) /*lint --e(826)*/ (((stb__arr *) (a)) - 1)
  2669. #ifdef STB_DEBUG
  2670. #define stb_arr_check(a) assert(!a || stb_arrhead(a)->signature == stb_arr_signature)
  2671. #define stb_arr_check2(a) assert(!a || stb_arrhead2(a)->signature == stb_arr_signature)
  2672. #else
  2673. #define stb_arr_check(a) ((void) 0)
  2674. #define stb_arr_check2(a) ((void) 0)
  2675. #endif
  2676. // ARRAY LENGTH
  2677. // get the array length; special case if pointer is NULL
  2678. #define stb_arr_len(a) (a ? stb_arrhead(a)->len : 0)
  2679. #define stb_arr_len2(a) ((stb__arr *) (a) ? stb_arrhead2(a)->len : 0)
  2680. #define stb_arr_lastn(a) (stb_arr_len(a)-1)
  2681. // check whether a given index is valid -- tests 0 <= i < stb_arr_len(a)
  2682. #define stb_arr_valid(a,i) (a ? (int) (i) < stb_arrhead(a)->len : 0)
  2683. // change the array length so is is exactly N entries long, creating
  2684. // uninitialized entries as needed
  2685. #define stb_arr_setlen(a,n) \
  2686. (stb__arr_setlen((void **) &(a), sizeof(a[0]), (n)))
  2687. // change the array length so that N is a valid index (that is, so
  2688. // it is at least N entries long), creating uninitialized entries as needed
  2689. #define stb_arr_makevalid(a,n) \
  2690. (stb_arr_len(a) < (n)+1 ? stb_arr_setlen(a,(n)+1),(a) : (a))
  2691. // remove the last element of the array, returning it
  2692. #define stb_arr_pop(a) ((stb_arr_check(a), (a))[--stb_arrhead(a)->len])
  2693. // access the last element in the array
  2694. #define stb_arr_last(a) ((stb_arr_check(a), (a))[stb_arr_len(a)-1])
  2695. // is iterator at end of list?
  2696. #define stb_arr_end(a,i) ((i) >= &(a)[stb_arr_len(a)])
  2697. // (internal) change the allocated length of the array
  2698. #define stb_arr__grow(a,n) (stb_arr_check(a), stb_arrhead(a)->len += (n))
  2699. // add N new unitialized elements to the end of the array
  2700. #define stb_arr__addn(a,n) /*lint --e(826)*/ \
  2701. ((stb_arr_len(a)+(n) > stb_arrcurmax(a)) \
  2702. ? (stb__arr_addlen((void **) &(a),sizeof(*a),(n)),0) \
  2703. : ((stb_arr__grow(a,n), 0)))
  2704. // add N new unitialized elements to the end of the array, and return
  2705. // a pointer to the first new one
  2706. #define stb_arr_addn(a,n) (stb_arr__addn((a),n),(a)+stb_arr_len(a)-(n))
  2707. // add N new uninitialized elements starting at index 'i'
  2708. #define stb_arr_insertn(a,i,n) (stb__arr_insertn((void **) &(a), sizeof(*a), i, n))
  2709. // insert an element at i
  2710. #define stb_arr_insert(a,i,v) (stb__arr_insertn((void **) &(a), sizeof(*a), i, 1), ((a)[i] = v))
  2711. // delete N elements from the middle starting at index 'i'
  2712. #define stb_arr_deleten(a,i,n) (stb__arr_deleten((void **) &(a), sizeof(*a), i, n))
  2713. // delete the i'th element
  2714. #define stb_arr_delete(a,i) stb_arr_deleten(a,i,1)
  2715. // delete the i'th element, swapping down from the end
  2716. #define stb_arr_fastdelete(a,i) \
  2717. (stb_swap(&a[i], &a[stb_arrhead(a)->len-1], sizeof(*a)), stb_arr_pop(a))
  2718. // ARRAY STORAGE
  2719. // get the array maximum storage; special case if NULL
  2720. #define stb_arrcurmax(a) (a ? stb_arrhead(a)->limit : 0)
  2721. #define stb_arrcurmax2(a) (a ? stb_arrhead2(a)->limit : 0)
  2722. // set the maxlength of the array to n in anticipation of further growth
  2723. #define stb_arr_setsize(a,n) (stb_arr_check(a), stb__arr_setsize((void **) &(a),sizeof((a)[0]),n))
  2724. // make sure maxlength is large enough for at least N new allocations
  2725. #define stb_arr_atleast(a,n) (stb_arr_len(a)+(n) > stb_arrcurmax(a) \
  2726. ? stb_arr_setsize((a), (n)) : 0)
  2727. // make a copy of a given array (copies contents via 'memcpy'!)
  2728. #define stb_arr_copy(a) stb__arr_copy(a, sizeof((a)[0]))
  2729. // compute the storage needed to store all the elements of the array
  2730. #define stb_arr_storage(a) (stb_arr_len(a) * sizeof((a)[0]))
  2731. #define stb_arr_for(v,arr) for((v)=(arr); (v) < (arr)+stb_arr_len(arr); ++(v))
  2732. // IMPLEMENTATION
  2733. STB_EXTERN void stb_arr_free_(void **p);
  2734. STB_EXTERN void *stb__arr_copy_(void *p, int elem_size);
  2735. STB_EXTERN void stb__arr_setsize_(void **p, int size, int limit STB__PARAMS);
  2736. STB_EXTERN void stb__arr_setlen_(void **p, int size, int newlen STB__PARAMS);
  2737. STB_EXTERN void stb__arr_addlen_(void **p, int size, int addlen STB__PARAMS);
  2738. STB_EXTERN void stb__arr_deleten_(void **p, int size, int loc, int n STB__PARAMS);
  2739. STB_EXTERN void stb__arr_insertn_(void **p, int size, int loc, int n STB__PARAMS);
  2740. #define stb_arr_free(p) stb_arr_free_((void **) &(p))
  2741. #define stb__arr_copy stb__arr_copy_
  2742. #ifndef STB_MALLOC_WRAPPER
  2743. #define stb__arr_setsize stb__arr_setsize_
  2744. #define stb__arr_setlen stb__arr_setlen_
  2745. #define stb__arr_addlen stb__arr_addlen_
  2746. #define stb__arr_deleten stb__arr_deleten_
  2747. #define stb__arr_insertn stb__arr_insertn_
  2748. #else
  2749. #define stb__arr_addlen(p,s,n) stb__arr_addlen_(p,s,n,__FILE__,__LINE__)
  2750. #define stb__arr_setlen(p,s,n) stb__arr_setlen_(p,s,n,__FILE__,__LINE__)
  2751. #define stb__arr_setsize(p,s,n) stb__arr_setsize_(p,s,n,__FILE__,__LINE__)
  2752. #define stb__arr_deleten(p,s,i,n) stb__arr_deleten_(p,s,i,n,__FILE__,__LINE__)
  2753. #define stb__arr_insertn(p,s,i,n) stb__arr_insertn_(p,s,i,n,__FILE__,__LINE__)
  2754. #endif
  2755. #ifdef STB_DEFINE
  2756. static void *stb__arr_context;
  2757. void *stb_arr_malloc_parent(void *p)
  2758. {
  2759. void *q = stb__arr_context;
  2760. stb__arr_context = p;
  2761. return q;
  2762. }
  2763. void stb_arr_malloc(void **target, void *context)
  2764. {
  2765. stb__arr *q = (stb__arr *) stb_malloc(context, sizeof(*q));
  2766. q->len = q->limit = 0;
  2767. q->stb_malloc = 1;
  2768. q->signature = stb_arr_signature;
  2769. *target = (void *) (q+1);
  2770. }
  2771. static void * stb__arr_malloc(int size)
  2772. {
  2773. if (stb__arr_context)
  2774. return stb_malloc(stb__arr_context, size);
  2775. return malloc(size);
  2776. }
  2777. void * stb__arr_copy_(void *p, int elem_size)
  2778. {
  2779. stb__arr *q;
  2780. if (p == NULL) return p;
  2781. q = (stb__arr *) stb__arr_malloc(sizeof(*q) + elem_size * stb_arrhead2(p)->limit);
  2782. stb_arr_check2(p);
  2783. memcpy(q, stb_arrhead2(p), sizeof(*q) + elem_size * stb_arrhead2(p)->len);
  2784. q->stb_malloc = !!stb__arr_context;
  2785. return q+1;
  2786. }
  2787. void stb_arr_free_(void **pp)
  2788. {
  2789. void *p = *pp;
  2790. stb_arr_check2(p);
  2791. if (p) {
  2792. stb__arr *q = stb_arrhead2(p);
  2793. if (q->stb_malloc)
  2794. stb_free(q);
  2795. else
  2796. free(q);
  2797. }
  2798. *pp = NULL;
  2799. }
  2800. static void stb__arrsize_(void **pp, int size, int limit, int len STB__PARAMS)
  2801. {
  2802. void *p = *pp;
  2803. stb__arr *a;
  2804. stb_arr_check2(p);
  2805. if (p == NULL) {
  2806. if (len == 0 && size == 0) return;
  2807. a = (stb__arr *) stb__arr_malloc(sizeof(*a) + size*limit);
  2808. a->limit = limit;
  2809. a->len = len;
  2810. a->stb_malloc = !!stb__arr_context;
  2811. a->signature = stb_arr_signature;
  2812. } else {
  2813. a = stb_arrhead2(p);
  2814. a->len = len;
  2815. if (a->limit < limit) {
  2816. void *p;
  2817. if (a->limit >= 4 && limit < a->limit * 2)
  2818. limit = a->limit * 2;
  2819. if (a->stb_malloc)
  2820. p = stb_realloc(a, sizeof(*a) + limit*size);
  2821. else
  2822. #ifdef STB_MALLOC_WRAPPER
  2823. p = stb__realloc(a, sizeof(*a) + limit*size, file, line);
  2824. #else
  2825. p = realloc(a, sizeof(*a) + limit*size);
  2826. #endif
  2827. if (p) {
  2828. a = (stb__arr *) p;
  2829. a->limit = limit;
  2830. } else {
  2831. // throw an error!
  2832. }
  2833. }
  2834. }
  2835. a->len = stb_min(a->len, a->limit);
  2836. *pp = a+1;
  2837. }
  2838. void stb__arr_setsize_(void **pp, int size, int limit STB__PARAMS)
  2839. {
  2840. void *p = *pp;
  2841. stb_arr_check2(p);
  2842. stb__arrsize_(pp, size, limit, stb_arr_len2(p) STB__ARGS);
  2843. }
  2844. void stb__arr_setlen_(void **pp, int size, int newlen STB__PARAMS)
  2845. {
  2846. void *p = *pp;
  2847. stb_arr_check2(p);
  2848. if (stb_arrcurmax2(p) < newlen || p == NULL) {
  2849. stb__arrsize_(pp, size, newlen, newlen STB__ARGS);
  2850. } else {
  2851. stb_arrhead2(p)->len = newlen;
  2852. }
  2853. }
  2854. void stb__arr_addlen_(void **p, int size, int addlen STB__PARAMS)
  2855. {
  2856. stb__arr_setlen_(p, size, stb_arr_len2(*p) + addlen STB__ARGS);
  2857. }
  2858. void stb__arr_insertn_(void **pp, int size, int i, int n STB__PARAMS)
  2859. {
  2860. void *p = *pp;
  2861. if (n) {
  2862. int z;
  2863. if (p == NULL) {
  2864. stb__arr_addlen_(pp, size, n STB__ARGS);
  2865. return;
  2866. }
  2867. z = stb_arr_len2(p);
  2868. stb__arr_addlen_(&p, size, n STB__ARGS);
  2869. memmove((char *) p + (i+n)*size, (char *) p + i*size, size * (z-i));
  2870. }
  2871. *pp = p;
  2872. }
  2873. void stb__arr_deleten_(void **pp, int size, int i, int n STB__PARAMS)
  2874. {
  2875. void *p = *pp;
  2876. if (n) {
  2877. memmove((char *) p + i*size, (char *) p + (i+n)*size, size * (stb_arr_len2(p)-(i+n)));
  2878. stb_arrhead2(p)->len -= n;
  2879. }
  2880. *pp = p;
  2881. }
  2882. #endif
  2883. //////////////////////////////////////////////////////////////////////////////
  2884. //
  2885. // Hashing
  2886. //
  2887. // typical use for this is to make a power-of-two hash table.
  2888. //
  2889. // let N = size of table (2^n)
  2890. // let H = stb_hash(str)
  2891. // let S = stb_rehash(H) | 1
  2892. //
  2893. // then hash probe sequence P(i) for i=0..N-1
  2894. // P(i) = (H + S*i) & (N-1)
  2895. //
  2896. // the idea is that H has 32 bits of hash information, but the
  2897. // table has only, say, 2^20 entries so only uses 20 of the bits.
  2898. // then by rehashing the original H we get 2^12 different probe
  2899. // sequences for a given initial probe location. (So it's optimal
  2900. // for 64K tables and its optimality decreases past that.)
  2901. //
  2902. // ok, so I've added something that generates _two separate_
  2903. // 32-bit hashes simultaneously which should scale better to
  2904. // very large tables.
  2905. STB_EXTERN unsigned int stb_hash(char *str);
  2906. STB_EXTERN unsigned int stb_hashptr(void *p);
  2907. STB_EXTERN unsigned int stb_hashlen(char *str, int len);
  2908. STB_EXTERN unsigned int stb_rehash_improved(unsigned int v);
  2909. STB_EXTERN unsigned int stb_hash_fast(void *p, int len);
  2910. STB_EXTERN unsigned int stb_hash2(char *str, unsigned int *hash2_ptr);
  2911. STB_EXTERN unsigned int stb_hash_number(unsigned int hash);
  2912. #define stb_rehash(x) ((x) + ((x) >> 6) + ((x) >> 19))
  2913. #ifdef STB_DEFINE
  2914. unsigned int stb_hash(char *str)
  2915. {
  2916. unsigned int hash = 0;
  2917. while (*str)
  2918. hash = (hash << 7) + (hash >> 25) + *str++;
  2919. return hash + (hash >> 16);
  2920. }
  2921. unsigned int stb_hashlen(char *str, int len)
  2922. {
  2923. unsigned int hash = 0;
  2924. while (len-- > 0 && *str)
  2925. hash = (hash << 7) + (hash >> 25) + *str++;
  2926. return hash + (hash >> 16);
  2927. }
  2928. unsigned int stb_hashptr(void *p)
  2929. {
  2930. unsigned int x = (unsigned int)(size_t) p;
  2931. // typically lacking in low bits and high bits
  2932. x = stb_rehash(x);
  2933. x += x << 16;
  2934. // pearson's shuffle
  2935. x ^= x << 3;
  2936. x += x >> 5;
  2937. x ^= x << 2;
  2938. x += x >> 15;
  2939. x ^= x << 10;
  2940. return stb_rehash(x);
  2941. }
  2942. unsigned int stb_rehash_improved(unsigned int v)
  2943. {
  2944. return stb_hashptr((void *)(size_t) v);
  2945. }
  2946. unsigned int stb_hash2(char *str, unsigned int *hash2_ptr)
  2947. {
  2948. unsigned int hash1 = 0x3141592c;
  2949. unsigned int hash2 = 0x77f044ed;
  2950. while (*str) {
  2951. hash1 = (hash1 << 7) + (hash1 >> 25) + *str;
  2952. hash2 = (hash2 << 11) + (hash2 >> 21) + *str;
  2953. ++str;
  2954. }
  2955. *hash2_ptr = hash2 + (hash1 >> 16);
  2956. return hash1 + (hash2 >> 16);
  2957. }
  2958. // Paul Hsieh hash
  2959. #define stb__get16_slow(p) ((p)[0] + ((p)[1] << 8))
  2960. #if defined(_MSC_VER)
  2961. #define stb__get16(p) (*((unsigned short *) (p)))
  2962. #else
  2963. #define stb__get16(p) stb__get16_slow(p)
  2964. #endif
  2965. unsigned int stb_hash_fast(void *p, int len)
  2966. {
  2967. unsigned char *q = (unsigned char *) p;
  2968. unsigned int hash = len;
  2969. if (len <= 0 || q == NULL) return 0;
  2970. /* Main loop */
  2971. if (((int)(size_t) q & 1) == 0) {
  2972. for (;len > 3; len -= 4) {
  2973. unsigned int val;
  2974. hash += stb__get16(q);
  2975. val = (stb__get16(q+2) << 11);
  2976. hash = (hash << 16) ^ hash ^ val;
  2977. q += 4;
  2978. hash += hash >> 11;
  2979. }
  2980. } else {
  2981. for (;len > 3; len -= 4) {
  2982. unsigned int val;
  2983. hash += stb__get16_slow(q);
  2984. val = (stb__get16_slow(q+2) << 11);
  2985. hash = (hash << 16) ^ hash ^ val;
  2986. q += 4;
  2987. hash += hash >> 11;
  2988. }
  2989. }
  2990. /* Handle end cases */
  2991. switch (len) {
  2992. case 3: hash += stb__get16_slow(q);
  2993. hash ^= hash << 16;
  2994. hash ^= q[2] << 18;
  2995. hash += hash >> 11;
  2996. break;
  2997. case 2: hash += stb__get16_slow(q);
  2998. hash ^= hash << 11;
  2999. hash += hash >> 17;
  3000. break;
  3001. case 1: hash += q[0];
  3002. hash ^= hash << 10;
  3003. hash += hash >> 1;
  3004. break;
  3005. case 0: break;
  3006. }
  3007. /* Force "avalanching" of final 127 bits */
  3008. hash ^= hash << 3;
  3009. hash += hash >> 5;
  3010. hash ^= hash << 4;
  3011. hash += hash >> 17;
  3012. hash ^= hash << 25;
  3013. hash += hash >> 6;
  3014. return hash;
  3015. }
  3016. unsigned int stb_hash_number(unsigned int hash)
  3017. {
  3018. hash ^= hash << 3;
  3019. hash += hash >> 5;
  3020. hash ^= hash << 4;
  3021. hash += hash >> 17;
  3022. hash ^= hash << 25;
  3023. hash += hash >> 6;
  3024. return hash;
  3025. }
  3026. #endif
  3027. //////////////////////////////////////////////////////////////////////////////
  3028. //
  3029. // Perfect hashing for ints/pointers
  3030. //
  3031. // This is mainly useful for making faster pointer-indexed tables
  3032. // that don't change frequently. E.g. for stb_ischar().
  3033. //
  3034. typedef struct
  3035. {
  3036. stb_uint32 addend;
  3037. stb_uint multiplicand;
  3038. stb_uint b_mask;
  3039. stb_uint8 small_bmap[16];
  3040. stb_uint16 *large_bmap;
  3041. stb_uint table_mask;
  3042. stb_uint32 *table;
  3043. } stb_perfect;
  3044. STB_EXTERN int stb_perfect_create(stb_perfect *,unsigned int*,int n);
  3045. STB_EXTERN void stb_perfect_destroy(stb_perfect *);
  3046. STB_EXTERN int stb_perfect_hash(stb_perfect *, unsigned int x);
  3047. extern int stb_perfect_hash_max_failures;
  3048. #ifdef STB_DEFINE
  3049. int stb_perfect_hash_max_failures;
  3050. int stb_perfect_hash(stb_perfect *p, unsigned int x)
  3051. {
  3052. stb_uint m = x * p->multiplicand;
  3053. stb_uint y = x >> 16;
  3054. stb_uint bv = (m >> 24) + y;
  3055. stb_uint av = (m + y) >> 12;
  3056. if (p->table == NULL) return -1; // uninitialized table fails
  3057. bv &= p->b_mask;
  3058. av &= p->table_mask;
  3059. if (p->large_bmap)
  3060. av ^= p->large_bmap[bv];
  3061. else
  3062. av ^= p->small_bmap[bv];
  3063. return p->table[av] == x ? av : -1;
  3064. }
  3065. static void stb__perfect_prehash(stb_perfect *p, stb_uint x, stb_uint16 *a, stb_uint16 *b)
  3066. {
  3067. stb_uint m = x * p->multiplicand;
  3068. stb_uint y = x >> 16;
  3069. stb_uint bv = (m >> 24) + y;
  3070. stb_uint av = (m + y) >> 12;
  3071. bv &= p->b_mask;
  3072. av &= p->table_mask;
  3073. *b = bv;
  3074. *a = av;
  3075. }
  3076. static unsigned long stb__perfect_rand(void)
  3077. {
  3078. static unsigned long stb__rand;
  3079. stb__rand = stb__rand * 2147001325 + 715136305;
  3080. return 0x31415926 ^ ((stb__rand >> 16) + (stb__rand << 16));
  3081. }
  3082. typedef struct {
  3083. unsigned short count;
  3084. unsigned short b;
  3085. unsigned short map;
  3086. unsigned short *entries;
  3087. } stb__slot;
  3088. static int stb__slot_compare(const void *p, const void *q)
  3089. {
  3090. stb__slot *a = (stb__slot *) p;
  3091. stb__slot *b = (stb__slot *) q;
  3092. return a->count > b->count ? -1 : a->count < b->count; // sort large to small
  3093. }
  3094. int stb_perfect_create(stb_perfect *p, unsigned int *v, int n)
  3095. {
  3096. unsigned int buffer1[64], buffer2[64], buffer3[64], buffer4[64], buffer5[32];
  3097. unsigned short *as = (unsigned short *) stb_temp(buffer1, sizeof(*v)*n);
  3098. unsigned short *bs = (unsigned short *) stb_temp(buffer2, sizeof(*v)*n);
  3099. unsigned short *entries = (unsigned short *) stb_temp(buffer4, sizeof(*entries) * n);
  3100. int size = 1 << stb_log2_ceil(n), bsize=8;
  3101. int failure = 0,i,j,k;
  3102. assert(n <= 32768);
  3103. p->large_bmap = NULL;
  3104. for(;;) {
  3105. stb__slot *bcount = (stb__slot *) stb_temp(buffer3, sizeof(*bcount) * bsize);
  3106. unsigned short *bloc = (unsigned short *) stb_temp(buffer5, sizeof(*bloc) * bsize);
  3107. unsigned short *e;
  3108. int bad=0;
  3109. p->addend = stb__perfect_rand();
  3110. p->multiplicand = stb__perfect_rand() | 1;
  3111. p->table_mask = size-1;
  3112. p->b_mask = bsize-1;
  3113. p->table = (stb_uint32 *) malloc(size * sizeof(*p->table));
  3114. for (i=0; i < bsize; ++i) {
  3115. bcount[i].b = i;
  3116. bcount[i].count = 0;
  3117. bcount[i].map = 0;
  3118. }
  3119. for (i=0; i < n; ++i) {
  3120. stb__perfect_prehash(p, v[i], as+i, bs+i);
  3121. ++bcount[bs[i]].count;
  3122. }
  3123. qsort(bcount, bsize, sizeof(*bcount), stb__slot_compare);
  3124. e = entries; // now setup up their entries index
  3125. for (i=0; i < bsize; ++i) {
  3126. bcount[i].entries = e;
  3127. e += bcount[i].count;
  3128. bcount[i].count = 0;
  3129. bloc[bcount[i].b] = i;
  3130. }
  3131. // now fill them out
  3132. for (i=0; i < n; ++i) {
  3133. int b = bs[i];
  3134. int w = bloc[b];
  3135. bcount[w].entries[bcount[w].count++] = i;
  3136. }
  3137. stb_tempfree(buffer5,bloc);
  3138. // verify
  3139. for (i=0; i < bsize; ++i)
  3140. for (j=0; j < bcount[i].count; ++j)
  3141. assert(bs[bcount[i].entries[j]] == bcount[i].b);
  3142. memset(p->table, 0, size*sizeof(*p->table));
  3143. // check if any b has duplicate a
  3144. for (i=0; i < bsize; ++i) {
  3145. if (bcount[i].count > 1) {
  3146. for (j=0; j < bcount[i].count; ++j) {
  3147. if (p->table[as[bcount[i].entries[j]]])
  3148. bad = 1;
  3149. p->table[as[bcount[i].entries[j]]] = 1;
  3150. }
  3151. for (j=0; j < bcount[i].count; ++j) {
  3152. p->table[as[bcount[i].entries[j]]] = 0;
  3153. }
  3154. if (bad) break;
  3155. }
  3156. }
  3157. if (!bad) {
  3158. // go through the bs and populate the table, first fit
  3159. for (i=0; i < bsize; ++i) {
  3160. if (bcount[i].count) {
  3161. // go through the candidate table[b] values
  3162. for (j=0; j < size; ++j) {
  3163. // go through the a values and see if they fit
  3164. for (k=0; k < bcount[i].count; ++k) {
  3165. int a = as[bcount[i].entries[k]];
  3166. if (p->table[(a^j)&p->table_mask]) {
  3167. break; // fails
  3168. }
  3169. }
  3170. // if succeeded, accept
  3171. if (k == bcount[i].count) {
  3172. bcount[i].map = j;
  3173. for (k=0; k < bcount[i].count; ++k) {
  3174. int a = as[bcount[i].entries[k]];
  3175. p->table[(a^j)&p->table_mask] = 1;
  3176. }
  3177. break;
  3178. }
  3179. }
  3180. if (j == size)
  3181. break; // no match for i'th entry, so break out in failure
  3182. }
  3183. }
  3184. if (i == bsize) {
  3185. // success... fill out map
  3186. if (bsize <= 16 && size <= 256) {
  3187. p->large_bmap = NULL;
  3188. for (i=0; i < bsize; ++i)
  3189. p->small_bmap[bcount[i].b] = (stb_uint8) bcount[i].map;
  3190. } else {
  3191. p->large_bmap = (unsigned short *) malloc(sizeof(*p->large_bmap) * bsize);
  3192. for (i=0; i < bsize; ++i)
  3193. p->large_bmap[bcount[i].b] = bcount[i].map;
  3194. }
  3195. // initialize table to v[0], so empty slots will fail
  3196. for (i=0; i < size; ++i)
  3197. p->table[i] = v[0];
  3198. for (i=0; i < n; ++i)
  3199. if (p->large_bmap)
  3200. p->table[as[i] ^ p->large_bmap[bs[i]]] = v[i];
  3201. else
  3202. p->table[as[i] ^ p->small_bmap[bs[i]]] = v[i];
  3203. // and now validate that none of them collided
  3204. for (i=0; i < n; ++i)
  3205. assert(stb_perfect_hash(p, v[i]) >= 0);
  3206. stb_tempfree(buffer3, bcount);
  3207. break;
  3208. }
  3209. }
  3210. free(p->table);
  3211. p->table = NULL;
  3212. stb_tempfree(buffer3, bcount);
  3213. ++failure;
  3214. if (failure >= 4 && bsize < size) bsize *= 2;
  3215. if (failure >= 8 && (failure & 3) == 0 && size < 4*n) {
  3216. size *= 2;
  3217. bsize *= 2;
  3218. }
  3219. if (failure == 6) {
  3220. // make sure the input data is unique, so we don't infinite loop
  3221. unsigned int *data = (unsigned int *) stb_temp(buffer3, n * sizeof(*data));
  3222. memcpy(data, v, sizeof(*data) * n);
  3223. qsort(data, n, sizeof(*data), stb_intcmp(0));
  3224. for (i=1; i < n; ++i) {
  3225. if (data[i] == data[i-1])
  3226. size = 0; // size is return value, so 0 it
  3227. }
  3228. stb_tempfree(buffer3, data);
  3229. if (!size) break;
  3230. }
  3231. }
  3232. if (failure > stb_perfect_hash_max_failures)
  3233. stb_perfect_hash_max_failures = failure;
  3234. stb_tempfree(buffer1, as);
  3235. stb_tempfree(buffer2, bs);
  3236. stb_tempfree(buffer4, entries);
  3237. return size;
  3238. }
  3239. void stb_perfect_destroy(stb_perfect *p)
  3240. {
  3241. if (p->large_bmap) free(p->large_bmap);
  3242. if (p->table ) free(p->table);
  3243. p->large_bmap = NULL;
  3244. p->table = NULL;
  3245. p->b_mask = 0;
  3246. p->table_mask = 0;
  3247. }
  3248. #endif
  3249. //////////////////////////////////////////////////////////////////////////////
  3250. //
  3251. // Perfect hash clients
  3252. STB_EXTERN int stb_ischar(char s, char *set);
  3253. #ifdef STB_DEFINE
  3254. int stb_ischar(char c, char *set)
  3255. {
  3256. static unsigned char bit[8] = { 1,2,4,8,16,32,64,128 };
  3257. static stb_perfect p;
  3258. static unsigned char (*tables)[256];
  3259. static char ** sets = NULL;
  3260. int z = stb_perfect_hash(&p, (int)(size_t) set);
  3261. if (z < 0) {
  3262. int i,k,n,j,f;
  3263. // special code that means free all existing data
  3264. if (set == NULL) {
  3265. stb_arr_free(sets);
  3266. free(tables);
  3267. tables = NULL;
  3268. stb_perfect_destroy(&p);
  3269. return 0;
  3270. }
  3271. stb_arr_push(sets, set);
  3272. stb_perfect_destroy(&p);
  3273. n = stb_perfect_create(&p, (unsigned int *) (char **) sets, stb_arr_len(sets));
  3274. assert(n != 0);
  3275. k = (n+7) >> 3;
  3276. tables = (unsigned char (*)[256]) realloc(tables, sizeof(*tables) * k);
  3277. memset(tables, 0, sizeof(*tables) * k);
  3278. for (i=0; i < stb_arr_len(sets); ++i) {
  3279. k = stb_perfect_hash(&p, (int)(size_t) sets[i]);
  3280. assert(k >= 0);
  3281. n = k >> 3;
  3282. f = bit[k&7];
  3283. for (j=0; !j || sets[i][j]; ++j) {
  3284. tables[n][(unsigned char) sets[i][j]] |= f;
  3285. }
  3286. }
  3287. z = stb_perfect_hash(&p, (int)(size_t) set);
  3288. }
  3289. return tables[z >> 3][(unsigned char) c] & bit[z & 7];
  3290. }
  3291. #endif
  3292. //////////////////////////////////////////////////////////////////////////////
  3293. //
  3294. // Instantiated data structures
  3295. //
  3296. // This is an attempt to implement a templated data structure.
  3297. //
  3298. // Hash table: call stb_define_hash(TYPE,N,KEY,K1,K2,HASH,VALUE)
  3299. // TYPE -- will define a structure type containing the hash table
  3300. // N -- the name, will prefix functions named:
  3301. // N create
  3302. // N destroy
  3303. // N get
  3304. // N set, N add, N update,
  3305. // N remove
  3306. // KEY -- the type of the key. 'x == y' must be valid
  3307. // K1,K2 -- keys never used by the app, used as flags in the hashtable
  3308. // HASH -- a piece of code ending with 'return' that hashes key 'k'
  3309. // VALUE -- the type of the value. 'x = y' must be valid
  3310. //
  3311. // Note that stb_define_hash_base can be used to define more sophisticated
  3312. // hash tables, e.g. those that make copies of the key or use special
  3313. // comparisons (e.g. strcmp).
  3314. #define STB_(prefix,name) stb__##prefix##name
  3315. #define STB__(prefix,name) prefix##name
  3316. #define STB__use(x) x
  3317. #define STB__skip(x)
  3318. #define stb_declare_hash(PREFIX,TYPE,N,KEY,VALUE) \
  3319. typedef struct stb__st_##TYPE TYPE;\
  3320. PREFIX int STB__(N, init)(TYPE *h, int count);\
  3321. PREFIX int STB__(N, memory_usage)(TYPE *h);\
  3322. PREFIX TYPE * STB__(N, create)(void);\
  3323. PREFIX TYPE * STB__(N, copy)(TYPE *h);\
  3324. PREFIX void STB__(N, destroy)(TYPE *h);\
  3325. PREFIX int STB__(N,get_flag)(TYPE *a, KEY k, VALUE *v);\
  3326. PREFIX VALUE STB__(N,get)(TYPE *a, KEY k);\
  3327. PREFIX int STB__(N, set)(TYPE *a, KEY k, VALUE v);\
  3328. PREFIX int STB__(N, add)(TYPE *a, KEY k, VALUE v);\
  3329. PREFIX int STB__(N, update)(TYPE*a,KEY k,VALUE v);\
  3330. PREFIX int STB__(N, remove)(TYPE *a, KEY k, VALUE *v);
  3331. #define STB_nocopy(x) (x)
  3332. #define STB_nodelete(x) 0
  3333. #define STB_nofields
  3334. #define STB_nonullvalue(x)
  3335. #define STB_nullvalue(x) x
  3336. #define STB_safecompare(x) x
  3337. #define STB_nosafe(x)
  3338. #define STB_noprefix
  3339. #ifdef __GNUC__
  3340. #define STB__nogcc(x)
  3341. #else
  3342. #define STB__nogcc(x) x
  3343. #endif
  3344. #define stb_define_hash_base(PREFIX,TYPE,FIELDS,N,NC,LOAD_FACTOR, \
  3345. KEY,EMPTY,DEL,COPY,DISPOSE,SAFE, \
  3346. VCOMPARE,CCOMPARE,HASH, \
  3347. VALUE,HASVNULL,VNULL) \
  3348. \
  3349. typedef struct \
  3350. { \
  3351. KEY k; \
  3352. VALUE v; \
  3353. } STB_(N,_hashpair); \
  3354. \
  3355. STB__nogcc( typedef struct stb__st_##TYPE TYPE; ) \
  3356. struct stb__st_##TYPE { \
  3357. FIELDS \
  3358. STB_(N,_hashpair) *table; \
  3359. unsigned int mask; \
  3360. int count, limit; \
  3361. int deleted; \
  3362. \
  3363. int delete_threshhold; \
  3364. int grow_threshhold; \
  3365. int shrink_threshhold; \
  3366. unsigned char alloced, has_empty, has_del; \
  3367. VALUE ev; VALUE dv; \
  3368. }; \
  3369. \
  3370. static unsigned int STB_(N, hash)(KEY k) \
  3371. { \
  3372. HASH \
  3373. } \
  3374. \
  3375. PREFIX int STB__(N, init)(TYPE *h, int count) \
  3376. { \
  3377. int i; \
  3378. if (count < 4) count = 4; \
  3379. h->limit = count; \
  3380. h->count = 0; \
  3381. h->mask = count-1; \
  3382. h->deleted = 0; \
  3383. h->grow_threshhold = (int) (count * LOAD_FACTOR); \
  3384. h->has_empty = h->has_del = 0; \
  3385. h->alloced = 0; \
  3386. if (count <= 64) \
  3387. h->shrink_threshhold = 0; \
  3388. else \
  3389. h->shrink_threshhold = (int) (count * (LOAD_FACTOR/2.25)); \
  3390. h->delete_threshhold = (int) (count * (1-LOAD_FACTOR)/2); \
  3391. h->table = (STB_(N,_hashpair)*) malloc(sizeof(h->table[0]) * count); \
  3392. if (h->table == NULL) return 0; \
  3393. /* ideally this gets turned into a memset32 automatically */ \
  3394. for (i=0; i < count; ++i) \
  3395. h->table[i].k = EMPTY; \
  3396. return 1; \
  3397. } \
  3398. \
  3399. PREFIX int STB__(N, memory_usage)(TYPE *h) \
  3400. { \
  3401. return sizeof(*h) + h->limit * sizeof(h->table[0]); \
  3402. } \
  3403. \
  3404. PREFIX TYPE * STB__(N, create)(void) \
  3405. { \
  3406. TYPE *h = (TYPE *) malloc(sizeof(*h)); \
  3407. if (h) { \
  3408. if (STB__(N, init)(h, 16)) \
  3409. h->alloced = 1; \
  3410. else { free(h); h=NULL; } \
  3411. } \
  3412. return h; \
  3413. } \
  3414. \
  3415. PREFIX void STB__(N, destroy)(TYPE *a) \
  3416. { \
  3417. int i; \
  3418. for (i=0; i < a->limit; ++i) \
  3419. if (!CCOMPARE(a->table[i].k,EMPTY) && !CCOMPARE(a->table[i].k, DEL)) \
  3420. DISPOSE(a->table[i].k); \
  3421. free(a->table); \
  3422. if (a->alloced) \
  3423. free(a); \
  3424. } \
  3425. \
  3426. static void STB_(N, rehash)(TYPE *a, int count); \
  3427. \
  3428. PREFIX int STB__(N,get_flag)(TYPE *a, KEY k, VALUE *v) \
  3429. { \
  3430. unsigned int h = STB_(N, hash)(k); \
  3431. unsigned int n = h & a->mask, s; \
  3432. if (CCOMPARE(k,EMPTY)){ if (a->has_empty) *v = a->ev; return a->has_empty;}\
  3433. if (CCOMPARE(k,DEL)) { if (a->has_del ) *v = a->dv; return a->has_del; }\
  3434. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3435. SAFE(if (!CCOMPARE(a->table[n].k,DEL))) \
  3436. if (VCOMPARE(a->table[n].k,k)) { *v = a->table[n].v; return 1; } \
  3437. s = stb_rehash(h) | 1; \
  3438. for(;;) { \
  3439. n = (n + s) & a->mask; \
  3440. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3441. SAFE(if (CCOMPARE(a->table[n].k,DEL)) continue;) \
  3442. if (VCOMPARE(a->table[n].k,k)) \
  3443. { *v = a->table[n].v; return 1; } \
  3444. } \
  3445. } \
  3446. \
  3447. HASVNULL( \
  3448. PREFIX VALUE STB__(N,get)(TYPE *a, KEY k) \
  3449. { \
  3450. VALUE v; \
  3451. if (STB__(N,get_flag)(a,k,&v)) return v; \
  3452. else return VNULL; \
  3453. } \
  3454. ) \
  3455. \
  3456. PREFIX int STB__(N,getkey)(TYPE *a, KEY k, KEY *kout) \
  3457. { \
  3458. unsigned int h = STB_(N, hash)(k); \
  3459. unsigned int n = h & a->mask, s; \
  3460. if (CCOMPARE(k,EMPTY)||CCOMPARE(k,DEL)) return 0; \
  3461. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3462. SAFE(if (!CCOMPARE(a->table[n].k,DEL))) \
  3463. if (VCOMPARE(a->table[n].k,k)) { *kout = a->table[n].k; return 1; } \
  3464. s = stb_rehash(h) | 1; \
  3465. for(;;) { \
  3466. n = (n + s) & a->mask; \
  3467. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3468. SAFE(if (CCOMPARE(a->table[n].k,DEL)) continue;) \
  3469. if (VCOMPARE(a->table[n].k,k)) \
  3470. { *kout = a->table[n].k; return 1; } \
  3471. } \
  3472. } \
  3473. \
  3474. static int STB_(N,addset)(TYPE *a, KEY k, VALUE v, \
  3475. int allow_new, int allow_old, int copy) \
  3476. { \
  3477. unsigned int h = STB_(N, hash)(k); \
  3478. unsigned int n = h & a->mask; \
  3479. int b = -1; \
  3480. if (CCOMPARE(k,EMPTY)) { \
  3481. if (a->has_empty ? allow_old : allow_new) { \
  3482. n=a->has_empty; a->ev = v; a->has_empty = 1; return !n; \
  3483. } else return 0; \
  3484. } \
  3485. if (CCOMPARE(k,DEL)) { \
  3486. if (a->has_del ? allow_old : allow_new) { \
  3487. n=a->has_del; a->dv = v; a->has_del = 1; return !n; \
  3488. } else return 0; \
  3489. } \
  3490. if (!CCOMPARE(a->table[n].k, EMPTY)) { \
  3491. unsigned int s; \
  3492. if (CCOMPARE(a->table[n].k, DEL)) \
  3493. b = n; \
  3494. else if (VCOMPARE(a->table[n].k,k)) { \
  3495. if (allow_old) \
  3496. a->table[n].v = v; \
  3497. return !allow_new; \
  3498. } \
  3499. s = stb_rehash(h) | 1; \
  3500. for(;;) { \
  3501. n = (n + s) & a->mask; \
  3502. if (CCOMPARE(a->table[n].k, EMPTY)) break; \
  3503. if (CCOMPARE(a->table[n].k, DEL)) { \
  3504. if (b < 0) b = n; \
  3505. } else if (VCOMPARE(a->table[n].k,k)) { \
  3506. if (allow_old) \
  3507. a->table[n].v = v; \
  3508. return !allow_new; \
  3509. } \
  3510. } \
  3511. } \
  3512. if (!allow_new) return 0; \
  3513. if (b < 0) b = n; else --a->deleted; \
  3514. a->table[b].k = copy ? COPY(k) : k; \
  3515. a->table[b].v = v; \
  3516. ++a->count; \
  3517. if (a->count > a->grow_threshhold) \
  3518. STB_(N,rehash)(a, a->limit*2); \
  3519. return 1; \
  3520. } \
  3521. \
  3522. PREFIX int STB__(N, set)(TYPE *a, KEY k, VALUE v){return STB_(N,addset)(a,k,v,1,1,1);}\
  3523. PREFIX int STB__(N, add)(TYPE *a, KEY k, VALUE v){return STB_(N,addset)(a,k,v,1,0,1);}\
  3524. PREFIX int STB__(N, update)(TYPE*a,KEY k,VALUE v){return STB_(N,addset)(a,k,v,0,1,1);}\
  3525. \
  3526. PREFIX int STB__(N, remove)(TYPE *a, KEY k, VALUE *v) \
  3527. { \
  3528. unsigned int h = STB_(N, hash)(k); \
  3529. unsigned int n = h & a->mask, s; \
  3530. if (CCOMPARE(k,EMPTY)) { if (a->has_empty) { if(v)*v = a->ev; a->has_empty=0; return 1; } return 0; } \
  3531. if (CCOMPARE(k,DEL)) { if (a->has_del ) { if(v)*v = a->dv; a->has_del =0; return 1; } return 0; } \
  3532. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3533. if (SAFE(CCOMPARE(a->table[n].k,DEL) || ) !VCOMPARE(a->table[n].k,k)) { \
  3534. s = stb_rehash(h) | 1; \
  3535. for(;;) { \
  3536. n = (n + s) & a->mask; \
  3537. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  3538. SAFE(if (CCOMPARE(a->table[n].k, DEL)) continue;) \
  3539. if (VCOMPARE(a->table[n].k,k)) break; \
  3540. } \
  3541. } \
  3542. DISPOSE(a->table[n].k); \
  3543. a->table[n].k = DEL; \
  3544. --a->count; \
  3545. ++a->deleted; \
  3546. if (v != NULL) \
  3547. *v = a->table[n].v; \
  3548. if (a->count < a->shrink_threshhold) \
  3549. STB_(N, rehash)(a, a->limit >> 1); \
  3550. else if (a->deleted > a->delete_threshhold) \
  3551. STB_(N, rehash)(a, a->limit); \
  3552. return 1; \
  3553. } \
  3554. \
  3555. PREFIX TYPE * STB__(NC, copy)(TYPE *a) \
  3556. { \
  3557. int i; \
  3558. TYPE *h = (TYPE *) malloc(sizeof(*h)); \
  3559. if (!h) return NULL; \
  3560. if (!STB__(N, init)(h, a->limit)) { free(h); return NULL; } \
  3561. h->count = a->count; \
  3562. h->deleted = a->deleted; \
  3563. h->alloced = 1; \
  3564. h->ev = a->ev; h->dv = a->dv; \
  3565. h->has_empty = a->has_empty; h->has_del = a->has_del; \
  3566. memcpy(h->table, a->table, h->limit * sizeof(h->table[0])); \
  3567. for (i=0; i < a->limit; ++i) \
  3568. if (!CCOMPARE(h->table[i].k,EMPTY) && !CCOMPARE(h->table[i].k,DEL)) \
  3569. h->table[i].k = COPY(h->table[i].k); \
  3570. return h; \
  3571. } \
  3572. \
  3573. static void STB_(N, rehash)(TYPE *a, int count) \
  3574. { \
  3575. int i; \
  3576. TYPE b; \
  3577. STB__(N, init)(&b, count); \
  3578. for (i=0; i < a->limit; ++i) \
  3579. if (!CCOMPARE(a->table[i].k,EMPTY) && !CCOMPARE(a->table[i].k,DEL)) \
  3580. STB_(N,addset)(&b, a->table[i].k, a->table[i].v,1,1,0); \
  3581. free(a->table); \
  3582. a->table = b.table; \
  3583. a->mask = b.mask; \
  3584. a->count = b.count; \
  3585. a->limit = b.limit; \
  3586. a->deleted = b.deleted; \
  3587. a->delete_threshhold = b.delete_threshhold; \
  3588. a->grow_threshhold = b.grow_threshhold; \
  3589. a->shrink_threshhold = b.shrink_threshhold; \
  3590. }
  3591. #define STB_equal(a,b) ((a) == (b))
  3592. #define stb_define_hash(TYPE,N,KEY,EMPTY,DEL,HASH,VALUE) \
  3593. stb_define_hash_base(STB_noprefix, TYPE,STB_nofields,N,NC,0.85f, \
  3594. KEY,EMPTY,DEL,STB_nocopy,STB_nodelete,STB_nosafe, \
  3595. STB_equal,STB_equal,HASH, \
  3596. VALUE,STB_nonullvalue,0)
  3597. #define stb_define_hash_vnull(TYPE,N,KEY,EMPTY,DEL,HASH,VALUE,VNULL) \
  3598. stb_define_hash_base(STB_noprefix, TYPE,STB_nofields,N,NC,0.85f, \
  3599. KEY,EMPTY,DEL,STB_nocopy,STB_nodelete,STB_nosafe, \
  3600. STB_equal,STB_equal,HASH, \
  3601. VALUE,STB_nullvalue,VNULL)
  3602. //////////////////////////////////////////////////////////////////////////////
  3603. //
  3604. // stb_ptrmap
  3605. //
  3606. // An stb_ptrmap data structure is an O(1) hash table between pointers. One
  3607. // application is to let you store "extra" data associated with pointers,
  3608. // which is why it was originally called stb_extra.
  3609. stb_declare_hash(STB_EXTERN, stb_ptrmap, stb_ptrmap_, void *, void *)
  3610. stb_declare_hash(STB_EXTERN, stb_idict, stb_idict_, stb_int32, stb_int32)
  3611. STB_EXTERN void stb_ptrmap_delete(stb_ptrmap *e, void (*free_func)(void *));
  3612. STB_EXTERN stb_ptrmap *stb_ptrmap_new(void);
  3613. STB_EXTERN stb_idict * stb_idict_new_size(int size);
  3614. STB_EXTERN void stb_idict_remove_all(stb_idict *e);
  3615. #ifdef STB_DEFINE
  3616. #define STB_EMPTY ((void *) 2)
  3617. #define STB_EDEL ((void *) 6)
  3618. stb_define_hash_base(STB_noprefix,stb_ptrmap, STB_nofields, stb_ptrmap_,stb_ptrmap_,0.85f,
  3619. void *,STB_EMPTY,STB_EDEL,STB_nocopy,STB_nodelete,STB_nosafe,
  3620. STB_equal,STB_equal,return stb_hashptr(k);,
  3621. void *,STB_nullvalue,NULL)
  3622. stb_ptrmap *stb_ptrmap_new(void)
  3623. {
  3624. return stb_ptrmap_create();
  3625. }
  3626. void stb_ptrmap_delete(stb_ptrmap *e, void (*free_func)(void *))
  3627. {
  3628. int i;
  3629. if (free_func)
  3630. for (i=0; i < e->limit; ++i)
  3631. if (e->table[i].k != STB_EMPTY && e->table[i].k != STB_EDEL) {
  3632. if (free_func == free)
  3633. free(e->table[i].v); // allow STB_MALLOC_WRAPPER to operate
  3634. else
  3635. free_func(e->table[i].v);
  3636. }
  3637. stb_ptrmap_destroy(e);
  3638. }
  3639. // extra fields needed for stua_dict
  3640. #define STB_IEMPTY ((int) 1)
  3641. #define STB_IDEL ((int) 3)
  3642. stb_define_hash_base(STB_noprefix, stb_idict, short type; short gc; STB_nofields, stb_idict_,stb_idict_,0.85f,
  3643. stb_int32,STB_IEMPTY,STB_IDEL,STB_nocopy,STB_nodelete,STB_nosafe,
  3644. STB_equal,STB_equal,
  3645. return stb_rehash_improved(k);,stb_int32,STB_nonullvalue,0)
  3646. stb_idict * stb_idict_new_size(int size)
  3647. {
  3648. stb_idict *e = (stb_idict *) malloc(sizeof(*e));
  3649. if (e) {
  3650. if (!stb_is_pow2(size))
  3651. size = 1 << stb_log2_ceil(size);
  3652. stb_idict_init(e, size);
  3653. e->alloced = 1;
  3654. }
  3655. return e;
  3656. }
  3657. void stb_idict_remove_all(stb_idict *e)
  3658. {
  3659. int n;
  3660. for (n=0; n < e->limit; ++n)
  3661. e->table[n].k = STB_IEMPTY;
  3662. e->has_empty = e->has_del = 0;
  3663. }
  3664. #endif
  3665. //////////////////////////////////////////////////////////////////////////////
  3666. //
  3667. // stb_sparse_ptr_matrix
  3668. //
  3669. // An stb_ptrmap data structure is an O(1) hash table storing an arbitrary
  3670. // block of data for a given pair of pointers.
  3671. //
  3672. // If create=0, returns
  3673. typedef struct stb__st_stb_spmatrix stb_spmatrix;
  3674. STB_EXTERN stb_spmatrix * stb_sparse_ptr_matrix_new(int val_size);
  3675. STB_EXTERN void stb_sparse_ptr_matrix_free(stb_spmatrix *z);
  3676. STB_EXTERN void * stb_sparse_ptr_matrix_get(stb_spmatrix *z, void *a, void *b, int create);
  3677. #ifdef STB_DEFINE
  3678. typedef struct
  3679. {
  3680. void *a;
  3681. void *b;
  3682. } stb__ptrpair;
  3683. static stb__ptrpair stb__ptrpair_empty = { (void *) 1, (void *) 1 };
  3684. static stb__ptrpair stb__ptrpair_del = { (void *) 2, (void *) 2 };
  3685. #define STB__equal_ptrpair(x,y) ((x).a == (y).a && (x).b == (y).b)
  3686. stb_define_hash_base(static, stb_spmatrix, int val_size; void *arena;, stb__spmatrix_,stb__spmatrix_, 0.85,
  3687. stb__ptrpair, stb__ptrpair_empty, stb__ptrpair_del,
  3688. STB_nocopy, STB_nodelete, STB_nosafe,
  3689. STB__equal_ptrpair, STB__equal_ptrpair, return stb_rehash(stb_hashptr(k.a))+stb_hashptr(k.b);,
  3690. void *, STB_nullvalue, 0)
  3691. stb_spmatrix *stb_sparse_ptr_matrix_new(int val_size)
  3692. {
  3693. stb_spmatrix *m = stb__spmatrix_create();
  3694. if (m) m->val_size = val_size;
  3695. if (m) m->arena = stb_malloc_global(1);
  3696. return m;
  3697. }
  3698. void stb_sparse_ptr_matrix_free(stb_spmatrix *z)
  3699. {
  3700. if (z->arena) stb_free(z->arena);
  3701. stb__spmatrix_destroy(z);
  3702. }
  3703. void *stb_sparse_ptr_matrix_get(stb_spmatrix *z, void *a, void *b, int create)
  3704. {
  3705. stb__ptrpair t = { a,b };
  3706. void *data = stb__spmatrix_get(z, t);
  3707. if (!data && create) {
  3708. data = stb_malloc_raw(z->arena, z->val_size);
  3709. if (!data) return NULL;
  3710. memset(data, 0, z->val_size);
  3711. stb__spmatrix_add(z, t, data);
  3712. }
  3713. return data;
  3714. }
  3715. #endif
  3716. //////////////////////////////////////////////////////////////////////////////
  3717. //
  3718. // SDICT: Hash Table for Strings (symbol table)
  3719. //
  3720. // if "use_arena=1", then strings will be copied
  3721. // into blocks and never freed until the sdict is freed;
  3722. // otherwise they're malloc()ed and free()d on the fly.
  3723. // (specify use_arena=1 if you never stb_sdict_remove)
  3724. stb_declare_hash(STB_EXTERN, stb_sdict, stb_sdict_, char *, void *)
  3725. STB_EXTERN stb_sdict * stb_sdict_new(int use_arena);
  3726. STB_EXTERN stb_sdict * stb_sdict_copy(stb_sdict*);
  3727. STB_EXTERN void stb_sdict_delete(stb_sdict *);
  3728. STB_EXTERN void * stb_sdict_change(stb_sdict *, char *str, void *p);
  3729. STB_EXTERN int stb_sdict_count(stb_sdict *d);
  3730. STB_EXTERN int stb_sdict_internal_limit(stb_sdict *d);
  3731. STB_EXTERN char * stb_sdict_internal_key(stb_sdict *d, int n);
  3732. STB_EXTERN void * stb_sdict_internal_value(stb_sdict *d, int n);
  3733. #define stb_sdict_for(d,i,q,z) \
  3734. 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) \
  3735. if (q==NULL||q==(void *) 1);else // reversed makes macro friendly
  3736. #ifdef STB_DEFINE
  3737. // if in same translation unit, for speed, don't call accessors
  3738. #undef stb_sdict_for
  3739. #define stb_sdict_for(d,i,q,z) \
  3740. for(i=0; i < (d)->limit ? (q=(d)->table[i].k,z=(d)->table[i].v,1) : 0; ++i) \
  3741. if (q==NULL||q==(void *) 1);else // reversed makes macro friendly
  3742. #define STB_DEL ((void *) 1)
  3743. #define STB_SDEL ((char *) 1)
  3744. #define stb_sdict__copy(x) \
  3745. strcpy(a->arena ? stb_malloc_string(a->arena, strlen(x)+1) \
  3746. : (char *) malloc(strlen(x)+1), x)
  3747. #define stb_sdict__dispose(x) if (!a->arena) free(x)
  3748. stb_define_hash_base(STB_noprefix, stb_sdict, void*arena;, stb_sdict_,stb_sdictinternal_, 0.85f,
  3749. char *, NULL, STB_SDEL, stb_sdict__copy, stb_sdict__dispose,
  3750. STB_safecompare, !strcmp, STB_equal, return stb_hash(k);,
  3751. void *, STB_nullvalue, NULL)
  3752. int stb_sdict_count(stb_sdict *a)
  3753. {
  3754. return a->count;
  3755. }
  3756. int stb_sdict_internal_limit(stb_sdict *a)
  3757. {
  3758. return a->limit;
  3759. }
  3760. char* stb_sdict_internal_key(stb_sdict *a, int n)
  3761. {
  3762. return a->table[n].k;
  3763. }
  3764. void* stb_sdict_internal_value(stb_sdict *a, int n)
  3765. {
  3766. return a->table[n].v;
  3767. }
  3768. stb_sdict * stb_sdict_new(int use_arena)
  3769. {
  3770. stb_sdict *d = stb_sdict_create();
  3771. if (d == NULL) return NULL;
  3772. d->arena = use_arena ? stb_malloc_global(1) : NULL;
  3773. return d;
  3774. }
  3775. stb_sdict* stb_sdict_copy(stb_sdict *old)
  3776. {
  3777. stb_sdict *n;
  3778. void *old_arena = old->arena;
  3779. void *new_arena = old_arena ? stb_malloc_global(1) : NULL;
  3780. old->arena = new_arena;
  3781. n = stb_sdictinternal_copy(old);
  3782. old->arena = old_arena;
  3783. if (n)
  3784. n->arena = new_arena;
  3785. else if (new_arena)
  3786. stb_free(new_arena);
  3787. return n;
  3788. }
  3789. void stb_sdict_delete(stb_sdict *d)
  3790. {
  3791. if (d->arena)
  3792. stb_free(d->arena);
  3793. stb_sdict_destroy(d);
  3794. }
  3795. void * stb_sdict_change(stb_sdict *d, char *str, void *p)
  3796. {
  3797. void *q = stb_sdict_get(d, str);
  3798. stb_sdict_set(d, str, p);
  3799. return q;
  3800. }
  3801. #endif
  3802. //////////////////////////////////////////////////////////////////////////////
  3803. //
  3804. // Instantiated data structures
  3805. //
  3806. // This is an attempt to implement a templated data structure.
  3807. // What you do is define a struct foo, and then include several
  3808. // pointer fields to struct foo in your struct. Then you call
  3809. // the instantiator, which creates the functions that implement
  3810. // the data structure. This requires massive undebuggable #defines,
  3811. // so we limit the cases where we do this.
  3812. //
  3813. // AA tree is an encoding of a 2-3 tree whereas RB trees encode a 2-3-4 tree;
  3814. // much simpler code due to fewer cases.
  3815. #define stb__bst_parent(x) x
  3816. #define stb__bst_noparent(x)
  3817. #define stb_bst_fields(N) \
  3818. *STB_(N,left), *STB_(N,right); \
  3819. unsigned char STB_(N,level)
  3820. #define stb_bst_fields_parent(N) \
  3821. *STB_(N,left), *STB_(N,right), *STB_(N,parent); \
  3822. unsigned char STB_(N,level)
  3823. #define STB__level(N,x) ((x) ? (x)->STB_(N,level) : 0)
  3824. #define stb_bst_base(TYPE, N, TREE, M, compare, PAR) \
  3825. \
  3826. static int STB_(N,_compare)(TYPE *p, TYPE *q) \
  3827. { \
  3828. compare \
  3829. } \
  3830. \
  3831. static void STB_(N,setleft)(TYPE *q, TYPE *v) \
  3832. { \
  3833. q->STB_(N,left) = v; \
  3834. PAR(if (v) v->STB_(N,parent) = q;) \
  3835. } \
  3836. \
  3837. static void STB_(N,setright)(TYPE *q, TYPE *v) \
  3838. { \
  3839. q->STB_(N,right) = v; \
  3840. PAR(if (v) v->STB_(N,parent) = q;) \
  3841. } \
  3842. \
  3843. static TYPE *STB_(N,skew)(TYPE *q) \
  3844. { \
  3845. if (q == NULL) return q; \
  3846. if (q->STB_(N,left) \
  3847. && q->STB_(N,left)->STB_(N,level) == q->STB_(N,level)) { \
  3848. TYPE *p = q->STB_(N,left); \
  3849. STB_(N,setleft)(q, p->STB_(N,right)); \
  3850. STB_(N,setright)(p, q); \
  3851. return p; \
  3852. } \
  3853. return q; \
  3854. } \
  3855. \
  3856. static TYPE *STB_(N,split)(TYPE *p) \
  3857. { \
  3858. TYPE *q = p->STB_(N,right); \
  3859. if (q && q->STB_(N,right) \
  3860. && q->STB_(N,right)->STB_(N,level) == p->STB_(N,level)) { \
  3861. STB_(N,setright)(p, q->STB_(N,left)); \
  3862. STB_(N,setleft)(q,p); \
  3863. ++q->STB_(N,level); \
  3864. return q; \
  3865. } \
  3866. return p; \
  3867. } \
  3868. \
  3869. TYPE *STB__(N,insert)(TYPE *tree, TYPE *item) \
  3870. { \
  3871. int c; \
  3872. if (tree == NULL) { \
  3873. item->STB_(N,left) = NULL; \
  3874. item->STB_(N,right) = NULL; \
  3875. item->STB_(N,level) = 1; \
  3876. PAR(item->STB_(N,parent) = NULL;) \
  3877. return item; \
  3878. } \
  3879. c = STB_(N,_compare)(item,tree); \
  3880. if (c == 0) { \
  3881. if (item != tree) { \
  3882. STB_(N,setleft)(item, tree->STB_(N,left)); \
  3883. STB_(N,setright)(item, tree->STB_(N,right)); \
  3884. item->STB_(N,level) = tree->STB_(N,level); \
  3885. PAR(item->STB_(N,parent) = NULL;) \
  3886. } \
  3887. return item; \
  3888. } \
  3889. if (c < 0) \
  3890. STB_(N,setleft )(tree, STB__(N,insert)(tree->STB_(N,left), item)); \
  3891. else \
  3892. STB_(N,setright)(tree, STB__(N,insert)(tree->STB_(N,right), item)); \
  3893. tree = STB_(N,skew)(tree); \
  3894. tree = STB_(N,split)(tree); \
  3895. PAR(tree->STB_(N,parent) = NULL;) \
  3896. return tree; \
  3897. } \
  3898. \
  3899. TYPE *STB__(N,remove)(TYPE *tree, TYPE *item) \
  3900. { \
  3901. static TYPE *delnode, *leaf, *restore; \
  3902. if (tree == NULL) return NULL; \
  3903. leaf = tree; \
  3904. if (STB_(N,_compare)(item, tree) < 0) { \
  3905. STB_(N,setleft)(tree, STB__(N,remove)(tree->STB_(N,left), item)); \
  3906. } else { \
  3907. TYPE *r; \
  3908. delnode = tree; \
  3909. r = STB__(N,remove)(tree->STB_(N,right), item); \
  3910. /* maybe move 'leaf' up to this location */ \
  3911. if (restore == tree) { tree = leaf; leaf = restore = NULL; } \
  3912. STB_(N,setright)(tree,r); \
  3913. assert(tree->STB_(N,right) != tree); \
  3914. } \
  3915. if (tree == leaf) { \
  3916. if (delnode == item) { \
  3917. tree = tree->STB_(N,right); \
  3918. assert(leaf->STB_(N,left) == NULL); \
  3919. /* move leaf (the right sibling) up to delnode */ \
  3920. STB_(N,setleft )(leaf, item->STB_(N,left )); \
  3921. STB_(N,setright)(leaf, item->STB_(N,right)); \
  3922. leaf->STB_(N,level) = item->STB_(N,level); \
  3923. if (leaf != item) \
  3924. restore = delnode; \
  3925. } \
  3926. delnode = NULL; \
  3927. } else { \
  3928. if (STB__level(N,tree->STB_(N,left) ) < tree->STB_(N,level)-1 || \
  3929. STB__level(N,tree->STB_(N,right)) < tree->STB_(N,level)-1) { \
  3930. --tree->STB_(N,level); \
  3931. if (STB__level(N,tree->STB_(N,right)) > tree->STB_(N,level)) \
  3932. tree->STB_(N,right)->STB_(N,level) = tree->STB_(N,level); \
  3933. tree = STB_(N,skew)(tree); \
  3934. STB_(N,setright)(tree, STB_(N,skew)(tree->STB_(N,right))); \
  3935. if (tree->STB_(N,right)) \
  3936. STB_(N,setright)(tree->STB_(N,right), \
  3937. STB_(N,skew)(tree->STB_(N,right)->STB_(N,right))); \
  3938. tree = STB_(N,split)(tree); \
  3939. if (tree->STB_(N,right)) \
  3940. STB_(N,setright)(tree, STB_(N,split)(tree->STB_(N,right))); \
  3941. } \
  3942. } \
  3943. PAR(if (tree) tree->STB_(N,parent) = NULL;) \
  3944. return tree; \
  3945. } \
  3946. \
  3947. TYPE *STB__(N,last)(TYPE *tree) \
  3948. { \
  3949. if (tree) \
  3950. while (tree->STB_(N,right)) tree = tree->STB_(N,right); \
  3951. return tree; \
  3952. } \
  3953. \
  3954. TYPE *STB__(N,first)(TYPE *tree) \
  3955. { \
  3956. if (tree) \
  3957. while (tree->STB_(N,left)) tree = tree->STB_(N,left); \
  3958. return tree; \
  3959. } \
  3960. \
  3961. TYPE *STB__(N,next)(TYPE *tree, TYPE *item) \
  3962. { \
  3963. TYPE *next = NULL; \
  3964. if (item->STB_(N,right)) \
  3965. return STB__(N,first)(item->STB_(N,right)); \
  3966. PAR( \
  3967. while(item->STB_(N,parent)) { \
  3968. TYPE *up = item->STB_(N,parent); \
  3969. if (up->STB_(N,left) == item) return up; \
  3970. item = up; \
  3971. } \
  3972. return NULL; \
  3973. ) \
  3974. while (tree != item) { \
  3975. if (STB_(N,_compare)(item, tree) < 0) { \
  3976. next = tree; \
  3977. tree = tree->STB_(N,left); \
  3978. } else { \
  3979. tree = tree->STB_(N,right); \
  3980. } \
  3981. } \
  3982. return next; \
  3983. } \
  3984. \
  3985. TYPE *STB__(N,prev)(TYPE *tree, TYPE *item) \
  3986. { \
  3987. TYPE *next = NULL; \
  3988. if (item->STB_(N,left)) \
  3989. return STB__(N,last)(item->STB_(N,left)); \
  3990. PAR( \
  3991. while(item->STB_(N,parent)) { \
  3992. TYPE *up = item->STB_(N,parent); \
  3993. if (up->STB_(N,right) == item) return up; \
  3994. item = up; \
  3995. } \
  3996. return NULL; \
  3997. ) \
  3998. while (tree != item) { \
  3999. if (STB_(N,_compare)(item, tree) < 0) { \
  4000. tree = tree->STB_(N,left); \
  4001. } else { \
  4002. next = tree; \
  4003. tree = tree->STB_(N,right); \
  4004. } \
  4005. } \
  4006. return next; \
  4007. } \
  4008. \
  4009. STB__DEBUG( \
  4010. void STB__(N,_validate)(TYPE *tree, int root) \
  4011. { \
  4012. if (tree == NULL) return; \
  4013. PAR(if(root) assert(tree->STB_(N,parent) == NULL);) \
  4014. assert(STB__level(N,tree->STB_(N,left) ) == tree->STB_(N,level)-1); \
  4015. assert(STB__level(N,tree->STB_(N,right)) <= tree->STB_(N,level)); \
  4016. assert(STB__level(N,tree->STB_(N,right)) >= tree->STB_(N,level)-1); \
  4017. if (tree->STB_(N,right)) { \
  4018. assert(STB__level(N,tree->STB_(N,right)->STB_(N,right)) \
  4019. != tree->STB_(N,level)); \
  4020. PAR(assert(tree->STB_(N,right)->STB_(N,parent) == tree);) \
  4021. } \
  4022. PAR(if(tree->STB_(N,left)) assert(tree->STB_(N,left)->STB_(N,parent) == tree);) \
  4023. STB__(N,_validate)(tree->STB_(N,left) ,0); \
  4024. STB__(N,_validate)(tree->STB_(N,right),0); \
  4025. } \
  4026. ) \
  4027. \
  4028. typedef struct \
  4029. { \
  4030. TYPE *root; \
  4031. } TREE; \
  4032. \
  4033. void STB__(M,Insert)(TREE *tree, TYPE *item) \
  4034. { tree->root = STB__(N,insert)(tree->root, item); } \
  4035. void STB__(M,Remove)(TREE *tree, TYPE *item) \
  4036. { tree->root = STB__(N,remove)(tree->root, item); } \
  4037. TYPE *STB__(M,Next)(TREE *tree, TYPE *item) \
  4038. { return STB__(N,next)(tree->root, item); } \
  4039. TYPE *STB__(M,Prev)(TREE *tree, TYPE *item) \
  4040. { return STB__(N,prev)(tree->root, item); } \
  4041. TYPE *STB__(M,First)(TREE *tree) { return STB__(N,first)(tree->root); } \
  4042. TYPE *STB__(M,Last) (TREE *tree) { return STB__(N,last) (tree->root); } \
  4043. void STB__(M,Init)(TREE *tree) { tree->root = NULL; }
  4044. #define stb_bst_find(N,tree,fcompare) \
  4045. { \
  4046. int c; \
  4047. while (tree != NULL) { \
  4048. fcompare \
  4049. if (c == 0) return tree; \
  4050. if (c < 0) tree = tree->STB_(N,left); \
  4051. else tree = tree->STB_(N,right); \
  4052. } \
  4053. return NULL; \
  4054. }
  4055. #define stb_bst_raw(TYPE,N,TREE,M,vfield,VTYPE,compare,PAR) \
  4056. stb_bst_base(TYPE,N,TREE,M, \
  4057. VTYPE a = p->vfield; VTYPE b = q->vfield; return (compare);, PAR ) \
  4058. \
  4059. TYPE *STB__(N,find)(TYPE *tree, VTYPE a) \
  4060. stb_bst_find(N,tree,VTYPE b = tree->vfield; c = (compare);) \
  4061. TYPE *STB__(M,Find)(TREE *tree, VTYPE a) \
  4062. { return STB__(N,find)(tree->root, a); }
  4063. #define stb_bst(TYPE,N,TREE,M,vfield,VTYPE,compare) \
  4064. stb_bst_raw(TYPE,N,TREE,M,vfield,VTYPE,compare,stb__bst_noparent)
  4065. #define stb_bst_parent(TYPE,N,TREE,M,vfield,VTYPE,compare) \
  4066. stb_bst_raw(TYPE,N,TREE,M,vfield,VTYPE,compare,stb__bst_parent)
  4067. //////////////////////////////////////////////////////////////////////////////
  4068. //
  4069. // Pointer Nulling
  4070. //
  4071. // This lets you automatically NULL dangling pointers to "registered"
  4072. // objects. Note that you have to make sure you call the appropriate
  4073. // functions when you free or realloc blocks of memory that contain
  4074. // pointers or pointer targets. stb.h can automatically do this for
  4075. // stb_arr, or for all frees/reallocs if it's wrapping them.
  4076. //
  4077. #ifdef STB_NPTR
  4078. STB_EXTERN void stb_nptr_set(void *address_of_pointer, void *value_to_write);
  4079. STB_EXTERN void stb_nptr_didset(void *address_of_pointer);
  4080. STB_EXTERN void stb_nptr_didfree(void *address_being_freed, int len);
  4081. STB_EXTERN void stb_nptr_free(void *address_being_freed, int len);
  4082. STB_EXTERN void stb_nptr_didrealloc(void *new_address, void *old_address, int len);
  4083. STB_EXTERN void stb_nptr_recache(void); // recache all known pointers
  4084. // do this after pointer sets outside your control, slow
  4085. #ifdef STB_DEFINE
  4086. // for fast updating on free/realloc, we need to be able to find
  4087. // all the objects (pointers and targets) within a given block;
  4088. // this precludes hashing
  4089. // we use a three-level hierarchy of memory to minimize storage:
  4090. // level 1: 65536 pointers to stb__memory_node (always uses 256 KB)
  4091. // level 2: each stb__memory_node represents a 64K block of memory
  4092. // with 256 stb__memory_leafs (worst case 64MB)
  4093. // level 3: each stb__memory_leaf represents 256 bytes of memory
  4094. // using a list of target locations and a list of pointers
  4095. // (which are hopefully fairly short normally!)
  4096. // this approach won't work in 64-bit, which has a much larger address
  4097. // space. need to redesign
  4098. #define STB__NPTR_ROOT_LOG2 16
  4099. #define STB__NPTR_ROOT_NUM (1 << STB__NPTR_ROOT_LOG2)
  4100. #define STB__NPTR_ROOT_SHIFT (32 - STB__NPTR_ROOT_LOG2)
  4101. #define STB__NPTR_NODE_LOG2 5
  4102. #define STB__NPTR_NODE_NUM (1 << STB__NPTR_NODE_LOG2)
  4103. #define STB__NPTR_NODE_MASK (STB__NPTR_NODE_NUM-1)
  4104. #define STB__NPTR_NODE_SHIFT (STB__NPTR_ROOT_SHIFT - STB__NPTR_NODE_LOG2)
  4105. #define STB__NPTR_NODE_OFFSET(x) (((x) >> STB__NPTR_NODE_SHIFT) & STB__NPTR_NODE_MASK)
  4106. typedef struct stb__st_nptr
  4107. {
  4108. void *ptr; // address of actual pointer
  4109. struct stb__st_nptr *next; // next pointer with same target
  4110. struct stb__st_nptr **prev; // prev pointer with same target, address of 'next' field (or first)
  4111. struct stb__st_nptr *next_in_block;
  4112. } stb__nptr;
  4113. typedef struct stb__st_nptr_target
  4114. {
  4115. void *ptr; // address of target
  4116. stb__nptr *first; // address of first nptr pointing to this
  4117. struct stb__st_nptr_target *next_in_block;
  4118. } stb__nptr_target;
  4119. typedef struct
  4120. {
  4121. stb__nptr *pointers;
  4122. stb__nptr_target *targets;
  4123. } stb__memory_leaf;
  4124. typedef struct
  4125. {
  4126. stb__memory_leaf *children[STB__NPTR_NODE_NUM];
  4127. } stb__memory_node;
  4128. stb__memory_node *stb__memtab_root[STB__NPTR_ROOT_NUM];
  4129. static stb__memory_leaf *stb__nptr_find_leaf(void *mem)
  4130. {
  4131. stb_uint32 address = (stb_uint32) mem;
  4132. stb__memory_node *z = stb__memtab_root[address >> STB__NPTR_ROOT_SHIFT];
  4133. if (z)
  4134. return z->children[STB__NPTR_NODE_OFFSET(address)];
  4135. else
  4136. return NULL;
  4137. }
  4138. static void * stb__nptr_alloc(int size)
  4139. {
  4140. return stb__realloc_raw(0,size);
  4141. }
  4142. static void stb__nptr_free(void *p)
  4143. {
  4144. stb__realloc_raw(p,0);
  4145. }
  4146. static stb__memory_leaf *stb__nptr_make_leaf(void *mem)
  4147. {
  4148. stb_uint32 address = (stb_uint32) mem;
  4149. stb__memory_node *z = stb__memtab_root[address >> STB__NPTR_ROOT_SHIFT];
  4150. stb__memory_leaf *f;
  4151. if (!z) {
  4152. int i;
  4153. z = (stb__memory_node *) stb__nptr_alloc(sizeof(*stb__memtab_root[0]));
  4154. stb__memtab_root[address >> STB__NPTR_ROOT_SHIFT] = z;
  4155. for (i=0; i < 256; ++i)
  4156. z->children[i] = 0;
  4157. }
  4158. f = (stb__memory_leaf *) stb__nptr_alloc(sizeof(*f));
  4159. z->children[STB__NPTR_NODE_OFFSET(address)] = f;
  4160. f->pointers = NULL;
  4161. f->targets = NULL;
  4162. return f;
  4163. }
  4164. static stb__nptr_target *stb__nptr_find_target(void *target, int force)
  4165. {
  4166. stb__memory_leaf *p = stb__nptr_find_leaf(target);
  4167. if (p) {
  4168. stb__nptr_target *t = p->targets;
  4169. while (t) {
  4170. if (t->ptr == target)
  4171. return t;
  4172. t = t->next_in_block;
  4173. }
  4174. }
  4175. if (force) {
  4176. stb__nptr_target *t = (stb__nptr_target*) stb__nptr_alloc(sizeof(*t));
  4177. if (!p) p = stb__nptr_make_leaf(target);
  4178. t->ptr = target;
  4179. t->first = NULL;
  4180. t->next_in_block = p->targets;
  4181. p->targets = t;
  4182. return t;
  4183. } else
  4184. return NULL;
  4185. }
  4186. static stb__nptr *stb__nptr_find_pointer(void *ptr, int force)
  4187. {
  4188. stb__memory_leaf *p = stb__nptr_find_leaf(ptr);
  4189. if (p) {
  4190. stb__nptr *t = p->pointers;
  4191. while (t) {
  4192. if (t->ptr == ptr)
  4193. return t;
  4194. t = t->next_in_block;
  4195. }
  4196. }
  4197. if (force) {
  4198. stb__nptr *t = (stb__nptr *) stb__nptr_alloc(sizeof(*t));
  4199. if (!p) p = stb__nptr_make_leaf(ptr);
  4200. t->ptr = ptr;
  4201. t->next = NULL;
  4202. t->prev = NULL;
  4203. t->next_in_block = p->pointers;
  4204. p->pointers = t;
  4205. return t;
  4206. } else
  4207. return NULL;
  4208. }
  4209. void stb_nptr_set(void *address_of_pointer, void *value_to_write)
  4210. {
  4211. if (*(void **)address_of_pointer != value_to_write) {
  4212. *(void **) address_of_pointer = value_to_write;
  4213. stb_nptr_didset(address_of_pointer);
  4214. }
  4215. }
  4216. void stb_nptr_didset(void *address_of_pointer)
  4217. {
  4218. // first unlink from old chain
  4219. void *new_address;
  4220. stb__nptr *p = stb__nptr_find_pointer(address_of_pointer, 1); // force building if doesn't exist
  4221. if (p->prev) { // if p->prev is NULL, we just built it, or it was NULL
  4222. *(p->prev) = p->next;
  4223. if (p->next) p->next->prev = p->prev;
  4224. }
  4225. // now add to new chain
  4226. new_address = *(void **)address_of_pointer;
  4227. if (new_address != NULL) {
  4228. stb__nptr_target *t = stb__nptr_find_target(new_address, 1);
  4229. p->next = t->first;
  4230. if (p->next) p->next->prev = &p->next;
  4231. p->prev = &t->first;
  4232. t->first = p;
  4233. } else {
  4234. p->prev = NULL;
  4235. p->next = NULL;
  4236. }
  4237. }
  4238. void stb__nptr_block(void *address, int len, void (*function)(stb__memory_leaf *f, int datum, void *start, void *end), int datum)
  4239. {
  4240. void *end_address = (void *) ((char *) address + len - 1);
  4241. stb__memory_node *n;
  4242. stb_uint32 start = (stb_uint32) address;
  4243. stb_uint32 end = start + len - 1;
  4244. int b0 = start >> STB__NPTR_ROOT_SHIFT;
  4245. int b1 = end >> STB__NPTR_ROOT_SHIFT;
  4246. int b=b0,i,e0,e1;
  4247. e0 = STB__NPTR_NODE_OFFSET(start);
  4248. if (datum <= 0) {
  4249. // first block
  4250. n = stb__memtab_root[b0];
  4251. if (n) {
  4252. if (b0 != b1)
  4253. e1 = STB__NPTR_NODE_NUM-1;
  4254. else
  4255. e1 = STB__NPTR_NODE_OFFSET(end);
  4256. for (i=e0; i <= e1; ++i)
  4257. if (n->children[i])
  4258. function(n->children[i], datum, address, end_address);
  4259. }
  4260. if (b1 > b0) {
  4261. // blocks other than the first and last block
  4262. for (b=b0+1; b < b1; ++b) {
  4263. n = stb__memtab_root[b];
  4264. if (n)
  4265. for (i=0; i <= STB__NPTR_NODE_NUM-1; ++i)
  4266. if (n->children[i])
  4267. function(n->children[i], datum, address, end_address);
  4268. }
  4269. // last block
  4270. n = stb__memtab_root[b1];
  4271. if (n) {
  4272. e1 = STB__NPTR_NODE_OFFSET(end);
  4273. for (i=0; i <= e1; ++i)
  4274. if (n->children[i])
  4275. function(n->children[i], datum, address, end_address);
  4276. }
  4277. }
  4278. } else {
  4279. if (b1 > b0) {
  4280. // last block
  4281. n = stb__memtab_root[b1];
  4282. if (n) {
  4283. e1 = STB__NPTR_NODE_OFFSET(end);
  4284. for (i=e1; i >= 0; --i)
  4285. if (n->children[i])
  4286. function(n->children[i], datum, address, end_address);
  4287. }
  4288. // blocks other than the first and last block
  4289. for (b=b1-1; b > b0; --b) {
  4290. n = stb__memtab_root[b];
  4291. if (n)
  4292. for (i=STB__NPTR_NODE_NUM-1; i >= 0; --i)
  4293. if (n->children[i])
  4294. function(n->children[i], datum, address, end_address);
  4295. }
  4296. }
  4297. // first block
  4298. n = stb__memtab_root[b0];
  4299. if (n) {
  4300. if (b0 != b1)
  4301. e1 = STB__NPTR_NODE_NUM-1;
  4302. else
  4303. e1 = STB__NPTR_NODE_OFFSET(end);
  4304. for (i=e1; i >= e0; --i)
  4305. if (n->children[i])
  4306. function(n->children[i], datum, address, end_address);
  4307. }
  4308. }
  4309. }
  4310. static void stb__nptr_delete_pointers(stb__memory_leaf *f, int offset, void *start, void *end)
  4311. {
  4312. stb__nptr **p = &f->pointers;
  4313. while (*p) {
  4314. stb__nptr *n = *p;
  4315. if (n->ptr >= start && n->ptr <= end) {
  4316. // unlink
  4317. if (n->prev) {
  4318. *(n->prev) = n->next;
  4319. if (n->next) n->next->prev = n->prev;
  4320. }
  4321. *p = n->next_in_block;
  4322. stb__nptr_free(n);
  4323. } else
  4324. p = &(n->next_in_block);
  4325. }
  4326. }
  4327. static void stb__nptr_delete_targets(stb__memory_leaf *f, int offset, void *start, void *end)
  4328. {
  4329. stb__nptr_target **p = &f->targets;
  4330. while (*p) {
  4331. stb__nptr_target *n = *p;
  4332. if (n->ptr >= start && n->ptr <= end) {
  4333. // null pointers
  4334. stb__nptr *z = n->first;
  4335. while (z) {
  4336. stb__nptr *y = z->next;
  4337. z->prev = NULL;
  4338. z->next = NULL;
  4339. *(void **) z->ptr = NULL;
  4340. z = y;
  4341. }
  4342. // unlink this target
  4343. *p = n->next_in_block;
  4344. stb__nptr_free(n);
  4345. } else
  4346. p = &(n->next_in_block);
  4347. }
  4348. }
  4349. void stb_nptr_didfree(void *address_being_freed, int len)
  4350. {
  4351. // step one: delete all pointers in this block
  4352. stb__nptr_block(address_being_freed, len, stb__nptr_delete_pointers, 0);
  4353. // step two: NULL all pointers to this block; do this second to avoid NULLing deleted pointers
  4354. stb__nptr_block(address_being_freed, len, stb__nptr_delete_targets, 0);
  4355. }
  4356. void stb_nptr_free(void *address_being_freed, int len)
  4357. {
  4358. free(address_being_freed);
  4359. stb_nptr_didfree(address_being_freed, len);
  4360. }
  4361. static void stb__nptr_move_targets(stb__memory_leaf *f, int offset, void *start, void *end)
  4362. {
  4363. stb__nptr_target **t = &f->targets;
  4364. while (*t) {
  4365. stb__nptr_target *n = *t;
  4366. if (n->ptr >= start && n->ptr <= end) {
  4367. stb__nptr *z;
  4368. stb__memory_leaf *f;
  4369. // unlink n
  4370. *t = n->next_in_block;
  4371. // update n to new address
  4372. n->ptr = (void *) ((char *) n->ptr + offset);
  4373. f = stb__nptr_find_leaf(n->ptr);
  4374. if (!f) f = stb__nptr_make_leaf(n->ptr);
  4375. n->next_in_block = f->targets;
  4376. f->targets = n;
  4377. // now go through all pointers and make them point here
  4378. z = n->first;
  4379. while (z) {
  4380. *(void**) z->ptr = n->ptr;
  4381. z = z->next;
  4382. }
  4383. } else
  4384. t = &(n->next_in_block);
  4385. }
  4386. }
  4387. static void stb__nptr_move_pointers(stb__memory_leaf *f, int offset, void *start, void *end)
  4388. {
  4389. stb__nptr **p = &f->pointers;
  4390. while (*p) {
  4391. stb__nptr *n = *p;
  4392. if (n->ptr >= start && n->ptr <= end) {
  4393. // unlink
  4394. *p = n->next_in_block;
  4395. n->ptr = (void *) ((int) n->ptr + offset);
  4396. // move to new block
  4397. f = stb__nptr_find_leaf(n->ptr);
  4398. if (!f) f = stb__nptr_make_leaf(n->ptr);
  4399. n->next_in_block = f->pointers;
  4400. f->pointers = n;
  4401. } else
  4402. p = &(n->next_in_block);
  4403. }
  4404. }
  4405. void stb_nptr_realloc(void *new_address, void *old_address, int len)
  4406. {
  4407. if (new_address == old_address) return;
  4408. // have to move the pointers first, because moving the targets
  4409. // requires writing to the pointers-to-the-targets, and if some of those moved too,
  4410. // we need to make sure we don't write to the old memory
  4411. // step one: move all pointers within the block
  4412. stb__nptr_block(old_address, len, stb__nptr_move_pointers, (char *) new_address - (char *) old_address);
  4413. // step two: move all targets within the block
  4414. stb__nptr_block(old_address, len, stb__nptr_move_targets, (char *) new_address - (char *) old_address);
  4415. }
  4416. void stb_nptr_move(void *new_address, void *old_address)
  4417. {
  4418. stb_nptr_realloc(new_address, old_address, 1);
  4419. }
  4420. void stb_nptr_recache(void)
  4421. {
  4422. int i,j;
  4423. for (i=0; i < STB__NPTR_ROOT_NUM; ++i)
  4424. if (stb__memtab_root[i])
  4425. for (j=0; j < STB__NPTR_NODE_NUM; ++j)
  4426. if (stb__memtab_root[i]->children[j]) {
  4427. stb__nptr *p = stb__memtab_root[i]->children[j]->pointers;
  4428. while (p) {
  4429. stb_nptr_didset(p->ptr);
  4430. p = p->next_in_block;
  4431. }
  4432. }
  4433. }
  4434. #endif // STB_DEFINE
  4435. #endif // STB_NPTR
  4436. //////////////////////////////////////////////////////////////////////////////
  4437. //
  4438. // File Processing
  4439. //
  4440. #ifdef _MSC_VER
  4441. #define stb_rename(x,y) _wrename((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y))
  4442. #define stb_mktemp _mktemp
  4443. #else
  4444. #define stb_mktemp mktemp
  4445. #define stb_rename rename
  4446. #endif
  4447. STB_EXTERN void stb_fput_varlen64(FILE *f, stb_uint64 v);
  4448. STB_EXTERN stb_uint64 stb_fget_varlen64(FILE *f);
  4449. STB_EXTERN int stb_size_varlen64(stb_uint64 v);
  4450. #define stb_filec (char *) stb_file
  4451. #define stb_fileu (unsigned char *) stb_file
  4452. STB_EXTERN void * stb_file(char *filename, size_t *length);
  4453. STB_EXTERN void * stb_file_max(char *filename, size_t *length);
  4454. STB_EXTERN size_t stb_filelen(FILE *f);
  4455. STB_EXTERN int stb_filewrite(char *filename, void *data, size_t length);
  4456. STB_EXTERN int stb_filewritestr(char *filename, char *data);
  4457. STB_EXTERN char ** stb_stringfile(char *filename, int *len);
  4458. STB_EXTERN char ** stb_stringfile_trimmed(char *name, int *len, char comm);
  4459. STB_EXTERN char * stb_fgets(char *buffer, int buflen, FILE *f);
  4460. STB_EXTERN char * stb_fgets_malloc(FILE *f);
  4461. STB_EXTERN int stb_fexists(char *filename);
  4462. STB_EXTERN int stb_fcmp(char *s1, char *s2);
  4463. STB_EXTERN int stb_feq(char *s1, char *s2);
  4464. STB_EXTERN time_t stb_ftimestamp(char *filename);
  4465. STB_EXTERN int stb_fullpath(char *abs, int abs_size, char *rel);
  4466. STB_EXTERN FILE * stb_fopen(char *filename, char *mode);
  4467. STB_EXTERN int stb_fclose(FILE *f, int keep);
  4468. enum
  4469. {
  4470. stb_keep_no = 0,
  4471. stb_keep_yes = 1,
  4472. stb_keep_if_different = 2,
  4473. };
  4474. STB_EXTERN int stb_copyfile(char *src, char *dest);
  4475. STB_EXTERN void stb_fput_varlen64(FILE *f, stb_uint64 v);
  4476. STB_EXTERN stb_uint64 stb_fget_varlen64(FILE *f);
  4477. STB_EXTERN int stb_size_varlen64(stb_uint64 v);
  4478. STB_EXTERN void stb_fwrite32(FILE *f, stb_uint32 datum);
  4479. STB_EXTERN void stb_fput_varlen (FILE *f, int v);
  4480. STB_EXTERN void stb_fput_varlenu(FILE *f, unsigned int v);
  4481. STB_EXTERN int stb_fget_varlen (FILE *f);
  4482. STB_EXTERN stb_uint stb_fget_varlenu(FILE *f);
  4483. STB_EXTERN void stb_fput_ranged (FILE *f, int v, int b, stb_uint n);
  4484. STB_EXTERN int stb_fget_ranged (FILE *f, int b, stb_uint n);
  4485. STB_EXTERN int stb_size_varlen (int v);
  4486. STB_EXTERN int stb_size_varlenu(unsigned int v);
  4487. STB_EXTERN int stb_size_ranged (int b, stb_uint n);
  4488. STB_EXTERN int stb_fread(void *data, size_t len, size_t count, void *f);
  4489. STB_EXTERN int stb_fwrite(void *data, size_t len, size_t count, void *f);
  4490. #if 0
  4491. typedef struct
  4492. {
  4493. FILE *base_file;
  4494. char *buffer;
  4495. int buffer_size;
  4496. int buffer_off;
  4497. int buffer_left;
  4498. } STBF;
  4499. STB_EXTERN STBF *stb_tfopen(char *filename, char *mode);
  4500. STB_EXTERN int stb_tfread(void *data, size_t len, size_t count, STBF *f);
  4501. STB_EXTERN int stb_tfwrite(void *data, size_t len, size_t count, STBF *f);
  4502. #endif
  4503. #ifdef STB_DEFINE
  4504. #if 0
  4505. STBF *stb_tfopen(char *filename, char *mode)
  4506. {
  4507. STBF *z;
  4508. FILE *f = fopen(filename, mode);
  4509. if (!f) return NULL;
  4510. z = (STBF *) malloc(sizeof(*z));
  4511. if (!z) { fclose(f); return NULL; }
  4512. z->base_file = f;
  4513. if (!strcmp(mode, "rb") || !strcmp(mode, "wb")) {
  4514. z->buffer_size = 4096;
  4515. z->buffer_off = z->buffer_size;
  4516. z->buffer_left = 0;
  4517. z->buffer = malloc(z->buffer_size);
  4518. if (!z->buffer) { free(z); fclose(f); return NULL; }
  4519. } else {
  4520. z->buffer = 0;
  4521. z->buffer_size = 0;
  4522. z->buffer_left = 0;
  4523. }
  4524. return z;
  4525. }
  4526. int stb_tfread(void *data, size_t len, size_t count, STBF *f)
  4527. {
  4528. int total = len*count, done=0;
  4529. if (!total) return 0;
  4530. if (total <= z->buffer_left) {
  4531. memcpy(data, z->buffer + z->buffer_off, total);
  4532. z->buffer_off += total;
  4533. z->buffer_left -= total;
  4534. return count;
  4535. } else {
  4536. char *out = (char *) data;
  4537. // consume all buffered data
  4538. memcpy(data, z->buffer + z->buffer_off, z->buffer_left);
  4539. done = z->buffer_left;
  4540. out += z->buffer_left;
  4541. z->buffer_left=0;
  4542. if (total-done > (z->buffer_size >> 1)) {
  4543. done += fread(out
  4544. }
  4545. }
  4546. }
  4547. #endif
  4548. void stb_fwrite32(FILE *f, stb_uint32 x)
  4549. {
  4550. fwrite(&x, 4, 1, f);
  4551. }
  4552. #if defined(_MSC_VER) || defined(__MINGW32__)
  4553. #define stb__stat _stat
  4554. #else
  4555. #define stb__stat stat
  4556. #endif
  4557. int stb_fexists(char *filename)
  4558. {
  4559. struct stb__stat buf;
  4560. return stb__windows(
  4561. _wstat((const wchar_t *)stb__from_utf8(filename), &buf),
  4562. stat(filename,&buf)
  4563. ) == 0;
  4564. }
  4565. time_t stb_ftimestamp(char *filename)
  4566. {
  4567. struct stb__stat buf;
  4568. if (stb__windows(
  4569. _wstat((const wchar_t *)stb__from_utf8(filename), &buf),
  4570. stat(filename,&buf)
  4571. ) == 0)
  4572. {
  4573. return buf.st_mtime;
  4574. } else {
  4575. return 0;
  4576. }
  4577. }
  4578. size_t stb_filelen(FILE *f)
  4579. {
  4580. size_t len, pos;
  4581. pos = ftell(f);
  4582. fseek(f, 0, SEEK_END);
  4583. len = ftell(f);
  4584. fseek(f, pos, SEEK_SET);
  4585. return len;
  4586. }
  4587. void *stb_file(char *filename, size_t *length)
  4588. {
  4589. FILE *f = stb__fopen(filename, "rb");
  4590. char *buffer;
  4591. size_t len, len2;
  4592. if (!f) return NULL;
  4593. len = stb_filelen(f);
  4594. buffer = (char *) malloc(len+2); // nul + extra
  4595. len2 = fread(buffer, 1, len, f);
  4596. if (len2 == len) {
  4597. if (length) *length = len;
  4598. buffer[len] = 0;
  4599. } else {
  4600. free(buffer);
  4601. buffer = NULL;
  4602. }
  4603. fclose(f);
  4604. return buffer;
  4605. }
  4606. int stb_filewrite(char *filename, void *data, size_t length)
  4607. {
  4608. FILE *f = stb_fopen(filename, "wb");
  4609. if (f) {
  4610. unsigned char *data_ptr = (unsigned char *) data;
  4611. size_t remaining = length;
  4612. while (remaining > 0) {
  4613. size_t len2 = remaining > 65536 ? 65536 : remaining;
  4614. size_t len3 = fwrite(data_ptr, 1, len2, f);
  4615. if (len2 != len3) {
  4616. fprintf(stderr, "Failed while writing %s\n", filename);
  4617. break;
  4618. }
  4619. remaining -= len2;
  4620. data_ptr += len2;
  4621. }
  4622. stb_fclose(f, stb_keep_if_different);
  4623. }
  4624. return f != NULL;
  4625. }
  4626. int stb_filewritestr(char *filename, char *data)
  4627. {
  4628. return stb_filewrite(filename, data, strlen(data));
  4629. }
  4630. void * stb_file_max(char *filename, size_t *length)
  4631. {
  4632. FILE *f = stb__fopen(filename, "rb");
  4633. char *buffer;
  4634. size_t len, maxlen;
  4635. if (!f) return NULL;
  4636. maxlen = *length;
  4637. buffer = (char *) malloc(maxlen+1);
  4638. len = fread(buffer, 1, maxlen, f);
  4639. buffer[len] = 0;
  4640. fclose(f);
  4641. *length = len;
  4642. return buffer;
  4643. }
  4644. char ** stb_stringfile(char *filename, int *plen)
  4645. {
  4646. FILE *f = stb__fopen(filename, "rb");
  4647. char *buffer, **list=NULL, *s;
  4648. size_t len, count, i;
  4649. if (!f) return NULL;
  4650. len = stb_filelen(f);
  4651. buffer = (char *) malloc(len+1);
  4652. len = fread(buffer, 1, len, f);
  4653. buffer[len] = 0;
  4654. fclose(f);
  4655. // two passes through: first time count lines, second time set them
  4656. for (i=0; i < 2; ++i) {
  4657. s = buffer;
  4658. if (i == 1)
  4659. list[0] = s;
  4660. count = 1;
  4661. while (*s) {
  4662. if (*s == '\n' || *s == '\r') {
  4663. // detect if both cr & lf are together
  4664. int crlf = (s[0] + s[1]) == ('\n' + '\r');
  4665. if (i == 1) *s = 0;
  4666. if (crlf) ++s;
  4667. if (s[1]) { // it's not over yet
  4668. if (i == 1) list[count] = s+1;
  4669. ++count;
  4670. }
  4671. }
  4672. ++s;
  4673. }
  4674. if (i == 0) {
  4675. list = (char **) malloc(sizeof(*list) * (count+1) + len+1);
  4676. if (!list) return NULL;
  4677. list[count] = 0;
  4678. // recopy the file so there's just a single allocation to free
  4679. memcpy(&list[count+1], buffer, len+1);
  4680. free(buffer);
  4681. buffer = (char *) &list[count+1];
  4682. if (plen) *plen = count;
  4683. }
  4684. }
  4685. return list;
  4686. }
  4687. char ** stb_stringfile_trimmed(char *name, int *len, char comment)
  4688. {
  4689. int i,n,o=0;
  4690. char **s = stb_stringfile(name, &n);
  4691. if (s == NULL) return NULL;
  4692. for (i=0; i < n; ++i) {
  4693. char *p = stb_skipwhite(s[i]);
  4694. if (*p && *p != comment)
  4695. s[o++] = p;
  4696. }
  4697. s[o] = NULL;
  4698. if (len) *len = o;
  4699. return s;
  4700. }
  4701. char * stb_fgets(char *buffer, int buflen, FILE *f)
  4702. {
  4703. char *p;
  4704. buffer[0] = 0;
  4705. p = fgets(buffer, buflen, f);
  4706. if (p) {
  4707. int n = strlen(p)-1;
  4708. if (n >= 0)
  4709. if (p[n] == '\n')
  4710. p[n] = 0;
  4711. }
  4712. return p;
  4713. }
  4714. char * stb_fgets_malloc(FILE *f)
  4715. {
  4716. // avoid reallocing for small strings
  4717. char quick_buffer[800];
  4718. quick_buffer[sizeof(quick_buffer)-2] = 0;
  4719. if (!fgets(quick_buffer, sizeof(quick_buffer), f))
  4720. return NULL;
  4721. if (quick_buffer[sizeof(quick_buffer)-2] == 0) {
  4722. int n = strlen(quick_buffer);
  4723. if (n > 0 && quick_buffer[n-1] == '\n')
  4724. quick_buffer[n-1] = 0;
  4725. return strdup(quick_buffer);
  4726. } else {
  4727. char *p;
  4728. char *a = strdup(quick_buffer);
  4729. int len = sizeof(quick_buffer)-1;
  4730. while (!feof(f)) {
  4731. if (a[len-1] == '\n') break;
  4732. a = (char *) realloc(a, len*2);
  4733. p = &a[len];
  4734. p[len-2] = 0;
  4735. if (!fgets(p, len, f))
  4736. break;
  4737. if (p[len-2] == 0) {
  4738. len += strlen(p);
  4739. break;
  4740. }
  4741. len = len + (len-1);
  4742. }
  4743. if (a[len-1] == '\n')
  4744. a[len-1] = 0;
  4745. return a;
  4746. }
  4747. }
  4748. int stb_fullpath(char *abs, int abs_size, char *rel)
  4749. {
  4750. #ifdef _MSC_VER
  4751. return _fullpath(abs, rel, abs_size) != NULL;
  4752. #else
  4753. if (rel[0] == '/' || rel[0] == '~') {
  4754. if ((int) strlen(rel) >= abs_size)
  4755. return 0;
  4756. strcpy(abs,rel);
  4757. return STB_TRUE;
  4758. } else {
  4759. int n;
  4760. getcwd(abs, abs_size);
  4761. n = strlen(abs);
  4762. if (n+(int) strlen(rel)+2 <= abs_size) {
  4763. abs[n] = '/';
  4764. strcpy(abs+n+1, rel);
  4765. return STB_TRUE;
  4766. } else {
  4767. return STB_FALSE;
  4768. }
  4769. }
  4770. #endif
  4771. }
  4772. static int stb_fcmp_core(FILE *f, FILE *g)
  4773. {
  4774. char buf1[1024],buf2[1024];
  4775. int n1,n2, res=0;
  4776. while (1) {
  4777. n1 = fread(buf1, 1, sizeof(buf1), f);
  4778. n2 = fread(buf2, 1, sizeof(buf2), g);
  4779. res = memcmp(buf1,buf2,stb_min(n1,n2));
  4780. if (res)
  4781. break;
  4782. if (n1 != n2) {
  4783. res = n1 < n2 ? -1 : 1;
  4784. break;
  4785. }
  4786. if (n1 == 0)
  4787. break;
  4788. }
  4789. fclose(f);
  4790. fclose(g);
  4791. return res;
  4792. }
  4793. int stb_fcmp(char *s1, char *s2)
  4794. {
  4795. FILE *f = stb__fopen(s1, "rb");
  4796. FILE *g = stb__fopen(s2, "rb");
  4797. if (f == NULL || g == NULL) {
  4798. if (f) fclose(f);
  4799. if (g) {
  4800. fclose(g);
  4801. return STB_TRUE;
  4802. }
  4803. return f != NULL;
  4804. }
  4805. return stb_fcmp_core(f,g);
  4806. }
  4807. int stb_feq(char *s1, char *s2)
  4808. {
  4809. FILE *f = stb__fopen(s1, "rb");
  4810. FILE *g = stb__fopen(s2, "rb");
  4811. if (f == NULL || g == NULL) {
  4812. if (f) fclose(f);
  4813. if (g) fclose(g);
  4814. return f == g;
  4815. }
  4816. // feq is faster because it shortcuts if they're different length
  4817. if (stb_filelen(f) != stb_filelen(g)) {
  4818. fclose(f);
  4819. fclose(g);
  4820. return 0;
  4821. }
  4822. return !stb_fcmp_core(f,g);
  4823. }
  4824. static stb_ptrmap *stb__files;
  4825. typedef struct
  4826. {
  4827. char *temp_name;
  4828. char *name;
  4829. int errors;
  4830. } stb__file_data;
  4831. static FILE *stb__open_temp_file(char *temp_name, char *src_name, char *mode)
  4832. {
  4833. int p;
  4834. #ifdef _MSC_VER
  4835. int j;
  4836. #endif
  4837. FILE *f;
  4838. // try to generate a temporary file in the same directory
  4839. p = strlen(src_name)-1;
  4840. while (p > 0 && src_name[p] != '/' && src_name[p] != '\\'
  4841. && src_name[p] != ':' && src_name[p] != '~')
  4842. --p;
  4843. ++p;
  4844. memcpy(temp_name, src_name, p);
  4845. #ifdef _MSC_VER
  4846. // try multiple times to make a temp file... just in
  4847. // case some other process makes the name first
  4848. for (j=0; j < 32; ++j) {
  4849. strcpy(temp_name+p, "stmpXXXXXX");
  4850. if (stb_mktemp(temp_name) == NULL)
  4851. return 0;
  4852. f = fopen(temp_name, mode);
  4853. if (f != NULL)
  4854. break;
  4855. }
  4856. #else
  4857. {
  4858. strcpy(temp_name+p, "stmpXXXXXX");
  4859. #ifdef __MINGW32__
  4860. int fd = open(mktemp(temp_name), O_RDWR);
  4861. #else
  4862. int fd = mkstemp(temp_name);
  4863. #endif
  4864. if (fd == -1) return NULL;
  4865. f = fdopen(fd, mode);
  4866. if (f == NULL) {
  4867. unlink(temp_name);
  4868. close(fd);
  4869. return NULL;
  4870. }
  4871. }
  4872. #endif
  4873. return f;
  4874. }
  4875. FILE * stb_fopen(char *filename, char *mode)
  4876. {
  4877. FILE *f;
  4878. char name_full[4096];
  4879. char temp_full[sizeof(name_full) + 12];
  4880. // @TODO: if the file doesn't exist, we can also use the fastpath here
  4881. if (mode[0] != 'w' && !strchr(mode, '+'))
  4882. return stb__fopen(filename, mode);
  4883. // save away the full path to the file so if the program
  4884. // changes the cwd everything still works right! unix has
  4885. // better ways to do this, but we have to work in windows
  4886. name_full[0] = '\0'; // stb_fullpath reads name_full[0]
  4887. if (stb_fullpath(name_full, sizeof(name_full), filename)==0)
  4888. return 0;
  4889. f = stb__open_temp_file(temp_full, name_full, mode);
  4890. if (f != NULL) {
  4891. stb__file_data *d = (stb__file_data *) malloc(sizeof(*d));
  4892. if (!d) { assert(0); /* NOTREACHED */fclose(f); return NULL; }
  4893. if (stb__files == NULL) stb__files = stb_ptrmap_create();
  4894. d->temp_name = strdup(temp_full);
  4895. d->name = strdup(name_full);
  4896. d->errors = 0;
  4897. stb_ptrmap_add(stb__files, f, d);
  4898. return f;
  4899. }
  4900. return NULL;
  4901. }
  4902. int stb_fclose(FILE *f, int keep)
  4903. {
  4904. stb__file_data *d;
  4905. int ok = STB_FALSE;
  4906. if (f == NULL) return 0;
  4907. if (ferror(f))
  4908. keep = stb_keep_no;
  4909. fclose(f);
  4910. if (stb__files && stb_ptrmap_remove(stb__files, f, (void **) &d)) {
  4911. if (stb__files->count == 0) {
  4912. stb_ptrmap_destroy(stb__files);
  4913. stb__files = NULL;
  4914. }
  4915. } else
  4916. return STB_TRUE; // not special
  4917. if (keep == stb_keep_if_different) {
  4918. // check if the files are identical
  4919. if (stb_feq(d->name, d->temp_name)) {
  4920. keep = stb_keep_no;
  4921. ok = STB_TRUE; // report success if no change
  4922. }
  4923. }
  4924. if (keep == stb_keep_no) {
  4925. remove(d->temp_name);
  4926. } else {
  4927. if (!stb_fexists(d->name)) {
  4928. // old file doesn't exist, so just move the new file over it
  4929. stb_rename(d->temp_name, d->name);
  4930. } else {
  4931. // don't delete the old file yet in case there are troubles! First rename it!
  4932. char preserved_old_file[4096];
  4933. // generate a temp filename in the same directory (also creates it, which we don't need)
  4934. FILE *dummy = stb__open_temp_file(preserved_old_file, d->name, "wb");
  4935. if (dummy != NULL) {
  4936. // we don't actually want the open file
  4937. fclose(dummy);
  4938. // discard what we just created
  4939. remove(preserved_old_file); // if this fails, there's nothing we can do, and following logic handles it as best as possible anyway
  4940. // move the existing file to the preserved name
  4941. if (0 != stb_rename(d->name, preserved_old_file)) { // 0 on success
  4942. // failed, state is:
  4943. // filename -> old file
  4944. // tempname -> new file
  4945. // keep tempname around so we don't lose data
  4946. } else {
  4947. // state is:
  4948. // preserved -> old file
  4949. // tempname -> new file
  4950. // move the new file to the old name
  4951. if (0 == stb_rename(d->temp_name, d->name)) {
  4952. // state is:
  4953. // preserved -> old file
  4954. // filename -> new file
  4955. ok = STB_TRUE;
  4956. // 'filename -> new file' has always been the goal, so clean up
  4957. remove(preserved_old_file); // nothing to be done if it fails
  4958. } else {
  4959. // couldn't rename, so try renaming preserved file back
  4960. // state is:
  4961. // preserved -> old file
  4962. // tempname -> new file
  4963. stb_rename(preserved_old_file, d->name);
  4964. // if the rename failed, there's nothing more we can do
  4965. }
  4966. }
  4967. } else {
  4968. // we couldn't get a temp filename. do this the naive way; the worst case failure here
  4969. // leaves the filename pointing to nothing and the new file as a tempfile
  4970. remove(d->name);
  4971. stb_rename(d->temp_name, d->name);
  4972. }
  4973. }
  4974. }
  4975. free(d->temp_name);
  4976. free(d->name);
  4977. free(d);
  4978. return ok;
  4979. }
  4980. int stb_copyfile(char *src, char *dest)
  4981. {
  4982. char raw_buffer[1024];
  4983. char *buffer;
  4984. int buf_size = 65536;
  4985. FILE *f, *g;
  4986. // if file already exists at destination, do nothing
  4987. if (stb_feq(src, dest)) return STB_TRUE;
  4988. // open file
  4989. f = stb__fopen(src, "rb");
  4990. if (f == NULL) return STB_FALSE;
  4991. // open file for writing
  4992. g = stb__fopen(dest, "wb");
  4993. if (g == NULL) {
  4994. fclose(f);
  4995. return STB_FALSE;
  4996. }
  4997. buffer = (char *) malloc(buf_size);
  4998. if (buffer == NULL) {
  4999. buffer = raw_buffer;
  5000. buf_size = sizeof(raw_buffer);
  5001. }
  5002. while (!feof(f)) {
  5003. int n = fread(buffer, 1, buf_size, f);
  5004. if (n != 0)
  5005. fwrite(buffer, 1, n, g);
  5006. }
  5007. fclose(f);
  5008. if (buffer != raw_buffer)
  5009. free(buffer);
  5010. fclose(g);
  5011. return STB_TRUE;
  5012. }
  5013. // varlen:
  5014. // v' = (v >> 31) + (v < 0 ? ~v : v)<<1; // small abs(v) => small v'
  5015. // output v as big endian v'+k for v' <= k:
  5016. // 1 byte : v' <= 0x00000080 ( -64 <= v < 64) 7 bits
  5017. // 2 bytes: v' <= 0x00004000 (-8192 <= v < 8192) 14 bits
  5018. // 3 bytes: v' <= 0x00200000 21 bits
  5019. // 4 bytes: v' <= 0x10000000 28 bits
  5020. // the number of most significant 1-bits in the first byte
  5021. // equals the number of bytes after the first
  5022. #define stb__varlen_xform(v) (v<0 ? (~v << 1)+1 : (v << 1))
  5023. int stb_size_varlen(int v) { return stb_size_varlenu(stb__varlen_xform(v)); }
  5024. int stb_size_varlenu(unsigned int v)
  5025. {
  5026. if (v < 0x00000080) return 1;
  5027. if (v < 0x00004000) return 2;
  5028. if (v < 0x00200000) return 3;
  5029. if (v < 0x10000000) return 4;
  5030. return 5;
  5031. }
  5032. void stb_fput_varlen(FILE *f, int v) { stb_fput_varlenu(f, stb__varlen_xform(v)); }
  5033. void stb_fput_varlenu(FILE *f, unsigned int z)
  5034. {
  5035. if (z >= 0x10000000) fputc(0xF0,f);
  5036. if (z >= 0x00200000) fputc((z < 0x10000000 ? 0xE0 : 0)+(z>>24),f);
  5037. if (z >= 0x00004000) fputc((z < 0x00200000 ? 0xC0 : 0)+(z>>16),f);
  5038. if (z >= 0x00000080) fputc((z < 0x00004000 ? 0x80 : 0)+(z>> 8),f);
  5039. fputc(z,f);
  5040. }
  5041. #define stb_fgetc(f) ((unsigned char) fgetc(f))
  5042. int stb_fget_varlen(FILE *f)
  5043. {
  5044. unsigned int z = stb_fget_varlenu(f);
  5045. return (z & 1) ? ~(z>>1) : (z>>1);
  5046. }
  5047. unsigned int stb_fget_varlenu(FILE *f)
  5048. {
  5049. unsigned int z;
  5050. unsigned char d;
  5051. d = stb_fgetc(f);
  5052. if (d >= 0x80) {
  5053. if (d >= 0xc0) {
  5054. if (d >= 0xe0) {
  5055. if (d == 0xf0) z = stb_fgetc(f) << 24;
  5056. else z = (d - 0xe0) << 24;
  5057. z += stb_fgetc(f) << 16;
  5058. }
  5059. else
  5060. z = (d - 0xc0) << 16;
  5061. z += stb_fgetc(f) << 8;
  5062. } else
  5063. z = (d - 0x80) << 8;
  5064. z += stb_fgetc(f);
  5065. } else
  5066. z = d;
  5067. return z;
  5068. }
  5069. stb_uint64 stb_fget_varlen64(FILE *f)
  5070. {
  5071. stb_uint64 z;
  5072. unsigned char d;
  5073. d = stb_fgetc(f);
  5074. if (d >= 0x80) {
  5075. if (d >= 0xc0) {
  5076. if (d >= 0xe0) {
  5077. if (d >= 0xf0) {
  5078. if (d >= 0xf8) {
  5079. if (d >= 0xfc) {
  5080. if (d >= 0xfe) {
  5081. if (d >= 0xff)
  5082. z = (stb_uint64) stb_fgetc(f) << 56;
  5083. else
  5084. z = (stb_uint64) (d - 0xfe) << 56;
  5085. z |= (stb_uint64) stb_fgetc(f) << 48;
  5086. } else z = (stb_uint64) (d - 0xfc) << 48;
  5087. z |= (stb_uint64) stb_fgetc(f) << 40;
  5088. } else z = (stb_uint64) (d - 0xf8) << 40;
  5089. z |= (stb_uint64) stb_fgetc(f) << 32;
  5090. } else z = (stb_uint64) (d - 0xf0) << 32;
  5091. z |= (stb_uint) stb_fgetc(f) << 24;
  5092. } else z = (stb_uint) (d - 0xe0) << 24;
  5093. z |= (stb_uint) stb_fgetc(f) << 16;
  5094. } else z = (stb_uint) (d - 0xc0) << 16;
  5095. z |= (stb_uint) stb_fgetc(f) << 8;
  5096. } else z = (stb_uint) (d - 0x80) << 8;
  5097. z |= stb_fgetc(f);
  5098. } else
  5099. z = d;
  5100. return (z & 1) ? ~(z >> 1) : (z >> 1);
  5101. }
  5102. int stb_size_varlen64(stb_uint64 v)
  5103. {
  5104. if (v < 0x00000080) return 1;
  5105. if (v < 0x00004000) return 2;
  5106. if (v < 0x00200000) return 3;
  5107. if (v < 0x10000000) return 4;
  5108. if (v < STB_IMM_UINT64(0x0000000800000000)) return 5;
  5109. if (v < STB_IMM_UINT64(0x0000040000000000)) return 6;
  5110. if (v < STB_IMM_UINT64(0x0002000000000000)) return 7;
  5111. if (v < STB_IMM_UINT64(0x0100000000000000)) return 8;
  5112. return 9;
  5113. }
  5114. void stb_fput_varlen64(FILE *f, stb_uint64 v)
  5115. {
  5116. stb_uint64 z = stb__varlen_xform(v);
  5117. int first=1;
  5118. if (z >= STB_IMM_UINT64(0x100000000000000)) {
  5119. fputc(0xff,f);
  5120. first=0;
  5121. }
  5122. if (z >= STB_IMM_UINT64(0x02000000000000)) fputc((first ? 0xFE : 0)+(char)(z>>56),f), first=0;
  5123. if (z >= STB_IMM_UINT64(0x00040000000000)) fputc((first ? 0xFC : 0)+(char)(z>>48),f), first=0;
  5124. if (z >= STB_IMM_UINT64(0x00000800000000)) fputc((first ? 0xF8 : 0)+(char)(z>>40),f), first=0;
  5125. if (z >= STB_IMM_UINT64(0x00000010000000)) fputc((first ? 0xF0 : 0)+(char)(z>>32),f), first=0;
  5126. if (z >= STB_IMM_UINT64(0x00000000200000)) fputc((first ? 0xE0 : 0)+(char)(z>>24),f), first=0;
  5127. if (z >= STB_IMM_UINT64(0x00000000004000)) fputc((first ? 0xC0 : 0)+(char)(z>>16),f), first=0;
  5128. if (z >= STB_IMM_UINT64(0x00000000000080)) fputc((first ? 0x80 : 0)+(char)(z>> 8),f), first=0;
  5129. fputc((char)z,f);
  5130. }
  5131. void stb_fput_ranged(FILE *f, int v, int b, stb_uint n)
  5132. {
  5133. v -= b;
  5134. if (n <= (1 << 31))
  5135. assert((stb_uint) v < n);
  5136. if (n > (1 << 24)) fputc(v >> 24, f);
  5137. if (n > (1 << 16)) fputc(v >> 16, f);
  5138. if (n > (1 << 8)) fputc(v >> 8, f);
  5139. fputc(v,f);
  5140. }
  5141. int stb_fget_ranged(FILE *f, int b, stb_uint n)
  5142. {
  5143. unsigned int v=0;
  5144. if (n > (1 << 24)) v += stb_fgetc(f) << 24;
  5145. if (n > (1 << 16)) v += stb_fgetc(f) << 16;
  5146. if (n > (1 << 8)) v += stb_fgetc(f) << 8;
  5147. v += stb_fgetc(f);
  5148. return b+v;
  5149. }
  5150. int stb_size_ranged(int b, stb_uint n)
  5151. {
  5152. if (n > (1 << 24)) return 4;
  5153. if (n > (1 << 16)) return 3;
  5154. if (n > (1 << 8)) return 2;
  5155. return 1;
  5156. }
  5157. void stb_fput_string(FILE *f, char *s)
  5158. {
  5159. int len = strlen(s);
  5160. stb_fput_varlenu(f, len);
  5161. fwrite(s, 1, len, f);
  5162. }
  5163. // inverse of the above algorithm
  5164. char *stb_fget_string(FILE *f, void *p)
  5165. {
  5166. char *s;
  5167. int len = stb_fget_varlenu(f);
  5168. if (len > 4096) return NULL;
  5169. s = p ? stb_malloc_string(p, len+1) : (char *) malloc(len+1);
  5170. fread(s, 1, len, f);
  5171. s[len] = 0;
  5172. return s;
  5173. }
  5174. char *stb_strdup(char *str, void *pool)
  5175. {
  5176. int len = strlen(str);
  5177. char *p = stb_malloc_string(pool, len+1);
  5178. strcpy(p, str);
  5179. return p;
  5180. }
  5181. // strip the trailing '/' or '\\' from a directory so we can refer to it
  5182. // as a file for _stat()
  5183. char *stb_strip_final_slash(char *t)
  5184. {
  5185. if (t[0]) {
  5186. char *z = t + strlen(t) - 1;
  5187. // *z is the last character
  5188. if (*z == '\\' || *z == '/')
  5189. if (z != t+2 || t[1] != ':') // but don't strip it if it's e.g. "c:/"
  5190. *z = 0;
  5191. if (*z == '\\')
  5192. *z = '/'; // canonicalize to make sure it matches db
  5193. }
  5194. return t;
  5195. }
  5196. char *stb_strip_final_slash_regardless(char *t)
  5197. {
  5198. if (t[0]) {
  5199. char *z = t + strlen(t) - 1;
  5200. // *z is the last character
  5201. if (*z == '\\' || *z == '/')
  5202. *z = 0;
  5203. if (*z == '\\')
  5204. *z = '/'; // canonicalize to make sure it matches db
  5205. }
  5206. return t;
  5207. }
  5208. #endif
  5209. //////////////////////////////////////////////////////////////////////////////
  5210. //
  5211. // Options parsing
  5212. //
  5213. STB_EXTERN char **stb_getopt_param(int *argc, char **argv, char *param);
  5214. STB_EXTERN char **stb_getopt(int *argc, char **argv);
  5215. STB_EXTERN void stb_getopt_free(char **opts);
  5216. #ifdef STB_DEFINE
  5217. void stb_getopt_free(char **opts)
  5218. {
  5219. int i;
  5220. char ** o2 = opts;
  5221. for (i=0; i < stb_arr_len(o2); ++i)
  5222. free(o2[i]);
  5223. stb_arr_free(o2);
  5224. }
  5225. char **stb_getopt(int *argc, char **argv)
  5226. {
  5227. return stb_getopt_param(argc, argv, "");
  5228. }
  5229. char **stb_getopt_param(int *argc, char **argv, char *param)
  5230. {
  5231. char ** opts=NULL;
  5232. int i,j=1;
  5233. for (i=1; i < *argc; ++i) {
  5234. if (argv[i][0] != '-') {
  5235. argv[j++] = argv[i];
  5236. } else {
  5237. if (argv[i][1] == 0) { // plain - == don't parse further options
  5238. ++i;
  5239. while (i < *argc)
  5240. argv[j++] = argv[i++];
  5241. break;
  5242. } else {
  5243. int k;
  5244. char *q = argv[i]; // traverse options list
  5245. for (k=1; q[k]; ++k) {
  5246. char *s;
  5247. if (strchr(param, q[k])) { // does it take a parameter?
  5248. char *t = &q[k+1], z = q[k];
  5249. int len=0;
  5250. if (*t == 0) {
  5251. if (i == *argc-1) { // takes a parameter, but none found
  5252. *argc = 0;
  5253. stb_getopt_free(opts);
  5254. return NULL;
  5255. }
  5256. t = argv[++i];
  5257. } else
  5258. k += strlen(t);
  5259. len = strlen(t);
  5260. s = (char *) malloc(len+2);
  5261. if (!s) return NULL;
  5262. s[0] = z;
  5263. strcpy(s+1, t);
  5264. } else {
  5265. // no parameter
  5266. s = (char *) malloc(2);
  5267. if (!s) return NULL;
  5268. s[0] = q[k];
  5269. s[1] = 0;
  5270. }
  5271. stb_arr_push(opts, s);
  5272. }
  5273. }
  5274. }
  5275. }
  5276. stb_arr_push(opts, NULL);
  5277. *argc = j;
  5278. return opts;
  5279. }
  5280. #endif
  5281. //////////////////////////////////////////////////////////////////////////////
  5282. //
  5283. // Portable directory reading
  5284. //
  5285. STB_EXTERN char **stb_readdir_files (char *dir);
  5286. STB_EXTERN char **stb_readdir_files_mask(char *dir, char *wild);
  5287. STB_EXTERN char **stb_readdir_subdirs(char *dir);
  5288. STB_EXTERN char **stb_readdir_subdirs_mask(char *dir, char *wild);
  5289. STB_EXTERN void stb_readdir_free (char **files);
  5290. STB_EXTERN char **stb_readdir_recursive(char *dir, char *filespec);
  5291. STB_EXTERN void stb_delete_directory_recursive(char *dir);
  5292. #ifdef STB_DEFINE
  5293. #ifdef _MSC_VER
  5294. #include <io.h>
  5295. #else
  5296. #include <unistd.h>
  5297. #include <dirent.h>
  5298. #endif
  5299. void stb_readdir_free(char **files)
  5300. {
  5301. char **f2 = files;
  5302. int i;
  5303. for (i=0; i < stb_arr_len(f2); ++i)
  5304. free(f2[i]);
  5305. stb_arr_free(f2);
  5306. }
  5307. static int isdotdirname(char *name)
  5308. {
  5309. if (name[0] == '.')
  5310. return (name[1] == '.') ? !name[2] : !name[1];
  5311. return 0;
  5312. }
  5313. STB_EXTERN int stb_wildmatchi(char *expr, char *candidate);
  5314. static char **readdir_raw(char *dir, int return_subdirs, char *mask)
  5315. {
  5316. char **results = NULL;
  5317. char buffer[4096], with_slash[4096];
  5318. size_t n;
  5319. #ifdef _MSC_VER
  5320. stb__wchar *ws;
  5321. struct _wfinddata_t data;
  5322. #ifdef _WIN64
  5323. const intptr_t none = -1;
  5324. intptr_t z;
  5325. #else
  5326. const long none = -1;
  5327. long z;
  5328. #endif
  5329. #else // !_MSC_VER
  5330. const DIR *none = NULL;
  5331. DIR *z;
  5332. #endif
  5333. n = stb_strscpy(buffer,dir,sizeof(buffer));
  5334. if (!n || n >= sizeof(buffer))
  5335. return NULL;
  5336. stb_fixpath(buffer);
  5337. n--;
  5338. if (n > 0 && (buffer[n-1] != '/')) {
  5339. buffer[n++] = '/';
  5340. }
  5341. buffer[n] = 0;
  5342. if (!stb_strscpy(with_slash,buffer,sizeof(with_slash)))
  5343. return NULL;
  5344. #ifdef _MSC_VER
  5345. if (!stb_strscpy(buffer+n,"*.*",sizeof(buffer)-n))
  5346. return NULL;
  5347. ws = stb__from_utf8(buffer);
  5348. z = _wfindfirst((const wchar_t *)ws, &data);
  5349. #else
  5350. z = opendir(dir);
  5351. #endif
  5352. if (z != none) {
  5353. int nonempty = STB_TRUE;
  5354. #ifndef _MSC_VER
  5355. struct dirent *data = readdir(z);
  5356. nonempty = (data != NULL);
  5357. #endif
  5358. if (nonempty) {
  5359. do {
  5360. int is_subdir;
  5361. #ifdef _MSC_VER
  5362. char *name = stb__to_utf8((stb__wchar *)data.name);
  5363. if (name == NULL) {
  5364. fprintf(stderr, "%s to convert '%S' to %s!\n", "Unable", data.name, "utf8");
  5365. continue;
  5366. }
  5367. is_subdir = !!(data.attrib & _A_SUBDIR);
  5368. #else
  5369. char *name = data->d_name;
  5370. if (!stb_strscpy(buffer+n,name,sizeof(buffer)-n))
  5371. break;
  5372. // Could follow DT_LNK, but would need to check for recursive links.
  5373. is_subdir = !!(data->d_type & DT_DIR);
  5374. #endif
  5375. if (is_subdir == return_subdirs) {
  5376. if (!is_subdir || !isdotdirname(name)) {
  5377. if (!mask || stb_wildmatchi(mask, name)) {
  5378. char buffer[4096],*p=buffer;
  5379. if ( stb_snprintf(buffer, sizeof(buffer), "%s%s", with_slash, name) < 0 )
  5380. break;
  5381. if (buffer[0] == '.' && buffer[1] == '/')
  5382. p = buffer+2;
  5383. stb_arr_push(results, strdup(p));
  5384. }
  5385. }
  5386. }
  5387. }
  5388. #ifdef _MSC_VER
  5389. while (0 == _wfindnext(z, &data));
  5390. #else
  5391. while ((data = readdir(z)) != NULL);
  5392. #endif
  5393. }
  5394. #ifdef _MSC_VER
  5395. _findclose(z);
  5396. #else
  5397. closedir(z);
  5398. #endif
  5399. }
  5400. return results;
  5401. }
  5402. char **stb_readdir_files (char *dir) { return readdir_raw(dir, 0, NULL); }
  5403. char **stb_readdir_subdirs(char *dir) { return readdir_raw(dir, 1, NULL); }
  5404. char **stb_readdir_files_mask(char *dir, char *wild) { return readdir_raw(dir, 0, wild); }
  5405. char **stb_readdir_subdirs_mask(char *dir, char *wild) { return readdir_raw(dir, 1, wild); }
  5406. int stb__rec_max=0x7fffffff;
  5407. static char **stb_readdir_rec(char **sofar, char *dir, char *filespec)
  5408. {
  5409. char **files;
  5410. char ** dirs;
  5411. char **p;
  5412. if (stb_arr_len(sofar) >= stb__rec_max) return sofar;
  5413. files = stb_readdir_files_mask(dir, filespec);
  5414. stb_arr_for(p, files) {
  5415. stb_arr_push(sofar, strdup(*p));
  5416. if (stb_arr_len(sofar) >= stb__rec_max) break;
  5417. }
  5418. stb_readdir_free(files);
  5419. if (stb_arr_len(sofar) >= stb__rec_max) return sofar;
  5420. dirs = stb_readdir_subdirs(dir);
  5421. stb_arr_for(p, dirs)
  5422. sofar = stb_readdir_rec(sofar, *p, filespec);
  5423. stb_readdir_free(dirs);
  5424. return sofar;
  5425. }
  5426. char **stb_readdir_recursive(char *dir, char *filespec)
  5427. {
  5428. return stb_readdir_rec(NULL, dir, filespec);
  5429. }
  5430. void stb_delete_directory_recursive(char *dir)
  5431. {
  5432. char **list = stb_readdir_subdirs(dir);
  5433. int i;
  5434. for (i=0; i < stb_arr_len(list); ++i)
  5435. stb_delete_directory_recursive(list[i]);
  5436. stb_arr_free(list);
  5437. list = stb_readdir_files(dir);
  5438. for (i=0; i < stb_arr_len(list); ++i)
  5439. if (!remove(list[i])) {
  5440. // on windows, try again after making it writeable; don't ALWAYS
  5441. // do this first since that would be slow in the normal case
  5442. #ifdef _MSC_VER
  5443. _chmod(list[i], _S_IWRITE);
  5444. remove(list[i]);
  5445. #endif
  5446. }
  5447. stb_arr_free(list);
  5448. stb__windows(_rmdir,rmdir)(dir);
  5449. }
  5450. #endif
  5451. //////////////////////////////////////////////////////////////////////////////
  5452. //
  5453. // construct trees from filenames; useful for cmirror summaries
  5454. typedef struct stb_dirtree2 stb_dirtree2;
  5455. struct stb_dirtree2
  5456. {
  5457. stb_dirtree2 **subdirs;
  5458. // make convenient for stb_summarize_tree
  5459. int num_subdir;
  5460. float weight;
  5461. // actual data
  5462. char *fullpath;
  5463. char *relpath;
  5464. char **files;
  5465. };
  5466. STB_EXTERN stb_dirtree2 *stb_dirtree2_from_files_relative(char *src, char **filelist, int count);
  5467. STB_EXTERN stb_dirtree2 *stb_dirtree2_from_files(char **filelist, int count);
  5468. STB_EXTERN int stb_dir_is_prefix(char *dir, int dirlen, char *file);
  5469. #ifdef STB_DEFINE
  5470. int stb_dir_is_prefix(char *dir, int dirlen, char *file)
  5471. {
  5472. if (dirlen == 0) return STB_TRUE;
  5473. if (stb_strnicmp(dir, file, dirlen)) return STB_FALSE;
  5474. if (file[dirlen] == '/' || file[dirlen] == '\\') return STB_TRUE;
  5475. return STB_FALSE;
  5476. }
  5477. stb_dirtree2 *stb_dirtree2_from_files_relative(char *src, char **filelist, int count)
  5478. {
  5479. char buffer1[1024];
  5480. int i;
  5481. int dlen = strlen(src), elen;
  5482. stb_dirtree2 *d;
  5483. char ** descendents = NULL;
  5484. char ** files = NULL;
  5485. char *s;
  5486. if (!count) return NULL;
  5487. // first find all the ones that belong here... note this is will take O(NM) with N files and M subdirs
  5488. for (i=0; i < count; ++i) {
  5489. if (stb_dir_is_prefix(src, dlen, filelist[i])) {
  5490. stb_arr_push(descendents, filelist[i]);
  5491. }
  5492. }
  5493. if (descendents == NULL)
  5494. return NULL;
  5495. elen = dlen;
  5496. // skip a leading slash
  5497. if (elen == 0 && (descendents[0][0] == '/' || descendents[0][0] == '\\'))
  5498. ++elen;
  5499. else if (elen)
  5500. ++elen;
  5501. // now extract all the ones that have their root here
  5502. for (i=0; i < stb_arr_len(descendents);) {
  5503. if (!stb_strchr2(descendents[i]+elen, '/', '\\')) {
  5504. stb_arr_push(files, descendents[i]);
  5505. descendents[i] = descendents[stb_arr_len(descendents)-1];
  5506. stb_arr_pop(descendents);
  5507. } else
  5508. ++i;
  5509. }
  5510. // now create a record
  5511. d = (stb_dirtree2 *) malloc(sizeof(*d));
  5512. d->files = files;
  5513. d->subdirs = NULL;
  5514. d->fullpath = strdup(src);
  5515. s = stb_strrchr2(d->fullpath, '/', '\\');
  5516. if (s)
  5517. ++s;
  5518. else
  5519. s = d->fullpath;
  5520. d->relpath = s;
  5521. // now create the children
  5522. qsort(descendents, stb_arr_len(descendents), sizeof(char *), stb_qsort_stricmp(0));
  5523. buffer1[0] = 0;
  5524. for (i=0; i < stb_arr_len(descendents); ++i) {
  5525. char buffer2[1024];
  5526. char *s = descendents[i] + elen, *t;
  5527. t = stb_strchr2(s, '/', '\\');
  5528. assert(t);
  5529. stb_strncpy(buffer2, descendents[i], t-descendents[i]+1);
  5530. if (stb_stricmp(buffer1, buffer2)) {
  5531. stb_dirtree2 *t = stb_dirtree2_from_files_relative(buffer2, descendents, stb_arr_len(descendents));
  5532. assert(t != NULL);
  5533. strcpy(buffer1, buffer2);
  5534. stb_arr_push(d->subdirs, t);
  5535. }
  5536. }
  5537. d->num_subdir = stb_arr_len(d->subdirs);
  5538. d->weight = 0;
  5539. return d;
  5540. }
  5541. stb_dirtree2 *stb_dirtree2_from_files(char **filelist, int count)
  5542. {
  5543. return stb_dirtree2_from_files_relative("", filelist, count);
  5544. }
  5545. #endif
  5546. //////////////////////////////////////////////////////////////////////////////
  5547. //
  5548. // Checksums: CRC-32, ADLER32, SHA-1
  5549. //
  5550. // CRC-32 and ADLER32 allow streaming blocks
  5551. // SHA-1 requires either a complete buffer, max size 2^32 - 73
  5552. // or it can checksum directly from a file, max 2^61
  5553. #define STB_ADLER32_SEED 1
  5554. #define STB_CRC32_SEED 0 // note that we logical NOT this in the code
  5555. STB_EXTERN stb_uint
  5556. stb_adler32(stb_uint adler32, stb_uchar *buffer, stb_uint buflen);
  5557. STB_EXTERN stb_uint
  5558. stb_crc32_block(stb_uint crc32, stb_uchar *buffer, stb_uint len);
  5559. STB_EXTERN stb_uint stb_crc32(unsigned char *buffer, stb_uint len);
  5560. STB_EXTERN void stb_sha1(
  5561. unsigned char output[20], unsigned char *buffer, unsigned int len);
  5562. STB_EXTERN int stb_sha1_file(unsigned char output[20], char *file);
  5563. STB_EXTERN void stb_sha1_readable(char display[27], unsigned char sha[20]);
  5564. #ifdef STB_DEFINE
  5565. stb_uint stb_crc32_block(stb_uint crc, unsigned char *buffer, stb_uint len)
  5566. {
  5567. static stb_uint crc_table[256];
  5568. stb_uint i,j,s;
  5569. crc = ~crc;
  5570. if (crc_table[1] == 0)
  5571. for(i=0; i < 256; i++) {
  5572. for (s=i, j=0; j < 8; ++j)
  5573. s = (s >> 1) ^ (s & 1 ? 0xedb88320 : 0);
  5574. crc_table[i] = s;
  5575. }
  5576. for (i=0; i < len; ++i)
  5577. crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
  5578. return ~crc;
  5579. }
  5580. stb_uint stb_crc32(unsigned char *buffer, stb_uint len)
  5581. {
  5582. return stb_crc32_block(0, buffer, len);
  5583. }
  5584. stb_uint stb_adler32(stb_uint adler32, stb_uchar *buffer, stb_uint buflen)
  5585. {
  5586. const unsigned long ADLER_MOD = 65521;
  5587. unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
  5588. unsigned long blocklen, i;
  5589. blocklen = buflen % 5552;
  5590. while (buflen) {
  5591. for (i=0; i + 7 < blocklen; i += 8) {
  5592. s1 += buffer[0], s2 += s1;
  5593. s1 += buffer[1], s2 += s1;
  5594. s1 += buffer[2], s2 += s1;
  5595. s1 += buffer[3], s2 += s1;
  5596. s1 += buffer[4], s2 += s1;
  5597. s1 += buffer[5], s2 += s1;
  5598. s1 += buffer[6], s2 += s1;
  5599. s1 += buffer[7], s2 += s1;
  5600. buffer += 8;
  5601. }
  5602. for (; i < blocklen; ++i)
  5603. s1 += *buffer++, s2 += s1;
  5604. s1 %= ADLER_MOD, s2 %= ADLER_MOD;
  5605. buflen -= blocklen;
  5606. blocklen = 5552;
  5607. }
  5608. return (s2 << 16) + s1;
  5609. }
  5610. static void stb__sha1(stb_uchar *chunk, stb_uint h[5])
  5611. {
  5612. int i;
  5613. stb_uint a,b,c,d,e;
  5614. stb_uint w[80];
  5615. for (i=0; i < 16; ++i)
  5616. w[i] = stb_big32(&chunk[i*4]);
  5617. for (i=16; i < 80; ++i) {
  5618. stb_uint t;
  5619. t = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
  5620. w[i] = (t + t) | (t >> 31);
  5621. }
  5622. a = h[0];
  5623. b = h[1];
  5624. c = h[2];
  5625. d = h[3];
  5626. e = h[4];
  5627. #define STB__SHA1(k,f) \
  5628. { \
  5629. stb_uint temp = (a << 5) + (a >> 27) + (f) + e + (k) + w[i]; \
  5630. e = d; \
  5631. d = c; \
  5632. c = (b << 30) + (b >> 2); \
  5633. b = a; \
  5634. a = temp; \
  5635. }
  5636. i=0;
  5637. for (; i < 20; ++i) STB__SHA1(0x5a827999, d ^ (b & (c ^ d)) );
  5638. for (; i < 40; ++i) STB__SHA1(0x6ed9eba1, b ^ c ^ d );
  5639. for (; i < 60; ++i) STB__SHA1(0x8f1bbcdc, (b & c) + (d & (b ^ c)) );
  5640. for (; i < 80; ++i) STB__SHA1(0xca62c1d6, b ^ c ^ d );
  5641. #undef STB__SHA1
  5642. h[0] += a;
  5643. h[1] += b;
  5644. h[2] += c;
  5645. h[3] += d;
  5646. h[4] += e;
  5647. }
  5648. void stb_sha1(stb_uchar output[20], stb_uchar *buffer, stb_uint len)
  5649. {
  5650. unsigned char final_block[128];
  5651. stb_uint end_start, final_len, j;
  5652. int i;
  5653. stb_uint h[5];
  5654. h[0] = 0x67452301;
  5655. h[1] = 0xefcdab89;
  5656. h[2] = 0x98badcfe;
  5657. h[3] = 0x10325476;
  5658. h[4] = 0xc3d2e1f0;
  5659. // we need to write padding to the last one or two
  5660. // blocks, so build those first into 'final_block'
  5661. // we have to write one special byte, plus the 8-byte length
  5662. // compute the block where the data runs out
  5663. end_start = len & ~63;
  5664. // compute the earliest we can encode the length
  5665. if (((len+9) & ~63) == end_start) {
  5666. // it all fits in one block, so fill a second-to-last block
  5667. end_start -= 64;
  5668. }
  5669. final_len = end_start + 128;
  5670. // now we need to copy the data in
  5671. assert(end_start + 128 >= len+9);
  5672. assert(end_start < len || len < 64-9);
  5673. j = 0;
  5674. if (end_start > len)
  5675. j = (stb_uint) - (int) end_start;
  5676. for (; end_start + j < len; ++j)
  5677. final_block[j] = buffer[end_start + j];
  5678. final_block[j++] = 0x80;
  5679. while (j < 128-5) // 5 byte length, so write 4 extra padding bytes
  5680. final_block[j++] = 0;
  5681. // big-endian size
  5682. final_block[j++] = len >> 29;
  5683. final_block[j++] = len >> 21;
  5684. final_block[j++] = len >> 13;
  5685. final_block[j++] = len >> 5;
  5686. final_block[j++] = len << 3;
  5687. assert(j == 128 && end_start + j == final_len);
  5688. for (j=0; j < final_len; j += 64) { // 512-bit chunks
  5689. if (j+64 >= end_start+64)
  5690. stb__sha1(&final_block[j - end_start], h);
  5691. else
  5692. stb__sha1(&buffer[j], h);
  5693. }
  5694. for (i=0; i < 5; ++i) {
  5695. output[i*4 + 0] = h[i] >> 24;
  5696. output[i*4 + 1] = h[i] >> 16;
  5697. output[i*4 + 2] = h[i] >> 8;
  5698. output[i*4 + 3] = h[i] >> 0;
  5699. }
  5700. }
  5701. #ifdef _MSC_VER
  5702. int stb_sha1_file(stb_uchar output[20], char *file)
  5703. {
  5704. int i;
  5705. stb_uint64 length=0;
  5706. unsigned char buffer[128];
  5707. FILE *f = stb__fopen(file, "rb");
  5708. stb_uint h[5];
  5709. if (f == NULL) return 0; // file not found
  5710. h[0] = 0x67452301;
  5711. h[1] = 0xefcdab89;
  5712. h[2] = 0x98badcfe;
  5713. h[3] = 0x10325476;
  5714. h[4] = 0xc3d2e1f0;
  5715. for(;;) {
  5716. int n = fread(buffer, 1, 64, f);
  5717. if (n == 64) {
  5718. stb__sha1(buffer, h);
  5719. length += n;
  5720. } else {
  5721. int block = 64;
  5722. length += n;
  5723. buffer[n++] = 0x80;
  5724. // if there isn't enough room for the length, double the block
  5725. if (n + 8 > 64)
  5726. block = 128;
  5727. // pad to end
  5728. memset(buffer+n, 0, block-8-n);
  5729. i = block - 8;
  5730. buffer[i++] = (stb_uchar) (length >> 53);
  5731. buffer[i++] = (stb_uchar) (length >> 45);
  5732. buffer[i++] = (stb_uchar) (length >> 37);
  5733. buffer[i++] = (stb_uchar) (length >> 29);
  5734. buffer[i++] = (stb_uchar) (length >> 21);
  5735. buffer[i++] = (stb_uchar) (length >> 13);
  5736. buffer[i++] = (stb_uchar) (length >> 5);
  5737. buffer[i++] = (stb_uchar) (length << 3);
  5738. assert(i == block);
  5739. stb__sha1(buffer, h);
  5740. if (block == 128)
  5741. stb__sha1(buffer+64, h);
  5742. else
  5743. assert(block == 64);
  5744. break;
  5745. }
  5746. }
  5747. fclose(f);
  5748. for (i=0; i < 5; ++i) {
  5749. output[i*4 + 0] = h[i] >> 24;
  5750. output[i*4 + 1] = h[i] >> 16;
  5751. output[i*4 + 2] = h[i] >> 8;
  5752. output[i*4 + 3] = h[i] >> 0;
  5753. }
  5754. return 1;
  5755. }
  5756. #endif // _MSC_VER
  5757. // client can truncate this wherever they like
  5758. void stb_sha1_readable(char display[27], unsigned char sha[20])
  5759. {
  5760. char encoding[65] = "0123456789abcdefghijklmnopqrstuv"
  5761. "wxyzABCDEFGHIJKLMNOPQRSTUVWXYZ%$";
  5762. int num_bits = 0, acc=0;
  5763. int i=0,o=0;
  5764. while (o < 26) {
  5765. int v;
  5766. // expand the accumulator
  5767. if (num_bits < 6) {
  5768. assert(i != 20);
  5769. acc += sha[i++] << num_bits;
  5770. num_bits += 8;
  5771. }
  5772. v = acc & ((1 << 6) - 1);
  5773. display[o++] = encoding[v];
  5774. acc >>= 6;
  5775. num_bits -= 6;
  5776. }
  5777. assert(num_bits == 20*8 - 26*6);
  5778. display[o++] = encoding[acc];
  5779. }
  5780. #endif // STB_DEFINE
  5781. ///////////////////////////////////////////////////////////
  5782. //
  5783. // simplified WINDOWS registry interface... hopefully
  5784. // we'll never actually use this?
  5785. #if defined(_WIN32)
  5786. STB_EXTERN void * stb_reg_open(char *mode, char *where); // mode: "rHKLM" or "rHKCU" or "w.."
  5787. STB_EXTERN void stb_reg_close(void *reg);
  5788. STB_EXTERN int stb_reg_read(void *zreg, char *str, void *data, unsigned long len);
  5789. STB_EXTERN int stb_reg_read_string(void *zreg, char *str, char *data, int len);
  5790. STB_EXTERN void stb_reg_write(void *zreg, char *str, void *data, unsigned long len);
  5791. STB_EXTERN void stb_reg_write_string(void *zreg, char *str, char *data);
  5792. #if defined(STB_DEFINE) && !defined(STB_NO_REGISTRY)
  5793. #define STB_HAS_REGISTRY
  5794. #ifndef _WINDOWS_
  5795. #define HKEY void *
  5796. STB_EXTERN __declspec(dllimport) long __stdcall RegCloseKey ( HKEY hKey );
  5797. STB_EXTERN __declspec(dllimport) long __stdcall RegCreateKeyExA ( HKEY hKey, const char * lpSubKey,
  5798. int Reserved, char * lpClass, int dwOptions,
  5799. int samDesired, void *lpSecurityAttributes, HKEY * phkResult, int * lpdwDisposition );
  5800. STB_EXTERN __declspec(dllimport) long __stdcall RegDeleteKeyA ( HKEY hKey, const char * lpSubKey );
  5801. STB_EXTERN __declspec(dllimport) long __stdcall RegQueryValueExA ( HKEY hKey, const char * lpValueName,
  5802. int * lpReserved, unsigned long * lpType, unsigned char * lpData, unsigned long * lpcbData );
  5803. STB_EXTERN __declspec(dllimport) long __stdcall RegSetValueExA ( HKEY hKey, const char * lpValueName,
  5804. int Reserved, int dwType, const unsigned char* lpData, int cbData );
  5805. STB_EXTERN __declspec(dllimport) long __stdcall RegOpenKeyExA ( HKEY hKey, const char * lpSubKey,
  5806. int ulOptions, int samDesired, HKEY * phkResult );
  5807. #endif // _WINDOWS_
  5808. #define STB__REG_OPTION_NON_VOLATILE 0
  5809. #define STB__REG_KEY_ALL_ACCESS 0x000f003f
  5810. #define STB__REG_KEY_READ 0x00020019
  5811. void *stb_reg_open(char *mode, char *where)
  5812. {
  5813. long res;
  5814. HKEY base;
  5815. HKEY zreg;
  5816. if (!stb_stricmp(mode+1, "cu") || !stb_stricmp(mode+1, "hkcu"))
  5817. base = (HKEY) 0x80000001; // HKCU
  5818. else if (!stb_stricmp(mode+1, "lm") || !stb_stricmp(mode+1, "hklm"))
  5819. base = (HKEY) 0x80000002; // HKLM
  5820. else
  5821. return NULL;
  5822. if (mode[0] == 'r')
  5823. res = RegOpenKeyExA(base, where, 0, STB__REG_KEY_READ, &zreg);
  5824. else if (mode[0] == 'w')
  5825. res = RegCreateKeyExA(base, where, 0, NULL, STB__REG_OPTION_NON_VOLATILE, STB__REG_KEY_ALL_ACCESS, NULL, &zreg, NULL);
  5826. else
  5827. return NULL;
  5828. return res ? NULL : zreg;
  5829. }
  5830. void stb_reg_close(void *reg)
  5831. {
  5832. RegCloseKey((HKEY) reg);
  5833. }
  5834. #define STB__REG_SZ 1
  5835. #define STB__REG_BINARY 3
  5836. #define STB__REG_DWORD 4
  5837. int stb_reg_read(void *zreg, char *str, void *data, unsigned long len)
  5838. {
  5839. unsigned long type;
  5840. unsigned long alen = len;
  5841. if (0 == RegQueryValueExA((HKEY) zreg, str, 0, &type, (unsigned char *) data, &len))
  5842. if (type == STB__REG_BINARY || type == STB__REG_SZ || type == STB__REG_DWORD) {
  5843. if (len < alen)
  5844. *((char *) data + len) = 0;
  5845. return 1;
  5846. }
  5847. return 0;
  5848. }
  5849. void stb_reg_write(void *zreg, char *str, void *data, unsigned long len)
  5850. {
  5851. if (zreg)
  5852. RegSetValueExA((HKEY) zreg, str, 0, STB__REG_BINARY, (const unsigned char *) data, len);
  5853. }
  5854. int stb_reg_read_string(void *zreg, char *str, char *data, int len)
  5855. {
  5856. if (!stb_reg_read(zreg, str, data, len)) return 0;
  5857. data[len-1] = 0; // force a 0 at the end of the string no matter what
  5858. return 1;
  5859. }
  5860. void stb_reg_write_string(void *zreg, char *str, char *data)
  5861. {
  5862. if (zreg)
  5863. RegSetValueExA((HKEY) zreg, str, 0, STB__REG_SZ, (const unsigned char *) data, strlen(data)+1);
  5864. }
  5865. #endif // STB_DEFINE
  5866. #endif // _WIN32
  5867. //////////////////////////////////////////////////////////////////////////////
  5868. //
  5869. // stb_cfg - This is like the registry, but the config info
  5870. // is all stored in plain old files where we can
  5871. // backup and restore them easily. The LOCATION of
  5872. // the config files is gotten from... the registry!
  5873. #ifndef STB_NO_STB_STRINGS
  5874. typedef struct stb_cfg_st stb_cfg;
  5875. STB_EXTERN stb_cfg * stb_cfg_open(char *config, char *mode); // mode = "r", "w"
  5876. STB_EXTERN void stb_cfg_close(stb_cfg *cfg);
  5877. STB_EXTERN int stb_cfg_read(stb_cfg *cfg, char *key, void *value, int len);
  5878. STB_EXTERN void stb_cfg_write(stb_cfg *cfg, char *key, void *value, int len);
  5879. STB_EXTERN int stb_cfg_read_string(stb_cfg *cfg, char *key, char *value, int len);
  5880. STB_EXTERN void stb_cfg_write_string(stb_cfg *cfg, char *key, char *value);
  5881. STB_EXTERN int stb_cfg_delete(stb_cfg *cfg, char *key);
  5882. STB_EXTERN void stb_cfg_set_directory(char *dir);
  5883. #ifdef STB_DEFINE
  5884. typedef struct
  5885. {
  5886. char *key;
  5887. void *value;
  5888. int value_len;
  5889. } stb__cfg_item;
  5890. struct stb_cfg_st
  5891. {
  5892. stb__cfg_item *data;
  5893. char *loaded_file; // this needs to be freed
  5894. FILE *f; // write the data to this file on close
  5895. };
  5896. static char *stb__cfg_sig = "sTbCoNfIg!\0\0";
  5897. static char stb__cfg_dir[512];
  5898. STB_EXTERN void stb_cfg_set_directory(char *dir)
  5899. {
  5900. strcpy(stb__cfg_dir, dir);
  5901. }
  5902. STB_EXTERN stb_cfg * stb_cfg_open(char *config, char *mode)
  5903. {
  5904. size_t len;
  5905. stb_cfg *z;
  5906. char file[512];
  5907. if (mode[0] != 'r' && mode[0] != 'w') return NULL;
  5908. if (!stb__cfg_dir[0]) {
  5909. #ifdef _WIN32
  5910. strcpy(stb__cfg_dir, "c:/stb");
  5911. #else
  5912. strcpy(stb__cfg_dir, "~/.stbconfig");
  5913. #endif
  5914. #ifdef STB_HAS_REGISTRY
  5915. {
  5916. void *reg = stb_reg_open("rHKLM", "Software\\SilverSpaceship\\stb");
  5917. if (reg) {
  5918. stb_reg_read_string(reg, "config_dir", stb__cfg_dir, sizeof(stb__cfg_dir));
  5919. stb_reg_close(reg);
  5920. }
  5921. }
  5922. #endif
  5923. }
  5924. sprintf(file, "%s/%s.cfg", stb__cfg_dir, config);
  5925. z = (stb_cfg *) stb_malloc(0, sizeof(*z));
  5926. z->data = NULL;
  5927. z->loaded_file = stb_filec(file, &len);
  5928. if (z->loaded_file) {
  5929. char *s = z->loaded_file;
  5930. if (!memcmp(s, stb__cfg_sig, 12)) {
  5931. char *s = z->loaded_file + 12;
  5932. while (s < z->loaded_file + len) {
  5933. stb__cfg_item a;
  5934. int n = *(stb_int16 *) s;
  5935. a.key = s+2;
  5936. s = s+2 + n;
  5937. a.value_len = *(int *) s;
  5938. s += 4;
  5939. a.value = s;
  5940. s += a.value_len;
  5941. stb_arr_push(z->data, a);
  5942. }
  5943. assert(s == z->loaded_file + len);
  5944. }
  5945. }
  5946. if (mode[0] == 'w')
  5947. z->f = fopen(file, "wb");
  5948. else
  5949. z->f = NULL;
  5950. return z;
  5951. }
  5952. void stb_cfg_close(stb_cfg *z)
  5953. {
  5954. if (z->f) {
  5955. int i;
  5956. // write the file out
  5957. fwrite(stb__cfg_sig, 12, 1, z->f);
  5958. for (i=0; i < stb_arr_len(z->data); ++i) {
  5959. stb_int16 n = strlen(z->data[i].key)+1;
  5960. fwrite(&n, 2, 1, z->f);
  5961. fwrite(z->data[i].key, n, 1, z->f);
  5962. fwrite(&z->data[i].value_len, 4, 1, z->f);
  5963. fwrite(z->data[i].value, z->data[i].value_len, 1, z->f);
  5964. }
  5965. fclose(z->f);
  5966. }
  5967. stb_arr_free(z->data);
  5968. stb_free(z);
  5969. }
  5970. int stb_cfg_read(stb_cfg *z, char *key, void *value, int len)
  5971. {
  5972. int i;
  5973. for (i=0; i < stb_arr_len(z->data); ++i) {
  5974. if (!stb_stricmp(z->data[i].key, key)) {
  5975. int n = stb_min(len, z->data[i].value_len);
  5976. memcpy(value, z->data[i].value, n);
  5977. if (n < len)
  5978. *((char *) value + n) = 0;
  5979. return 1;
  5980. }
  5981. }
  5982. return 0;
  5983. }
  5984. void stb_cfg_write(stb_cfg *z, char *key, void *value, int len)
  5985. {
  5986. int i;
  5987. for (i=0; i < stb_arr_len(z->data); ++i)
  5988. if (!stb_stricmp(z->data[i].key, key))
  5989. break;
  5990. if (i == stb_arr_len(z->data)) {
  5991. stb__cfg_item p;
  5992. p.key = stb_strdup(key, z);
  5993. p.value = NULL;
  5994. p.value_len = 0;
  5995. stb_arr_push(z->data, p);
  5996. }
  5997. z->data[i].value = stb_malloc(z, len);
  5998. z->data[i].value_len = len;
  5999. memcpy(z->data[i].value, value, len);
  6000. }
  6001. int stb_cfg_delete(stb_cfg *z, char *key)
  6002. {
  6003. int i;
  6004. for (i=0; i < stb_arr_len(z->data); ++i)
  6005. if (!stb_stricmp(z->data[i].key, key)) {
  6006. stb_arr_fastdelete(z->data, i);
  6007. return 1;
  6008. }
  6009. return 0;
  6010. }
  6011. int stb_cfg_read_string(stb_cfg *z, char *key, char *value, int len)
  6012. {
  6013. if (!stb_cfg_read(z, key, value, len)) return 0;
  6014. value[len-1] = 0;
  6015. return 1;
  6016. }
  6017. void stb_cfg_write_string(stb_cfg *z, char *key, char *value)
  6018. {
  6019. stb_cfg_write(z, key, value, strlen(value)+1);
  6020. }
  6021. #endif
  6022. //////////////////////////////////////////////////////////////////////////////
  6023. //
  6024. // stb_dirtree - load a description of a directory tree
  6025. // uses a cache and stat()s the directories for changes
  6026. // MUCH faster on NTFS, _wrong_ on FAT32, so should
  6027. // ignore the db on FAT32
  6028. #ifdef _WIN32
  6029. typedef struct
  6030. {
  6031. char * path; // full path from passed-in root
  6032. time_t last_modified;
  6033. int num_files;
  6034. int flag;
  6035. } stb_dirtree_dir;
  6036. typedef struct
  6037. {
  6038. char *name; // name relative to path
  6039. int dir; // index into dirs[] array
  6040. stb_int64 size; // size, max 4GB
  6041. time_t last_modified;
  6042. int flag;
  6043. } stb_dirtree_file;
  6044. typedef struct
  6045. {
  6046. stb_dirtree_dir *dirs;
  6047. stb_dirtree_file *files;
  6048. // internal use
  6049. void * string_pool; // used to free data en masse
  6050. } stb_dirtree;
  6051. extern void stb_dirtree_free ( stb_dirtree *d );
  6052. extern stb_dirtree *stb_dirtree_get ( char *dir);
  6053. extern stb_dirtree *stb_dirtree_get_dir ( char *dir, char *cache_dir);
  6054. extern stb_dirtree *stb_dirtree_get_with_file ( char *dir, char *cache_file);
  6055. // get a list of all the files recursively underneath 'dir'
  6056. //
  6057. // cache_file is used to store a copy of the directory tree to speed up
  6058. // later calls. It must be unique to 'dir' and the current working
  6059. // directory! Otherwise who knows what will happen (a good solution
  6060. // is to put it _in_ dir, but this API doesn't force that).
  6061. //
  6062. // Also, it might be possible to break this if you have two different processes
  6063. // do a call to stb_dirtree_get() with the same cache file at about the same
  6064. // time, but I _think_ it might just work.
  6065. // i needed to build an identical data structure representing the state of
  6066. // a mirrored copy WITHOUT bothering to rescan it (i.e. we're mirroring to
  6067. // it WITHOUT scanning it, e.g. it's over the net), so this requires access
  6068. // to all of the innards.
  6069. extern void stb_dirtree_db_add_dir(stb_dirtree *active, char *path, time_t last);
  6070. extern void stb_dirtree_db_add_file(stb_dirtree *active, char *name, int dir, stb_int64 size, time_t last);
  6071. extern void stb_dirtree_db_read(stb_dirtree *target, char *filename, char *dir);
  6072. extern void stb_dirtree_db_write(stb_dirtree *target, char *filename, char *dir);
  6073. #ifdef STB_DEFINE
  6074. static void stb__dirtree_add_dir(char *path, time_t last, stb_dirtree *active)
  6075. {
  6076. stb_dirtree_dir d;
  6077. d.last_modified = last;
  6078. d.num_files = 0;
  6079. d.path = stb_strdup(path, active->string_pool);
  6080. stb_arr_push(active->dirs, d);
  6081. }
  6082. static void stb__dirtree_add_file(char *name, int dir, stb_int64 size, time_t last, stb_dirtree *active)
  6083. {
  6084. stb_dirtree_file f;
  6085. f.dir = dir;
  6086. f.size = size;
  6087. f.last_modified = last;
  6088. f.name = stb_strdup(name, active->string_pool);
  6089. ++active->dirs[dir].num_files;
  6090. stb_arr_push(active->files, f);
  6091. }
  6092. // version 02 supports > 4GB files
  6093. static char stb__signature[12] = { 's', 'T', 'b', 'D', 'i', 'R', 't', 'R', 'e', 'E', '0', '2' };
  6094. static void stb__dirtree_save_db(char *filename, stb_dirtree *data, char *root)
  6095. {
  6096. int i, num_dirs_final=0, num_files_final;
  6097. char *info = root ? root : "";
  6098. int *remap;
  6099. FILE *f = fopen(filename, "wb");
  6100. if (!f) return;
  6101. fwrite(stb__signature, sizeof(stb__signature), 1, f);
  6102. fwrite(info, strlen(info)+1, 1, f);
  6103. // need to be slightly tricky and not write out NULLed directories, nor the root
  6104. // build remapping table of all dirs we'll be writing out
  6105. remap = (int *) malloc(sizeof(remap[0]) * stb_arr_len(data->dirs));
  6106. for (i=0; i < stb_arr_len(data->dirs); ++i) {
  6107. if (data->dirs[i].path == NULL || (root && 0==stb_stricmp(data->dirs[i].path, root))) {
  6108. remap[i] = -1;
  6109. } else {
  6110. remap[i] = num_dirs_final++;
  6111. }
  6112. }
  6113. fwrite(&num_dirs_final, 4, 1, f);
  6114. for (i=0; i < stb_arr_len(data->dirs); ++i) {
  6115. if (remap[i] >= 0) {
  6116. fwrite(&data->dirs[i].last_modified, 4, 1, f);
  6117. stb_fput_string(f, data->dirs[i].path);
  6118. }
  6119. }
  6120. num_files_final = 0;
  6121. for (i=0; i < stb_arr_len(data->files); ++i)
  6122. if (remap[data->files[i].dir] >= 0 && data->files[i].name)
  6123. ++num_files_final;
  6124. fwrite(&num_files_final, 4, 1, f);
  6125. for (i=0; i < stb_arr_len(data->files); ++i) {
  6126. if (remap[data->files[i].dir] >= 0 && data->files[i].name) {
  6127. stb_fput_ranged(f, remap[data->files[i].dir], 0, num_dirs_final);
  6128. stb_fput_varlen64(f, data->files[i].size);
  6129. fwrite(&data->files[i].last_modified, 4, 1, f);
  6130. stb_fput_string(f, data->files[i].name);
  6131. }
  6132. }
  6133. fclose(f);
  6134. }
  6135. // note: stomps any existing data, rather than appending
  6136. static void stb__dirtree_load_db(char *filename, stb_dirtree *data, char *dir)
  6137. {
  6138. char sig[2048];
  6139. int i,n;
  6140. FILE *f = fopen(filename, "rb");
  6141. if (!f) return;
  6142. data->string_pool = stb_malloc(0,1);
  6143. fread(sig, sizeof(stb__signature), 1, f);
  6144. if (memcmp(stb__signature, sig, sizeof(stb__signature))) { fclose(f); return; }
  6145. if (!fread(sig, strlen(dir)+1, 1, f)) { fclose(f); return; }
  6146. if (stb_stricmp(sig,dir)) { fclose(f); return; }
  6147. // we can just read them straight in, because they're guaranteed to be valid
  6148. fread(&n, 4, 1, f);
  6149. stb_arr_setlen(data->dirs, n);
  6150. for(i=0; i < stb_arr_len(data->dirs); ++i) {
  6151. fread(&data->dirs[i].last_modified, 4, 1, f);
  6152. data->dirs[i].path = stb_fget_string(f, data->string_pool);
  6153. if (data->dirs[i].path == NULL) goto bail;
  6154. }
  6155. fread(&n, 4, 1, f);
  6156. stb_arr_setlen(data->files, n);
  6157. for (i=0; i < stb_arr_len(data->files); ++i) {
  6158. data->files[i].dir = stb_fget_ranged(f, 0, stb_arr_len(data->dirs));
  6159. data->files[i].size = stb_fget_varlen64(f);
  6160. fread(&data->files[i].last_modified, 4, 1, f);
  6161. data->files[i].name = stb_fget_string(f, data->string_pool);
  6162. if (data->files[i].name == NULL) goto bail;
  6163. }
  6164. if (0) {
  6165. bail:
  6166. stb_arr_free(data->dirs);
  6167. stb_arr_free(data->files);
  6168. }
  6169. fclose(f);
  6170. }
  6171. static int stb__dircount, stb__dircount_mask, stb__showfile;
  6172. static void stb__dirtree_scandir(char *path, time_t last_time, stb_dirtree *active)
  6173. {
  6174. // this is dumb depth first; theoretically it might be faster
  6175. // to fully traverse each directory before visiting its children,
  6176. // but it's complicated and didn't seem like a gain in the test app
  6177. int n;
  6178. struct _wfinddatai64_t c_file;
  6179. long hFile;
  6180. stb__wchar full_path[1024];
  6181. int has_slash;
  6182. if (stb__showfile) printf("<");
  6183. has_slash = (path[0] && path[strlen(path)-1] == '/');
  6184. // @TODO: do this concatenation without using swprintf to avoid this mess:
  6185. #if defined(_MSC_VER) && _MSC_VER < 1400
  6186. if (has_slash)
  6187. swprintf(full_path, L"%s*", stb__from_utf8(path));
  6188. else
  6189. swprintf(full_path, L"%s/*", stb__from_utf8(path));
  6190. #else
  6191. if (has_slash)
  6192. swprintf(full_path, 1024, L"%s*", stb__from_utf8(path));
  6193. else
  6194. swprintf(full_path, 1024, L"%s/*", stb__from_utf8(path));
  6195. #endif
  6196. // it's possible this directory is already present: that means it was in the
  6197. // cache, but its parent wasn't... in that case, we're done with it
  6198. if (stb__showfile) printf("C[%d]", stb_arr_len(active->dirs));
  6199. for (n=0; n < stb_arr_len(active->dirs); ++n)
  6200. if (0 == stb_stricmp(active->dirs[n].path, path)) {
  6201. if (stb__showfile) printf("D");
  6202. return;
  6203. }
  6204. if (stb__showfile) printf("E");
  6205. // otherwise, we need to add it
  6206. stb__dirtree_add_dir(path, last_time, active);
  6207. n = stb_arr_lastn(active->dirs);
  6208. if (stb__showfile) printf("[");
  6209. if( (hFile = _wfindfirsti64( full_path, &c_file )) != -1L ) {
  6210. do {
  6211. if (stb__showfile) printf(")");
  6212. if (c_file.attrib & _A_SUBDIR) {
  6213. // ignore subdirectories starting with '.', e.g. "." and ".."
  6214. if (c_file.name[0] != '.') {
  6215. char *new_path = (char *) full_path;
  6216. char *temp = stb__to_utf8(c_file.name);
  6217. if (has_slash)
  6218. sprintf(new_path, "%s%s", path, temp);
  6219. else
  6220. sprintf(new_path, "%s/%s", path, temp);
  6221. if (stb__dircount_mask) {
  6222. ++stb__dircount;
  6223. if (!(stb__dircount & stb__dircount_mask)) {
  6224. printf("%s\r", new_path);
  6225. }
  6226. }
  6227. stb__dirtree_scandir(new_path, c_file.time_write, active);
  6228. }
  6229. } else {
  6230. char *temp = stb__to_utf8(c_file.name);
  6231. stb__dirtree_add_file(temp, n, c_file.size, c_file.time_write, active);
  6232. }
  6233. if (stb__showfile) printf("(");
  6234. } while( _wfindnexti64( hFile, &c_file ) == 0 );
  6235. if (stb__showfile) printf("]");
  6236. _findclose( hFile );
  6237. }
  6238. if (stb__showfile) printf(">\n");
  6239. }
  6240. // scan the database and see if it's all valid
  6241. static int stb__dirtree_update_db(stb_dirtree *db, stb_dirtree *active)
  6242. {
  6243. int changes_detected = STB_FALSE;
  6244. int i;
  6245. int *remap;
  6246. int *rescan=NULL;
  6247. remap = (int *) malloc(sizeof(remap[0]) * stb_arr_len(db->dirs));
  6248. memset(remap, 0, sizeof(remap[0]) * stb_arr_len(db->dirs));
  6249. rescan = NULL;
  6250. for (i=0; i < stb_arr_len(db->dirs); ++i) {
  6251. struct _stat info;
  6252. if (stb__dircount_mask) {
  6253. ++stb__dircount;
  6254. if (!(stb__dircount & stb__dircount_mask)) {
  6255. printf(".");
  6256. }
  6257. }
  6258. if (0 == _stat(db->dirs[i].path, &info)) {
  6259. if (info.st_mode & _S_IFDIR) {
  6260. // it's still a directory, as expected
  6261. int n = abs(info.st_mtime - db->dirs[i].last_modified);
  6262. 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
  6263. // it's changed! force a rescan
  6264. // we don't want to scan it until we've stat()d its
  6265. // subdirs, though, so we queue it
  6266. if (stb__showfile) printf("Changed: %s - %08x:%08x\n", db->dirs[i].path, db->dirs[i].last_modified, info.st_mtime);
  6267. stb_arr_push(rescan, i);
  6268. // update the last_mod time
  6269. db->dirs[i].last_modified = info.st_mtime;
  6270. // ignore existing files in this dir
  6271. remap[i] = -1;
  6272. changes_detected = STB_TRUE;
  6273. } else {
  6274. // it hasn't changed, just copy it through unchanged
  6275. stb__dirtree_add_dir(db->dirs[i].path, db->dirs[i].last_modified, active);
  6276. remap[i] = stb_arr_lastn(active->dirs);
  6277. }
  6278. } else {
  6279. // this path used to refer to a directory, but now it's a file!
  6280. // assume that the parent directory is going to be forced to rescan anyway
  6281. goto delete_entry;
  6282. }
  6283. } else {
  6284. delete_entry:
  6285. // directory no longer exists, so don't copy it
  6286. // we don't free it because it's in the string pool now
  6287. db->dirs[i].path = NULL;
  6288. remap[i] = -1;
  6289. changes_detected = STB_TRUE;
  6290. }
  6291. }
  6292. // at this point, we have:
  6293. //
  6294. // <rescan> holds a list of directory indices that need to be scanned due to being out of date
  6295. // <remap> holds the directory index in <active> for each dir in <db>, if it exists; -1 if not
  6296. // directories in <rescan> are not in <active> yet
  6297. // so we can go ahead and remap all the known files right now
  6298. for (i=0; i < stb_arr_len(db->files); ++i) {
  6299. int dir = db->files[i].dir;
  6300. if (remap[dir] >= 0) {
  6301. stb__dirtree_add_file(db->files[i].name, remap[dir], db->files[i].size, db->files[i].last_modified, active);
  6302. }
  6303. }
  6304. // at this point we're done with db->files, and done with remap
  6305. free(remap);
  6306. // now scan those directories using the standard scan
  6307. for (i=0; i < stb_arr_len(rescan); ++i) {
  6308. int z = rescan[i];
  6309. stb__dirtree_scandir(db->dirs[z].path, db->dirs[z].last_modified, active);
  6310. }
  6311. stb_arr_free(rescan);
  6312. return changes_detected;
  6313. }
  6314. static void stb__dirtree_free_raw(stb_dirtree *d)
  6315. {
  6316. stb_free(d->string_pool);
  6317. stb_arr_free(d->dirs);
  6318. stb_arr_free(d->files);
  6319. }
  6320. stb_dirtree *stb_dirtree_get_with_file(char *dir, char *cache_file)
  6321. {
  6322. stb_dirtree *output = (stb_dirtree *) malloc(sizeof(*output));
  6323. stb_dirtree db,active;
  6324. int prev_dir_count, cache_mismatch;
  6325. char *stripped_dir; // store the directory name without a trailing '/' or '\\'
  6326. // load the database of last-known state on disk
  6327. db.string_pool = NULL;
  6328. db.files = NULL;
  6329. db.dirs = NULL;
  6330. stripped_dir = stb_strip_final_slash(strdup(dir));
  6331. if (cache_file != NULL)
  6332. stb__dirtree_load_db(cache_file, &db, stripped_dir);
  6333. else if (stb__showfile)
  6334. printf("No cache file\n");
  6335. active.files = NULL;
  6336. active.dirs = NULL;
  6337. active.string_pool = stb_malloc(0,1); // @TODO: share string pools between both?
  6338. // check all the directories in the database; make note if
  6339. // anything we scanned had changed, and rescan those things
  6340. cache_mismatch = stb__dirtree_update_db(&db, &active);
  6341. // check the root tree
  6342. prev_dir_count = stb_arr_len(active.dirs); // record how many directories we've seen
  6343. stb__dirtree_scandir(stripped_dir, 0, &active); // no last_modified time available for root
  6344. if (stb__dircount_mask)
  6345. printf(" \r");
  6346. // done with the DB; write it back out if any changes, i.e. either
  6347. // 1. any inconsistency found between cached information and actual disk
  6348. // or 2. if scanning the root found any new directories--which we detect because
  6349. // more than one directory got added to the active db during that scan
  6350. if (cache_mismatch || stb_arr_len(active.dirs) > prev_dir_count+1)
  6351. stb__dirtree_save_db(cache_file, &active, stripped_dir);
  6352. free(stripped_dir);
  6353. stb__dirtree_free_raw(&db);
  6354. *output = active;
  6355. return output;
  6356. }
  6357. stb_dirtree *stb_dirtree_get_dir(char *dir, char *cache_dir)
  6358. {
  6359. int i;
  6360. stb_uint8 sha[20];
  6361. char dir_lower[1024];
  6362. char cache_file[1024],*s;
  6363. if (cache_dir == NULL)
  6364. return stb_dirtree_get_with_file(dir, NULL);
  6365. strcpy(dir_lower, dir);
  6366. stb_tolower(dir_lower);
  6367. stb_sha1(sha, (unsigned char *) dir_lower, strlen(dir_lower));
  6368. strcpy(cache_file, cache_dir);
  6369. s = cache_file + strlen(cache_file);
  6370. if (s[-1] != '//' && s[-1] != '\\') *s++ = '/';
  6371. strcpy(s, "dirtree_");
  6372. s += strlen(s);
  6373. for (i=0; i < 8; ++i) {
  6374. char *hex = "0123456789abcdef";
  6375. stb_uint z = sha[i];
  6376. *s++ = hex[z >> 4];
  6377. *s++ = hex[z & 15];
  6378. }
  6379. strcpy(s, ".bin");
  6380. return stb_dirtree_get_with_file(dir, cache_file);
  6381. }
  6382. stb_dirtree *stb_dirtree_get(char *dir)
  6383. {
  6384. char cache_dir[256];
  6385. strcpy(cache_dir, "c:/stb");
  6386. #ifdef STB_HAS_REGISTRY
  6387. {
  6388. void *reg = stb_reg_open("rHKLM", "Software\\SilverSpaceship\\stb");
  6389. if (reg) {
  6390. stb_reg_read(reg, "dirtree", cache_dir, sizeof(cache_dir));
  6391. stb_reg_close(reg);
  6392. }
  6393. }
  6394. #endif
  6395. return stb_dirtree_get_dir(dir, cache_dir);
  6396. }
  6397. void stb_dirtree_free(stb_dirtree *d)
  6398. {
  6399. stb__dirtree_free_raw(d);
  6400. free(d);
  6401. }
  6402. void stb_dirtree_db_add_dir(stb_dirtree *active, char *path, time_t last)
  6403. {
  6404. stb__dirtree_add_dir(path, last, active);
  6405. }
  6406. void stb_dirtree_db_add_file(stb_dirtree *active, char *name, int dir, stb_int64 size, time_t last)
  6407. {
  6408. stb__dirtree_add_file(name, dir, size, last, active);
  6409. }
  6410. void stb_dirtree_db_read(stb_dirtree *target, char *filename, char *dir)
  6411. {
  6412. char *s = stb_strip_final_slash(strdup(dir));
  6413. target->dirs = 0;
  6414. target->files = 0;
  6415. target->string_pool = 0;
  6416. stb__dirtree_load_db(filename, target, s);
  6417. free(s);
  6418. }
  6419. void stb_dirtree_db_write(stb_dirtree *target, char *filename, char *dir)
  6420. {
  6421. stb__dirtree_save_db(filename, target, 0); // don't strip out any directories
  6422. }
  6423. #endif // STB_DEFINE
  6424. #endif // _WIN32
  6425. #endif // STB_NO_STB_STRINGS
  6426. //////////////////////////////////////////////////////////////////////////////
  6427. //
  6428. // STB_MALLOC_WRAPPER
  6429. //
  6430. // you can use the wrapper functions with your own malloc wrapper,
  6431. // or define STB_MALLOC_WRAPPER project-wide to have
  6432. // malloc/free/realloc/strdup all get vectored to it
  6433. // this has too many very specific error messages you could google for and find in stb.h,
  6434. // so don't use it if they don't want any stb.h-identifiable strings
  6435. #if defined(STB_DEFINE) && !defined(STB_NO_STB_STRINGS)
  6436. typedef struct
  6437. {
  6438. void *p;
  6439. char *file;
  6440. int line;
  6441. int size;
  6442. } stb_malloc_record;
  6443. #ifndef STB_MALLOC_HISTORY_COUNT
  6444. #define STB_MALLOC_HISTORY_COUNT 50 // 800 bytes
  6445. #endif
  6446. stb_malloc_record *stb__allocations;
  6447. static int stb__alloc_size, stb__alloc_limit, stb__alloc_mask;
  6448. int stb__alloc_count;
  6449. stb_malloc_record stb__alloc_history[STB_MALLOC_HISTORY_COUNT];
  6450. int stb__history_pos;
  6451. static int stb__hashfind(void *p)
  6452. {
  6453. stb_uint32 h = stb_hashptr(p);
  6454. int s,n = h & stb__alloc_mask;
  6455. if (stb__allocations[n].p == p)
  6456. return n;
  6457. s = stb_rehash(h)|1;
  6458. for(;;) {
  6459. if (stb__allocations[n].p == NULL)
  6460. return -1;
  6461. n = (n+s) & stb__alloc_mask;
  6462. if (stb__allocations[n].p == p)
  6463. return n;
  6464. }
  6465. }
  6466. int stb_wrapper_allocsize(void *p)
  6467. {
  6468. int n = stb__hashfind(p);
  6469. if (n < 0) return 0;
  6470. return stb__allocations[n].size;
  6471. }
  6472. static int stb__historyfind(void *p)
  6473. {
  6474. int n = stb__history_pos;
  6475. int i;
  6476. for (i=0; i < STB_MALLOC_HISTORY_COUNT; ++i) {
  6477. if (--n < 0) n = STB_MALLOC_HISTORY_COUNT-1;
  6478. if (stb__alloc_history[n].p == p)
  6479. return n;
  6480. }
  6481. return -1;
  6482. }
  6483. static void stb__add_alloc(void *p, int sz, char *file, int line);
  6484. static void stb__grow_alloc(void)
  6485. {
  6486. int i,old_num = stb__alloc_size;
  6487. stb_malloc_record *old = stb__allocations;
  6488. if (stb__alloc_size == 0)
  6489. stb__alloc_size = 64;
  6490. else
  6491. stb__alloc_size *= 2;
  6492. stb__allocations = (stb_malloc_record *) stb__realloc_raw(NULL, stb__alloc_size * sizeof(stb__allocations[0]));
  6493. if (stb__allocations == NULL)
  6494. stb_fatal("Internal error: couldn't grow malloc wrapper table");
  6495. memset(stb__allocations, 0, stb__alloc_size * sizeof(stb__allocations[0]));
  6496. stb__alloc_limit = (stb__alloc_size*3)>>2;
  6497. stb__alloc_mask = stb__alloc_size-1;
  6498. stb__alloc_count = 0;
  6499. for (i=0; i < old_num; ++i)
  6500. if (old[i].p > STB_DEL) {
  6501. stb__add_alloc(old[i].p, old[i].size, old[i].file, old[i].line);
  6502. assert(stb__hashfind(old[i].p) >= 0);
  6503. }
  6504. for (i=0; i < old_num; ++i)
  6505. if (old[i].p > STB_DEL)
  6506. assert(stb__hashfind(old[i].p) >= 0);
  6507. stb__realloc_raw(old, 0);
  6508. }
  6509. static void stb__add_alloc(void *p, int sz, char *file, int line)
  6510. {
  6511. stb_uint32 h;
  6512. int n;
  6513. if (stb__alloc_count >= stb__alloc_limit)
  6514. stb__grow_alloc();
  6515. h = stb_hashptr(p);
  6516. n = h & stb__alloc_mask;
  6517. if (stb__allocations[n].p > STB_DEL) {
  6518. int s = stb_rehash(h)|1;
  6519. do {
  6520. n = (n+s) & stb__alloc_mask;
  6521. } while (stb__allocations[n].p > STB_DEL);
  6522. }
  6523. assert(stb__allocations[n].p == NULL || stb__allocations[n].p == STB_DEL);
  6524. stb__allocations[n].p = p;
  6525. stb__allocations[n].size = sz;
  6526. stb__allocations[n].line = line;
  6527. stb__allocations[n].file = file;
  6528. ++stb__alloc_count;
  6529. }
  6530. static void stb__remove_alloc(int n, char *file, int line)
  6531. {
  6532. stb__alloc_history[stb__history_pos] = stb__allocations[n];
  6533. stb__alloc_history[stb__history_pos].file = file;
  6534. stb__alloc_history[stb__history_pos].line = line;
  6535. if (++stb__history_pos == STB_MALLOC_HISTORY_COUNT)
  6536. stb__history_pos = 0;
  6537. stb__allocations[n].p = STB_DEL;
  6538. --stb__alloc_count;
  6539. }
  6540. void stb_wrapper_malloc(void *p, int sz, char *file, int line)
  6541. {
  6542. if (!p) return;
  6543. stb__add_alloc(p,sz,file,line);
  6544. }
  6545. void stb_wrapper_free(void *p, char *file, int line)
  6546. {
  6547. int n;
  6548. if (p == NULL) return;
  6549. n = stb__hashfind(p);
  6550. if (n >= 0)
  6551. stb__remove_alloc(n, file, line);
  6552. else {
  6553. // tried to free something we hadn't allocated!
  6554. n = stb__historyfind(p);
  6555. assert(0); /* NOTREACHED */
  6556. if (n >= 0)
  6557. stb_fatal("Attempted to free %d-byte block %p at %s:%d previously freed/realloced at %s:%d",
  6558. stb__alloc_history[n].size, p,
  6559. file, line,
  6560. stb__alloc_history[n].file, stb__alloc_history[n].line);
  6561. else
  6562. stb_fatal("Attempted to free unknown block %p at %s:%d", p, file,line);
  6563. }
  6564. }
  6565. void stb_wrapper_check(void *p)
  6566. {
  6567. int n;
  6568. if (p == NULL) return;
  6569. n = stb__hashfind(p);
  6570. if (n >= 0) return;
  6571. for (n=0; n < stb__alloc_size; ++n)
  6572. if (stb__allocations[n].p == p)
  6573. stb_fatal("Internal error: pointer %p was allocated, but hash search failed", p);
  6574. // tried to free something that wasn't allocated!
  6575. n = stb__historyfind(p);
  6576. if (n >= 0)
  6577. stb_fatal("Checked %d-byte block %p previously freed/realloced at %s:%d",
  6578. stb__alloc_history[n].size, p,
  6579. stb__alloc_history[n].file, stb__alloc_history[n].line);
  6580. stb_fatal("Checked unknown block %p");
  6581. }
  6582. void stb_wrapper_realloc(void *p, void *q, int sz, char *file, int line)
  6583. {
  6584. int n;
  6585. if (p == NULL) { stb_wrapper_malloc(q, sz, file, line); return; }
  6586. if (q == NULL) return; // nothing happened
  6587. n = stb__hashfind(p);
  6588. if (n == -1) {
  6589. // tried to free something we hadn't allocated!
  6590. // this is weird, though, because we got past the realloc!
  6591. n = stb__historyfind(p);
  6592. assert(0); /* NOTREACHED */
  6593. if (n >= 0)
  6594. stb_fatal("Attempted to realloc %d-byte block %p at %s:%d previously freed/realloced at %s:%d",
  6595. stb__alloc_history[n].size, p,
  6596. file, line,
  6597. stb__alloc_history[n].file, stb__alloc_history[n].line);
  6598. else
  6599. stb_fatal("Attempted to realloc unknown block %p at %s:%d", p, file,line);
  6600. } else {
  6601. if (q == p) {
  6602. stb__allocations[n].size = sz;
  6603. stb__allocations[n].file = file;
  6604. stb__allocations[n].line = line;
  6605. } else {
  6606. stb__remove_alloc(n, file, line);
  6607. stb__add_alloc(q,sz,file,line);
  6608. }
  6609. }
  6610. }
  6611. void stb_wrapper_listall(void (*func)(void *ptr, int sz, char *file, int line))
  6612. {
  6613. int i;
  6614. for (i=0; i < stb__alloc_size; ++i)
  6615. if (stb__allocations[i].p > STB_DEL)
  6616. func(stb__allocations[i].p , stb__allocations[i].size,
  6617. stb__allocations[i].file, stb__allocations[i].line);
  6618. }
  6619. void stb_wrapper_dump(char *filename)
  6620. {
  6621. int i;
  6622. FILE *f = fopen(filename, "w");
  6623. if (!f) return;
  6624. for (i=0; i < stb__alloc_size; ++i)
  6625. if (stb__allocations[i].p > STB_DEL)
  6626. fprintf(f, "%p %7d - %4d %s\n",
  6627. stb__allocations[i].p , stb__allocations[i].size,
  6628. stb__allocations[i].line, stb__allocations[i].file);
  6629. }
  6630. #endif // STB_DEFINE
  6631. //////////////////////////////////////////////////////////////////////////////
  6632. //
  6633. // stb_pointer_set
  6634. //
  6635. //
  6636. // For data structures that support querying by key, data structure
  6637. // classes always hand-wave away the issue of what to do if two entries
  6638. // have the same key: basically, store a linked list of all the nodes
  6639. // which have the same key (a LISP-style list).
  6640. //
  6641. // The thing is, it's not that trivial. If you have an O(log n)
  6642. // lookup data structure, but then n/4 items have the same value,
  6643. // you don't want to spend O(n) time scanning that list when
  6644. // deleting an item if you already have a pointer to the item.
  6645. // (You have to spend O(n) time enumerating all the items with
  6646. // a given key, sure, and you can't accelerate deleting a particular
  6647. // item if you only have the key, not a pointer to the item.)
  6648. //
  6649. // I'm going to call this data structure, whatever it turns out to
  6650. // be, a "pointer set", because we don't store any associated data for
  6651. // items in this data structure, we just answer the question of
  6652. // whether an item is in it or not (it's effectively one bit per pointer).
  6653. // Technically they don't have to be pointers; you could cast ints
  6654. // to (void *) if you want, but you can't store 0 or 1 because of the
  6655. // hash table.
  6656. //
  6657. // Since the fastest data structure we might want to add support for
  6658. // identical-keys to is a hash table with O(1)-ish lookup time,
  6659. // that means that the conceptual "linked list of all items with
  6660. // the same indexed value" that we build needs to have the same
  6661. // performance; that way when we index a table we think is arbitrary
  6662. // ints, but in fact half of them are 0, we don't get screwed.
  6663. //
  6664. // Therefore, it needs to be a hash table, at least when it gets
  6665. // large. On the other hand, when the data has totally arbitrary ints
  6666. // or floats, there won't be many collisions, and we'll have tons of
  6667. // 1-item bitmaps. That will be grossly inefficient as hash tables;
  6668. // trade-off; the hash table is reasonably efficient per-item when
  6669. // it's large, but not when it's small. So we need to do something
  6670. // Judy-like and use different strategies depending on the size.
  6671. //
  6672. // Like Judy, we'll use the bottom bit to encode the strategy:
  6673. //
  6674. // bottom bits:
  6675. // 00 - direct pointer
  6676. // 01 - 4-item bucket (16 bytes, no length, NULLs)
  6677. // 10 - N-item array
  6678. // 11 - hash table
  6679. typedef struct stb_ps stb_ps;
  6680. STB_EXTERN int stb_ps_find (stb_ps *ps, void *value);
  6681. STB_EXTERN stb_ps * stb_ps_add (stb_ps *ps, void *value);
  6682. STB_EXTERN stb_ps * stb_ps_remove(stb_ps *ps, void *value);
  6683. STB_EXTERN stb_ps * stb_ps_remove_any(stb_ps *ps, void **value);
  6684. STB_EXTERN void stb_ps_delete(stb_ps *ps);
  6685. STB_EXTERN int stb_ps_count (stb_ps *ps);
  6686. STB_EXTERN stb_ps * stb_ps_copy (stb_ps *ps);
  6687. STB_EXTERN int stb_ps_subset(stb_ps *bigger, stb_ps *smaller);
  6688. STB_EXTERN int stb_ps_eq (stb_ps *p0, stb_ps *p1);
  6689. STB_EXTERN void ** stb_ps_getlist (stb_ps *ps, int *count);
  6690. STB_EXTERN int stb_ps_writelist(stb_ps *ps, void **list, int size );
  6691. // enum and fastlist don't allocate storage, but you must consume the
  6692. // list before there's any chance the data structure gets screwed up;
  6693. STB_EXTERN int stb_ps_enum (stb_ps *ps, void *data,
  6694. int (*func)(void *value, void*data) );
  6695. STB_EXTERN void ** stb_ps_fastlist(stb_ps *ps, int *count);
  6696. // result:
  6697. // returns a list, *count is the length of that list,
  6698. // but some entries of the list may be invalid;
  6699. // test with 'stb_ps_fastlist_valid(x)'
  6700. #define stb_ps_fastlist_valid(x) ((stb_uinta) (x) > 1)
  6701. #ifdef STB_DEFINE
  6702. enum
  6703. {
  6704. STB_ps_direct = 0,
  6705. STB_ps_bucket = 1,
  6706. STB_ps_array = 2,
  6707. STB_ps_hash = 3,
  6708. };
  6709. #define STB_BUCKET_SIZE 4
  6710. typedef struct
  6711. {
  6712. void *p[STB_BUCKET_SIZE];
  6713. } stb_ps_bucket;
  6714. #define GetBucket(p) ((stb_ps_bucket *) ((char *) (p) - STB_ps_bucket))
  6715. #define EncodeBucket(p) ((stb_ps *) ((char *) (p) + STB_ps_bucket))
  6716. static void stb_bucket_free(stb_ps_bucket *b)
  6717. {
  6718. free(b);
  6719. }
  6720. static stb_ps_bucket *stb_bucket_create2(void *v0, void *v1)
  6721. {
  6722. stb_ps_bucket *b = (stb_ps_bucket*) malloc(sizeof(*b));
  6723. b->p[0] = v0;
  6724. b->p[1] = v1;
  6725. b->p[2] = NULL;
  6726. b->p[3] = NULL;
  6727. return b;
  6728. }
  6729. static stb_ps_bucket * stb_bucket_create3(void **v)
  6730. {
  6731. stb_ps_bucket *b = (stb_ps_bucket*) malloc(sizeof(*b));
  6732. b->p[0] = v[0];
  6733. b->p[1] = v[1];
  6734. b->p[2] = v[2];
  6735. b->p[3] = NULL;
  6736. return b;
  6737. }
  6738. // could use stb_arr, but this will save us memory
  6739. typedef struct
  6740. {
  6741. int count;
  6742. void *p[1];
  6743. } stb_ps_array;
  6744. #define GetArray(p) ((stb_ps_array *) ((char *) (p) - STB_ps_array))
  6745. #define EncodeArray(p) ((stb_ps *) ((char *) (p) + STB_ps_array))
  6746. static int stb_ps_array_max = 13;
  6747. typedef struct
  6748. {
  6749. int size, mask;
  6750. int count, count_deletes;
  6751. int grow_threshhold;
  6752. int shrink_threshhold;
  6753. int rehash_threshhold;
  6754. int any_offset;
  6755. void *table[1];
  6756. } stb_ps_hash;
  6757. #define GetHash(p) ((stb_ps_hash *) ((char *) (p) - STB_ps_hash))
  6758. #define EncodeHash(p) ((stb_ps *) ((char *) (p) + STB_ps_hash))
  6759. #define stb_ps_empty(v) (((stb_uint32) v) <= 1)
  6760. static stb_ps_hash *stb_ps_makehash(int size, int old_size, void **old_data)
  6761. {
  6762. int i;
  6763. stb_ps_hash *h = (stb_ps_hash *) malloc(sizeof(*h) + (size-1) * sizeof(h->table[0]));
  6764. assert(stb_is_pow2(size));
  6765. h->size = size;
  6766. h->mask = size-1;
  6767. h->shrink_threshhold = (int) (0.3f * size);
  6768. h-> grow_threshhold = (int) (0.8f * size);
  6769. h->rehash_threshhold = (int) (0.9f * size);
  6770. h->count = 0;
  6771. h->count_deletes = 0;
  6772. h->any_offset = 0;
  6773. memset(h->table, 0, size * sizeof(h->table[0]));
  6774. for (i=0; i < old_size; ++i)
  6775. if (!stb_ps_empty((size_t)old_data[i]))
  6776. stb_ps_add(EncodeHash(h), old_data[i]);
  6777. return h;
  6778. }
  6779. void stb_ps_delete(stb_ps *ps)
  6780. {
  6781. switch (3 & (int)(size_t) ps) {
  6782. case STB_ps_direct: break;
  6783. case STB_ps_bucket: stb_bucket_free(GetBucket(ps)); break;
  6784. case STB_ps_array : free(GetArray(ps)); break;
  6785. case STB_ps_hash : free(GetHash(ps)); break;
  6786. }
  6787. }
  6788. stb_ps *stb_ps_copy(stb_ps *ps)
  6789. {
  6790. int i;
  6791. // not a switch: order based on expected performance/power-law distribution
  6792. switch (3 & (int)(size_t) ps) {
  6793. case STB_ps_direct: return ps;
  6794. case STB_ps_bucket: {
  6795. stb_ps_bucket *n = (stb_ps_bucket *) malloc(sizeof(*n));
  6796. *n = *GetBucket(ps);
  6797. return EncodeBucket(n);
  6798. }
  6799. case STB_ps_array: {
  6800. stb_ps_array *a = GetArray(ps);
  6801. stb_ps_array *n = (stb_ps_array *) malloc(sizeof(*n) + stb_ps_array_max * sizeof(n->p[0]));
  6802. n->count = a->count;
  6803. for (i=0; i < a->count; ++i)
  6804. n->p[i] = a->p[i];
  6805. return EncodeArray(n);
  6806. }
  6807. case STB_ps_hash: {
  6808. stb_ps_hash *h = GetHash(ps);
  6809. stb_ps_hash *n = stb_ps_makehash(h->size, h->size, h->table);
  6810. return EncodeHash(n);
  6811. }
  6812. }
  6813. assert(0); /* NOTREACHED */
  6814. return NULL;
  6815. }
  6816. int stb_ps_find(stb_ps *ps, void *value)
  6817. {
  6818. int i, code = 3 & (int)(size_t) ps;
  6819. assert((3 & (int)(size_t) value) == STB_ps_direct);
  6820. assert(stb_ps_fastlist_valid(value));
  6821. // not a switch: order based on expected performance/power-law distribution
  6822. if (code == STB_ps_direct)
  6823. return value == ps;
  6824. if (code == STB_ps_bucket) {
  6825. stb_ps_bucket *b = GetBucket(ps);
  6826. assert(STB_BUCKET_SIZE == 4);
  6827. if (b->p[0] == value || b->p[1] == value ||
  6828. b->p[2] == value || b->p[3] == value)
  6829. return STB_TRUE;
  6830. return STB_FALSE;
  6831. }
  6832. if (code == STB_ps_array) {
  6833. stb_ps_array *a = GetArray(ps);
  6834. for (i=0; i < a->count; ++i)
  6835. if (a->p[i] == value)
  6836. return STB_TRUE;
  6837. return STB_FALSE;
  6838. } else {
  6839. stb_ps_hash *h = GetHash(ps);
  6840. stb_uint32 hash = stb_hashptr(value);
  6841. stb_uint32 s, n = hash & h->mask;
  6842. void **t = h->table;
  6843. if (t[n] == value) return STB_TRUE;
  6844. if (t[n] == NULL) return STB_FALSE;
  6845. s = stb_rehash(hash) | 1;
  6846. do {
  6847. n = (n + s) & h->mask;
  6848. if (t[n] == value) return STB_TRUE;
  6849. } while (t[n] != NULL);
  6850. return STB_FALSE;
  6851. }
  6852. }
  6853. stb_ps * stb_ps_add (stb_ps *ps, void *value)
  6854. {
  6855. #ifdef STB_DEBUG
  6856. assert(!stb_ps_find(ps,value));
  6857. #endif
  6858. if (value == NULL) return ps; // ignore NULL adds to avoid bad breakage
  6859. assert((3 & (int)(size_t) value) == STB_ps_direct);
  6860. assert(stb_ps_fastlist_valid(value));
  6861. assert(value != STB_DEL); // STB_DEL is less likely
  6862. switch (3 & (int)(size_t) ps) {
  6863. case STB_ps_direct:
  6864. if (ps == NULL) return (stb_ps *) value;
  6865. return EncodeBucket(stb_bucket_create2(ps,value));
  6866. case STB_ps_bucket: {
  6867. stb_ps_bucket *b = GetBucket(ps);
  6868. stb_ps_array *a;
  6869. assert(STB_BUCKET_SIZE == 4);
  6870. if (b->p[0] == NULL) { b->p[0] = value; return ps; }
  6871. if (b->p[1] == NULL) { b->p[1] = value; return ps; }
  6872. if (b->p[2] == NULL) { b->p[2] = value; return ps; }
  6873. if (b->p[3] == NULL) { b->p[3] = value; return ps; }
  6874. a = (stb_ps_array *) malloc(sizeof(*a) + 7 * sizeof(a->p[0])); // 8 slots, must be 2^k
  6875. memcpy(a->p, b, sizeof(*b));
  6876. a->p[4] = value;
  6877. a->count = 5;
  6878. stb_bucket_free(b);
  6879. return EncodeArray(a);
  6880. }
  6881. case STB_ps_array: {
  6882. stb_ps_array *a = GetArray(ps);
  6883. if (a->count == stb_ps_array_max) {
  6884. // promote from array to hash
  6885. stb_ps_hash *h = stb_ps_makehash(2 << stb_log2_ceil(a->count), a->count, a->p);
  6886. free(a);
  6887. return stb_ps_add(EncodeHash(h), value);
  6888. }
  6889. // do we need to resize the array? the array doubles in size when it
  6890. // crosses a power-of-two
  6891. if ((a->count & (a->count-1))==0) {
  6892. int newsize = a->count*2;
  6893. // clamp newsize to max if:
  6894. // 1. it's larger than max
  6895. // 2. newsize*1.5 is larger than max (to avoid extra resizing)
  6896. if (newsize + a->count > stb_ps_array_max)
  6897. newsize = stb_ps_array_max;
  6898. a = (stb_ps_array *) realloc(a, sizeof(*a) + (newsize-1) * sizeof(a->p[0]));
  6899. }
  6900. a->p[a->count++] = value;
  6901. return EncodeArray(a);
  6902. }
  6903. case STB_ps_hash: {
  6904. stb_ps_hash *h = GetHash(ps);
  6905. stb_uint32 hash = stb_hashptr(value);
  6906. stb_uint32 n = hash & h->mask;
  6907. void **t = h->table;
  6908. // find first NULL or STB_DEL entry
  6909. if (!stb_ps_empty((size_t)t[n])) {
  6910. stb_uint32 s = stb_rehash(hash) | 1;
  6911. do {
  6912. n = (n + s) & h->mask;
  6913. } while (!stb_ps_empty((size_t)t[n]));
  6914. }
  6915. if (t[n] == STB_DEL)
  6916. -- h->count_deletes;
  6917. t[n] = value;
  6918. ++ h->count;
  6919. if (h->count == h->grow_threshhold) {
  6920. stb_ps_hash *h2 = stb_ps_makehash(h->size*2, h->size, t);
  6921. free(h);
  6922. return EncodeHash(h2);
  6923. }
  6924. if (h->count + h->count_deletes == h->rehash_threshhold) {
  6925. stb_ps_hash *h2 = stb_ps_makehash(h->size, h->size, t);
  6926. free(h);
  6927. return EncodeHash(h2);
  6928. }
  6929. return ps;
  6930. }
  6931. }
  6932. return NULL; /* NOTREACHED */
  6933. }
  6934. stb_ps *stb_ps_remove(stb_ps *ps, void *value)
  6935. {
  6936. #ifdef STB_DEBUG
  6937. assert(stb_ps_find(ps, value));
  6938. #endif
  6939. assert((3 & (int)(size_t) value) == STB_ps_direct);
  6940. if (value == NULL) return ps; // ignore NULL removes to avoid bad breakage
  6941. switch (3 & (int)(size_t) ps) {
  6942. case STB_ps_direct:
  6943. return ps == value ? NULL : ps;
  6944. case STB_ps_bucket: {
  6945. stb_ps_bucket *b = GetBucket(ps);
  6946. int count=0;
  6947. assert(STB_BUCKET_SIZE == 4);
  6948. if (b->p[0] == value) b->p[0] = NULL; else count += (b->p[0] != NULL);
  6949. if (b->p[1] == value) b->p[1] = NULL; else count += (b->p[1] != NULL);
  6950. if (b->p[2] == value) b->p[2] = NULL; else count += (b->p[2] != NULL);
  6951. if (b->p[3] == value) b->p[3] = NULL; else count += (b->p[3] != NULL);
  6952. if (count == 1) { // shrink bucket at size 1
  6953. value = b->p[0];
  6954. if (value == NULL) value = b->p[1];
  6955. if (value == NULL) value = b->p[2];
  6956. if (value == NULL) value = b->p[3];
  6957. assert(value != NULL);
  6958. stb_bucket_free(b);
  6959. return (stb_ps *) value; // return STB_ps_direct of value
  6960. }
  6961. return ps;
  6962. }
  6963. case STB_ps_array: {
  6964. stb_ps_array *a = GetArray(ps);
  6965. int i;
  6966. for (i=0; i < a->count; ++i) {
  6967. if (a->p[i] == value) {
  6968. a->p[i] = a->p[--a->count];
  6969. if (a->count == 3) { // shrink to bucket!
  6970. stb_ps_bucket *b = stb_bucket_create3(a->p);
  6971. free(a);
  6972. return EncodeBucket(b);
  6973. }
  6974. return ps;
  6975. }
  6976. }
  6977. return ps;
  6978. }
  6979. case STB_ps_hash: {
  6980. stb_ps_hash *h = GetHash(ps);
  6981. stb_uint32 hash = stb_hashptr(value);
  6982. stb_uint32 s, n = hash & h->mask;
  6983. void **t = h->table;
  6984. if (t[n] != value) {
  6985. s = stb_rehash(hash) | 1;
  6986. do {
  6987. n = (n + s) & h->mask;
  6988. } while (t[n] != value);
  6989. }
  6990. t[n] = STB_DEL;
  6991. -- h->count;
  6992. ++ h->count_deletes;
  6993. // should we shrink down to an array?
  6994. if (h->count < stb_ps_array_max) {
  6995. int n = 1 << stb_log2_floor(stb_ps_array_max);
  6996. if (h->count < n) {
  6997. stb_ps_array *a = (stb_ps_array *) malloc(sizeof(*a) + (n-1) * sizeof(a->p[0]));
  6998. int i,j=0;
  6999. for (i=0; i < h->size; ++i)
  7000. if (!stb_ps_empty((size_t)t[i]))
  7001. a->p[j++] = t[i];
  7002. assert(j == h->count);
  7003. a->count = j;
  7004. free(h);
  7005. return EncodeArray(a);
  7006. }
  7007. }
  7008. if (h->count == h->shrink_threshhold) {
  7009. stb_ps_hash *h2 = stb_ps_makehash(h->size >> 1, h->size, t);
  7010. free(h);
  7011. return EncodeHash(h2);
  7012. }
  7013. return ps;
  7014. }
  7015. }
  7016. return ps; /* NOTREACHED */
  7017. }
  7018. stb_ps *stb_ps_remove_any(stb_ps *ps, void **value)
  7019. {
  7020. assert(ps != NULL);
  7021. switch (3 & (int)(size_t) ps) {
  7022. case STB_ps_direct:
  7023. *value = ps;
  7024. return NULL;
  7025. case STB_ps_bucket: {
  7026. stb_ps_bucket *b = GetBucket(ps);
  7027. int count=0, slast=0, last=0;
  7028. assert(STB_BUCKET_SIZE == 4);
  7029. if (b->p[0]) { ++count; last = 0; }
  7030. if (b->p[1]) { ++count; slast = last; last = 1; }
  7031. if (b->p[2]) { ++count; slast = last; last = 2; }
  7032. if (b->p[3]) { ++count; slast = last; last = 3; }
  7033. *value = b->p[last];
  7034. b->p[last] = 0;
  7035. if (count == 2) {
  7036. void *leftover = b->p[slast]; // second to last
  7037. stb_bucket_free(b);
  7038. return (stb_ps *) leftover;
  7039. }
  7040. return ps;
  7041. }
  7042. case STB_ps_array: {
  7043. stb_ps_array *a = GetArray(ps);
  7044. *value = a->p[a->count-1];
  7045. if (a->count == 4)
  7046. return stb_ps_remove(ps, *value);
  7047. --a->count;
  7048. return ps;
  7049. }
  7050. case STB_ps_hash: {
  7051. stb_ps_hash *h = GetHash(ps);
  7052. void **t = h->table;
  7053. stb_uint32 n = h->any_offset;
  7054. while (stb_ps_empty((size_t)t[n]))
  7055. n = (n + 1) & h->mask;
  7056. *value = t[n];
  7057. h->any_offset = (n+1) & h->mask;
  7058. // check if we need to skip down to the previous type
  7059. if (h->count-1 < stb_ps_array_max || h->count-1 == h->shrink_threshhold)
  7060. return stb_ps_remove(ps, *value);
  7061. t[n] = STB_DEL;
  7062. -- h->count;
  7063. ++ h->count_deletes;
  7064. return ps;
  7065. }
  7066. }
  7067. return ps; /* NOTREACHED */
  7068. }
  7069. void ** stb_ps_getlist(stb_ps *ps, int *count)
  7070. {
  7071. int i,n=0;
  7072. void **p = NULL;
  7073. switch (3 & (int)(size_t) ps) {
  7074. case STB_ps_direct:
  7075. if (ps == NULL) { *count = 0; return NULL; }
  7076. p = (void **) malloc(sizeof(*p) * 1);
  7077. p[0] = ps;
  7078. *count = 1;
  7079. return p;
  7080. case STB_ps_bucket: {
  7081. stb_ps_bucket *b = GetBucket(ps);
  7082. p = (void **) malloc(sizeof(*p) * STB_BUCKET_SIZE);
  7083. for (i=0; i < STB_BUCKET_SIZE; ++i)
  7084. if (b->p[i] != NULL)
  7085. p[n++] = b->p[i];
  7086. break;
  7087. }
  7088. case STB_ps_array: {
  7089. stb_ps_array *a = GetArray(ps);
  7090. p = (void **) malloc(sizeof(*p) * a->count);
  7091. memcpy(p, a->p, sizeof(*p) * a->count);
  7092. *count = a->count;
  7093. return p;
  7094. }
  7095. case STB_ps_hash: {
  7096. stb_ps_hash *h = GetHash(ps);
  7097. p = (void **) malloc(sizeof(*p) * h->count);
  7098. for (i=0; i < h->size; ++i)
  7099. if (!stb_ps_empty((size_t)h->table[i]))
  7100. p[n++] = h->table[i];
  7101. break;
  7102. }
  7103. }
  7104. *count = n;
  7105. return p;
  7106. }
  7107. int stb_ps_writelist(stb_ps *ps, void **list, int size )
  7108. {
  7109. int i,n=0;
  7110. switch (3 & (int)(size_t) ps) {
  7111. case STB_ps_direct:
  7112. if (ps == NULL || size <= 0) return 0;
  7113. list[0] = ps;
  7114. return 1;
  7115. case STB_ps_bucket: {
  7116. stb_ps_bucket *b = GetBucket(ps);
  7117. for (i=0; i < STB_BUCKET_SIZE; ++i)
  7118. if (b->p[i] != NULL && n < size)
  7119. list[n++] = b->p[i];
  7120. return n;
  7121. }
  7122. case STB_ps_array: {
  7123. stb_ps_array *a = GetArray(ps);
  7124. n = stb_min(size, a->count);
  7125. memcpy(list, a->p, sizeof(*list) * n);
  7126. return n;
  7127. }
  7128. case STB_ps_hash: {
  7129. stb_ps_hash *h = GetHash(ps);
  7130. if (size <= 0) return 0;
  7131. for (i=0; i < h->count; ++i) {
  7132. if (!stb_ps_empty((size_t)h->table[i])) {
  7133. list[n++] = h->table[i];
  7134. if (n == size) break;
  7135. }
  7136. }
  7137. return n;
  7138. }
  7139. }
  7140. return 0; /* NOTREACHED */
  7141. }
  7142. int stb_ps_enum(stb_ps *ps, void *data, int (*func)(void *value, void *data))
  7143. {
  7144. int i;
  7145. switch (3 & (int)(size_t) ps) {
  7146. case STB_ps_direct:
  7147. if (ps == NULL) return STB_TRUE;
  7148. return func(ps, data);
  7149. case STB_ps_bucket: {
  7150. stb_ps_bucket *b = GetBucket(ps);
  7151. for (i=0; i < STB_BUCKET_SIZE; ++i)
  7152. if (b->p[i] != NULL)
  7153. if (!func(b->p[i], data))
  7154. return STB_FALSE;
  7155. return STB_TRUE;
  7156. }
  7157. case STB_ps_array: {
  7158. stb_ps_array *a = GetArray(ps);
  7159. for (i=0; i < a->count; ++i)
  7160. if (!func(a->p[i], data))
  7161. return STB_FALSE;
  7162. return STB_TRUE;
  7163. }
  7164. case STB_ps_hash: {
  7165. stb_ps_hash *h = GetHash(ps);
  7166. for (i=0; i < h->count; ++i)
  7167. if (!stb_ps_empty((size_t)h->table[i]))
  7168. if (!func(h->table[i], data))
  7169. return STB_FALSE;
  7170. return STB_TRUE;
  7171. }
  7172. }
  7173. return STB_TRUE; /* NOTREACHED */
  7174. }
  7175. int stb_ps_count (stb_ps *ps)
  7176. {
  7177. switch (3 & (int)(size_t) ps) {
  7178. case STB_ps_direct:
  7179. return ps != NULL;
  7180. case STB_ps_bucket: {
  7181. stb_ps_bucket *b = GetBucket(ps);
  7182. return (b->p[0] != NULL) + (b->p[1] != NULL) +
  7183. (b->p[2] != NULL) + (b->p[3] != NULL);
  7184. }
  7185. case STB_ps_array: {
  7186. stb_ps_array *a = GetArray(ps);
  7187. return a->count;
  7188. }
  7189. case STB_ps_hash: {
  7190. stb_ps_hash *h = GetHash(ps);
  7191. return h->count;
  7192. }
  7193. }
  7194. return 0;
  7195. }
  7196. void ** stb_ps_fastlist(stb_ps *ps, int *count)
  7197. {
  7198. static void *storage;
  7199. switch (3 & (int)(size_t) ps) {
  7200. case STB_ps_direct:
  7201. if (ps == NULL) { *count = 0; return NULL; }
  7202. storage = ps;
  7203. *count = 1;
  7204. return &storage;
  7205. case STB_ps_bucket: {
  7206. stb_ps_bucket *b = GetBucket(ps);
  7207. *count = STB_BUCKET_SIZE;
  7208. return b->p;
  7209. }
  7210. case STB_ps_array: {
  7211. stb_ps_array *a = GetArray(ps);
  7212. *count = a->count;
  7213. return a->p;
  7214. }
  7215. case STB_ps_hash: {
  7216. stb_ps_hash *h = GetHash(ps);
  7217. *count = h->size;
  7218. return h->table;
  7219. }
  7220. }
  7221. return NULL; /* NOTREACHED */
  7222. }
  7223. int stb_ps_subset(stb_ps *bigger, stb_ps *smaller)
  7224. {
  7225. int i, listlen;
  7226. void **list = stb_ps_fastlist(smaller, &listlen);
  7227. for(i=0; i < listlen; ++i)
  7228. if (stb_ps_fastlist_valid(list[i]))
  7229. if (!stb_ps_find(bigger, list[i]))
  7230. return 0;
  7231. return 1;
  7232. }
  7233. int stb_ps_eq(stb_ps *p0, stb_ps *p1)
  7234. {
  7235. if (stb_ps_count(p0) != stb_ps_count(p1))
  7236. return 0;
  7237. return stb_ps_subset(p0, p1);
  7238. }
  7239. #undef GetBucket
  7240. #undef GetArray
  7241. #undef GetHash
  7242. #undef EncodeBucket
  7243. #undef EncodeArray
  7244. #undef EncodeHash
  7245. #endif
  7246. //////////////////////////////////////////////////////////////////////////////
  7247. //
  7248. // Random Numbers via Meresenne Twister or LCG
  7249. //
  7250. STB_EXTERN unsigned long stb_srandLCG(unsigned long seed);
  7251. STB_EXTERN unsigned long stb_randLCG(void);
  7252. STB_EXTERN double stb_frandLCG(void);
  7253. STB_EXTERN void stb_srand(unsigned long seed);
  7254. STB_EXTERN unsigned long stb_rand(void);
  7255. STB_EXTERN double stb_frand(void);
  7256. STB_EXTERN void stb_shuffle(void *p, size_t n, size_t sz,
  7257. unsigned long seed);
  7258. STB_EXTERN void stb_reverse(void *p, size_t n, size_t sz);
  7259. STB_EXTERN unsigned long stb_randLCG_explicit(unsigned long seed);
  7260. #define stb_rand_define(x,y) \
  7261. \
  7262. unsigned long x(void) \
  7263. { \
  7264. static unsigned long stb__rand = y; \
  7265. stb__rand = stb__rand * 2147001325 + 715136305; /* BCPL */ \
  7266. return 0x31415926 ^ ((stb__rand >> 16) + (stb__rand << 16)); \
  7267. }
  7268. #ifdef STB_DEFINE
  7269. unsigned long stb_randLCG_explicit(unsigned long seed)
  7270. {
  7271. return seed * 2147001325 + 715136305;
  7272. }
  7273. static unsigned long stb__rand_seed=0;
  7274. unsigned long stb_srandLCG(unsigned long seed)
  7275. {
  7276. unsigned long previous = stb__rand_seed;
  7277. stb__rand_seed = seed;
  7278. return previous;
  7279. }
  7280. unsigned long stb_randLCG(void)
  7281. {
  7282. stb__rand_seed = stb__rand_seed * 2147001325 + 715136305; // BCPL generator
  7283. // shuffle non-random bits to the middle, and xor to decorrelate with seed
  7284. return 0x31415926 ^ ((stb__rand_seed >> 16) + (stb__rand_seed << 16));
  7285. }
  7286. double stb_frandLCG(void)
  7287. {
  7288. return stb_randLCG() / ((double) (1 << 16) * (1 << 16));
  7289. }
  7290. void stb_shuffle(void *p, size_t n, size_t sz, unsigned long seed)
  7291. {
  7292. char *a;
  7293. unsigned long old_seed;
  7294. int i;
  7295. if (seed)
  7296. old_seed = stb_srandLCG(seed);
  7297. a = (char *) p + (n-1) * sz;
  7298. for (i=n; i > 1; --i) {
  7299. int j = stb_randLCG() % i;
  7300. stb_swap(a, (char *) p + j * sz, sz);
  7301. a -= sz;
  7302. }
  7303. if (seed)
  7304. stb_srandLCG(old_seed);
  7305. }
  7306. void stb_reverse(void *p, size_t n, size_t sz)
  7307. {
  7308. int i,j = n-1;
  7309. for (i=0; i < j; ++i,--j) {
  7310. stb_swap((char *) p + i * sz, (char *) p + j * sz, sz);
  7311. }
  7312. }
  7313. // public domain Mersenne Twister by Michael Brundage
  7314. #define STB__MT_LEN 624
  7315. int stb__mt_index = STB__MT_LEN*sizeof(unsigned long)+1;
  7316. unsigned long stb__mt_buffer[STB__MT_LEN];
  7317. void stb_srand(unsigned long seed)
  7318. {
  7319. int i;
  7320. unsigned long old = stb_srandLCG(seed);
  7321. for (i = 0; i < STB__MT_LEN; i++)
  7322. stb__mt_buffer[i] = stb_randLCG();
  7323. stb_srandLCG(old);
  7324. stb__mt_index = STB__MT_LEN*sizeof(unsigned long);
  7325. }
  7326. #define STB__MT_IA 397
  7327. #define STB__MT_IB (STB__MT_LEN - STB__MT_IA)
  7328. #define STB__UPPER_MASK 0x80000000
  7329. #define STB__LOWER_MASK 0x7FFFFFFF
  7330. #define STB__MATRIX_A 0x9908B0DF
  7331. #define STB__TWIST(b,i,j) ((b)[i] & STB__UPPER_MASK) | ((b)[j] & STB__LOWER_MASK)
  7332. #define STB__MAGIC(s) (((s)&1)*STB__MATRIX_A)
  7333. unsigned long stb_rand()
  7334. {
  7335. unsigned long * b = stb__mt_buffer;
  7336. int idx = stb__mt_index;
  7337. unsigned long s,r;
  7338. int i;
  7339. if (idx >= STB__MT_LEN*sizeof(unsigned long)) {
  7340. if (idx > STB__MT_LEN*sizeof(unsigned long))
  7341. stb_srand(0);
  7342. idx = 0;
  7343. i = 0;
  7344. for (; i < STB__MT_IB; i++) {
  7345. s = STB__TWIST(b, i, i+1);
  7346. b[i] = b[i + STB__MT_IA] ^ (s >> 1) ^ STB__MAGIC(s);
  7347. }
  7348. for (; i < STB__MT_LEN-1; i++) {
  7349. s = STB__TWIST(b, i, i+1);
  7350. b[i] = b[i - STB__MT_IB] ^ (s >> 1) ^ STB__MAGIC(s);
  7351. }
  7352. s = STB__TWIST(b, STB__MT_LEN-1, 0);
  7353. b[STB__MT_LEN-1] = b[STB__MT_IA-1] ^ (s >> 1) ^ STB__MAGIC(s);
  7354. }
  7355. stb__mt_index = idx + sizeof(unsigned long);
  7356. r = *(unsigned long *)((unsigned char *)b + idx);
  7357. r ^= (r >> 11);
  7358. r ^= (r << 7) & 0x9D2C5680;
  7359. r ^= (r << 15) & 0xEFC60000;
  7360. r ^= (r >> 18);
  7361. return r;
  7362. }
  7363. double stb_frand(void)
  7364. {
  7365. return stb_rand() / ((double) (1 << 16) * (1 << 16));
  7366. }
  7367. #endif
  7368. //////////////////////////////////////////////////////////////////////////////
  7369. //
  7370. // stb_dupe
  7371. //
  7372. // stb_dupe is a duplicate-finding system for very, very large data
  7373. // structures--large enough that sorting is too slow, but not so large
  7374. // that we can't keep all the data in memory. using it works as follows:
  7375. //
  7376. // 1. create an stb_dupe:
  7377. // provide a hash function
  7378. // provide an equality function
  7379. // provide an estimate for the size
  7380. // optionally provide a comparison function
  7381. //
  7382. // 2. traverse your data, 'adding' pointers to the stb_dupe
  7383. //
  7384. // 3. finish and ask for duplicates
  7385. //
  7386. // the stb_dupe will discard its intermediate data and build
  7387. // a collection of sorted lists of duplicates, with non-duplicate
  7388. // entries omitted entirely
  7389. //
  7390. //
  7391. // Implementation strategy:
  7392. //
  7393. // while collecting the N items, we keep a hash table of approximate
  7394. // size sqrt(N). (if you tell use the N up front, the hash table is
  7395. // just that size exactly)
  7396. //
  7397. // each entry in the hash table is just an stb__arr of pointers (no need
  7398. // to use stb_ps, because we don't need to delete from these)
  7399. //
  7400. // for step 3, for each entry in the hash table, we apply stb_dupe to it
  7401. // recursively. once the size gets small enough (or doesn't decrease
  7402. // significantly), we switch to either using qsort() on the comparison
  7403. // function, or else we just do the icky N^2 gather
  7404. typedef struct stb_dupe stb_dupe;
  7405. typedef int (*stb_compare_func)(void *a, void *b);
  7406. typedef int (*stb_hash_func)(void *a, unsigned int seed);
  7407. STB_EXTERN void stb_dupe_free(stb_dupe *sd);
  7408. STB_EXTERN stb_dupe *stb_dupe_create(stb_hash_func hash,
  7409. stb_compare_func eq, int size, stb_compare_func ineq);
  7410. STB_EXTERN void stb_dupe_add(stb_dupe *sd, void *item);
  7411. STB_EXTERN void stb_dupe_finish(stb_dupe *sd);
  7412. STB_EXTERN int stb_dupe_numsets(stb_dupe *sd);
  7413. STB_EXTERN void **stb_dupe_set(stb_dupe *sd, int num);
  7414. STB_EXTERN int stb_dupe_set_count(stb_dupe *sd, int num);
  7415. struct stb_dupe
  7416. {
  7417. void ***hash_table;
  7418. int hash_size;
  7419. int size_log2;
  7420. int population;
  7421. int hash_shift;
  7422. stb_hash_func hash;
  7423. stb_compare_func eq;
  7424. stb_compare_func ineq;
  7425. void ***dupes;
  7426. };
  7427. #ifdef STB_DEFINE
  7428. int stb_dupe_numsets(stb_dupe *sd)
  7429. {
  7430. assert(sd->hash_table == NULL);
  7431. return stb_arr_len(sd->dupes);
  7432. }
  7433. void **stb_dupe_set(stb_dupe *sd, int num)
  7434. {
  7435. assert(sd->hash_table == NULL);
  7436. return sd->dupes[num];
  7437. }
  7438. int stb_dupe_set_count(stb_dupe *sd, int num)
  7439. {
  7440. assert(sd->hash_table == NULL);
  7441. return stb_arr_len(sd->dupes[num]);
  7442. }
  7443. stb_dupe *stb_dupe_create(stb_hash_func hash, stb_compare_func eq, int size,
  7444. stb_compare_func ineq)
  7445. {
  7446. int i, hsize;
  7447. stb_dupe *sd = (stb_dupe *) malloc(sizeof(*sd));
  7448. sd->size_log2 = 4;
  7449. hsize = 1 << sd->size_log2;
  7450. while (hsize * hsize < size) {
  7451. ++sd->size_log2;
  7452. hsize *= 2;
  7453. }
  7454. sd->hash = hash;
  7455. sd->eq = eq;
  7456. sd->ineq = ineq;
  7457. sd->hash_shift = 0;
  7458. sd->population = 0;
  7459. sd->hash_size = hsize;
  7460. sd->hash_table = (void ***) malloc(sizeof(*sd->hash_table) * hsize);
  7461. for (i=0; i < hsize; ++i)
  7462. sd->hash_table[i] = NULL;
  7463. sd->dupes = NULL;
  7464. return sd;
  7465. }
  7466. void stb_dupe_add(stb_dupe *sd, void *item)
  7467. {
  7468. stb_uint32 hash = sd->hash(item, sd->hash_shift);
  7469. int z = hash & (sd->hash_size-1);
  7470. stb_arr_push(sd->hash_table[z], item);
  7471. ++sd->population;
  7472. }
  7473. void stb_dupe_free(stb_dupe *sd)
  7474. {
  7475. int i;
  7476. for (i=0; i < stb_arr_len(sd->dupes); ++i)
  7477. if (sd->dupes[i])
  7478. stb_arr_free(sd->dupes[i]);
  7479. stb_arr_free(sd->dupes);
  7480. free(sd);
  7481. }
  7482. static stb_compare_func stb__compare;
  7483. static int stb__dupe_compare(const void *a, const void *b)
  7484. {
  7485. void *p = *(void **) a;
  7486. void *q = *(void **) b;
  7487. return stb__compare(p,q);
  7488. }
  7489. void stb_dupe_finish(stb_dupe *sd)
  7490. {
  7491. int i,j,k;
  7492. assert(sd->dupes == NULL);
  7493. for (i=0; i < sd->hash_size; ++i) {
  7494. void ** list = sd->hash_table[i];
  7495. if (list != NULL) {
  7496. int n = stb_arr_len(list);
  7497. // @TODO: measure to find good numbers instead of just making them up!
  7498. int thresh = (sd->ineq ? 200 : 20);
  7499. // if n is large enough to be worth it, and n is smaller than
  7500. // before (so we can guarantee we'll use a smaller hash table);
  7501. // and there are enough hash bits left, assuming full 32-bit hash
  7502. if (n > thresh && n < (sd->population >> 3) && sd->hash_shift + sd->size_log2*2 < 32) {
  7503. // recursively process this row using stb_dupe, O(N log log N)
  7504. stb_dupe *d = stb_dupe_create(sd->hash, sd->eq, n, sd->ineq);
  7505. d->hash_shift = stb_randLCG_explicit(sd->hash_shift);
  7506. for (j=0; j < n; ++j)
  7507. stb_dupe_add(d, list[j]);
  7508. stb_arr_free(sd->hash_table[i]);
  7509. stb_dupe_finish(d);
  7510. for (j=0; j < stb_arr_len(d->dupes); ++j) {
  7511. stb_arr_push(sd->dupes, d->dupes[j]);
  7512. d->dupes[j] = NULL; // take over ownership
  7513. }
  7514. stb_dupe_free(d);
  7515. } else if (sd->ineq) {
  7516. // process this row using qsort(), O(N log N)
  7517. stb__compare = sd->ineq;
  7518. qsort(list, n, sizeof(list[0]), stb__dupe_compare);
  7519. // find equal subsequences of the list
  7520. for (j=0; j < n-1; ) {
  7521. // find a subsequence from j..k
  7522. for (k=j; k < n; ++k)
  7523. // only use ineq so eq can be left undefined
  7524. if (sd->ineq(list[j], list[k]))
  7525. break;
  7526. // k is the first one not in the subsequence
  7527. if (k-j > 1) {
  7528. void **mylist = NULL;
  7529. stb_arr_setlen(mylist, k-j);
  7530. memcpy(mylist, list+j, sizeof(list[j]) * (k-j));
  7531. stb_arr_push(sd->dupes, mylist);
  7532. }
  7533. j = k;
  7534. }
  7535. stb_arr_free(sd->hash_table[i]);
  7536. } else {
  7537. // process this row using eq(), O(N^2)
  7538. for (j=0; j < n; ++j) {
  7539. if (list[j] != NULL) {
  7540. void **output = NULL;
  7541. for (k=j+1; k < n; ++k) {
  7542. if (sd->eq(list[j], list[k])) {
  7543. if (output == NULL)
  7544. stb_arr_push(output, list[j]);
  7545. stb_arr_push(output, list[k]);
  7546. list[k] = NULL;
  7547. }
  7548. }
  7549. list[j] = NULL;
  7550. if (output)
  7551. stb_arr_push(sd->dupes, output);
  7552. }
  7553. }
  7554. stb_arr_free(sd->hash_table[i]);
  7555. }
  7556. }
  7557. }
  7558. free(sd->hash_table);
  7559. sd->hash_table = NULL;
  7560. }
  7561. #endif
  7562. //////////////////////////////////////////////////////////////////////////////
  7563. //
  7564. // templatized Sort routine
  7565. //
  7566. // This is an attempt to implement a templated sorting algorithm.
  7567. // To use it, you have to explicitly instantiate it as a _function_,
  7568. // then you call that function. This allows the comparison to be inlined,
  7569. // giving the sort similar performance to C++ sorts.
  7570. //
  7571. // It implements quicksort with three-way-median partitioning (generally
  7572. // well-behaved), with a final insertion sort pass.
  7573. //
  7574. // When you define the compare expression, you should assume you have
  7575. // elements of your array pointed to by 'a' and 'b', and perform the comparison
  7576. // on those. OR you can use one or more statements; first say '0;', then
  7577. // write whatever code you want, and compute the result into a variable 'c'.
  7578. #define stb_declare_sort(FUNCNAME, TYPE) \
  7579. void FUNCNAME(TYPE *p, int n)
  7580. #define stb_define_sort(FUNCNAME,TYPE,COMPARE) \
  7581. stb__define_sort( void, FUNCNAME,TYPE,COMPARE)
  7582. #define stb_define_sort_static(FUNCNAME,TYPE,COMPARE) \
  7583. stb__define_sort(static void, FUNCNAME,TYPE,COMPARE)
  7584. #define stb__define_sort(MODE, FUNCNAME, TYPE, COMPARE) \
  7585. \
  7586. static void STB_(FUNCNAME,_ins_sort)(TYPE *p, int n) \
  7587. { \
  7588. int i,j; \
  7589. for (i=1; i < n; ++i) { \
  7590. TYPE t = p[i], *a = &t; \
  7591. j = i; \
  7592. while (j > 0) { \
  7593. TYPE *b = &p[j-1]; \
  7594. int c = COMPARE; \
  7595. if (!c) break; \
  7596. p[j] = p[j-1]; \
  7597. --j; \
  7598. } \
  7599. if (i != j) \
  7600. p[j] = t; \
  7601. } \
  7602. } \
  7603. \
  7604. static void STB_(FUNCNAME,_quicksort)(TYPE *p, int n) \
  7605. { \
  7606. /* threshhold for transitioning to insertion sort */ \
  7607. while (n > 12) { \
  7608. TYPE *a,*b,t; \
  7609. int c01,c12,c,m,i,j; \
  7610. \
  7611. /* compute median of three */ \
  7612. m = n >> 1; \
  7613. a = &p[0]; \
  7614. b = &p[m]; \
  7615. c = COMPARE; \
  7616. c01 = c; \
  7617. a = &p[m]; \
  7618. b = &p[n-1]; \
  7619. c = COMPARE; \
  7620. c12 = c; \
  7621. /* if 0 >= mid >= end, or 0 < mid < end, then use mid */ \
  7622. if (c01 != c12) { \
  7623. /* otherwise, we'll need to swap something else to middle */ \
  7624. int z; \
  7625. a = &p[0]; \
  7626. b = &p[n-1]; \
  7627. c = COMPARE; \
  7628. /* 0>mid && mid<n: 0>n => n; 0<n => 0 */ \
  7629. /* 0<mid && mid>n: 0>n => 0; 0<n => n */ \
  7630. z = (c == c12) ? 0 : n-1; \
  7631. t = p[z]; \
  7632. p[z] = p[m]; \
  7633. p[m] = t; \
  7634. } \
  7635. /* now p[m] is the median-of-three */ \
  7636. /* swap it to the beginning so it won't move around */ \
  7637. t = p[0]; \
  7638. p[0] = p[m]; \
  7639. p[m] = t; \
  7640. \
  7641. /* partition loop */ \
  7642. i=1; \
  7643. j=n-1; \
  7644. for(;;) { \
  7645. /* handling of equality is crucial here */ \
  7646. /* for sentinels & efficiency with duplicates */ \
  7647. b = &p[0]; \
  7648. for (;;++i) { \
  7649. a=&p[i]; \
  7650. c = COMPARE; \
  7651. if (!c) break; \
  7652. } \
  7653. a = &p[0]; \
  7654. for (;;--j) { \
  7655. b=&p[j]; \
  7656. c = COMPARE; \
  7657. if (!c) break; \
  7658. } \
  7659. /* make sure we haven't crossed */ \
  7660. if (i >= j) break; \
  7661. t = p[i]; \
  7662. p[i] = p[j]; \
  7663. p[j] = t; \
  7664. \
  7665. ++i; \
  7666. --j; \
  7667. } \
  7668. /* recurse on smaller side, iterate on larger */ \
  7669. if (j < (n-i)) { \
  7670. STB_(FUNCNAME,_quicksort)(p,j); \
  7671. p = p+i; \
  7672. n = n-i; \
  7673. } else { \
  7674. STB_(FUNCNAME,_quicksort)(p+i, n-i); \
  7675. n = j; \
  7676. } \
  7677. } \
  7678. } \
  7679. \
  7680. MODE FUNCNAME(TYPE *p, int n) \
  7681. { \
  7682. STB_(FUNCNAME, _quicksort)(p, n); \
  7683. STB_(FUNCNAME, _ins_sort)(p, n); \
  7684. } \
  7685. //////////////////////////////////////////////////////////////////////////////
  7686. //
  7687. // stb_bitset an array of booleans indexed by integers
  7688. //
  7689. typedef stb_uint32 stb_bitset;
  7690. STB_EXTERN stb_bitset *stb_bitset_new(int value, int len);
  7691. #define stb_bitset_clearall(arr,len) (memset(arr, 0, 4 * (len)))
  7692. #define stb_bitset_setall(arr,len) (memset(arr, 255, 4 * (len)))
  7693. #define stb_bitset_setbit(arr,n) ((arr)[(n) >> 5] |= (1 << (n & 31)))
  7694. #define stb_bitset_clearbit(arr,n) ((arr)[(n) >> 5] &= ~(1 << (n & 31)))
  7695. #define stb_bitset_testbit(arr,n) ((arr)[(n) >> 5] & (1 << (n & 31)))
  7696. STB_EXTERN stb_bitset *stb_bitset_union(stb_bitset *p0, stb_bitset *p1, int len);
  7697. STB_EXTERN int *stb_bitset_getlist(stb_bitset *out, int start, int end);
  7698. STB_EXTERN int stb_bitset_eq(stb_bitset *p0, stb_bitset *p1, int len);
  7699. STB_EXTERN int stb_bitset_disjoint(stb_bitset *p0, stb_bitset *p1, int len);
  7700. STB_EXTERN int stb_bitset_disjoint_0(stb_bitset *p0, stb_bitset *p1, int len);
  7701. STB_EXTERN int stb_bitset_subset(stb_bitset *bigger, stb_bitset *smaller, int len);
  7702. STB_EXTERN int stb_bitset_unioneq_changed(stb_bitset *p0, stb_bitset *p1, int len);
  7703. #ifdef STB_DEFINE
  7704. int stb_bitset_eq(stb_bitset *p0, stb_bitset *p1, int len)
  7705. {
  7706. int i;
  7707. for (i=0; i < len; ++i)
  7708. if (p0[i] != p1[i]) return 0;
  7709. return 1;
  7710. }
  7711. int stb_bitset_disjoint(stb_bitset *p0, stb_bitset *p1, int len)
  7712. {
  7713. int i;
  7714. for (i=0; i < len; ++i)
  7715. if (p0[i] & p1[i]) return 0;
  7716. return 1;
  7717. }
  7718. int stb_bitset_disjoint_0(stb_bitset *p0, stb_bitset *p1, int len)
  7719. {
  7720. int i;
  7721. for (i=0; i < len; ++i)
  7722. if ((p0[i] | p1[i]) != 0xffffffff) return 0;
  7723. return 1;
  7724. }
  7725. int stb_bitset_subset(stb_bitset *bigger, stb_bitset *smaller, int len)
  7726. {
  7727. int i;
  7728. for (i=0; i < len; ++i)
  7729. if ((bigger[i] & smaller[i]) != smaller[i]) return 0;
  7730. return 1;
  7731. }
  7732. stb_bitset *stb_bitset_union(stb_bitset *p0, stb_bitset *p1, int len)
  7733. {
  7734. int i;
  7735. stb_bitset *d = (stb_bitset *) malloc(sizeof(*d) * len);
  7736. for (i=0; i < len; ++i) d[i] = p0[i] | p1[i];
  7737. return d;
  7738. }
  7739. int stb_bitset_unioneq_changed(stb_bitset *p0, stb_bitset *p1, int len)
  7740. {
  7741. int i, changed=0;
  7742. for (i=0; i < len; ++i) {
  7743. stb_bitset d = p0[i] | p1[i];
  7744. if (d != p0[i]) {
  7745. p0[i] = d;
  7746. changed = 1;
  7747. }
  7748. }
  7749. return changed;
  7750. }
  7751. stb_bitset *stb_bitset_new(int value, int len)
  7752. {
  7753. int i;
  7754. stb_bitset *d = (stb_bitset *) malloc(sizeof(*d) * len);
  7755. if (value) value = 0xffffffff;
  7756. for (i=0; i < len; ++i) d[i] = value;
  7757. return d;
  7758. }
  7759. int *stb_bitset_getlist(stb_bitset *out, int start, int end)
  7760. {
  7761. int *list = NULL;
  7762. int i;
  7763. for (i=start; i < end; ++i)
  7764. if (stb_bitset_testbit(out, i))
  7765. stb_arr_push(list, i);
  7766. return list;
  7767. }
  7768. #endif
  7769. //////////////////////////////////////////////////////////////////////////////
  7770. //
  7771. // stb_wordwrap quality word-wrapping for fixed-width fonts
  7772. //
  7773. STB_EXTERN int stb_wordwrap(int *pairs, int pair_max, int count, char *str);
  7774. STB_EXTERN int *stb_wordwrapalloc(int count, char *str);
  7775. #ifdef STB_DEFINE
  7776. int stb_wordwrap(int *pairs, int pair_max, int count, char *str)
  7777. {
  7778. int n=0,i=0, start=0,nonwhite=0;
  7779. if (pairs == NULL) pair_max = 0x7ffffff0;
  7780. else pair_max *= 2;
  7781. // parse
  7782. for(;;) {
  7783. int s=i; // first whitespace char; last nonwhite+1
  7784. int w; // word start
  7785. // accept whitespace
  7786. while (isspace(str[i])) {
  7787. if (str[i] == '\n' || str[i] == '\r') {
  7788. if (str[i] + str[i+1] == '\n' + '\r') ++i;
  7789. if (n >= pair_max) return -1;
  7790. if (pairs) pairs[n] = start, pairs[n+1] = s-start;
  7791. n += 2;
  7792. nonwhite=0;
  7793. start = i+1;
  7794. s = start;
  7795. }
  7796. ++i;
  7797. }
  7798. if (i >= start+count) {
  7799. // we've gone off the end using whitespace
  7800. if (nonwhite) {
  7801. if (n >= pair_max) return -1;
  7802. if (pairs) pairs[n] = start, pairs[n+1] = s-start;
  7803. n += 2;
  7804. start = s = i;
  7805. nonwhite=0;
  7806. } else {
  7807. // output all the whitespace
  7808. while (i >= start+count) {
  7809. if (n >= pair_max) return -1;
  7810. if (pairs) pairs[n] = start, pairs[n+1] = count;
  7811. n += 2;
  7812. start += count;
  7813. }
  7814. s = start;
  7815. }
  7816. }
  7817. if (str[i] == 0) break;
  7818. // now scan out a word and see if it fits
  7819. w = i;
  7820. while (str[i] && !isspace(str[i])) {
  7821. ++i;
  7822. }
  7823. // wrapped?
  7824. if (i > start + count) {
  7825. // huge?
  7826. if (i-s <= count) {
  7827. if (n >= pair_max) return -1;
  7828. if (pairs) pairs[n] = start, pairs[n+1] = s-start;
  7829. n += 2;
  7830. start = w;
  7831. } else {
  7832. // This word is longer than one line. If we wrap it onto N lines
  7833. // there are leftover chars. do those chars fit on the cur line?
  7834. // But if we have leading whitespace, we force it to start here.
  7835. if ((w-start) + ((i-w) % count) <= count || !nonwhite) {
  7836. // output a full line
  7837. if (n >= pair_max) return -1;
  7838. if (pairs) pairs[n] = start, pairs[n+1] = count;
  7839. n += 2;
  7840. start += count;
  7841. w = start;
  7842. } else {
  7843. // output a partial line, trimming trailing whitespace
  7844. if (s != start) {
  7845. if (n >= pair_max) return -1;
  7846. if (pairs) pairs[n] = start, pairs[n+1] = s-start;
  7847. n += 2;
  7848. start = w;
  7849. }
  7850. }
  7851. // now output full lines as needed
  7852. while (start + count <= i) {
  7853. if (n >= pair_max) return -1;
  7854. if (pairs) pairs[n] = start, pairs[n+1] = count;
  7855. n += 2;
  7856. start += count;
  7857. }
  7858. }
  7859. }
  7860. nonwhite=1;
  7861. }
  7862. if (start < i) {
  7863. if (n >= pair_max) return -1;
  7864. if (pairs) pairs[n] = start, pairs[n+1] = i-start;
  7865. n += 2;
  7866. }
  7867. return n>>1;
  7868. }
  7869. int *stb_wordwrapalloc(int count, char *str)
  7870. {
  7871. int n = stb_wordwrap(NULL,0,count,str);
  7872. int *z = NULL;
  7873. stb_arr_setlen(z, n*2);
  7874. stb_wordwrap(z, n, count, str);
  7875. return z;
  7876. }
  7877. #endif
  7878. //////////////////////////////////////////////////////////////////////////////
  7879. //
  7880. // stb_match: wildcards and regexping
  7881. //
  7882. STB_EXTERN int stb_wildmatch (char *expr, char *candidate);
  7883. STB_EXTERN int stb_wildmatchi(char *expr, char *candidate);
  7884. STB_EXTERN int stb_wildfind (char *expr, char *candidate);
  7885. STB_EXTERN int stb_wildfindi (char *expr, char *candidate);
  7886. STB_EXTERN int stb_regex(char *regex, char *candidate);
  7887. typedef struct stb_matcher stb_matcher;
  7888. STB_EXTERN stb_matcher *stb_regex_matcher(char *regex);
  7889. STB_EXTERN int stb_matcher_match(stb_matcher *m, char *str);
  7890. STB_EXTERN int stb_matcher_find(stb_matcher *m, char *str);
  7891. STB_EXTERN void stb_matcher_free(stb_matcher *f);
  7892. STB_EXTERN stb_matcher *stb_lex_matcher(void);
  7893. STB_EXTERN int stb_lex_item(stb_matcher *m, char *str, int result);
  7894. STB_EXTERN int stb_lex_item_wild(stb_matcher *matcher, char *regex, int result);
  7895. STB_EXTERN int stb_lex(stb_matcher *m, char *str, int *len);
  7896. #ifdef STB_DEFINE
  7897. static int stb__match_qstring(char *candidate, char *qstring, int qlen, int insensitive)
  7898. {
  7899. int i;
  7900. if (insensitive) {
  7901. for (i=0; i < qlen; ++i)
  7902. if (qstring[i] == '?') {
  7903. if (!candidate[i]) return 0;
  7904. } else
  7905. if (tolower(qstring[i]) != tolower(candidate[i]))
  7906. return 0;
  7907. } else {
  7908. for (i=0; i < qlen; ++i)
  7909. if (qstring[i] == '?') {
  7910. if (!candidate[i]) return 0;
  7911. } else
  7912. if (qstring[i] != candidate[i])
  7913. return 0;
  7914. }
  7915. return 1;
  7916. }
  7917. static int stb__find_qstring(char *candidate, char *qstring, int qlen, int insensitive)
  7918. {
  7919. char c;
  7920. int offset=0;
  7921. while (*qstring == '?') {
  7922. ++qstring;
  7923. --qlen;
  7924. ++candidate;
  7925. if (qlen == 0) return 0;
  7926. if (*candidate == 0) return -1;
  7927. }
  7928. c = *qstring++;
  7929. --qlen;
  7930. if (insensitive) c = tolower(c);
  7931. while (candidate[offset]) {
  7932. if (c == (insensitive ? tolower(candidate[offset]) : candidate[offset]))
  7933. if (stb__match_qstring(candidate+offset+1, qstring, qlen, insensitive))
  7934. return offset;
  7935. ++offset;
  7936. }
  7937. return -1;
  7938. }
  7939. int stb__wildmatch_raw2(char *expr, char *candidate, int search, int insensitive)
  7940. {
  7941. int where=0;
  7942. int start = -1;
  7943. if (!search) {
  7944. // parse to first '*'
  7945. if (*expr != '*')
  7946. start = 0;
  7947. while (*expr != '*') {
  7948. if (!*expr)
  7949. return *candidate == 0 ? 0 : -1;
  7950. if (*expr == '?') {
  7951. if (!*candidate) return -1;
  7952. } else {
  7953. if (insensitive) {
  7954. if (tolower(*candidate) != tolower(*expr))
  7955. return -1;
  7956. } else
  7957. if (*candidate != *expr)
  7958. return -1;
  7959. }
  7960. ++candidate, ++expr, ++where;
  7961. }
  7962. } else {
  7963. // 0-length search string
  7964. if (!*expr)
  7965. return 0;
  7966. }
  7967. assert(search || *expr == '*');
  7968. if (!search)
  7969. ++expr;
  7970. // implicit '*' at this point
  7971. while (*expr) {
  7972. int o=0;
  7973. // combine redundant * characters
  7974. while (expr[0] == '*') ++expr;
  7975. // ok, at this point, expr[-1] == '*',
  7976. // and expr[0] != '*'
  7977. if (!expr[0]) return start >= 0 ? start : 0;
  7978. // now find next '*'
  7979. o = 0;
  7980. while (expr[o] != '*') {
  7981. if (expr[o] == 0)
  7982. break;
  7983. ++o;
  7984. }
  7985. // if no '*', scan to end, then match at end
  7986. if (expr[o] == 0 && !search) {
  7987. int z;
  7988. for (z=0; z < o; ++z)
  7989. if (candidate[z] == 0)
  7990. return -1;
  7991. while (candidate[z])
  7992. ++z;
  7993. // ok, now check if they match
  7994. if (stb__match_qstring(candidate+z-o, expr, o, insensitive))
  7995. return start >= 0 ? start : 0;
  7996. return -1;
  7997. } else {
  7998. // if yes '*', then do stb__find_qmatch on the intervening chars
  7999. int n = stb__find_qstring(candidate, expr, o, insensitive);
  8000. if (n < 0)
  8001. return -1;
  8002. if (start < 0)
  8003. start = where + n;
  8004. expr += o;
  8005. candidate += n+o;
  8006. }
  8007. if (*expr == 0) {
  8008. assert(search);
  8009. return start;
  8010. }
  8011. assert(*expr == '*');
  8012. ++expr;
  8013. }
  8014. return start >= 0 ? start : 0;
  8015. }
  8016. int stb__wildmatch_raw(char *expr, char *candidate, int search, int insensitive)
  8017. {
  8018. char buffer[256];
  8019. // handle multiple search strings
  8020. char *s = strchr(expr, ';');
  8021. char *last = expr;
  8022. while (s) {
  8023. int z;
  8024. // need to allow for non-writeable strings... assume they're small
  8025. if (s - last < 256) {
  8026. stb_strncpy(buffer, last, s-last+1);
  8027. z = stb__wildmatch_raw2(buffer, candidate, search, insensitive);
  8028. } else {
  8029. *s = 0;
  8030. z = stb__wildmatch_raw2(last, candidate, search, insensitive);
  8031. *s = ';';
  8032. }
  8033. if (z >= 0) return z;
  8034. last = s+1;
  8035. s = strchr(last, ';');
  8036. }
  8037. return stb__wildmatch_raw2(last, candidate, search, insensitive);
  8038. }
  8039. int stb_wildmatch(char *expr, char *candidate)
  8040. {
  8041. return stb__wildmatch_raw(expr, candidate, 0,0) >= 0;
  8042. }
  8043. int stb_wildmatchi(char *expr, char *candidate)
  8044. {
  8045. return stb__wildmatch_raw(expr, candidate, 0,1) >= 0;
  8046. }
  8047. int stb_wildfind(char *expr, char *candidate)
  8048. {
  8049. return stb__wildmatch_raw(expr, candidate, 1,0);
  8050. }
  8051. int stb_wildfindi(char *expr, char *candidate)
  8052. {
  8053. return stb__wildmatch_raw(expr, candidate, 1,1);
  8054. }
  8055. typedef struct
  8056. {
  8057. stb_int16 transition[256];
  8058. } stb_dfa;
  8059. // an NFA node represents a state you're in; it then has
  8060. // an arbitrary number of edges dangling off of it
  8061. // note this isn't utf8-y
  8062. typedef struct
  8063. {
  8064. stb_int16 match; // character/set to match
  8065. stb_uint16 node; // output node to go to
  8066. } stb_nfa_edge;
  8067. typedef struct
  8068. {
  8069. stb_int16 goal; // does reaching this win the prize?
  8070. stb_uint8 active; // is this in the active list
  8071. stb_nfa_edge *out;
  8072. stb_uint16 *eps; // list of epsilon closures
  8073. } stb_nfa_node;
  8074. #define STB__DFA_UNDEF -1
  8075. #define STB__DFA_GOAL -2
  8076. #define STB__DFA_END -3
  8077. #define STB__DFA_MGOAL -4
  8078. #define STB__DFA_VALID 0
  8079. #define STB__NFA_STOP_GOAL -1
  8080. // compiled regexp
  8081. struct stb_matcher
  8082. {
  8083. stb_uint16 start_node;
  8084. stb_int16 dfa_start;
  8085. stb_uint32 *charset;
  8086. int num_charset;
  8087. int match_start;
  8088. stb_nfa_node *nodes;
  8089. int does_lex;
  8090. // dfa matcher
  8091. stb_dfa * dfa;
  8092. stb_uint32 * dfa_mapping;
  8093. stb_int16 * dfa_result;
  8094. int num_words_per_dfa;
  8095. };
  8096. static int stb__add_node(stb_matcher *matcher)
  8097. {
  8098. stb_nfa_node z;
  8099. z.active = 0;
  8100. z.eps = 0;
  8101. z.goal = 0;
  8102. z.out = 0;
  8103. stb_arr_push(matcher->nodes, z);
  8104. return stb_arr_len(matcher->nodes)-1;
  8105. }
  8106. static void stb__add_epsilon(stb_matcher *matcher, int from, int to)
  8107. {
  8108. assert(from != to);
  8109. if (matcher->nodes[from].eps == NULL)
  8110. stb_arr_malloc((void **) &matcher->nodes[from].eps, matcher);
  8111. stb_arr_push(matcher->nodes[from].eps, to);
  8112. }
  8113. static void stb__add_edge(stb_matcher *matcher, int from, int to, int type)
  8114. {
  8115. stb_nfa_edge z = { (stb_int16)type, (stb_uint16)to };
  8116. if (matcher->nodes[from].out == NULL)
  8117. stb_arr_malloc((void **) &matcher->nodes[from].out, matcher);
  8118. stb_arr_push(matcher->nodes[from].out, z);
  8119. }
  8120. static char *stb__reg_parse_alt(stb_matcher *m, int s, char *r, stb_uint16 *e);
  8121. static char *stb__reg_parse(stb_matcher *matcher, int start, char *regex, stb_uint16 *end)
  8122. {
  8123. int n;
  8124. int last_start = -1;
  8125. stb_uint16 last_end = start;
  8126. while (*regex) {
  8127. switch (*regex) {
  8128. case '(':
  8129. last_start = last_end;
  8130. regex = stb__reg_parse_alt(matcher, last_end, regex+1, &last_end);
  8131. if (regex == NULL || *regex != ')')
  8132. return NULL;
  8133. ++regex;
  8134. break;
  8135. case '|':
  8136. case ')':
  8137. *end = last_end;
  8138. return regex;
  8139. case '?':
  8140. if (last_start < 0) return NULL;
  8141. stb__add_epsilon(matcher, last_start, last_end);
  8142. ++regex;
  8143. break;
  8144. case '*':
  8145. if (last_start < 0) return NULL;
  8146. stb__add_epsilon(matcher, last_start, last_end);
  8147. // fall through
  8148. case '+':
  8149. if (last_start < 0) return NULL;
  8150. stb__add_epsilon(matcher, last_end, last_start);
  8151. // prevent links back to last_end from chaining to last_start
  8152. n = stb__add_node(matcher);
  8153. stb__add_epsilon(matcher, last_end, n);
  8154. last_end = n;
  8155. ++regex;
  8156. break;
  8157. case '{': // not supported!
  8158. // @TODO: given {n,m}, clone last_start to last_end m times,
  8159. // and include epsilons from start to first m-n blocks
  8160. return NULL;
  8161. case '\\':
  8162. ++regex;
  8163. if (!*regex) return NULL;
  8164. // fallthrough
  8165. default: // match exactly this character
  8166. n = stb__add_node(matcher);
  8167. stb__add_edge(matcher, last_end, n, *regex);
  8168. last_start = last_end;
  8169. last_end = n;
  8170. ++regex;
  8171. break;
  8172. case '$':
  8173. n = stb__add_node(matcher);
  8174. stb__add_edge(matcher, last_end, n, '\n');
  8175. last_start = last_end;
  8176. last_end = n;
  8177. ++regex;
  8178. break;
  8179. case '.':
  8180. n = stb__add_node(matcher);
  8181. stb__add_edge(matcher, last_end, n, -1);
  8182. last_start = last_end;
  8183. last_end = n;
  8184. ++regex;
  8185. break;
  8186. case '[': {
  8187. stb_uint8 flags[256];
  8188. int invert = 0,z;
  8189. ++regex;
  8190. if (matcher->num_charset == 0) {
  8191. matcher->charset = (stb_uint *) stb_malloc(matcher, sizeof(*matcher->charset) * 256);
  8192. memset(matcher->charset, 0, sizeof(*matcher->charset) * 256);
  8193. }
  8194. memset(flags,0,sizeof(flags));
  8195. // leading ^ is special
  8196. if (*regex == '^')
  8197. ++regex, invert = 1;
  8198. // leading ] is special
  8199. if (*regex == ']') {
  8200. flags[']'] = 1;
  8201. ++regex;
  8202. }
  8203. while (*regex != ']') {
  8204. stb_uint a;
  8205. if (!*regex) return NULL;
  8206. a = *regex++;
  8207. if (regex[0] == '-' && regex[1] != ']') {
  8208. stb_uint i,b = regex[1];
  8209. regex += 2;
  8210. if (b == 0) return NULL;
  8211. if (a > b) return NULL;
  8212. for (i=a; i <= b; ++i)
  8213. flags[i] = 1;
  8214. } else
  8215. flags[a] = 1;
  8216. }
  8217. ++regex;
  8218. if (invert) {
  8219. int i;
  8220. for (i=0; i < 256; ++i)
  8221. flags[i] = 1-flags[i];
  8222. }
  8223. // now check if any existing charset matches
  8224. for (z=0; z < matcher->num_charset; ++z) {
  8225. int i, k[2] = { 0, 1 << z};
  8226. for (i=0; i < 256; ++i) {
  8227. unsigned int f = k[flags[i]];
  8228. if ((matcher->charset[i] & k[1]) != f)
  8229. break;
  8230. }
  8231. if (i == 256) break;
  8232. }
  8233. if (z == matcher->num_charset) {
  8234. int i;
  8235. ++matcher->num_charset;
  8236. if (matcher->num_charset > 32) {
  8237. assert(0); /* NOTREACHED */
  8238. return NULL; // too many charsets, oops
  8239. }
  8240. for (i=0; i < 256; ++i)
  8241. if (flags[i])
  8242. matcher->charset[i] |= (1 << z);
  8243. }
  8244. n = stb__add_node(matcher);
  8245. stb__add_edge(matcher, last_end, n, -2 - z);
  8246. last_start = last_end;
  8247. last_end = n;
  8248. break;
  8249. }
  8250. }
  8251. }
  8252. *end = last_end;
  8253. return regex;
  8254. }
  8255. static char *stb__reg_parse_alt(stb_matcher *matcher, int start, char *regex, stb_uint16 *end)
  8256. {
  8257. stb_uint16 last_end = start;
  8258. stb_uint16 main_end;
  8259. int head, tail;
  8260. head = stb__add_node(matcher);
  8261. stb__add_epsilon(matcher, start, head);
  8262. regex = stb__reg_parse(matcher, head, regex, &last_end);
  8263. if (regex == NULL) return NULL;
  8264. if (*regex == 0 || *regex == ')') {
  8265. *end = last_end;
  8266. return regex;
  8267. }
  8268. main_end = last_end;
  8269. tail = stb__add_node(matcher);
  8270. stb__add_epsilon(matcher, last_end, tail);
  8271. // start alternatives from the same starting node; use epsilon
  8272. // transitions to combine their endings
  8273. while(*regex && *regex != ')') {
  8274. assert(*regex == '|');
  8275. head = stb__add_node(matcher);
  8276. stb__add_epsilon(matcher, start, head);
  8277. regex = stb__reg_parse(matcher, head, regex+1, &last_end);
  8278. if (regex == NULL)
  8279. return NULL;
  8280. stb__add_epsilon(matcher, last_end, tail);
  8281. }
  8282. *end = tail;
  8283. return regex;
  8284. }
  8285. static char *stb__wild_parse(stb_matcher *matcher, int start, char *str, stb_uint16 *end)
  8286. {
  8287. int n;
  8288. stb_uint16 last_end;
  8289. last_end = stb__add_node(matcher);
  8290. stb__add_epsilon(matcher, start, last_end);
  8291. while (*str) {
  8292. switch (*str) {
  8293. // fallthrough
  8294. default: // match exactly this character
  8295. n = stb__add_node(matcher);
  8296. if (toupper(*str) == tolower(*str)) {
  8297. stb__add_edge(matcher, last_end, n, *str);
  8298. } else {
  8299. stb__add_edge(matcher, last_end, n, tolower(*str));
  8300. stb__add_edge(matcher, last_end, n, toupper(*str));
  8301. }
  8302. last_end = n;
  8303. ++str;
  8304. break;
  8305. case '?':
  8306. n = stb__add_node(matcher);
  8307. stb__add_edge(matcher, last_end, n, -1);
  8308. last_end = n;
  8309. ++str;
  8310. break;
  8311. case '*':
  8312. n = stb__add_node(matcher);
  8313. stb__add_edge(matcher, last_end, n, -1);
  8314. stb__add_epsilon(matcher, last_end, n);
  8315. stb__add_epsilon(matcher, n, last_end);
  8316. last_end = n;
  8317. ++str;
  8318. break;
  8319. }
  8320. }
  8321. // now require end of string to match
  8322. n = stb__add_node(matcher);
  8323. stb__add_edge(matcher, last_end, n, 0);
  8324. last_end = n;
  8325. *end = last_end;
  8326. return str;
  8327. }
  8328. static int stb__opt(stb_matcher *m, int n)
  8329. {
  8330. for(;;) {
  8331. stb_nfa_node *p = &m->nodes[n];
  8332. if (p->goal) return n;
  8333. if (stb_arr_len(p->out)) return n;
  8334. if (stb_arr_len(p->eps) != 1) return n;
  8335. n = p->eps[0];
  8336. }
  8337. }
  8338. static void stb__optimize(stb_matcher *m)
  8339. {
  8340. // if the target of any edge is a node with exactly
  8341. // one out-epsilon, shorten it
  8342. int i,j;
  8343. for (i=0; i < stb_arr_len(m->nodes); ++i) {
  8344. stb_nfa_node *p = &m->nodes[i];
  8345. for (j=0; j < stb_arr_len(p->out); ++j)
  8346. p->out[j].node = stb__opt(m,p->out[j].node);
  8347. for (j=0; j < stb_arr_len(p->eps); ++j)
  8348. p->eps[j] = stb__opt(m,p->eps[j] );
  8349. }
  8350. m->start_node = stb__opt(m,m->start_node);
  8351. }
  8352. void stb_matcher_free(stb_matcher *f)
  8353. {
  8354. stb_free(f);
  8355. }
  8356. static stb_matcher *stb__alloc_matcher(void)
  8357. {
  8358. stb_matcher *matcher = (stb_matcher *) stb_malloc(0,sizeof(*matcher));
  8359. matcher->start_node = 0;
  8360. stb_arr_malloc((void **) &matcher->nodes, matcher);
  8361. matcher->num_charset = 0;
  8362. matcher->match_start = 0;
  8363. matcher->does_lex = 0;
  8364. matcher->dfa_start = STB__DFA_UNDEF;
  8365. stb_arr_malloc((void **) &matcher->dfa, matcher);
  8366. stb_arr_malloc((void **) &matcher->dfa_mapping, matcher);
  8367. stb_arr_malloc((void **) &matcher->dfa_result, matcher);
  8368. stb__add_node(matcher);
  8369. return matcher;
  8370. }
  8371. static void stb__lex_reset(stb_matcher *matcher)
  8372. {
  8373. // flush cached dfa data
  8374. stb_arr_setlen(matcher->dfa, 0);
  8375. stb_arr_setlen(matcher->dfa_mapping, 0);
  8376. stb_arr_setlen(matcher->dfa_result, 0);
  8377. matcher->dfa_start = STB__DFA_UNDEF;
  8378. }
  8379. stb_matcher *stb_regex_matcher(char *regex)
  8380. {
  8381. char *z;
  8382. stb_uint16 end;
  8383. stb_matcher *matcher = stb__alloc_matcher();
  8384. if (*regex == '^') {
  8385. matcher->match_start = 1;
  8386. ++regex;
  8387. }
  8388. z = stb__reg_parse_alt(matcher, matcher->start_node, regex, &end);
  8389. if (!z || *z) {
  8390. stb_free(matcher);
  8391. return NULL;
  8392. }
  8393. ((matcher->nodes)[(int) end]).goal = STB__NFA_STOP_GOAL;
  8394. return matcher;
  8395. }
  8396. stb_matcher *stb_lex_matcher(void)
  8397. {
  8398. stb_matcher *matcher = stb__alloc_matcher();
  8399. matcher->match_start = 1;
  8400. matcher->does_lex = 1;
  8401. return matcher;
  8402. }
  8403. int stb_lex_item(stb_matcher *matcher, char *regex, int result)
  8404. {
  8405. char *z;
  8406. stb_uint16 end;
  8407. z = stb__reg_parse_alt(matcher, matcher->start_node, regex, &end);
  8408. if (z == NULL)
  8409. return 0;
  8410. stb__lex_reset(matcher);
  8411. matcher->nodes[(int) end].goal = result;
  8412. return 1;
  8413. }
  8414. int stb_lex_item_wild(stb_matcher *matcher, char *regex, int result)
  8415. {
  8416. char *z;
  8417. stb_uint16 end;
  8418. z = stb__wild_parse(matcher, matcher->start_node, regex, &end);
  8419. if (z == NULL)
  8420. return 0;
  8421. stb__lex_reset(matcher);
  8422. matcher->nodes[(int) end].goal = result;
  8423. return 1;
  8424. }
  8425. static void stb__clear(stb_matcher *m, stb_uint16 *list)
  8426. {
  8427. int i;
  8428. for (i=0; i < stb_arr_len(list); ++i)
  8429. m->nodes[(int) list[i]].active = 0;
  8430. }
  8431. static int stb__clear_goalcheck(stb_matcher *m, stb_uint16 *list)
  8432. {
  8433. int i, t=0;
  8434. for (i=0; i < stb_arr_len(list); ++i) {
  8435. t += m->nodes[(int) list[i]].goal;
  8436. m->nodes[(int) list[i]].active = 0;
  8437. }
  8438. return t;
  8439. }
  8440. static stb_uint16 * stb__add_if_inactive(stb_matcher *m, stb_uint16 *list, int n)
  8441. {
  8442. if (!m->nodes[n].active) {
  8443. stb_arr_push(list, n);
  8444. m->nodes[n].active = 1;
  8445. }
  8446. return list;
  8447. }
  8448. static stb_uint16 * stb__eps_closure(stb_matcher *m, stb_uint16 *list)
  8449. {
  8450. int i,n = stb_arr_len(list);
  8451. for(i=0; i < n; ++i) {
  8452. stb_uint16 *e = m->nodes[(int) list[i]].eps;
  8453. if (e) {
  8454. int j,k = stb_arr_len(e);
  8455. for (j=0; j < k; ++j)
  8456. list = stb__add_if_inactive(m, list, e[j]);
  8457. n = stb_arr_len(list);
  8458. }
  8459. }
  8460. return list;
  8461. }
  8462. int stb_matcher_match(stb_matcher *m, char *str)
  8463. {
  8464. int result = 0;
  8465. int i,j,y,z;
  8466. stb_uint16 *previous = NULL;
  8467. stb_uint16 *current = NULL;
  8468. stb_uint16 *temp;
  8469. stb_arr_setsize(previous, 4);
  8470. stb_arr_setsize(current, 4);
  8471. previous = stb__add_if_inactive(m, previous, m->start_node);
  8472. previous = stb__eps_closure(m,previous);
  8473. stb__clear(m, previous);
  8474. while (*str && stb_arr_len(previous)) {
  8475. y = stb_arr_len(previous);
  8476. for (i=0; i < y; ++i) {
  8477. stb_nfa_node *n = &m->nodes[(int) previous[i]];
  8478. z = stb_arr_len(n->out);
  8479. for (j=0; j < z; ++j) {
  8480. if (n->out[j].match >= 0) {
  8481. if (n->out[j].match == *str)
  8482. current = stb__add_if_inactive(m, current, n->out[j].node);
  8483. } else if (n->out[j].match == -1) {
  8484. if (*str != '\n')
  8485. current = stb__add_if_inactive(m, current, n->out[j].node);
  8486. } else if (n->out[j].match < -1) {
  8487. int z = -n->out[j].match - 2;
  8488. if (m->charset[(stb_uint8) *str] & (1 << z))
  8489. current = stb__add_if_inactive(m, current, n->out[j].node);
  8490. }
  8491. }
  8492. }
  8493. stb_arr_setlen(previous, 0);
  8494. temp = previous;
  8495. previous = current;
  8496. current = temp;
  8497. previous = stb__eps_closure(m,previous);
  8498. stb__clear(m, previous);
  8499. ++str;
  8500. }
  8501. // transition to pick up a '$' at the end
  8502. y = stb_arr_len(previous);
  8503. for (i=0; i < y; ++i)
  8504. m->nodes[(int) previous[i]].active = 1;
  8505. for (i=0; i < y; ++i) {
  8506. stb_nfa_node *n = &m->nodes[(int) previous[i]];
  8507. z = stb_arr_len(n->out);
  8508. for (j=0; j < z; ++j) {
  8509. if (n->out[j].match == '\n')
  8510. current = stb__add_if_inactive(m, current, n->out[j].node);
  8511. }
  8512. }
  8513. previous = stb__eps_closure(m,previous);
  8514. stb__clear(m, previous);
  8515. y = stb_arr_len(previous);
  8516. for (i=0; i < y; ++i)
  8517. if (m->nodes[(int) previous[i]].goal)
  8518. result = 1;
  8519. stb_arr_free(previous);
  8520. stb_arr_free(current);
  8521. return result && *str == 0;
  8522. }
  8523. stb_int16 stb__get_dfa_node(stb_matcher *m, stb_uint16 *list)
  8524. {
  8525. stb_uint16 node;
  8526. stb_uint32 data[8], *state, *newstate;
  8527. int i,j,n;
  8528. state = (stb_uint32 *) stb_temp(data, m->num_words_per_dfa * 4);
  8529. memset(state, 0, m->num_words_per_dfa*4);
  8530. n = stb_arr_len(list);
  8531. for (i=0; i < n; ++i) {
  8532. int x = list[i];
  8533. state[x >> 5] |= 1 << (x & 31);
  8534. }
  8535. // @TODO use a hash table
  8536. n = stb_arr_len(m->dfa_mapping);
  8537. i=j=0;
  8538. for(; j < n; ++i, j += m->num_words_per_dfa) {
  8539. // @TODO special case for <= 32
  8540. if (!memcmp(state, m->dfa_mapping + j, m->num_words_per_dfa*4)) {
  8541. node = i;
  8542. goto done;
  8543. }
  8544. }
  8545. assert(stb_arr_len(m->dfa) == i);
  8546. node = i;
  8547. newstate = stb_arr_addn(m->dfa_mapping, m->num_words_per_dfa);
  8548. memcpy(newstate, state, m->num_words_per_dfa*4);
  8549. // set all transitions to 'unknown'
  8550. stb_arr_add(m->dfa);
  8551. memset(m->dfa[i].transition, -1, sizeof(m->dfa[i].transition));
  8552. if (m->does_lex) {
  8553. int result = -1;
  8554. n = stb_arr_len(list);
  8555. for (i=0; i < n; ++i) {
  8556. if (m->nodes[(int) list[i]].goal > result)
  8557. result = m->nodes[(int) list[i]].goal;
  8558. }
  8559. stb_arr_push(m->dfa_result, result);
  8560. }
  8561. done:
  8562. stb_tempfree(data, state);
  8563. return node;
  8564. }
  8565. static int stb__matcher_dfa(stb_matcher *m, char *str_c, int *len)
  8566. {
  8567. stb_uint8 *str = (stb_uint8 *) str_c;
  8568. stb_int16 node,prevnode;
  8569. stb_dfa *trans;
  8570. int match_length = 0;
  8571. stb_int16 match_result=0;
  8572. if (m->dfa_start == STB__DFA_UNDEF) {
  8573. stb_uint16 *list;
  8574. m->num_words_per_dfa = (stb_arr_len(m->nodes)+31) >> 5;
  8575. stb__optimize(m);
  8576. list = stb__add_if_inactive(m, NULL, m->start_node);
  8577. list = stb__eps_closure(m,list);
  8578. if (m->does_lex) {
  8579. m->dfa_start = stb__get_dfa_node(m,list);
  8580. stb__clear(m, list);
  8581. // DON'T allow start state to be a goal state!
  8582. // this allows people to specify regexes that can match 0
  8583. // characters without them actually matching (also we don't
  8584. // check _before_ advancing anyway
  8585. if (m->dfa_start <= STB__DFA_MGOAL)
  8586. m->dfa_start = -(m->dfa_start - STB__DFA_MGOAL);
  8587. } else {
  8588. if (stb__clear_goalcheck(m, list))
  8589. m->dfa_start = STB__DFA_GOAL;
  8590. else
  8591. m->dfa_start = stb__get_dfa_node(m,list);
  8592. }
  8593. stb_arr_free(list);
  8594. }
  8595. prevnode = STB__DFA_UNDEF;
  8596. node = m->dfa_start;
  8597. trans = m->dfa;
  8598. if (m->dfa_start == STB__DFA_GOAL)
  8599. return 1;
  8600. for(;;) {
  8601. assert(node >= STB__DFA_VALID);
  8602. // fast inner DFA loop; especially if STB__DFA_VALID is 0
  8603. do {
  8604. prevnode = node;
  8605. node = trans[node].transition[*str++];
  8606. } while (node >= STB__DFA_VALID);
  8607. assert(node >= STB__DFA_MGOAL - stb_arr_len(m->dfa));
  8608. assert(node < stb_arr_len(m->dfa));
  8609. // special case for lex: need _longest_ match, so notice goal
  8610. // state without stopping
  8611. if (node <= STB__DFA_MGOAL) {
  8612. match_length = str - (stb_uint8 *) str_c;
  8613. node = -(node - STB__DFA_MGOAL);
  8614. match_result = node;
  8615. continue;
  8616. }
  8617. // slow NFA->DFA conversion
  8618. // or we hit the goal or the end of the string, but those
  8619. // can only happen once per search...
  8620. if (node == STB__DFA_UNDEF) {
  8621. // build a list -- @TODO special case <= 32 states
  8622. // heck, use a more compact data structure for <= 16 and <= 8 ?!
  8623. // @TODO keep states/newstates around instead of reallocating them
  8624. stb_uint16 *states = NULL;
  8625. stb_uint16 *newstates = NULL;
  8626. int i,j,y,z;
  8627. stb_uint32 *flags = &m->dfa_mapping[prevnode * m->num_words_per_dfa];
  8628. assert(prevnode != STB__DFA_UNDEF);
  8629. stb_arr_setsize(states, 4);
  8630. stb_arr_setsize(newstates,4);
  8631. for (j=0; j < m->num_words_per_dfa; ++j) {
  8632. for (i=0; i < 32; ++i) {
  8633. if (*flags & (1 << i))
  8634. stb_arr_push(states, j*32+i);
  8635. }
  8636. ++flags;
  8637. }
  8638. // states is now the states we were in in the previous node;
  8639. // so now we can compute what node it transitions to on str[-1]
  8640. y = stb_arr_len(states);
  8641. for (i=0; i < y; ++i) {
  8642. stb_nfa_node *n = &m->nodes[(int) states[i]];
  8643. z = stb_arr_len(n->out);
  8644. for (j=0; j < z; ++j) {
  8645. if (n->out[j].match >= 0) {
  8646. if (n->out[j].match == str[-1] || (str[-1] == 0 && n->out[j].match == '\n'))
  8647. newstates = stb__add_if_inactive(m, newstates, n->out[j].node);
  8648. } else if (n->out[j].match == -1) {
  8649. if (str[-1] != '\n' && str[-1])
  8650. newstates = stb__add_if_inactive(m, newstates, n->out[j].node);
  8651. } else if (n->out[j].match < -1) {
  8652. int z = -n->out[j].match - 2;
  8653. if (m->charset[str[-1]] & (1 << z))
  8654. newstates = stb__add_if_inactive(m, newstates, n->out[j].node);
  8655. }
  8656. }
  8657. }
  8658. // AND add in the start state!
  8659. if (!m->match_start || (str[-1] == '\n' && !m->does_lex))
  8660. newstates = stb__add_if_inactive(m, newstates, m->start_node);
  8661. // AND epsilon close it
  8662. newstates = stb__eps_closure(m, newstates);
  8663. // if it's a goal state, then that's all there is to it
  8664. if (stb__clear_goalcheck(m, newstates)) {
  8665. if (m->does_lex) {
  8666. match_length = str - (stb_uint8 *) str_c;
  8667. node = stb__get_dfa_node(m,newstates);
  8668. match_result = node;
  8669. node = -node + STB__DFA_MGOAL;
  8670. trans = m->dfa; // could have gotten realloc()ed
  8671. } else
  8672. node = STB__DFA_GOAL;
  8673. } else if (str[-1] == 0 || stb_arr_len(newstates) == 0) {
  8674. node = STB__DFA_END;
  8675. } else {
  8676. node = stb__get_dfa_node(m,newstates);
  8677. trans = m->dfa; // could have gotten realloc()ed
  8678. }
  8679. trans[prevnode].transition[str[-1]] = node;
  8680. if (node <= STB__DFA_MGOAL)
  8681. node = -(node - STB__DFA_MGOAL);
  8682. stb_arr_free(newstates);
  8683. stb_arr_free(states);
  8684. }
  8685. if (node == STB__DFA_GOAL) {
  8686. return 1;
  8687. }
  8688. if (node == STB__DFA_END) {
  8689. if (m->does_lex) {
  8690. if (match_result) {
  8691. if (len) *len = match_length;
  8692. return m->dfa_result[(int) match_result];
  8693. }
  8694. }
  8695. return 0;
  8696. }
  8697. assert(node != STB__DFA_UNDEF);
  8698. }
  8699. }
  8700. int stb_matcher_find(stb_matcher *m, char *str)
  8701. {
  8702. assert(m->does_lex == 0);
  8703. return stb__matcher_dfa(m, str, NULL);
  8704. }
  8705. int stb_lex(stb_matcher *m, char *str, int *len)
  8706. {
  8707. assert(m->does_lex);
  8708. return stb__matcher_dfa(m, str, len);
  8709. }
  8710. int stb_regex(char *regex, char *str)
  8711. {
  8712. static stb_perfect p;
  8713. static stb_matcher ** matchers;
  8714. static char ** regexps;
  8715. static char ** regexp_cache;
  8716. static unsigned short *mapping;
  8717. int z = stb_perfect_hash(&p, (int)(size_t) regex);
  8718. if (z >= 0) {
  8719. if (strcmp(regex, regexp_cache[(int) mapping[z]])) {
  8720. int i = mapping[z];
  8721. stb_matcher_free(matchers[i]);
  8722. free(regexp_cache[i]);
  8723. regexps[i] = regex;
  8724. regexp_cache[i] = strdup(regex);
  8725. matchers[i] = stb_regex_matcher(regex);
  8726. }
  8727. } else {
  8728. int i,n;
  8729. if (regex == NULL) {
  8730. for (i=0; i < stb_arr_len(matchers); ++i) {
  8731. stb_matcher_free(matchers[i]);
  8732. free(regexp_cache[i]);
  8733. }
  8734. stb_arr_free(matchers);
  8735. stb_arr_free(regexps);
  8736. stb_arr_free(regexp_cache);
  8737. stb_perfect_destroy(&p);
  8738. free(mapping); mapping = NULL;
  8739. return -1;
  8740. }
  8741. stb_arr_push(regexps, regex);
  8742. stb_arr_push(regexp_cache, strdup(regex));
  8743. stb_arr_push(matchers, stb_regex_matcher(regex));
  8744. stb_perfect_destroy(&p);
  8745. n = stb_perfect_create(&p, (unsigned int *) (char **) regexps, stb_arr_len(regexps));
  8746. mapping = (unsigned short *) realloc(mapping, n * sizeof(*mapping));
  8747. for (i=0; i < stb_arr_len(regexps); ++i)
  8748. mapping[stb_perfect_hash(&p, (int)(size_t) regexps[i])] = i;
  8749. z = stb_perfect_hash(&p, (int)(size_t) regex);
  8750. }
  8751. return stb_matcher_find(matchers[(int) mapping[z]], str);
  8752. }
  8753. #endif // STB_DEFINE
  8754. #if 0
  8755. //////////////////////////////////////////////////////////////////////////////
  8756. //
  8757. // C source-code introspection
  8758. //
  8759. // runtime structure
  8760. typedef struct
  8761. {
  8762. char *name;
  8763. char *type; // base type
  8764. char *comment; // content of comment field
  8765. int size; // size of base type
  8766. int offset; // field offset
  8767. int arrcount[8]; // array sizes; -1 = pointer indirection; 0 = end of list
  8768. } stb_info_field;
  8769. typedef struct
  8770. {
  8771. char *structname;
  8772. int size;
  8773. int num_fields;
  8774. stb_info_field *fields;
  8775. } stb_info_struct;
  8776. extern stb_info_struct stb_introspect_output[];
  8777. //
  8778. STB_EXTERN void stb_introspect_precompiled(stb_info_struct *compiled);
  8779. STB_EXTERN void stb__introspect(char *path, char *file);
  8780. #define stb_introspect_ship() stb__introspect(NULL, NULL, stb__introspect_output)
  8781. #ifdef STB_SHIP
  8782. #define stb_introspect() stb_introspect_ship()
  8783. #define stb_introspect_path(p) stb_introspect_ship()
  8784. #else
  8785. // bootstrapping: define stb_introspect() (or 'path') the first time
  8786. #define stb_introspect() stb__introspect(NULL, __FILE__, NULL)
  8787. #define stb_introspect_auto() stb__introspect(NULL, __FILE__, stb__introspect_output)
  8788. #define stb_introspect_path(p) stb__introspect(p, __FILE__, NULL)
  8789. #define stb_introspect_path(p) stb__introspect(p, __FILE__, NULL)
  8790. #endif
  8791. #ifdef STB_DEFINE
  8792. #ifndef STB_INTROSPECT_CPP
  8793. #ifdef __cplusplus
  8794. #define STB_INTROSPECT_CPP 1
  8795. #else
  8796. #define STB_INTROSPECT_CPP 0
  8797. #endif
  8798. #endif
  8799. void stb_introspect_precompiled(stb_info_struct *compiled)
  8800. {
  8801. }
  8802. static void stb__introspect_filename(char *buffer, char *path)
  8803. {
  8804. #if STB_INTROSPECT_CPP
  8805. sprintf(buffer, "%s/stb_introspect.cpp", path);
  8806. #else
  8807. sprintf(buffer, "%s/stb_introspect.c", path);
  8808. #endif
  8809. }
  8810. static void stb__introspect_compute(char *path, char *file)
  8811. {
  8812. int i;
  8813. char ** include_list = NULL;
  8814. char ** introspect_list = NULL;
  8815. FILE *f;
  8816. f = fopen(file, "w");
  8817. if (!f) return;
  8818. fputs("// if you get compiler errors, change the following 0 to a 1:\n", f);
  8819. fputs("#define STB_INTROSPECT_INVALID 0\n\n", f);
  8820. fputs("// this will force the code to compile, and force the introspector\n", f);
  8821. fputs("// to run and then exit, allowing you to recompile\n\n\n", f);
  8822. fputs("#include \"stb.h\"\n\n",f );
  8823. fputs("#if STB_INTROSPECT_INVALID\n", f);
  8824. fputs(" stb_info_struct stb__introspect_output[] = { (void *) 1 }\n", f);
  8825. fputs("#else\n\n", f);
  8826. for (i=0; i < stb_arr_len(include_list); ++i)
  8827. fprintf(f, " #include \"%s\"\n", include_list[i]);
  8828. fputs(" stb_info_struct stb__introspect_output[] =\n{\n", f);
  8829. for (i=0; i < stb_arr_len(introspect_list); ++i)
  8830. fprintf(f, " stb_introspect_%s,\n", introspect_list[i]);
  8831. fputs(" };\n", f);
  8832. fputs("#endif\n", f);
  8833. fclose(f);
  8834. }
  8835. static stb_info_struct *stb__introspect_info;
  8836. #ifndef STB_SHIP
  8837. #endif
  8838. void stb__introspect(char *path, char *file, stb_info_struct *compiled)
  8839. {
  8840. static int first=1;
  8841. if (!first) return;
  8842. first=0;
  8843. stb__introspect_info = compiled;
  8844. #ifndef STB_SHIP
  8845. if (path || file) {
  8846. int bail_flag = compiled && compiled[0].structname == (void *) 1;
  8847. int needs_building = bail_flag;
  8848. struct stb__stat st;
  8849. char buffer[1024], buffer2[1024];
  8850. if (!path) {
  8851. stb_splitpath(buffer, file, STB_PATH);
  8852. path = buffer;
  8853. }
  8854. // bail if the source path doesn't exist
  8855. if (!stb_fexists(path)) return;
  8856. stb__introspect_filename(buffer2, path);
  8857. // get source/include files timestamps, compare to output-file timestamp;
  8858. // if mismatched, regenerate
  8859. if (stb__stat(buffer2, &st))
  8860. needs_building = STB_TRUE;
  8861. {
  8862. // find any file that contains an introspection command and is newer
  8863. // if needs_building is already true, we don't need to do this test,
  8864. // but we still need these arrays, so go ahead and get them
  8865. char **all[3];
  8866. all[0] = stb_readdir_files_mask(path, "*.h");
  8867. all[1] = stb_readdir_files_mask(path, "*.c");
  8868. all[2] = stb_readdir_files_mask(path, "*.cpp");
  8869. int i,j;
  8870. if (needs_building) {
  8871. for (j=0; j < 3; ++j) {
  8872. for (i=0; i < stb_arr_len(all[j]); ++i) {
  8873. struct stb__stat st2;
  8874. if (!stb__stat(all[j][i], &st2)) {
  8875. if (st.st_mtime < st2.st_mtime) {
  8876. char *z = stb_filec(all[j][i], NULL);
  8877. int found=STB_FALSE;
  8878. while (y) {
  8879. y = strstr(y, "//si");
  8880. if (y && isspace(y[4])) {
  8881. found = STB_TRUE;
  8882. break;
  8883. }
  8884. }
  8885. needs_building = STB_TRUE;
  8886. goto done;
  8887. }
  8888. }
  8889. }
  8890. }
  8891. done:;
  8892. }
  8893. char *z = stb_filec(all[i], NULL), *y = z;
  8894. int found=STB_FALSE;
  8895. while (y) {
  8896. y = strstr(y, "//si");
  8897. if (y && isspace(y[4])) {
  8898. found = STB_TRUE;
  8899. break;
  8900. }
  8901. }
  8902. if (found)
  8903. stb_arr_push(introspect_h, strdup(all[i]));
  8904. free(z);
  8905. }
  8906. }
  8907. stb_readdir_free(all);
  8908. if (!needs_building) {
  8909. for (i=0; i < stb_arr_len(introspect_h); ++i) {
  8910. struct stb__stat st2;
  8911. if (!stb__stat(introspect_h[i], &st2))
  8912. if (st.st_mtime < st2.st_mtime)
  8913. needs_building = STB_TRUE;
  8914. }
  8915. }
  8916. if (needs_building) {
  8917. stb__introspect_compute(path, buffer2);
  8918. }
  8919. }
  8920. }
  8921. #endif
  8922. }
  8923. #endif
  8924. #endif
  8925. #ifdef STB_INTROSPECT
  8926. // compile-time code-generator
  8927. #define INTROSPECT(x) int main(int argc, char **argv) { stb__introspect(__FILE__); return 0; }
  8928. #define FILE(x)
  8929. void stb__introspect(char *filename)
  8930. {
  8931. char *file = stb_file(filename, NULL);
  8932. char *s = file, *t, **p;
  8933. char *out_name = "stb_introspect.c";
  8934. char *out_path;
  8935. STB_ARR(char) filelist = NULL;
  8936. int i,n;
  8937. if (!file) stb_fatal("Couldn't open %s", filename);
  8938. out_path = stb_splitpathdup(filename, STB_PATH);
  8939. // search for the macros
  8940. while (*s) {
  8941. char buffer[256];
  8942. while (*s && !isupper(*s)) ++s;
  8943. s = stb_strtok_invert(buffer, s, "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
  8944. s = stb_skipwhite(s);
  8945. if (*s == '(') {
  8946. ++s;
  8947. t = strchr(s, ')');
  8948. if (t == NULL) stb_fatal("Error parsing %s", filename);
  8949. }
  8950. }
  8951. }
  8952. #endif
  8953. //////////////////////////////////////////////////////////////////////////////
  8954. //
  8955. // STB-C sliding-window dictionary compression
  8956. //
  8957. // This uses a DEFLATE-style sliding window, but no bitwise entropy.
  8958. // Everything is on byte boundaries, so you could then apply a byte-wise
  8959. // entropy code, though that's nowhere near as effective.
  8960. //
  8961. // An STB-C stream begins with a 16-byte header:
  8962. // 4 bytes: 0x57 0xBC 0x00 0x00
  8963. // 8 bytes: big-endian size of decompressed data, 64-bits
  8964. // 4 bytes: big-endian size of window (how far back decompressor may need)
  8965. //
  8966. // The following symbols appear in the stream (these were determined ad hoc,
  8967. // not by analysis):
  8968. //
  8969. // [dict] 00000100 yyyyyyyy yyyyyyyy yyyyyyyy xxxxxxxx xxxxxxxx
  8970. // [END] 00000101 11111010 cccccccc cccccccc cccccccc cccccccc
  8971. // [dict] 00000110 yyyyyyyy yyyyyyyy yyyyyyyy xxxxxxxx
  8972. // [literals] 00000111 zzzzzzzz zzzzzzzz
  8973. // [literals] 00001zzz zzzzzzzz
  8974. // [dict] 00010yyy yyyyyyyy yyyyyyyy xxxxxxxx xxxxxxxx
  8975. // [dict] 00011yyy yyyyyyyy yyyyyyyy xxxxxxxx
  8976. // [literals] 001zzzzz
  8977. // [dict] 01yyyyyy yyyyyyyy xxxxxxxx
  8978. // [dict] 1xxxxxxx yyyyyyyy
  8979. //
  8980. // xxxxxxxx: match length - 1
  8981. // yyyyyyyy: backwards distance - 1
  8982. // zzzzzzzz: num literals - 1
  8983. // cccccccc: adler32 checksum of decompressed data
  8984. // (all big-endian)
  8985. STB_EXTERN stb_uint stb_decompress_length(stb_uchar *input);
  8986. STB_EXTERN stb_uint stb_decompress(stb_uchar *out,stb_uchar *in,stb_uint len);
  8987. STB_EXTERN stb_uint stb_compress (stb_uchar *out,stb_uchar *in,stb_uint len);
  8988. STB_EXTERN void stb_compress_window(int z);
  8989. STB_EXTERN void stb_compress_hashsize(unsigned int z);
  8990. STB_EXTERN int stb_compress_tofile(char *filename, char *in, stb_uint len);
  8991. STB_EXTERN int stb_compress_intofile(FILE *f, char *input, stb_uint len);
  8992. STB_EXTERN char *stb_decompress_fromfile(char *filename, stb_uint *len);
  8993. STB_EXTERN int stb_compress_stream_start(FILE *f);
  8994. STB_EXTERN void stb_compress_stream_end(int close);
  8995. STB_EXTERN void stb_write(char *data, int data_len);
  8996. #ifdef STB_DEFINE
  8997. stb_uint stb_decompress_length(stb_uchar *input)
  8998. {
  8999. return (input[8] << 24) + (input[9] << 16) + (input[10] << 8) + input[11];
  9000. }
  9001. //////////////////// decompressor ///////////////////////
  9002. // simple implementation that just writes whole thing into big block
  9003. static unsigned char *stb__barrier;
  9004. static unsigned char *stb__barrier2;
  9005. static unsigned char *stb__barrier3;
  9006. static unsigned char *stb__barrier4;
  9007. static stb_uchar *stb__dout;
  9008. static void stb__match(stb_uchar *data, stb_uint length)
  9009. {
  9010. // INVERSE of memmove... write each byte before copying the next...
  9011. assert (stb__dout + length <= stb__barrier);
  9012. if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
  9013. if (data < stb__barrier4) { stb__dout = stb__barrier+1; return; }
  9014. while (length--) *stb__dout++ = *data++;
  9015. }
  9016. static void stb__lit(stb_uchar *data, stb_uint length)
  9017. {
  9018. assert (stb__dout + length <= stb__barrier);
  9019. if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
  9020. if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; }
  9021. memcpy(stb__dout, data, length);
  9022. stb__dout += length;
  9023. }
  9024. #define stb__in2(x) ((i[x] << 8) + i[(x)+1])
  9025. #define stb__in3(x) ((i[x] << 16) + stb__in2((x)+1))
  9026. #define stb__in4(x) ((i[x] << 24) + stb__in3((x)+1))
  9027. static stb_uchar *stb_decompress_token(stb_uchar *i)
  9028. {
  9029. if (*i >= 0x20) { // use fewer if's for cases that expand small
  9030. if (*i >= 0x80) stb__match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2;
  9031. else if (*i >= 0x40) stb__match(stb__dout-(stb__in2(0) - 0x4000 + 1), i[2]+1), i += 3;
  9032. else /* *i >= 0x20 */ stb__lit(i+1, i[0] - 0x20 + 1), i += 1 + (i[0] - 0x20 + 1);
  9033. } else { // more ifs for cases that expand large, since overhead is amortized
  9034. if (*i >= 0x18) stb__match(stb__dout-(stb__in3(0) - 0x180000 + 1), i[3]+1), i += 4;
  9035. else if (*i >= 0x10) stb__match(stb__dout-(stb__in3(0) - 0x100000 + 1), stb__in2(3)+1), i += 5;
  9036. else if (*i >= 0x08) stb__lit(i+2, stb__in2(0) - 0x0800 + 1), i += 2 + (stb__in2(0) - 0x0800 + 1);
  9037. else if (*i == 0x07) stb__lit(i+3, stb__in2(1) + 1), i += 3 + (stb__in2(1) + 1);
  9038. else if (*i == 0x06) stb__match(stb__dout-(stb__in3(1)+1), i[4]+1), i += 5;
  9039. else if (*i == 0x04) stb__match(stb__dout-(stb__in3(1)+1), stb__in2(4)+1), i += 6;
  9040. }
  9041. return i;
  9042. }
  9043. stb_uint stb_decompress(stb_uchar *output, stb_uchar *i, stb_uint length)
  9044. {
  9045. stb_uint olen;
  9046. if (stb__in4(0) != 0x57bC0000) return 0;
  9047. if (stb__in4(4) != 0) return 0; // error! stream is > 4GB
  9048. olen = stb_decompress_length(i);
  9049. stb__barrier2 = i;
  9050. stb__barrier3 = i+length;
  9051. stb__barrier = output + olen;
  9052. stb__barrier4 = output;
  9053. i += 16;
  9054. stb__dout = output;
  9055. while (1) {
  9056. stb_uchar *old_i = i;
  9057. i = stb_decompress_token(i);
  9058. if (i == old_i) {
  9059. if (*i == 0x05 && i[1] == 0xfa) {
  9060. assert(stb__dout == output + olen);
  9061. if (stb__dout != output + olen) return 0;
  9062. if (stb_adler32(1, output, olen) != (stb_uint) stb__in4(2))
  9063. return 0;
  9064. return olen;
  9065. } else {
  9066. assert(0); /* NOTREACHED */
  9067. return 0;
  9068. }
  9069. }
  9070. assert(stb__dout <= output + olen);
  9071. if (stb__dout > output + olen)
  9072. return 0;
  9073. }
  9074. }
  9075. char *stb_decompress_fromfile(char *filename, unsigned int *len)
  9076. {
  9077. unsigned int n;
  9078. char *q;
  9079. unsigned char *p;
  9080. FILE *f = fopen(filename, "rb"); if (f == NULL) return NULL;
  9081. fseek(f, 0, SEEK_END);
  9082. n = ftell(f);
  9083. fseek(f, 0, SEEK_SET);
  9084. p = (unsigned char * ) malloc(n); if (p == NULL) return NULL;
  9085. fread(p, 1, n, f);
  9086. fclose(f);
  9087. if (p == NULL) return NULL;
  9088. if (p[0] != 0x57 || p[1] != 0xBc || p[2] || p[3]) { free(p); return NULL; }
  9089. q = (char *) malloc(stb_decompress_length(p)+1);
  9090. if (!q) { free(p); return NULL; }
  9091. *len = stb_decompress((unsigned char *) q, p, n);
  9092. if (*len) q[*len] = 0;
  9093. free(p);
  9094. return q;
  9095. }
  9096. #if 0
  9097. // streaming decompressor
  9098. static struct
  9099. {
  9100. stb__uchar *in_buffer;
  9101. stb__uchar *match;
  9102. stb__uint pending_literals;
  9103. stb__uint pending_match;
  9104. } xx;
  9105. static void stb__match(stb_uchar *data, stb_uint length)
  9106. {
  9107. // INVERSE of memmove... write each byte before copying the next...
  9108. assert (stb__dout + length <= stb__barrier);
  9109. if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
  9110. if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; }
  9111. while (length--) *stb__dout++ = *data++;
  9112. }
  9113. static void stb__lit(stb_uchar *data, stb_uint length)
  9114. {
  9115. assert (stb__dout + length <= stb__barrier);
  9116. if (stb__dout + length > stb__barrier) { stb__dout += length; return; }
  9117. if (data < stb__barrier2) { stb__dout = stb__barrier+1; return; }
  9118. memcpy(stb__dout, data, length);
  9119. stb__dout += length;
  9120. }
  9121. static void sx_match(stb_uchar *data, stb_uint length)
  9122. {
  9123. xx.match = data;
  9124. xx.pending_match = length;
  9125. }
  9126. static void sx_lit(stb_uchar *data, stb_uint length)
  9127. {
  9128. xx.pending_lit = length;
  9129. }
  9130. static int stb_decompress_token_state(void)
  9131. {
  9132. stb__uchar *i = xx.in_buffer;
  9133. if (*i >= 0x20) { // use fewer if's for cases that expand small
  9134. if (*i >= 0x80) sx_match(stb__dout-i[1]-1, i[0] - 0x80 + 1), i += 2;
  9135. else if (*i >= 0x40) sx_match(stb__dout-(stb__in2(0) - 0x4000 + 1), i[2]+1), i += 3;
  9136. else /* *i >= 0x20 */ sx_lit(i+1, i[0] - 0x20 + 1), i += 1;
  9137. } else { // more ifs for cases that expand large, since overhead is amortized
  9138. if (*i >= 0x18) sx_match(stb__dout-(stb__in3(0) - 0x180000 + 1), i[3]+1), i += 4;
  9139. else if (*i >= 0x10) sx_match(stb__dout-(stb__in3(0) - 0x100000 + 1), stb__in2(3)+1), i += 5;
  9140. else if (*i >= 0x08) sx_lit(i+2, stb__in2(0) - 0x0800 + 1), i += 2;
  9141. else if (*i == 0x07) sx_lit(i+3, stb__in2(1) + 1), i += 3;
  9142. else if (*i == 0x06) sx_match(stb__dout-(stb__in3(1)+1), i[4]+1), i += 5;
  9143. else if (*i == 0x04) sx_match(stb__dout-(stb__in3(1)+1), stb__in2(4)+1), i += 6;
  9144. else return 0;
  9145. }
  9146. xx.in_buffer = i;
  9147. return 1;
  9148. }
  9149. #endif
  9150. //////////////////// compressor ///////////////////////
  9151. static unsigned int stb_matchlen(stb_uchar *m1, stb_uchar *m2, stb_uint maxlen)
  9152. {
  9153. stb_uint i;
  9154. for (i=0; i < maxlen; ++i)
  9155. if (m1[i] != m2[i]) return i;
  9156. return i;
  9157. }
  9158. // simple implementation that just takes the source data in a big block
  9159. static stb_uchar *stb__out;
  9160. static FILE *stb__outfile;
  9161. static stb_uint stb__outbytes;
  9162. static void stb__write(unsigned char v)
  9163. {
  9164. fputc(v, stb__outfile);
  9165. ++stb__outbytes;
  9166. }
  9167. #define stb_out(v) (stb__out ? (void)(*stb__out++ = (stb_uchar) (v)) : stb__write((stb_uchar) (v)))
  9168. static void stb_out2(stb_uint v)
  9169. {
  9170. stb_out(v >> 8);
  9171. stb_out(v);
  9172. }
  9173. static void stb_out3(stb_uint v) { stb_out(v >> 16); stb_out(v >> 8); stb_out(v); }
  9174. static void stb_out4(stb_uint v) { stb_out(v >> 24); stb_out(v >> 16);
  9175. stb_out(v >> 8 ); stb_out(v); }
  9176. static void outliterals(stb_uchar *in, int numlit)
  9177. {
  9178. while (numlit > 65536) {
  9179. outliterals(in,65536);
  9180. in += 65536;
  9181. numlit -= 65536;
  9182. }
  9183. if (numlit == 0) ;
  9184. else if (numlit <= 32) stb_out (0x000020 + numlit-1);
  9185. else if (numlit <= 2048) stb_out2(0x000800 + numlit-1);
  9186. else /* numlit <= 65536) */ stb_out3(0x070000 + numlit-1);
  9187. if (stb__out) {
  9188. memcpy(stb__out,in,numlit);
  9189. stb__out += numlit;
  9190. } else
  9191. fwrite(in, 1, numlit, stb__outfile);
  9192. }
  9193. static int stb__window = 0x40000; // 256K
  9194. void stb_compress_window(int z)
  9195. {
  9196. if (z >= 0x1000000) z = 0x1000000; // limit of implementation
  9197. if (z < 0x100) z = 0x100; // insanely small
  9198. stb__window = z;
  9199. }
  9200. static int stb_not_crap(int best, int dist)
  9201. {
  9202. return ((best > 2 && dist <= 0x00100)
  9203. || (best > 5 && dist <= 0x04000)
  9204. || (best > 7 && dist <= 0x80000));
  9205. }
  9206. static stb_uint stb__hashsize = 32768;
  9207. void stb_compress_hashsize(unsigned int y)
  9208. {
  9209. unsigned int z = 1024;
  9210. while (z < y) z <<= 1;
  9211. stb__hashsize = z >> 2; // pass in bytes, store #pointers
  9212. }
  9213. // note that you can play with the hashing functions all you
  9214. // want without needing to change the decompressor
  9215. #define stb__hc(q,h,c) (((h) << 7) + ((h) >> 25) + q[c])
  9216. #define stb__hc2(q,h,c,d) (((h) << 14) + ((h) >> 18) + (q[c] << 7) + q[d])
  9217. #define stb__hc3(q,c,d,e) ((q[c] << 14) + (q[d] << 7) + q[e])
  9218. static stb_uint32 stb__running_adler;
  9219. static int stb_compress_chunk(stb_uchar *history,
  9220. stb_uchar *start,
  9221. stb_uchar *end,
  9222. int length,
  9223. int *pending_literals,
  9224. stb_uchar **chash,
  9225. stb_uint mask)
  9226. {
  9227. int window = stb__window;
  9228. stb_uint match_max;
  9229. stb_uchar *lit_start = start - *pending_literals;
  9230. stb_uchar *q = start;
  9231. #define STB__SCRAMBLE(h) (((h) + ((h) >> 16)) & mask)
  9232. // stop short of the end so we don't scan off the end doing
  9233. // the hashing; this means we won't compress the last few bytes
  9234. // unless they were part of something longer
  9235. while (q < start+length && q+12 < end) {
  9236. int m;
  9237. stb_uint h1,h2,h3,h4, h;
  9238. stb_uchar *t;
  9239. int best = 2, dist=0;
  9240. if (q+65536 > end)
  9241. match_max = end-q;
  9242. else
  9243. match_max = 65536;
  9244. #define stb__nc(b,d) ((d) <= window && ((b) > 9 || stb_not_crap(b,d)))
  9245. #define STB__TRY(t,p) /* avoid retrying a match we already tried */ \
  9246. if (p ? dist != q-t : 1) \
  9247. if ((m = stb_matchlen(t, q, match_max)) > best) \
  9248. if (stb__nc(m,q-(t))) \
  9249. best = m, dist = q - (t)
  9250. // rather than search for all matches, only try 4 candidate locations,
  9251. // chosen based on 4 different hash functions of different lengths.
  9252. // this strategy is inspired by LZO; hashing is unrolled here using the
  9253. // 'hc' macro
  9254. h = stb__hc3(q,0, 1, 2); h1 = STB__SCRAMBLE(h);
  9255. t = chash[h1]; if (t) STB__TRY(t,0);
  9256. h = stb__hc2(q,h, 3, 4); h2 = STB__SCRAMBLE(h);
  9257. h = stb__hc2(q,h, 5, 6); t = chash[h2]; if (t) STB__TRY(t,1);
  9258. h = stb__hc2(q,h, 7, 8); h3 = STB__SCRAMBLE(h);
  9259. h = stb__hc2(q,h, 9,10); t = chash[h3]; if (t) STB__TRY(t,1);
  9260. h = stb__hc2(q,h,11,12); h4 = STB__SCRAMBLE(h);
  9261. t = chash[h4]; if (t) STB__TRY(t,1);
  9262. // because we use a shared hash table, can only update it
  9263. // _after_ we've probed all of them
  9264. chash[h1] = chash[h2] = chash[h3] = chash[h4] = q;
  9265. if (best > 2)
  9266. assert(dist > 0);
  9267. // see if our best match qualifies
  9268. if (best < 3) { // fast path literals
  9269. ++q;
  9270. } else if (best > 2 && best <= 0x80 && dist <= 0x100) {
  9271. outliterals(lit_start, q-lit_start); lit_start = (q += best);
  9272. stb_out(0x80 + best-1);
  9273. stb_out(dist-1);
  9274. } else if (best > 5 && best <= 0x100 && dist <= 0x4000) {
  9275. outliterals(lit_start, q-lit_start); lit_start = (q += best);
  9276. stb_out2(0x4000 + dist-1);
  9277. stb_out(best-1);
  9278. } else if (best > 7 && best <= 0x100 && dist <= 0x80000) {
  9279. outliterals(lit_start, q-lit_start); lit_start = (q += best);
  9280. stb_out3(0x180000 + dist-1);
  9281. stb_out(best-1);
  9282. } else if (best > 8 && best <= 0x10000 && dist <= 0x80000) {
  9283. outliterals(lit_start, q-lit_start); lit_start = (q += best);
  9284. stb_out3(0x100000 + dist-1);
  9285. stb_out2(best-1);
  9286. } else if (best > 9 && dist <= 0x1000000) {
  9287. if (best > 65536) best = 65536;
  9288. outliterals(lit_start, q-lit_start); lit_start = (q += best);
  9289. if (best <= 0x100) {
  9290. stb_out(0x06);
  9291. stb_out3(dist-1);
  9292. stb_out(best-1);
  9293. } else {
  9294. stb_out(0x04);
  9295. stb_out3(dist-1);
  9296. stb_out2(best-1);
  9297. }
  9298. } else { // fallback literals if no match was a balanced tradeoff
  9299. ++q;
  9300. }
  9301. }
  9302. // if we didn't get all the way, add the rest to literals
  9303. if (q-start < length)
  9304. q = start+length;
  9305. // the literals are everything from lit_start to q
  9306. *pending_literals = (q - lit_start);
  9307. stb__running_adler = stb_adler32(stb__running_adler, start, q - start);
  9308. return q - start;
  9309. }
  9310. static int stb_compress_inner(stb_uchar *input, stb_uint length)
  9311. {
  9312. int literals = 0;
  9313. stb_uint len,i;
  9314. stb_uchar **chash;
  9315. chash = (stb_uchar**) malloc(stb__hashsize * sizeof(stb_uchar*));
  9316. if (chash == NULL) return 0; // failure
  9317. for (i=0; i < stb__hashsize; ++i)
  9318. chash[i] = NULL;
  9319. // stream signature
  9320. stb_out(0x57); stb_out(0xbc);
  9321. stb_out2(0);
  9322. stb_out4(0); // 64-bit length requires 32-bit leading 0
  9323. stb_out4(length);
  9324. stb_out4(stb__window);
  9325. stb__running_adler = 1;
  9326. len = stb_compress_chunk(input, input, input+length, length, &literals, chash, stb__hashsize-1);
  9327. assert(len == length);
  9328. outliterals(input+length - literals, literals);
  9329. free(chash);
  9330. stb_out2(0x05fa); // end opcode
  9331. stb_out4(stb__running_adler);
  9332. return 1; // success
  9333. }
  9334. stb_uint stb_compress(stb_uchar *out, stb_uchar *input, stb_uint length)
  9335. {
  9336. stb__out = out;
  9337. stb__outfile = NULL;
  9338. stb_compress_inner(input, length);
  9339. return stb__out - out;
  9340. }
  9341. int stb_compress_tofile(char *filename, char *input, unsigned int length)
  9342. {
  9343. //int maxlen = length + 512 + (length >> 2); // total guess
  9344. //char *buffer = (char *) malloc(maxlen);
  9345. //int blen = stb_compress((stb_uchar*)buffer, (stb_uchar*)input, length);
  9346. stb__out = NULL;
  9347. stb__outfile = fopen(filename, "wb");
  9348. if (!stb__outfile) return 0;
  9349. stb__outbytes = 0;
  9350. if (!stb_compress_inner((stb_uchar*)input, length))
  9351. return 0;
  9352. fclose(stb__outfile);
  9353. return stb__outbytes;
  9354. }
  9355. int stb_compress_intofile(FILE *f, char *input, unsigned int length)
  9356. {
  9357. //int maxlen = length + 512 + (length >> 2); // total guess
  9358. //char *buffer = (char*)malloc(maxlen);
  9359. //int blen = stb_compress((stb_uchar*)buffer, (stb_uchar*)input, length);
  9360. stb__out = NULL;
  9361. stb__outfile = f;
  9362. if (!stb__outfile) return 0;
  9363. stb__outbytes = 0;
  9364. if (!stb_compress_inner((stb_uchar*)input, length))
  9365. return 0;
  9366. return stb__outbytes;
  9367. }
  9368. ////////////////////// streaming I/O version /////////////////////
  9369. static size_t stb_out_backpatch_id(void)
  9370. {
  9371. if (stb__out)
  9372. return (size_t) stb__out;
  9373. else
  9374. return ftell(stb__outfile);
  9375. }
  9376. static void stb_out_backpatch(size_t id, stb_uint value)
  9377. {
  9378. stb_uchar data[4] = { (stb_uchar)(value >> 24), (stb_uchar)(value >> 16), (stb_uchar)(value >> 8), (stb_uchar)(value) };
  9379. if (stb__out) {
  9380. memcpy((void *) id, data, 4);
  9381. } else {
  9382. stb_uint where = ftell(stb__outfile);
  9383. fseek(stb__outfile, id, SEEK_SET);
  9384. fwrite(data, 4, 1, stb__outfile);
  9385. fseek(stb__outfile, where, SEEK_SET);
  9386. }
  9387. }
  9388. // ok, the wraparound buffer was a total failure. let's instead
  9389. // use a copying-in-place buffer, which lets us share the code.
  9390. // This is way less efficient but it'll do for now.
  9391. static struct
  9392. {
  9393. stb_uchar *buffer;
  9394. int size; // physical size of buffer in bytes
  9395. int valid; // amount of valid data in bytes
  9396. int start; // bytes of data already output
  9397. int window;
  9398. int fsize;
  9399. int pending_literals; // bytes not-quite output but counted in start
  9400. int length_id;
  9401. stb_uint total_bytes;
  9402. stb_uchar **chash;
  9403. stb_uint hashmask;
  9404. } xtb;
  9405. static int stb_compress_streaming_start(void)
  9406. {
  9407. stb_uint i;
  9408. xtb.size = stb__window * 3;
  9409. xtb.buffer = (stb_uchar*)malloc(xtb.size);
  9410. if (!xtb.buffer) return 0;
  9411. xtb.chash = (stb_uchar**)malloc(sizeof(*xtb.chash) * stb__hashsize);
  9412. if (!xtb.chash) {
  9413. free(xtb.buffer);
  9414. return 0;
  9415. }
  9416. for (i=0; i < stb__hashsize; ++i)
  9417. xtb.chash[i] = NULL;
  9418. xtb.hashmask = stb__hashsize-1;
  9419. xtb.valid = 0;
  9420. xtb.start = 0;
  9421. xtb.window = stb__window;
  9422. xtb.fsize = stb__window;
  9423. xtb.pending_literals = 0;
  9424. xtb.total_bytes = 0;
  9425. // stream signature
  9426. stb_out(0x57); stb_out(0xbc); stb_out2(0);
  9427. stb_out4(0); // 64-bit length requires 32-bit leading 0
  9428. xtb.length_id = stb_out_backpatch_id();
  9429. stb_out4(0); // we don't know the output length yet
  9430. stb_out4(stb__window);
  9431. stb__running_adler = 1;
  9432. return 1;
  9433. }
  9434. static int stb_compress_streaming_end(void)
  9435. {
  9436. // flush out any remaining data
  9437. stb_compress_chunk(xtb.buffer, xtb.buffer+xtb.start, xtb.buffer+xtb.valid,
  9438. xtb.valid-xtb.start, &xtb.pending_literals, xtb.chash, xtb.hashmask);
  9439. // write out pending literals
  9440. outliterals(xtb.buffer + xtb.valid - xtb.pending_literals, xtb.pending_literals);
  9441. stb_out2(0x05fa); // end opcode
  9442. stb_out4(stb__running_adler);
  9443. stb_out_backpatch(xtb.length_id, xtb.total_bytes);
  9444. free(xtb.buffer);
  9445. free(xtb.chash);
  9446. return 1;
  9447. }
  9448. void stb_write(char *data, int data_len)
  9449. {
  9450. stb_uint i;
  9451. // @TODO: fast path for filling the buffer and doing nothing else
  9452. // if (xtb.valid + data_len < xtb.size)
  9453. xtb.total_bytes += data_len;
  9454. while (data_len) {
  9455. // fill buffer
  9456. if (xtb.valid < xtb.size) {
  9457. int amt = xtb.size - xtb.valid;
  9458. if (data_len < amt) amt = data_len;
  9459. memcpy(xtb.buffer + xtb.valid, data, amt);
  9460. data_len -= amt;
  9461. data += amt;
  9462. xtb.valid += amt;
  9463. }
  9464. if (xtb.valid < xtb.size)
  9465. return;
  9466. // at this point, the buffer is full
  9467. // if we can process some data, go for it; make sure
  9468. // we leave an 'fsize's worth of data, though
  9469. if (xtb.start + xtb.fsize < xtb.valid) {
  9470. int amount = (xtb.valid - xtb.fsize) - xtb.start;
  9471. int n;
  9472. assert(amount > 0);
  9473. n = stb_compress_chunk(xtb.buffer, xtb.buffer + xtb.start, xtb.buffer + xtb.valid,
  9474. amount, &xtb.pending_literals, xtb.chash, xtb.hashmask);
  9475. xtb.start += n;
  9476. }
  9477. assert(xtb.start + xtb.fsize >= xtb.valid);
  9478. // at this point, our future size is too small, so we
  9479. // need to flush some history. we, in fact, flush exactly
  9480. // one window's worth of history
  9481. {
  9482. int flush = xtb.window;
  9483. assert(xtb.start >= flush);
  9484. assert(xtb.valid >= flush);
  9485. // if 'pending literals' extends back into the shift region,
  9486. // write them out
  9487. if (xtb.start - xtb.pending_literals < flush) {
  9488. outliterals(xtb.buffer + xtb.start - xtb.pending_literals, xtb.pending_literals);
  9489. xtb.pending_literals = 0;
  9490. }
  9491. // now shift the window
  9492. memmove(xtb.buffer, xtb.buffer + flush, xtb.valid - flush);
  9493. xtb.start -= flush;
  9494. xtb.valid -= flush;
  9495. for (i=0; i <= xtb.hashmask; ++i)
  9496. if (xtb.chash[i] < xtb.buffer + flush)
  9497. xtb.chash[i] = NULL;
  9498. else
  9499. xtb.chash[i] -= flush;
  9500. }
  9501. // and now that we've made room for more data, go back to the top
  9502. }
  9503. }
  9504. int stb_compress_stream_start(FILE *f)
  9505. {
  9506. stb__out = NULL;
  9507. stb__outfile = f;
  9508. if (f == NULL)
  9509. return 0;
  9510. if (!stb_compress_streaming_start())
  9511. return 0;
  9512. return 1;
  9513. }
  9514. void stb_compress_stream_end(int close)
  9515. {
  9516. stb_compress_streaming_end();
  9517. if (close && stb__outfile) {
  9518. fclose(stb__outfile);
  9519. }
  9520. }
  9521. #endif // STB_DEFINE
  9522. //////////////////////////////////////////////////////////////////////////////
  9523. //
  9524. // File abstraction... tired of not having this... we can write
  9525. // compressors to be layers over these that auto-close their children.
  9526. typedef struct stbfile
  9527. {
  9528. int (*getbyte)(struct stbfile *); // -1 on EOF
  9529. unsigned int (*getdata)(struct stbfile *, void *block, unsigned int len);
  9530. int (*putbyte)(struct stbfile *, int byte);
  9531. unsigned int (*putdata)(struct stbfile *, void *block, unsigned int len);
  9532. unsigned int (*size)(struct stbfile *);
  9533. unsigned int (*tell)(struct stbfile *);
  9534. void (*backpatch)(struct stbfile *, unsigned int tell, void *block, unsigned int len);
  9535. void (*close)(struct stbfile *);
  9536. FILE *f; // file to fread/fwrite
  9537. unsigned char *buffer; // input/output buffer
  9538. unsigned char *indata, *inend; // input buffer
  9539. union {
  9540. int various;
  9541. void *ptr;
  9542. };
  9543. } stbfile;
  9544. STB_EXTERN unsigned int stb_getc(stbfile *f); // read
  9545. STB_EXTERN int stb_putc(stbfile *f, int ch); // write
  9546. STB_EXTERN unsigned int stb_getdata(stbfile *f, void *buffer, unsigned int len); // read
  9547. STB_EXTERN unsigned int stb_putdata(stbfile *f, void *buffer, unsigned int len); // write
  9548. STB_EXTERN unsigned int stb_tell(stbfile *f); // read
  9549. STB_EXTERN unsigned int stb_size(stbfile *f); // read/write
  9550. STB_EXTERN void stb_backpatch(stbfile *f, unsigned int tell, void *buffer, unsigned int len); // write
  9551. #ifdef STB_DEFINE
  9552. unsigned int stb_getc(stbfile *f) { return f->getbyte(f); }
  9553. int stb_putc(stbfile *f, int ch) { return f->putbyte(f, ch); }
  9554. unsigned int stb_getdata(stbfile *f, void *buffer, unsigned int len)
  9555. {
  9556. return f->getdata(f, buffer, len);
  9557. }
  9558. unsigned int stb_putdata(stbfile *f, void *buffer, unsigned int len)
  9559. {
  9560. return f->putdata(f, buffer, len);
  9561. }
  9562. void stb_close(stbfile *f)
  9563. {
  9564. f->close(f);
  9565. free(f);
  9566. }
  9567. unsigned int stb_tell(stbfile *f) { return f->tell(f); }
  9568. unsigned int stb_size(stbfile *f) { return f->size(f); }
  9569. void stb_backpatch(stbfile *f, unsigned int tell, void *buffer, unsigned int len)
  9570. {
  9571. f->backpatch(f,tell,buffer,len);
  9572. }
  9573. // FILE * implementation
  9574. static int stb__fgetbyte(stbfile *f) { return fgetc(f->f); }
  9575. static int stb__fputbyte(stbfile *f, int ch) { return fputc(ch, f->f)==0; }
  9576. static unsigned int stb__fgetdata(stbfile *f, void *buffer, unsigned int len) { return fread(buffer,1,len,f->f); }
  9577. static unsigned int stb__fputdata(stbfile *f, void *buffer, unsigned int len) { return fwrite(buffer,1,len,f->f); }
  9578. static unsigned int stb__fsize(stbfile *f) { return stb_filelen(f->f); }
  9579. static unsigned int stb__ftell(stbfile *f) { return ftell(f->f); }
  9580. static void stb__fbackpatch(stbfile *f, unsigned int where, void *buffer, unsigned int len)
  9581. {
  9582. fseek(f->f, where, SEEK_SET);
  9583. fwrite(buffer, 1, len, f->f);
  9584. fseek(f->f, 0, SEEK_END);
  9585. }
  9586. static void stb__fclose(stbfile *f) { fclose(f->f); }
  9587. stbfile *stb_openf(FILE *f)
  9588. {
  9589. stbfile m = { stb__fgetbyte, stb__fgetdata,
  9590. stb__fputbyte, stb__fputdata,
  9591. stb__fsize, stb__ftell, stb__fbackpatch, stb__fclose,
  9592. 0,0,0, };
  9593. stbfile *z = (stbfile *) malloc(sizeof(*z));
  9594. if (z) {
  9595. *z = m;
  9596. z->f = f;
  9597. }
  9598. return z;
  9599. }
  9600. static int stb__nogetbyte(stbfile *f) { assert(0); return -1; }
  9601. static unsigned int stb__nogetdata(stbfile *f, void *buffer, unsigned int len) { assert(0); return 0; }
  9602. static int stb__noputbyte(stbfile *f, int ch) { assert(0); return 0; }
  9603. static unsigned int stb__noputdata(stbfile *f, void *buffer, unsigned int len) { assert(0); return 0; }
  9604. static void stb__nobackpatch(stbfile *f, unsigned int where, void *buffer, unsigned int len) { assert(0); }
  9605. static int stb__bgetbyte(stbfile *s)
  9606. {
  9607. if (s->indata < s->inend)
  9608. return *s->indata++;
  9609. else
  9610. return -1;
  9611. }
  9612. static unsigned int stb__bgetdata(stbfile *s, void *buffer, unsigned int len)
  9613. {
  9614. if (s->indata + len > s->inend)
  9615. len = s->inend - s->indata;
  9616. memcpy(buffer, s->indata, len);
  9617. s->indata += len;
  9618. return len;
  9619. }
  9620. static unsigned int stb__bsize(stbfile *s) { return s->inend - s->buffer; }
  9621. static unsigned int stb__btell(stbfile *s) { return s->indata - s->buffer; }
  9622. static void stb__bclose(stbfile *s)
  9623. {
  9624. if (s->various)
  9625. free(s->buffer);
  9626. }
  9627. stbfile *stb_open_inbuffer(void *buffer, unsigned int len)
  9628. {
  9629. stbfile m = { stb__bgetbyte, stb__bgetdata,
  9630. stb__noputbyte, stb__noputdata,
  9631. stb__bsize, stb__btell, stb__nobackpatch, stb__bclose };
  9632. stbfile *z = (stbfile *) malloc(sizeof(*z));
  9633. if (z) {
  9634. *z = m;
  9635. z->buffer = (unsigned char *) buffer;
  9636. z->indata = z->buffer;
  9637. z->inend = z->indata + len;
  9638. }
  9639. return z;
  9640. }
  9641. stbfile *stb_open_inbuffer_free(void *buffer, unsigned int len)
  9642. {
  9643. stbfile *z = stb_open_inbuffer(buffer, len);
  9644. if (z)
  9645. z->various = 1; // free
  9646. return z;
  9647. }
  9648. #ifndef STB_VERSION
  9649. // if we've been cut-and-pasted elsewhere, you get a limited
  9650. // version of stb_open, without the 'k' flag and utf8 support
  9651. static void stb__fclose2(stbfile *f)
  9652. {
  9653. fclose(f->f);
  9654. }
  9655. stbfile *stb_open(char *filename, char *mode)
  9656. {
  9657. FILE *f = fopen(filename, mode);
  9658. stbfile *s;
  9659. if (f == NULL) return NULL;
  9660. s = stb_openf(f);
  9661. if (s)
  9662. s->close = stb__fclose2;
  9663. return s;
  9664. }
  9665. #else
  9666. // the full version depends on some code in stb.h; this
  9667. // also includes the memory buffer output format implemented with stb_arr
  9668. static void stb__fclose2(stbfile *f)
  9669. {
  9670. stb_fclose(f->f, f->various);
  9671. }
  9672. stbfile *stb_open(char *filename, char *mode)
  9673. {
  9674. FILE *f = stb_fopen(filename, mode[0] == 'k' ? mode+1 : mode);
  9675. stbfile *s;
  9676. if (f == NULL) return NULL;
  9677. s = stb_openf(f);
  9678. if (s) {
  9679. s->close = stb__fclose2;
  9680. s->various = mode[0] == 'k' ? stb_keep_if_different : stb_keep_yes;
  9681. }
  9682. return s;
  9683. }
  9684. static int stb__aputbyte(stbfile *f, int ch)
  9685. {
  9686. stb_arr_push(f->buffer, ch);
  9687. return 1;
  9688. }
  9689. static unsigned int stb__aputdata(stbfile *f, void *data, unsigned int len)
  9690. {
  9691. memcpy(stb_arr_addn(f->buffer, (int) len), data, len);
  9692. return len;
  9693. }
  9694. static unsigned int stb__asize(stbfile *f) { return stb_arr_len(f->buffer); }
  9695. static void stb__abackpatch(stbfile *f, unsigned int where, void *data, unsigned int len)
  9696. {
  9697. memcpy(f->buffer+where, data, len);
  9698. }
  9699. static void stb__aclose(stbfile *f)
  9700. {
  9701. *(unsigned char **) f->ptr = f->buffer;
  9702. }
  9703. stbfile *stb_open_outbuffer(unsigned char **update_on_close)
  9704. {
  9705. stbfile m = { stb__nogetbyte, stb__nogetdata,
  9706. stb__aputbyte, stb__aputdata,
  9707. stb__asize, stb__asize, stb__abackpatch, stb__aclose };
  9708. stbfile *z = (stbfile *) malloc(sizeof(*z));
  9709. if (z) {
  9710. z->ptr = update_on_close;
  9711. *z = m;
  9712. }
  9713. return z;
  9714. }
  9715. #endif
  9716. #endif
  9717. //////////////////////////////////////////////////////////////////////////////
  9718. //
  9719. // Arithmetic coder... based on cbloom's notes on the subject, should be
  9720. // less code than a huffman code.
  9721. typedef struct
  9722. {
  9723. unsigned int range_low;
  9724. unsigned int range_high;
  9725. unsigned int code, range; // decode
  9726. int buffered_u8;
  9727. int pending_ffs;
  9728. stbfile *output;
  9729. } stb_arith;
  9730. STB_EXTERN void stb_arith_init_encode(stb_arith *a, stbfile *out);
  9731. STB_EXTERN void stb_arith_init_decode(stb_arith *a, stbfile *in);
  9732. STB_EXTERN stbfile *stb_arith_encode_close(stb_arith *a);
  9733. STB_EXTERN stbfile *stb_arith_decode_close(stb_arith *a);
  9734. STB_EXTERN void stb_arith_encode(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq);
  9735. STB_EXTERN void stb_arith_encode_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq);
  9736. STB_EXTERN unsigned int stb_arith_decode_value(stb_arith *a, unsigned int totalfreq);
  9737. STB_EXTERN void stb_arith_decode_advance(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq);
  9738. STB_EXTERN unsigned int stb_arith_decode_value_log2(stb_arith *a, unsigned int totalfreq2);
  9739. STB_EXTERN void stb_arith_decode_advance_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq);
  9740. STB_EXTERN void stb_arith_encode_byte(stb_arith *a, int byte);
  9741. STB_EXTERN int stb_arith_decode_byte(stb_arith *a);
  9742. // this is a memory-inefficient way of doing things, but it's
  9743. // fast(?) and simple
  9744. typedef struct
  9745. {
  9746. unsigned short cumfreq;
  9747. unsigned short samples;
  9748. } stb_arith_symstate_item;
  9749. typedef struct
  9750. {
  9751. int num_sym;
  9752. unsigned int pow2;
  9753. int countdown;
  9754. stb_arith_symstate_item data[1];
  9755. } stb_arith_symstate;
  9756. #ifdef STB_DEFINE
  9757. void stb_arith_init_encode(stb_arith *a, stbfile *out)
  9758. {
  9759. a->range_low = 0;
  9760. a->range_high = 0xffffffff;
  9761. a->pending_ffs = -1; // means no buffered character currently, to speed up normal case
  9762. a->output = out;
  9763. }
  9764. static void stb__arith_carry(stb_arith *a)
  9765. {
  9766. int i;
  9767. assert(a->pending_ffs != -1); // can't carry with no data
  9768. stb_putc(a->output, a->buffered_u8);
  9769. for (i=0; i < a->pending_ffs; ++i)
  9770. stb_putc(a->output, 0);
  9771. }
  9772. static void stb__arith_putbyte(stb_arith *a, int byte)
  9773. {
  9774. if (a->pending_ffs) {
  9775. if (a->pending_ffs == -1) { // means no buffered data; encoded for fast path efficiency
  9776. if (byte == 0xff)
  9777. stb_putc(a->output, byte); // just write it immediately
  9778. else {
  9779. a->buffered_u8 = byte;
  9780. a->pending_ffs = 0;
  9781. }
  9782. } else if (byte == 0xff) {
  9783. ++a->pending_ffs;
  9784. } else {
  9785. int i;
  9786. stb_putc(a->output, a->buffered_u8);
  9787. for (i=0; i < a->pending_ffs; ++i)
  9788. stb_putc(a->output, 0xff);
  9789. }
  9790. } else if (byte == 0xff) {
  9791. ++a->pending_ffs;
  9792. } else {
  9793. // fast path
  9794. stb_putc(a->output, a->buffered_u8);
  9795. a->buffered_u8 = byte;
  9796. }
  9797. }
  9798. static void stb__arith_flush(stb_arith *a)
  9799. {
  9800. if (a->pending_ffs >= 0) {
  9801. int i;
  9802. stb_putc(a->output, a->buffered_u8);
  9803. for (i=0; i < a->pending_ffs; ++i)
  9804. stb_putc(a->output, 0xff);
  9805. }
  9806. }
  9807. static void stb__renorm_encoder(stb_arith *a)
  9808. {
  9809. stb__arith_putbyte(a, a->range_low >> 24);
  9810. a->range_low <<= 8;
  9811. a->range_high = (a->range_high << 8) | 0xff;
  9812. }
  9813. static void stb__renorm_decoder(stb_arith *a)
  9814. {
  9815. int c = stb_getc(a->output);
  9816. a->code = (a->code << 8) + (c >= 0 ? c : 0); // if EOF, insert 0
  9817. }
  9818. void stb_arith_encode(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq)
  9819. {
  9820. unsigned int range = a->range_high - a->range_low;
  9821. unsigned int old = a->range_low;
  9822. range /= totalfreq;
  9823. a->range_low += range * cumfreq;
  9824. a->range_high = a->range_low + range*freq;
  9825. if (a->range_low < old)
  9826. stb__arith_carry(a);
  9827. while (a->range_high - a->range_low < 0x1000000)
  9828. stb__renorm_encoder(a);
  9829. }
  9830. void stb_arith_encode_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq)
  9831. {
  9832. unsigned int range = a->range_high - a->range_low;
  9833. unsigned int old = a->range_low;
  9834. range >>= totalfreq2;
  9835. a->range_low += range * cumfreq;
  9836. a->range_high = a->range_low + range*freq;
  9837. if (a->range_low < old)
  9838. stb__arith_carry(a);
  9839. while (a->range_high - a->range_low < 0x1000000)
  9840. stb__renorm_encoder(a);
  9841. }
  9842. unsigned int stb_arith_decode_value(stb_arith *a, unsigned int totalfreq)
  9843. {
  9844. unsigned int freqsize = a->range / totalfreq;
  9845. unsigned int z = a->code / freqsize;
  9846. return z >= totalfreq ? totalfreq-1 : z;
  9847. }
  9848. void stb_arith_decode_advance(stb_arith *a, unsigned int totalfreq, unsigned int freq, unsigned int cumfreq)
  9849. {
  9850. unsigned int freqsize = a->range / totalfreq; // @OPTIMIZE, share with above divide somehow?
  9851. a->code -= freqsize * cumfreq;
  9852. a->range = freqsize * freq;
  9853. while (a->range < 0x1000000)
  9854. stb__renorm_decoder(a);
  9855. }
  9856. unsigned int stb_arith_decode_value_log2(stb_arith *a, unsigned int totalfreq2)
  9857. {
  9858. unsigned int freqsize = a->range >> totalfreq2;
  9859. unsigned int z = a->code / freqsize;
  9860. return z >= (1U<<totalfreq2) ? (1U<<totalfreq2)-1 : z;
  9861. }
  9862. void stb_arith_decode_advance_log2(stb_arith *a, unsigned int totalfreq2, unsigned int freq, unsigned int cumfreq)
  9863. {
  9864. unsigned int freqsize = a->range >> totalfreq2;
  9865. a->code -= freqsize * cumfreq;
  9866. a->range = freqsize * freq;
  9867. while (a->range < 0x1000000)
  9868. stb__renorm_decoder(a);
  9869. }
  9870. stbfile *stb_arith_encode_close(stb_arith *a)
  9871. {
  9872. // put exactly as many bytes as we'll read, so we can turn on/off arithmetic coding in a stream
  9873. stb__arith_putbyte(a, a->range_low >> 24);
  9874. stb__arith_putbyte(a, a->range_low >> 16);
  9875. stb__arith_putbyte(a, a->range_low >> 8);
  9876. stb__arith_putbyte(a, a->range_low >> 0);
  9877. stb__arith_flush(a);
  9878. return a->output;
  9879. }
  9880. stbfile *stb_arith_decode_close(stb_arith *a)
  9881. {
  9882. return a->output;
  9883. }
  9884. // this is a simple power-of-two based model -- using
  9885. // power of two means we need one divide per decode,
  9886. // not two.
  9887. #define POW2_LIMIT 12
  9888. stb_arith_symstate *stb_arith_state_create(int num_sym)
  9889. {
  9890. stb_arith_symstate *s = (stb_arith_symstate *) malloc(sizeof(*s) + (num_sym-1) * sizeof(s->data[0]));
  9891. if (s) {
  9892. int i, cf, cf_next, next;
  9893. int start_freq, extra;
  9894. s->num_sym = num_sym;
  9895. s->pow2 = 4;
  9896. while (s->pow2 < 15 && (1 << s->pow2) < 3*num_sym) {
  9897. ++s->pow2;
  9898. }
  9899. start_freq = (1 << s->pow2) / num_sym;
  9900. assert(start_freq >= 1);
  9901. extra = (1 << s->pow2) % num_sym;
  9902. // now set up the initial stats
  9903. if (s->pow2 < POW2_LIMIT)
  9904. next = 0;
  9905. else
  9906. next = 1;
  9907. cf = cf_next = 0;
  9908. for (i=0; i < extra; ++i) {
  9909. s->data[i].cumfreq = cf;
  9910. s->data[i].samples = next;
  9911. cf += start_freq+1;
  9912. cf_next += next;
  9913. }
  9914. for (; i < num_sym; ++i) {
  9915. s->data[i].cumfreq = cf;
  9916. s->data[i].samples = next;
  9917. cf += start_freq;
  9918. cf_next += next;
  9919. }
  9920. assert(cf == (1 << s->pow2));
  9921. // now, how long should we go until we have 2 << s->pow2 samples?
  9922. s->countdown = (2 << s->pow2) - cf - cf_next;
  9923. }
  9924. return s;
  9925. }
  9926. static void stb_arith_state_rescale(stb_arith_symstate *s)
  9927. {
  9928. if (s->pow2 < POW2_LIMIT) {
  9929. int pcf, cf, cf_next, next, i;
  9930. ++s->pow2;
  9931. if (s->pow2 < POW2_LIMIT)
  9932. next = 0;
  9933. else
  9934. next = 1;
  9935. cf = cf_next = 0;
  9936. pcf = 0;
  9937. for (i=0; i < s->num_sym; ++i) {
  9938. int sample = s->data[i].cumfreq - pcf + s->data[i].samples;
  9939. s->data[i].cumfreq = cf;
  9940. cf += sample;
  9941. s->data[i].samples = next;
  9942. cf_next += next;
  9943. }
  9944. assert(cf == (1 << s->pow2));
  9945. s->countdown = (2 << s->pow2) - cf - cf_next;
  9946. } else {
  9947. int pcf, cf, cf_next, i;
  9948. cf = cf_next = 0;
  9949. pcf = 0;
  9950. for (i=0; i < s->num_sym; ++i) {
  9951. int sample = (s->data[i].cumfreq - pcf + s->data[i].samples) >> 1;
  9952. s->data[i].cumfreq = cf;
  9953. cf += sample;
  9954. s->data[i].samples = 1;
  9955. cf_next += 1;
  9956. }
  9957. assert(cf == (1 << s->pow2)); // this isn't necessarily true, due to rounding down!
  9958. s->countdown = (2 << s->pow2) - cf - cf_next;
  9959. }
  9960. }
  9961. void stb_arith_encode_byte(stb_arith *a, int byte)
  9962. {
  9963. }
  9964. int stb_arith_decode_byte(stb_arith *a)
  9965. {
  9966. return -1;
  9967. }
  9968. #endif
  9969. //////////////////////////////////////////////////////////////////////////////
  9970. //
  9971. // Threads
  9972. //
  9973. #ifndef _WIN32
  9974. #ifdef STB_THREADS
  9975. #error "threads not implemented except for Windows"
  9976. #endif
  9977. #endif
  9978. // call this function to free any global variables for memory testing
  9979. STB_EXTERN void stb_thread_cleanup(void);
  9980. typedef void * (*stb_thread_func)(void *);
  9981. // do not rely on these types, this is an implementation detail.
  9982. // compare against STB_THREAD_NULL and ST_SEMAPHORE_NULL
  9983. typedef void *stb_thread;
  9984. typedef void *stb_semaphore;
  9985. typedef void *stb_mutex;
  9986. typedef struct stb__sync *stb_sync;
  9987. #define STB_SEMAPHORE_NULL NULL
  9988. #define STB_THREAD_NULL NULL
  9989. #define STB_MUTEX_NULL NULL
  9990. #define STB_SYNC_NULL NULL
  9991. // get the number of processors (limited to those in the affinity mask for this process).
  9992. STB_EXTERN int stb_processor_count(void);
  9993. // force to run on a single core -- needed for RDTSC to work, e.g. for iprof
  9994. STB_EXTERN void stb_force_uniprocessor(void);
  9995. // stb_work functions: queue up work to be done by some worker threads
  9996. // set number of threads to serve the queue; you can change this on the fly,
  9997. // but if you decrease it, it won't decrease until things currently on the
  9998. // queue are finished
  9999. STB_EXTERN void stb_work_numthreads(int n);
  10000. // set maximum number of units in the queue; you can only set this BEFORE running any work functions
  10001. STB_EXTERN int stb_work_maxunits(int n);
  10002. // enqueue some work to be done (can do this from any thread, or even from a piece of work);
  10003. // return value of f is stored in *return_code if non-NULL
  10004. STB_EXTERN int stb_work(stb_thread_func f, void *d, volatile void **return_code);
  10005. // as above, but stb_sync_reach is called on 'rel' after work is complete
  10006. STB_EXTERN int stb_work_reach(stb_thread_func f, void *d, volatile void **return_code, stb_sync rel);
  10007. // necessary to call this when using volatile to order writes/reads
  10008. STB_EXTERN void stb_barrier(void);
  10009. // support for independent queues with their own threads
  10010. typedef struct stb__workqueue stb_workqueue;
  10011. STB_EXTERN stb_workqueue*stb_workq_new(int numthreads, int max_units);
  10012. STB_EXTERN stb_workqueue*stb_workq_new_flags(int numthreads, int max_units, int no_add_mutex, int no_remove_mutex);
  10013. STB_EXTERN void stb_workq_delete(stb_workqueue *q);
  10014. STB_EXTERN void stb_workq_numthreads(stb_workqueue *q, int n);
  10015. STB_EXTERN int stb_workq(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code);
  10016. STB_EXTERN int stb_workq_reach(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code, stb_sync rel);
  10017. STB_EXTERN int stb_workq_length(stb_workqueue *q);
  10018. STB_EXTERN stb_thread stb_create_thread (stb_thread_func f, void *d);
  10019. STB_EXTERN stb_thread stb_create_thread2(stb_thread_func f, void *d, volatile void **return_code, stb_semaphore rel);
  10020. STB_EXTERN void stb_destroy_thread(stb_thread t);
  10021. STB_EXTERN stb_semaphore stb_sem_new(int max_val);
  10022. STB_EXTERN stb_semaphore stb_sem_new_extra(int max_val, int start_val);
  10023. STB_EXTERN void stb_sem_delete (stb_semaphore s);
  10024. STB_EXTERN void stb_sem_waitfor(stb_semaphore s);
  10025. STB_EXTERN void stb_sem_release(stb_semaphore s);
  10026. STB_EXTERN stb_mutex stb_mutex_new(void);
  10027. STB_EXTERN void stb_mutex_delete(stb_mutex m);
  10028. STB_EXTERN void stb_mutex_begin(stb_mutex m);
  10029. STB_EXTERN void stb_mutex_end(stb_mutex m);
  10030. STB_EXTERN stb_sync stb_sync_new(void);
  10031. STB_EXTERN void stb_sync_delete(stb_sync s);
  10032. STB_EXTERN int stb_sync_set_target(stb_sync s, int count);
  10033. STB_EXTERN void stb_sync_reach_and_wait(stb_sync s); // wait for 'target' reachers
  10034. STB_EXTERN int stb_sync_reach(stb_sync s);
  10035. typedef struct stb__threadqueue stb_threadqueue;
  10036. #define STB_THREADQ_DYNAMIC 0
  10037. STB_EXTERN stb_threadqueue *stb_threadq_new(int item_size, int num_items, int many_add, int many_remove);
  10038. STB_EXTERN void stb_threadq_delete(stb_threadqueue *tq);
  10039. STB_EXTERN int stb_threadq_get(stb_threadqueue *tq, void *output);
  10040. STB_EXTERN void stb_threadq_get_block(stb_threadqueue *tq, void *output);
  10041. STB_EXTERN int stb_threadq_add(stb_threadqueue *tq, void *input);
  10042. // can return FALSE if STB_THREADQ_DYNAMIC and attempt to grow fails
  10043. STB_EXTERN int stb_threadq_add_block(stb_threadqueue *tq, void *input);
  10044. #ifdef STB_THREADS
  10045. #ifdef STB_DEFINE
  10046. typedef struct
  10047. {
  10048. stb_thread_func f;
  10049. void *d;
  10050. volatile void **return_val;
  10051. stb_semaphore sem;
  10052. } stb__thread;
  10053. // this is initialized along all possible paths to create threads, therefore
  10054. // it's always initialized before any other threads are create, therefore
  10055. // it's free of races AS LONG AS you only create threads through stb_*
  10056. static stb_mutex stb__threadmutex, stb__workmutex;
  10057. static void stb__threadmutex_init(void)
  10058. {
  10059. if (stb__threadmutex == STB_SEMAPHORE_NULL) {
  10060. stb__threadmutex = stb_mutex_new();
  10061. stb__workmutex = stb_mutex_new();
  10062. }
  10063. }
  10064. #ifdef STB_THREAD_TEST
  10065. volatile float stb__t1=1, stb__t2;
  10066. static void stb__wait(int n)
  10067. {
  10068. float z = 0;
  10069. int i;
  10070. for (i=0; i < n; ++i)
  10071. z += 1 / (stb__t1+i);
  10072. stb__t2 = z;
  10073. }
  10074. #else
  10075. #define stb__wait(x)
  10076. #endif
  10077. #ifdef _WIN32
  10078. // avoid including windows.h -- note that our definitions aren't
  10079. // exactly the same (we don't define the security descriptor struct)
  10080. // so if you want to include windows.h, make sure you do it first.
  10081. #include <process.h>
  10082. #ifndef _WINDOWS_ // check windows.h guard
  10083. #define STB__IMPORT STB_EXTERN __declspec(dllimport)
  10084. #define STB__DW unsigned long
  10085. STB__IMPORT int __stdcall TerminateThread(void *, STB__DW);
  10086. STB__IMPORT void * __stdcall CreateSemaphoreA(void *sec, long,long,char*);
  10087. STB__IMPORT int __stdcall CloseHandle(void *);
  10088. STB__IMPORT STB__DW __stdcall WaitForSingleObject(void *, STB__DW);
  10089. STB__IMPORT int __stdcall ReleaseSemaphore(void *, long, long *);
  10090. STB__IMPORT void __stdcall Sleep(STB__DW);
  10091. #endif
  10092. // necessary to call this when using volatile to order writes/reads
  10093. void stb_barrier(void)
  10094. {
  10095. #ifdef MemoryBarrier
  10096. MemoryBarrier();
  10097. #else
  10098. long temp;
  10099. __asm xchg temp,eax;
  10100. #endif
  10101. }
  10102. static void stb__thread_run(void *t)
  10103. {
  10104. void *res;
  10105. stb__thread info = * (stb__thread *) t;
  10106. free(t);
  10107. res = info.f(info.d);
  10108. if (info.return_val)
  10109. *info.return_val = res;
  10110. if (info.sem != STB_SEMAPHORE_NULL)
  10111. stb_sem_release(info.sem);
  10112. }
  10113. static stb_thread stb_create_thread_raw(stb_thread_func f, void *d, volatile void **return_code, stb_semaphore rel)
  10114. {
  10115. #ifdef _MT
  10116. #if defined(STB_FASTMALLOC) && !defined(STB_FASTMALLOC_ITS_OKAY_I_ONLY_MALLOC_IN_ONE_THREAD)
  10117. stb_fatal("Error! Cannot use STB_FASTMALLOC with threads.\n");
  10118. return STB_THREAD_NULL;
  10119. #else
  10120. unsigned long id;
  10121. stb__thread *data = (stb__thread *) malloc(sizeof(*data));
  10122. if (!data) return NULL;
  10123. stb__threadmutex_init();
  10124. data->f = f;
  10125. data->d = d;
  10126. data->return_val = return_code;
  10127. data->sem = rel;
  10128. id = _beginthread(stb__thread_run, 0, data);
  10129. if (id == -1) return NULL;
  10130. return (void *) id;
  10131. #endif
  10132. #else
  10133. #ifdef STB_NO_STB_STRINGS
  10134. stb_fatal("Invalid compilation");
  10135. #else
  10136. stb_fatal("Must compile mult-threaded to use stb_thread/stb_work.");
  10137. #endif
  10138. return NULL;
  10139. #endif
  10140. }
  10141. // trivial win32 wrappers
  10142. void stb_destroy_thread(stb_thread t) { TerminateThread(t,0); }
  10143. stb_semaphore stb_sem_new(int maxv) {return CreateSemaphoreA(NULL,0,maxv,NULL); }
  10144. stb_semaphore stb_sem_new_extra(int maxv,int start){return CreateSemaphoreA(NULL,start,maxv,NULL); }
  10145. void stb_sem_delete(stb_semaphore s) { if (s != NULL) CloseHandle(s); }
  10146. void stb_sem_waitfor(stb_semaphore s) { WaitForSingleObject(s, 0xffffffff); } // INFINITE
  10147. void stb_sem_release(stb_semaphore s) { ReleaseSemaphore(s,1,NULL); }
  10148. static void stb__thread_sleep(int ms) { Sleep(ms); }
  10149. #ifndef _WINDOWS_
  10150. STB__IMPORT int __stdcall GetProcessAffinityMask(void *, STB__DW *, STB__DW *);
  10151. STB__IMPORT void * __stdcall GetCurrentProcess(void);
  10152. STB__IMPORT int __stdcall SetProcessAffinityMask(void *, STB__DW);
  10153. #endif
  10154. int stb_processor_count(void)
  10155. {
  10156. unsigned long proc,sys;
  10157. GetProcessAffinityMask(GetCurrentProcess(), &proc, &sys);
  10158. return stb_bitcount(proc);
  10159. }
  10160. void stb_force_uniprocessor(void)
  10161. {
  10162. unsigned long proc,sys;
  10163. GetProcessAffinityMask(GetCurrentProcess(), &proc, &sys);
  10164. if (stb_bitcount(proc) > 1) {
  10165. int z;
  10166. for (z=0; z < 32; ++z)
  10167. if (proc & (1 << z))
  10168. break;
  10169. if (z < 32) {
  10170. proc = 1 << z;
  10171. SetProcessAffinityMask(GetCurrentProcess(), proc);
  10172. }
  10173. }
  10174. }
  10175. #ifdef _WINDOWS_
  10176. #define STB_MUTEX_NATIVE
  10177. void *stb_mutex_new(void)
  10178. {
  10179. CRITICAL_SECTION *p = (CRITICAL_SECTION *) malloc(sizeof(*p));
  10180. if (p)
  10181. #if _WIN32_WINNT >= 0x0500
  10182. InitializeCriticalSectionAndSpinCount(p, 500);
  10183. #else
  10184. InitializeCriticalSection(p);
  10185. #endif
  10186. return p;
  10187. }
  10188. void stb_mutex_delete(void *p)
  10189. {
  10190. if (p) {
  10191. DeleteCriticalSection((CRITICAL_SECTION *) p);
  10192. free(p);
  10193. }
  10194. }
  10195. void stb_mutex_begin(void *p)
  10196. {
  10197. stb__wait(500);
  10198. if (p)
  10199. EnterCriticalSection((CRITICAL_SECTION *) p);
  10200. }
  10201. void stb_mutex_end(void *p)
  10202. {
  10203. if (p)
  10204. LeaveCriticalSection((CRITICAL_SECTION *) p);
  10205. stb__wait(500);
  10206. }
  10207. #endif // _WINDOWS_
  10208. #if 0
  10209. // for future reference,
  10210. // InterlockedCompareExchange for x86:
  10211. int cas64_mp(void * dest, void * xcmp, void * xxchg) {
  10212. __asm
  10213. {
  10214. mov esi, [xxchg] ; exchange
  10215. mov ebx, [esi + 0]
  10216. mov ecx, [esi + 4]
  10217. mov esi, [xcmp] ; comparand
  10218. mov eax, [esi + 0]
  10219. mov edx, [esi + 4]
  10220. mov edi, [dest] ; destination
  10221. lock cmpxchg8b [edi]
  10222. jz yyyy;
  10223. mov [esi + 0], eax;
  10224. mov [esi + 4], edx;
  10225. yyyy:
  10226. xor eax, eax;
  10227. setz al;
  10228. };
  10229. inline unsigned __int64 _InterlockedCompareExchange64(volatile unsigned __int64 *dest
  10230. ,unsigned __int64 exchange
  10231. ,unsigned __int64 comperand)
  10232. {
  10233. //value returned in eax::edx
  10234. __asm {
  10235. lea esi,comperand;
  10236. lea edi,exchange;
  10237. mov eax,[esi];
  10238. mov edx,4[esi];
  10239. mov ebx,[edi];
  10240. mov ecx,4[edi];
  10241. mov esi,dest;
  10242. lock CMPXCHG8B [esi];
  10243. }
  10244. #endif // #if 0
  10245. #endif // _WIN32
  10246. stb_thread stb_create_thread2(stb_thread_func f, void *d, volatile void **return_code, stb_semaphore rel)
  10247. {
  10248. return stb_create_thread_raw(f,d,return_code,rel);
  10249. }
  10250. stb_thread stb_create_thread(stb_thread_func f, void *d)
  10251. {
  10252. return stb_create_thread2(f,d,NULL,STB_SEMAPHORE_NULL);
  10253. }
  10254. // mutex implemented by wrapping semaphore
  10255. #ifndef STB_MUTEX_NATIVE
  10256. stb_mutex stb_mutex_new(void) { return stb_sem_new_extra(1,1); }
  10257. void stb_mutex_delete(stb_mutex m) { stb_sem_delete (m); }
  10258. void stb_mutex_begin(stb_mutex m) { stb__wait(500); if (m) stb_sem_waitfor(m); }
  10259. void stb_mutex_end(stb_mutex m) { if (m) stb_sem_release(m); stb__wait(500); }
  10260. #endif
  10261. // thread merge operation
  10262. struct stb__sync
  10263. {
  10264. int target; // target number of threads to hit it
  10265. int sofar; // total threads that hit it
  10266. int waiting; // total threads waiting
  10267. stb_mutex start; // mutex to prevent starting again before finishing previous
  10268. stb_mutex mutex; // mutex while tweaking state
  10269. stb_semaphore release; // semaphore wake up waiting threads
  10270. // we have to wake them up one at a time, rather than using a single release
  10271. // call, because win32 semaphores don't let you dynamically change the max count!
  10272. };
  10273. stb_sync stb_sync_new(void)
  10274. {
  10275. stb_sync s = (stb_sync) malloc(sizeof(*s));
  10276. if (!s) return s;
  10277. s->target = s->sofar = s->waiting = 0;
  10278. s->mutex = stb_mutex_new();
  10279. s->start = stb_mutex_new();
  10280. s->release = stb_sem_new(1);
  10281. if (s->mutex == STB_MUTEX_NULL || s->release == STB_SEMAPHORE_NULL || s->start == STB_MUTEX_NULL) {
  10282. stb_mutex_delete(s->mutex);
  10283. stb_mutex_delete(s->mutex);
  10284. stb_sem_delete(s->release);
  10285. free(s);
  10286. return NULL;
  10287. }
  10288. return s;
  10289. }
  10290. void stb_sync_delete(stb_sync s)
  10291. {
  10292. if (s->waiting) {
  10293. // it's bad to delete while there are threads waiting!
  10294. // shall we wait for them to reach, or just bail? just bail
  10295. assert(0);
  10296. }
  10297. stb_mutex_delete(s->mutex);
  10298. stb_mutex_delete(s->release);
  10299. free(s);
  10300. }
  10301. int stb_sync_set_target(stb_sync s, int count)
  10302. {
  10303. // don't allow setting a target until the last one is fully released;
  10304. // note that this can lead to inefficient pipelining, and maybe we'd
  10305. // be better off ping-ponging between two internal syncs?
  10306. // I tried seeing how often this happened using TryEnterCriticalSection
  10307. // and could _never_ get it to happen in imv(stb), even with more threads
  10308. // than processors. So who knows!
  10309. stb_mutex_begin(s->start);
  10310. // this mutex is pointless, since it's not valid for threads
  10311. // to call reach() before anyone calls set_target() anyway
  10312. stb_mutex_begin(s->mutex);
  10313. assert(s->target == 0); // enforced by start mutex
  10314. s->target = count;
  10315. s->sofar = 0;
  10316. s->waiting = 0;
  10317. stb_mutex_end(s->mutex);
  10318. return STB_TRUE;
  10319. }
  10320. void stb__sync_release(stb_sync s)
  10321. {
  10322. if (s->waiting)
  10323. stb_sem_release(s->release);
  10324. else {
  10325. s->target = 0;
  10326. stb_mutex_end(s->start);
  10327. }
  10328. }
  10329. int stb_sync_reach(stb_sync s)
  10330. {
  10331. int n;
  10332. stb_mutex_begin(s->mutex);
  10333. assert(s->sofar < s->target);
  10334. n = ++s->sofar; // record this value to avoid possible race if we did 'return s->sofar';
  10335. if (s->sofar == s->target)
  10336. stb__sync_release(s);
  10337. stb_mutex_end(s->mutex);
  10338. return n;
  10339. }
  10340. void stb_sync_reach_and_wait(stb_sync s)
  10341. {
  10342. stb_mutex_begin(s->mutex);
  10343. assert(s->sofar < s->target);
  10344. ++s->sofar;
  10345. if (s->sofar == s->target) {
  10346. stb__sync_release(s);
  10347. stb_mutex_end(s->mutex);
  10348. } else {
  10349. ++s->waiting; // we're waiting, so one more waiter
  10350. stb_mutex_end(s->mutex); // release the mutex to other threads
  10351. stb_sem_waitfor(s->release); // wait for merge completion
  10352. stb_mutex_begin(s->mutex); // on merge completion, grab the mutex
  10353. --s->waiting; // we're done waiting
  10354. stb__sync_release(s); // restart the next waiter
  10355. stb_mutex_end(s->mutex); // and now we're done
  10356. // this ends the same as the first case, but it's a lot
  10357. // clearer to understand without sharing the code
  10358. }
  10359. }
  10360. struct stb__threadqueue
  10361. {
  10362. stb_mutex add, remove;
  10363. stb_semaphore nonempty, nonfull;
  10364. int head_blockers; // number of threads blocking--used to know whether to release(avail)
  10365. int tail_blockers;
  10366. int head, tail, array_size, growable;
  10367. int item_size;
  10368. char *data;
  10369. };
  10370. static int stb__tq_wrap(volatile stb_threadqueue *z, int p)
  10371. {
  10372. if (p == z->array_size)
  10373. return p - z->array_size;
  10374. else
  10375. return p;
  10376. }
  10377. int stb__threadq_get_raw(stb_threadqueue *tq2, void *output, int block)
  10378. {
  10379. volatile stb_threadqueue *tq = (volatile stb_threadqueue *) tq2;
  10380. if (tq->head == tq->tail && !block) return 0;
  10381. stb_mutex_begin(tq->remove);
  10382. while (tq->head == tq->tail) {
  10383. if (!block) {
  10384. stb_mutex_end(tq->remove);
  10385. return 0;
  10386. }
  10387. ++tq->head_blockers;
  10388. stb_mutex_end(tq->remove);
  10389. stb_sem_waitfor(tq->nonempty);
  10390. stb_mutex_begin(tq->remove);
  10391. --tq->head_blockers;
  10392. }
  10393. memcpy(output, tq->data + tq->head*tq->item_size, tq->item_size);
  10394. stb_barrier();
  10395. tq->head = stb__tq_wrap(tq, tq->head+1);
  10396. stb_sem_release(tq->nonfull);
  10397. if (tq->head_blockers) // can't check if actually non-empty due to race?
  10398. stb_sem_release(tq->nonempty); // if there are other blockers, wake one
  10399. stb_mutex_end(tq->remove);
  10400. return STB_TRUE;
  10401. }
  10402. int stb__threadq_grow(volatile stb_threadqueue *tq)
  10403. {
  10404. int n;
  10405. char *p;
  10406. assert(tq->remove != STB_MUTEX_NULL); // must have this to allow growth!
  10407. stb_mutex_begin(tq->remove);
  10408. n = tq->array_size * 2;
  10409. p = (char *) realloc(tq->data, n * tq->item_size);
  10410. if (p == NULL) {
  10411. stb_mutex_end(tq->remove);
  10412. stb_mutex_end(tq->add);
  10413. return STB_FALSE;
  10414. }
  10415. if (tq->tail < tq->head) {
  10416. memcpy(p + tq->array_size * tq->item_size, p, tq->tail * tq->item_size);
  10417. tq->tail += tq->array_size;
  10418. }
  10419. tq->data = p;
  10420. tq->array_size = n;
  10421. stb_mutex_end(tq->remove);
  10422. return STB_TRUE;
  10423. }
  10424. int stb__threadq_add_raw(stb_threadqueue *tq2, void *input, int block)
  10425. {
  10426. int tail,pos;
  10427. volatile stb_threadqueue *tq = (volatile stb_threadqueue *) tq2;
  10428. stb_mutex_begin(tq->add);
  10429. for(;;) {
  10430. pos = tq->tail;
  10431. tail = stb__tq_wrap(tq, pos+1);
  10432. if (tail != tq->head) break;
  10433. // full
  10434. if (tq->growable) {
  10435. if (!stb__threadq_grow(tq)) {
  10436. stb_mutex_end(tq->add);
  10437. return STB_FALSE; // out of memory
  10438. }
  10439. } else if (!block) {
  10440. stb_mutex_end(tq->add);
  10441. return STB_FALSE;
  10442. } else {
  10443. ++tq->tail_blockers;
  10444. stb_mutex_end(tq->add);
  10445. stb_sem_waitfor(tq->nonfull);
  10446. stb_mutex_begin(tq->add);
  10447. --tq->tail_blockers;
  10448. }
  10449. }
  10450. memcpy(tq->data + tq->item_size * pos, input, tq->item_size);
  10451. stb_barrier();
  10452. tq->tail = tail;
  10453. stb_sem_release(tq->nonempty);
  10454. if (tq->tail_blockers) // can't check if actually non-full due to race?
  10455. stb_sem_release(tq->nonfull);
  10456. stb_mutex_end(tq->add);
  10457. return STB_TRUE;
  10458. }
  10459. int stb_threadq_length(stb_threadqueue *tq2)
  10460. {
  10461. int a,b,n;
  10462. volatile stb_threadqueue *tq = (volatile stb_threadqueue *) tq2;
  10463. stb_mutex_begin(tq->add);
  10464. a = tq->head;
  10465. b = tq->tail;
  10466. n = tq->array_size;
  10467. stb_mutex_end(tq->add);
  10468. if (a > b) b += n;
  10469. return b-a;
  10470. }
  10471. int stb_threadq_get(stb_threadqueue *tq, void *output)
  10472. {
  10473. return stb__threadq_get_raw(tq, output, STB_FALSE);
  10474. }
  10475. void stb_threadq_get_block(stb_threadqueue *tq, void *output)
  10476. {
  10477. stb__threadq_get_raw(tq, output, STB_TRUE);
  10478. }
  10479. int stb_threadq_add(stb_threadqueue *tq, void *input)
  10480. {
  10481. return stb__threadq_add_raw(tq, input, STB_FALSE);
  10482. }
  10483. int stb_threadq_add_block(stb_threadqueue *tq, void *input)
  10484. {
  10485. return stb__threadq_add_raw(tq, input, STB_TRUE);
  10486. }
  10487. void stb_threadq_delete(stb_threadqueue *tq)
  10488. {
  10489. if (tq) {
  10490. free(tq->data);
  10491. stb_mutex_delete(tq->add);
  10492. stb_mutex_delete(tq->remove);
  10493. stb_sem_delete(tq->nonempty);
  10494. stb_sem_delete(tq->nonfull);
  10495. free(tq);
  10496. }
  10497. }
  10498. #define STB_THREADQUEUE_DYNAMIC 0
  10499. stb_threadqueue *stb_threadq_new(int item_size, int num_items, int many_add, int many_remove)
  10500. {
  10501. int error=0;
  10502. stb_threadqueue *tq = (stb_threadqueue *) malloc(sizeof(*tq));
  10503. if (tq == NULL) return NULL;
  10504. if (num_items == STB_THREADQUEUE_DYNAMIC) {
  10505. tq->growable = STB_TRUE;
  10506. num_items = 32;
  10507. } else
  10508. tq->growable = STB_FALSE;
  10509. tq->item_size = item_size;
  10510. tq->array_size = num_items+1;
  10511. tq->add = tq->remove = STB_MUTEX_NULL;
  10512. tq->nonempty = tq->nonfull = STB_SEMAPHORE_NULL;
  10513. tq->data = NULL;
  10514. if (many_add)
  10515. { tq->add = stb_mutex_new(); if (tq->add == STB_MUTEX_NULL) goto error; }
  10516. if (many_remove || tq->growable)
  10517. { tq->remove = stb_mutex_new(); if (tq->remove == STB_MUTEX_NULL) goto error; }
  10518. tq->nonempty = stb_sem_new(1); if (tq->nonempty == STB_SEMAPHORE_NULL) goto error;
  10519. tq->nonfull = stb_sem_new(1); if (tq->nonfull == STB_SEMAPHORE_NULL) goto error;
  10520. tq->data = (char *) malloc(tq->item_size * tq->array_size);
  10521. if (tq->data == NULL) goto error;
  10522. tq->head = tq->tail = 0;
  10523. tq->head_blockers = tq->tail_blockers = 0;
  10524. return tq;
  10525. error:
  10526. stb_threadq_delete(tq);
  10527. return NULL;
  10528. }
  10529. typedef struct
  10530. {
  10531. stb_thread_func f;
  10532. void *d;
  10533. volatile void **retval;
  10534. stb_sync sync;
  10535. } stb__workinfo;
  10536. //static volatile stb__workinfo *stb__work;
  10537. struct stb__workqueue
  10538. {
  10539. int numthreads;
  10540. stb_threadqueue *tq;
  10541. };
  10542. static stb_workqueue *stb__work_global;
  10543. static void *stb__thread_workloop(void *p)
  10544. {
  10545. volatile stb_workqueue *q = (volatile stb_workqueue *) p;
  10546. for(;;) {
  10547. void *z;
  10548. stb__workinfo w;
  10549. stb_threadq_get_block(q->tq, &w);
  10550. if (w.f == NULL) // null work is a signal to end the thread
  10551. return NULL;
  10552. z = w.f(w.d);
  10553. if (w.retval) { stb_barrier(); *w.retval = z; }
  10554. if (w.sync != STB_SYNC_NULL) stb_sync_reach(w.sync);
  10555. }
  10556. }
  10557. stb_workqueue *stb_workq_new(int num_threads, int max_units)
  10558. {
  10559. return stb_workq_new_flags(num_threads, max_units, 0,0);
  10560. }
  10561. stb_workqueue *stb_workq_new_flags(int numthreads, int max_units, int no_add_mutex, int no_remove_mutex)
  10562. {
  10563. stb_workqueue *q = (stb_workqueue *) malloc(sizeof(*q));
  10564. if (q == NULL) return NULL;
  10565. q->tq = stb_threadq_new(sizeof(stb__workinfo), max_units, !no_add_mutex, !no_remove_mutex);
  10566. if (q->tq == NULL) { free(q); return NULL; }
  10567. q->numthreads = 0;
  10568. stb_workq_numthreads(q, numthreads);
  10569. return q;
  10570. }
  10571. void stb_workq_delete(stb_workqueue *q)
  10572. {
  10573. while (stb_workq_length(q) != 0)
  10574. stb__thread_sleep(1);
  10575. stb_threadq_delete(q->tq);
  10576. free(q);
  10577. }
  10578. static int stb__work_maxitems = STB_THREADQUEUE_DYNAMIC;
  10579. static void stb_work_init(int num_threads)
  10580. {
  10581. if (stb__work_global == NULL) {
  10582. stb__threadmutex_init();
  10583. stb_mutex_begin(stb__workmutex);
  10584. stb_barrier();
  10585. if (*(stb_workqueue * volatile *) &stb__work_global == NULL)
  10586. stb__work_global = stb_workq_new(num_threads, stb__work_maxitems);
  10587. stb_mutex_end(stb__workmutex);
  10588. }
  10589. }
  10590. static int stb__work_raw(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code, stb_sync rel)
  10591. {
  10592. stb__workinfo w;
  10593. if (q == NULL) {
  10594. stb_work_init(1);
  10595. q = stb__work_global;
  10596. }
  10597. w.f = f;
  10598. w.d = d;
  10599. w.retval = return_code;
  10600. w.sync = rel;
  10601. return stb_threadq_add(q->tq, &w);
  10602. }
  10603. int stb_workq_length(stb_workqueue *q)
  10604. {
  10605. return stb_threadq_length(q->tq);
  10606. }
  10607. int stb_workq(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code)
  10608. {
  10609. if (f == NULL) return 0;
  10610. return stb_workq_reach(q, f, d, return_code, NULL);
  10611. }
  10612. int stb_workq_reach(stb_workqueue *q, stb_thread_func f, void *d, volatile void **return_code, stb_sync rel)
  10613. {
  10614. if (f == NULL) return 0;
  10615. return stb__work_raw(q, f, d, return_code, rel);
  10616. }
  10617. static void stb__workq_numthreads(stb_workqueue *q, int n)
  10618. {
  10619. while (q->numthreads < n) {
  10620. stb_create_thread(stb__thread_workloop, q);
  10621. ++q->numthreads;
  10622. }
  10623. while (q->numthreads > n) {
  10624. stb__work_raw(q, NULL, NULL, NULL, NULL);
  10625. --q->numthreads;
  10626. }
  10627. }
  10628. void stb_workq_numthreads(stb_workqueue *q, int n)
  10629. {
  10630. stb_mutex_begin(stb__threadmutex);
  10631. stb__workq_numthreads(q,n);
  10632. stb_mutex_end(stb__threadmutex);
  10633. }
  10634. int stb_work_maxunits(int n)
  10635. {
  10636. if (stb__work_global == NULL) {
  10637. stb__work_maxitems = n;
  10638. stb_work_init(1);
  10639. }
  10640. return stb__work_maxitems;
  10641. }
  10642. int stb_work(stb_thread_func f, void *d, volatile void **return_code)
  10643. {
  10644. return stb_workq(stb__work_global, f,d,return_code);
  10645. }
  10646. int stb_work_reach(stb_thread_func f, void *d, volatile void **return_code, stb_sync rel)
  10647. {
  10648. return stb_workq_reach(stb__work_global, f,d,return_code,rel);
  10649. }
  10650. void stb_work_numthreads(int n)
  10651. {
  10652. if (stb__work_global == NULL)
  10653. stb_work_init(n);
  10654. else
  10655. stb_workq_numthreads(stb__work_global, n);
  10656. }
  10657. #endif // STB_DEFINE
  10658. //////////////////////////////////////////////////////////////////////////////
  10659. //
  10660. // Background disk I/O
  10661. //
  10662. //
  10663. #define STB_BGIO_READ_ALL (-1)
  10664. STB_EXTERN int stb_bgio_read (char *filename, int offset, int len, stb_uchar **result, int *olen);
  10665. STB_EXTERN int stb_bgio_readf (FILE *f , int offset, int len, stb_uchar **result, int *olen);
  10666. STB_EXTERN int stb_bgio_read_to (char *filename, int offset, int len, stb_uchar *buffer, int *olen);
  10667. STB_EXTERN int stb_bgio_readf_to(FILE *f , int offset, int len, stb_uchar *buffer, int *olen);
  10668. typedef struct
  10669. {
  10670. int have_data;
  10671. int is_valid;
  10672. int is_dir;
  10673. time_t filetime;
  10674. stb_int64 filesize;
  10675. } stb_bgstat;
  10676. STB_EXTERN int stb_bgio_stat (char *filename, stb_bgstat *result);
  10677. #ifdef STB_DEFINE
  10678. static stb_workqueue *stb__diskio;
  10679. static stb_mutex stb__diskio_mutex;
  10680. void stb_thread_cleanup(void)
  10681. {
  10682. if (stb__work_global) stb_workq_delete(stb__work_global); stb__work_global = NULL;
  10683. if (stb__threadmutex) stb_mutex_delete(stb__threadmutex); stb__threadmutex = NULL;
  10684. if (stb__workmutex) stb_mutex_delete(stb__workmutex); stb__workmutex = NULL;
  10685. if (stb__diskio) stb_workq_delete(stb__diskio); stb__diskio = NULL;
  10686. if (stb__diskio_mutex)stb_mutex_delete(stb__diskio_mutex);stb__diskio_mutex= NULL;
  10687. }
  10688. typedef struct
  10689. {
  10690. char *filename;
  10691. FILE *f;
  10692. int offset;
  10693. int len;
  10694. stb_bgstat *stat_out;
  10695. stb_uchar *output;
  10696. stb_uchar **result;
  10697. int *len_output;
  10698. int *flag;
  10699. } stb__disk_command;
  10700. #define STB__MAX_DISK_COMMAND 100
  10701. static stb__disk_command stb__dc_queue[STB__MAX_DISK_COMMAND];
  10702. static int stb__dc_offset;
  10703. void stb__io_init(void)
  10704. {
  10705. if (!stb__diskio) {
  10706. stb__threadmutex_init();
  10707. stb_mutex_begin(stb__threadmutex);
  10708. stb_barrier();
  10709. if (*(stb_thread * volatile *) &stb__diskio == NULL) {
  10710. stb__diskio_mutex = stb_mutex_new();
  10711. // use many threads so OS can try to schedule seeks
  10712. stb__diskio = stb_workq_new_flags(16,STB__MAX_DISK_COMMAND,STB_FALSE,STB_FALSE);
  10713. }
  10714. stb_mutex_end(stb__threadmutex);
  10715. }
  10716. }
  10717. static void * stb__io_error(stb__disk_command *dc)
  10718. {
  10719. if (dc->len_output) *dc->len_output = 0;
  10720. if (dc->result) *dc->result = NULL;
  10721. if (dc->flag) *dc->flag = -1;
  10722. return NULL;
  10723. }
  10724. static void * stb__io_task(void *p)
  10725. {
  10726. stb__disk_command *dc = (stb__disk_command *) p;
  10727. int len;
  10728. FILE *f;
  10729. stb_uchar *buf;
  10730. if (dc->stat_out) {
  10731. struct _stati64 s;
  10732. if (!_stati64(dc->filename, &s)) {
  10733. dc->stat_out->filesize = s.st_size;
  10734. dc->stat_out->filetime = s.st_mtime;
  10735. dc->stat_out->is_dir = s.st_mode & _S_IFDIR;
  10736. dc->stat_out->is_valid = (s.st_mode & _S_IFREG) || dc->stat_out->is_dir;
  10737. } else
  10738. dc->stat_out->is_valid = 0;
  10739. stb_barrier();
  10740. dc->stat_out->have_data = 1;
  10741. free(dc->filename);
  10742. return 0;
  10743. }
  10744. if (dc->f) {
  10745. #ifdef WIN32
  10746. f = _fdopen(_dup(_fileno(dc->f)), "rb");
  10747. #else
  10748. f = fdopen(dup(fileno(dc->f)), "rb");
  10749. #endif
  10750. if (!f)
  10751. return stb__io_error(dc);
  10752. } else {
  10753. f = fopen(dc->filename, "rb");
  10754. free(dc->filename);
  10755. if (!f)
  10756. return stb__io_error(dc);
  10757. }
  10758. len = dc->len;
  10759. if (len < 0) {
  10760. fseek(f, 0, SEEK_END);
  10761. len = ftell(f) - dc->offset;
  10762. }
  10763. if (fseek(f, dc->offset, SEEK_SET)) {
  10764. fclose(f);
  10765. return stb__io_error(dc);
  10766. }
  10767. if (dc->output)
  10768. buf = dc->output;
  10769. else {
  10770. buf = (stb_uchar *) malloc(len);
  10771. if (buf == NULL) {
  10772. fclose(f);
  10773. return stb__io_error(dc);
  10774. }
  10775. }
  10776. len = fread(buf, 1, len, f);
  10777. fclose(f);
  10778. if (dc->len_output) *dc->len_output = len;
  10779. if (dc->result) *dc->result = buf;
  10780. if (dc->flag) *dc->flag = 1;
  10781. return NULL;
  10782. }
  10783. 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)
  10784. {
  10785. int res;
  10786. stb__io_init();
  10787. // do memory allocation outside of mutex
  10788. if (fname) fname = strdup(fname);
  10789. stb_mutex_begin(stb__diskio_mutex);
  10790. {
  10791. stb__disk_command *dc = &stb__dc_queue[stb__dc_offset];
  10792. dc->filename = fname;
  10793. dc->f = f;
  10794. dc->offset = off;
  10795. dc->len = len;
  10796. dc->output = out;
  10797. dc->result = result;
  10798. dc->len_output = olen;
  10799. dc->flag = flag;
  10800. dc->stat_out = stat;
  10801. res = stb_workq(stb__diskio, stb__io_task, dc, NULL);
  10802. if (res)
  10803. stb__dc_offset = (stb__dc_offset + 1 == STB__MAX_DISK_COMMAND ? 0 : stb__dc_offset+1);
  10804. }
  10805. stb_mutex_end(stb__diskio_mutex);
  10806. return res;
  10807. }
  10808. int stb_bgio_read(char *filename, int offset, int len, stb_uchar **result, int *olen)
  10809. {
  10810. return stb__io_add(filename,NULL,offset,len,NULL,result,olen,NULL,NULL);
  10811. }
  10812. int stb_bgio_readf(FILE *f, int offset, int len, stb_uchar **result, int *olen)
  10813. {
  10814. return stb__io_add(NULL,f,offset,len,NULL,result,olen,NULL,NULL);
  10815. }
  10816. int stb_bgio_read_to(char *filename, int offset, int len, stb_uchar *buffer, int *olen)
  10817. {
  10818. return stb__io_add(filename,NULL,offset,len,buffer,NULL,olen,NULL,NULL);
  10819. }
  10820. int stb_bgio_readf_to(FILE *f, int offset, int len, stb_uchar *buffer, int *olen)
  10821. {
  10822. return stb__io_add(NULL,f,offset,len,buffer,NULL,olen,NULL,NULL);
  10823. }
  10824. STB_EXTERN int stb_bgio_stat (char *filename, stb_bgstat *result)
  10825. {
  10826. result->have_data = 0;
  10827. return stb__io_add(filename,NULL,0,0,0,NULL,0,NULL, result);
  10828. }
  10829. #endif
  10830. #endif
  10831. //////////////////////////////////////////////////////////////////////////////
  10832. //
  10833. // Fast malloc implementation
  10834. //
  10835. // This is a clone of TCMalloc, but without the thread support.
  10836. // 1. large objects are allocated directly, page-aligned
  10837. // 2. small objects are allocated in homogeonous heaps, 0 overhead
  10838. //
  10839. // We keep an allocation table for pages a la TCMalloc. This would
  10840. // require 4MB for the entire address space, but we only allocate
  10841. // the parts that are in use. The overhead from using homogenous heaps
  10842. // everywhere is 3MB. (That is, if you allocate 1 object of each size,
  10843. // you'll use 3MB.)
  10844. #if defined(STB_DEFINE) && (defined(_WIN32) || defined(STB_FASTMALLOC))
  10845. #ifdef _WIN32
  10846. #ifndef _WINDOWS_
  10847. #ifndef STB__IMPORT
  10848. #define STB__IMPORT STB_EXTERN __declspec(dllimport)
  10849. #define STB__DW unsigned long
  10850. #endif
  10851. STB__IMPORT void * __stdcall VirtualAlloc(void *p, unsigned long size, unsigned long type, unsigned long protect);
  10852. STB__IMPORT int __stdcall VirtualFree(void *p, unsigned long size, unsigned long freetype);
  10853. #endif
  10854. #define stb__alloc_pages_raw(x) (stb_uint32) VirtualAlloc(NULL, (x), 0x3000, 0x04)
  10855. #define stb__dealloc_pages_raw(p) VirtualFree((void *) p, 0, 0x8000)
  10856. #else
  10857. #error "Platform not currently supported"
  10858. #endif
  10859. typedef struct stb__span
  10860. {
  10861. int start, len;
  10862. struct stb__span *next, *prev;
  10863. void *first_free;
  10864. unsigned short list; // 1..256 free; 257..511 sizeclass; 0=large block
  10865. short allocations; // # outstanding allocations for sizeclass
  10866. } stb__span; // 24
  10867. static stb__span **stb__span_for_page;
  10868. static int stb__firstpage, stb__lastpage;
  10869. static void stb__update_page_range(int first, int last)
  10870. {
  10871. stb__span **sfp;
  10872. int i, f,l;
  10873. if (first >= stb__firstpage && last <= stb__lastpage) return;
  10874. if (stb__span_for_page == NULL) {
  10875. f = first;
  10876. l = f+stb_max(last-f, 16384);
  10877. l = stb_min(l, 1<<20);
  10878. } else if (last > stb__lastpage) {
  10879. f = stb__firstpage;
  10880. l = f + (stb__lastpage - f) * 2;
  10881. l = stb_clamp(last, l,1<<20);
  10882. } else {
  10883. l = stb__lastpage;
  10884. f = l - (l - stb__firstpage) * 2;
  10885. f = stb_clamp(f, 0,first);
  10886. }
  10887. sfp = (stb__span **) stb__alloc_pages_raw(sizeof(void *) * (l-f));
  10888. for (i=f; i < stb__firstpage; ++i) sfp[i - f] = NULL;
  10889. for ( ; i < stb__lastpage ; ++i) sfp[i - f] = stb__span_for_page[i - stb__firstpage];
  10890. for ( ; i < l ; ++i) sfp[i - f] = NULL;
  10891. if (stb__span_for_page) stb__dealloc_pages_raw(stb__span_for_page);
  10892. stb__firstpage = f;
  10893. stb__lastpage = l;
  10894. stb__span_for_page = sfp;
  10895. }
  10896. static stb__span *stb__span_free=NULL;
  10897. static stb__span *stb__span_first, *stb__span_end;
  10898. static stb__span *stb__span_alloc(void)
  10899. {
  10900. stb__span *s = stb__span_free;
  10901. if (s)
  10902. stb__span_free = s->next;
  10903. else {
  10904. if (!stb__span_first) {
  10905. stb__span_first = (stb__span *) stb__alloc_pages_raw(65536);
  10906. if (stb__span_first == NULL) return NULL;
  10907. stb__span_end = stb__span_first + (65536 / sizeof(stb__span));
  10908. }
  10909. s = stb__span_first++;
  10910. if (stb__span_first == stb__span_end) stb__span_first = NULL;
  10911. }
  10912. return s;
  10913. }
  10914. static stb__span *stb__spanlist[512];
  10915. static void stb__spanlist_unlink(stb__span *s)
  10916. {
  10917. if (s->prev)
  10918. s->prev->next = s->next;
  10919. else {
  10920. int n = s->list;
  10921. assert(stb__spanlist[n] == s);
  10922. stb__spanlist[n] = s->next;
  10923. }
  10924. if (s->next)
  10925. s->next->prev = s->prev;
  10926. s->next = s->prev = NULL;
  10927. s->list = 0;
  10928. }
  10929. static void stb__spanlist_add(int n, stb__span *s)
  10930. {
  10931. s->list = n;
  10932. s->next = stb__spanlist[n];
  10933. s->prev = NULL;
  10934. stb__spanlist[n] = s;
  10935. if (s->next) s->next->prev = s;
  10936. }
  10937. #define stb__page_shift 12
  10938. #define stb__page_size (1 << stb__page_shift)
  10939. #define stb__page_number(x) ((x) >> stb__page_shift)
  10940. #define stb__page_address(x) ((x) << stb__page_shift)
  10941. static void stb__set_span_for_page(stb__span *s)
  10942. {
  10943. int i;
  10944. for (i=0; i < s->len; ++i)
  10945. stb__span_for_page[s->start + i - stb__firstpage] = s;
  10946. }
  10947. static stb__span *stb__coalesce(stb__span *a, stb__span *b)
  10948. {
  10949. assert(a->start + a->len == b->start);
  10950. if (a->list) stb__spanlist_unlink(a);
  10951. if (b->list) stb__spanlist_unlink(b);
  10952. a->len += b->len;
  10953. b->len = 0;
  10954. b->next = stb__span_free;
  10955. stb__span_free = b;
  10956. stb__set_span_for_page(a);
  10957. return a;
  10958. }
  10959. static void stb__free_span(stb__span *s)
  10960. {
  10961. stb__span *n = NULL;
  10962. if (s->start > stb__firstpage) {
  10963. n = stb__span_for_page[s->start-1 - stb__firstpage];
  10964. if (n && n->allocations == -2 && n->start + n->len == s->start) s = stb__coalesce(n,s);
  10965. }
  10966. if (s->start + s->len < stb__lastpage) {
  10967. n = stb__span_for_page[s->start + s->len - stb__firstpage];
  10968. if (n && n->allocations == -2 && s->start + s->len == n->start) s = stb__coalesce(s,n);
  10969. }
  10970. s->allocations = -2;
  10971. stb__spanlist_add(s->len > 256 ? 256 : s->len, s);
  10972. }
  10973. static stb__span *stb__alloc_pages(int num)
  10974. {
  10975. stb__span *s = stb__span_alloc();
  10976. int p;
  10977. if (!s) return NULL;
  10978. p = stb__alloc_pages_raw(num << stb__page_shift);
  10979. if (p == 0) { s->next = stb__span_free; stb__span_free = s; return 0; }
  10980. assert(stb__page_address(stb__page_number(p)) == p);
  10981. p = stb__page_number(p);
  10982. stb__update_page_range(p, p+num);
  10983. s->start = p;
  10984. s->len = num;
  10985. s->next = NULL;
  10986. s->prev = NULL;
  10987. stb__set_span_for_page(s);
  10988. return s;
  10989. }
  10990. static stb__span *stb__alloc_span(int pagecount)
  10991. {
  10992. int i;
  10993. stb__span *p = NULL;
  10994. for(i=pagecount; i < 256; ++i)
  10995. if (stb__spanlist[i]) {
  10996. p = stb__spanlist[i];
  10997. break;
  10998. }
  10999. if (!p) {
  11000. p = stb__spanlist[256];
  11001. while (p && p->len < pagecount)
  11002. p = p->next;
  11003. }
  11004. if (!p) {
  11005. p = stb__alloc_pages(pagecount < 16 ? 16 : pagecount);
  11006. if (p == NULL) return 0;
  11007. } else
  11008. stb__spanlist_unlink(p);
  11009. if (p->len > pagecount) {
  11010. stb__span *q = stb__span_alloc();
  11011. if (q) {
  11012. q->start = p->start + pagecount;
  11013. q->len = p->len - pagecount;
  11014. p->len = pagecount;
  11015. for (i=0; i < q->len; ++i)
  11016. stb__span_for_page[q->start+i - stb__firstpage] = q;
  11017. stb__spanlist_add(q->len > 256 ? 256 : q->len, q);
  11018. }
  11019. }
  11020. return p;
  11021. }
  11022. #define STB__MAX_SMALL_SIZE 32768
  11023. #define STB__MAX_SIZE_CLASSES 256
  11024. static unsigned char stb__class_base[32];
  11025. static unsigned char stb__class_shift[32];
  11026. static unsigned char stb__pages_for_class[STB__MAX_SIZE_CLASSES];
  11027. static int stb__size_for_class[STB__MAX_SIZE_CLASSES];
  11028. stb__span *stb__get_nonempty_sizeclass(int c)
  11029. {
  11030. int s = c + 256, i, size, tsize; // remap to span-list index
  11031. char *z;
  11032. void *q;
  11033. stb__span *p = stb__spanlist[s];
  11034. if (p) {
  11035. if (p->first_free) return p; // fast path: it's in the first one in list
  11036. for (p=p->next; p; p=p->next)
  11037. if (p->first_free) {
  11038. // move to front for future queries
  11039. stb__spanlist_unlink(p);
  11040. stb__spanlist_add(s, p);
  11041. return p;
  11042. }
  11043. }
  11044. // no non-empty ones, so allocate a new one
  11045. p = stb__alloc_span(stb__pages_for_class[c]);
  11046. if (!p) return NULL;
  11047. // create the free list up front
  11048. size = stb__size_for_class[c];
  11049. tsize = stb__pages_for_class[c] << stb__page_shift;
  11050. i = 0;
  11051. z = (char *) stb__page_address(p->start);
  11052. q = NULL;
  11053. while (i + size <= tsize) {
  11054. * (void **) z = q; q = z;
  11055. z += size;
  11056. i += size;
  11057. }
  11058. p->first_free = q;
  11059. p->allocations = 0;
  11060. stb__spanlist_add(s,p);
  11061. return p;
  11062. }
  11063. static int stb__sizeclass(size_t sz)
  11064. {
  11065. int z = stb_log2_floor(sz); // -1 below to group e.g. 13,14,15,16 correctly
  11066. return stb__class_base[z] + ((sz-1) >> stb__class_shift[z]);
  11067. }
  11068. static void stb__init_sizeclass(void)
  11069. {
  11070. int i, size, overhead;
  11071. int align_shift = 2; // allow 4-byte and 12-byte blocks as well, vs. TCMalloc
  11072. int next_class = 1;
  11073. int last_log = 0;
  11074. for (i = 0; i < align_shift; i++) {
  11075. stb__class_base [i] = next_class;
  11076. stb__class_shift[i] = align_shift;
  11077. }
  11078. for (size = 1 << align_shift; size <= STB__MAX_SMALL_SIZE; size += 1 << align_shift) {
  11079. i = stb_log2_floor(size);
  11080. if (i > last_log) {
  11081. if (size == 16) ++align_shift; // switch from 4-byte to 8-byte alignment
  11082. else if (size >= 128 && align_shift < 8) ++align_shift;
  11083. stb__class_base[i] = next_class - ((size-1) >> align_shift);
  11084. stb__class_shift[i] = align_shift;
  11085. last_log = i;
  11086. }
  11087. stb__size_for_class[next_class++] = size;
  11088. }
  11089. for (i=1; i <= STB__MAX_SMALL_SIZE; ++i)
  11090. assert(i <= stb__size_for_class[stb__sizeclass(i)]);
  11091. overhead = 0;
  11092. for (i = 1; i < next_class; i++) {
  11093. int s = stb__size_for_class[i];
  11094. size = stb__page_size;
  11095. while (size % s > size >> 3)
  11096. size += stb__page_size;
  11097. stb__pages_for_class[i] = (unsigned char) (size >> stb__page_shift);
  11098. overhead += size;
  11099. }
  11100. assert(overhead < (4 << 20)); // make sure it's under 4MB of overhead
  11101. }
  11102. #ifdef STB_DEBUG
  11103. #define stb__smemset(a,b,c) memset((void *) a, b, c)
  11104. #elif defined(STB_FASTMALLOC_INIT)
  11105. #define stb__smemset(a,b,c) memset((void *) a, b, c)
  11106. #else
  11107. #define stb__smemset(a,b,c)
  11108. #endif
  11109. void *stb_smalloc(size_t sz)
  11110. {
  11111. stb__span *s;
  11112. if (sz == 0) return NULL;
  11113. if (stb__size_for_class[1] == 0) stb__init_sizeclass();
  11114. if (sz > STB__MAX_SMALL_SIZE) {
  11115. s = stb__alloc_span((sz + stb__page_size - 1) >> stb__page_shift);
  11116. if (s == NULL) return NULL;
  11117. s->list = 0;
  11118. s->next = s->prev = NULL;
  11119. s->allocations = -32767;
  11120. stb__smemset(stb__page_address(s->start), 0xcd, (sz+3)&~3);
  11121. return (void *) stb__page_address(s->start);
  11122. } else {
  11123. void *p;
  11124. int c = stb__sizeclass(sz);
  11125. s = stb__spanlist[256+c];
  11126. if (!s || !s->first_free)
  11127. s = stb__get_nonempty_sizeclass(c);
  11128. if (s == NULL) return NULL;
  11129. p = s->first_free;
  11130. s->first_free = * (void **) p;
  11131. ++s->allocations;
  11132. stb__smemset(p,0xcd, sz);
  11133. return p;
  11134. }
  11135. }
  11136. int stb_ssize(void *p)
  11137. {
  11138. stb__span *s;
  11139. if (p == NULL) return 0;
  11140. s = stb__span_for_page[stb__page_number((stb_uint) p) - stb__firstpage];
  11141. if (s->list >= 256) {
  11142. return stb__size_for_class[s->list - 256];
  11143. } else {
  11144. assert(s->list == 0);
  11145. return s->len << stb__page_shift;
  11146. }
  11147. }
  11148. void stb_sfree(void *p)
  11149. {
  11150. stb__span *s;
  11151. if (p == NULL) return;
  11152. s = stb__span_for_page[stb__page_number((stb_uint) p) - stb__firstpage];
  11153. if (s->list >= 256) {
  11154. stb__smemset(p, 0xfe, stb__size_for_class[s->list-256]);
  11155. * (void **) p = s->first_free;
  11156. s->first_free = p;
  11157. if (--s->allocations == 0) {
  11158. stb__spanlist_unlink(s);
  11159. stb__free_span(s);
  11160. }
  11161. } else {
  11162. assert(s->list == 0);
  11163. stb__smemset(p, 0xfe, stb_ssize(p));
  11164. stb__free_span(s);
  11165. }
  11166. }
  11167. void *stb_srealloc(void *p, size_t sz)
  11168. {
  11169. size_t cur_size;
  11170. if (p == NULL) return stb_smalloc(sz);
  11171. if (sz == 0) { stb_sfree(p); return NULL; }
  11172. cur_size = stb_ssize(p);
  11173. if (sz > cur_size || sz <= (cur_size >> 1)) {
  11174. void *q;
  11175. if (sz > cur_size && sz < (cur_size << 1)) sz = cur_size << 1;
  11176. q = stb_smalloc(sz); if (q == NULL) return NULL;
  11177. memcpy(q, p, sz < cur_size ? sz : cur_size);
  11178. stb_sfree(p);
  11179. return q;
  11180. }
  11181. return p;
  11182. }
  11183. void *stb_scalloc(size_t n, size_t sz)
  11184. {
  11185. void *p;
  11186. if (n == 0 || sz == 0) return NULL;
  11187. if (stb_log2_ceil(n) + stb_log2_ceil(n) >= 32) return NULL;
  11188. p = stb_smalloc(n*sz);
  11189. if (p) memset(p, 0, n*sz);
  11190. return p;
  11191. }
  11192. char *stb_sstrdup(char *s)
  11193. {
  11194. int n = strlen(s);
  11195. char *p = (char *) stb_smalloc(n+1);
  11196. if (p) strcpy(p,s);
  11197. return p;
  11198. }
  11199. #endif // STB_DEFINE
  11200. //////////////////////////////////////////////////////////////////////////////
  11201. //
  11202. // Source code constants
  11203. //
  11204. // This is a trivial system to let you specify constants in source code,
  11205. // then while running you can change the constants.
  11206. //
  11207. // Note that you can't wrap the #defines, because we need to know their
  11208. // names. So we provide a pre-wrapped version without 'STB_' for convenience;
  11209. // to request it, #define STB_CONVENIENT_H, yielding:
  11210. // KI -- integer
  11211. // KU -- unsigned integer
  11212. // KF -- float
  11213. // KD -- double
  11214. // KS -- string constant
  11215. //
  11216. // Defaults to functioning in debug build, not in release builds.
  11217. // To force on, define STB_ALWAYS_H
  11218. #ifdef STB_CONVENIENT_H
  11219. #define KI(x) STB_I(x)
  11220. #define KU(x) STB_UI(x)
  11221. #define KF(x) STB_F(x)
  11222. #define KD(x) STB_D(x)
  11223. #define KS(x) STB_S(x)
  11224. #endif
  11225. STB_EXTERN void stb_source_path(char *str);
  11226. #ifdef STB_DEFINE
  11227. char *stb__source_path;
  11228. void stb_source_path(char *path)
  11229. {
  11230. stb__source_path = path;
  11231. }
  11232. char *stb__get_sourcefile_path(char *file)
  11233. {
  11234. static char filebuf[512];
  11235. if (stb__source_path) {
  11236. sprintf(filebuf, "%s/%s", stb__source_path, file);
  11237. if (stb_fexists(filebuf)) return filebuf;
  11238. }
  11239. if (stb_fexists(file)) return file;
  11240. sprintf(filebuf, "../%s", file);
  11241. if (!stb_fexists(filebuf)) return filebuf;
  11242. return file;
  11243. }
  11244. #endif
  11245. #define STB_F(x) ((float) STB_H(x))
  11246. #define STB_UI(x) ((unsigned int) STB_I(x))
  11247. #if !defined(STB_DEBUG) && !defined(STB_ALWAYS_H)
  11248. #define STB_D(x) ((double) (x))
  11249. #define STB_I(x) ((int) (x))
  11250. #define STB_S(x) ((char *) (x))
  11251. #else
  11252. #define STB_D(x) stb__double_constant(__FILE__, __LINE__-1, (x))
  11253. #define STB_I(x) stb__int_constant(__FILE__, __LINE__-1, (x))
  11254. #define STB_S(x) stb__string_constant(__FILE__, __LINE__-1, (x))
  11255. STB_EXTERN double stb__double_constant(char *file, int line, double x);
  11256. STB_EXTERN int stb__int_constant(char *file, int line, int x);
  11257. STB_EXTERN char * stb__string_constant(char *file, int line, char *str);
  11258. #ifdef STB_DEFINE
  11259. enum
  11260. {
  11261. STB__CTYPE_int,
  11262. STB__CTYPE_uint,
  11263. STB__CTYPE_float,
  11264. STB__CTYPE_double,
  11265. STB__CTYPE_string,
  11266. };
  11267. typedef struct
  11268. {
  11269. int line;
  11270. int type;
  11271. union {
  11272. int ival;
  11273. double dval;
  11274. char *sval;
  11275. };
  11276. } stb__Entry;
  11277. typedef struct
  11278. {
  11279. stb__Entry *entries;
  11280. char *filename;
  11281. time_t timestamp;
  11282. char **file_data;
  11283. int file_len;
  11284. unsigned short *line_index;
  11285. } stb__FileEntry;
  11286. static void stb__constant_parse(stb__FileEntry *f, int i)
  11287. {
  11288. char *s;
  11289. int n;
  11290. if (!stb_arr_valid(f->entries, i)) return;
  11291. n = f->entries[i].line;
  11292. if (n >= f->file_len) return;
  11293. s = f->file_data[n];
  11294. switch (f->entries[i].type) {
  11295. case STB__CTYPE_float:
  11296. while (*s) {
  11297. if (!strncmp(s, "STB_D(", 6)) { s+=6; goto matched_float; }
  11298. if (!strncmp(s, "STB_F(", 6)) { s+=6; goto matched_float; }
  11299. if (!strncmp(s, "KD(", 3)) { s+=3; goto matched_float; }
  11300. if (!strncmp(s, "KF(", 3)) { s+=3; goto matched_float; }
  11301. ++s;
  11302. }
  11303. break;
  11304. matched_float:
  11305. f->entries[i].dval = strtod(s, NULL);
  11306. break;
  11307. case STB__CTYPE_int:
  11308. while (*s) {
  11309. if (!strncmp(s, "STB_I(", 6)) { s+=6; goto matched_int; }
  11310. if (!strncmp(s, "STB_UI(", 7)) { s+=7; goto matched_int; }
  11311. if (!strncmp(s, "KI(", 3)) { s+=3; goto matched_int; }
  11312. if (!strncmp(s, "KU(", 3)) { s+=3; goto matched_int; }
  11313. ++s;
  11314. }
  11315. break;
  11316. matched_int: {
  11317. int neg=0;
  11318. s = stb_skipwhite(s);
  11319. while (*s == '-') { neg = !neg; s = stb_skipwhite(s+1); } // handle '- - 5', pointlessly
  11320. if (s[0] == '0' && tolower(s[1]) == 'x')
  11321. f->entries[i].ival = strtol(s, NULL, 16);
  11322. else if (s[0] == '0')
  11323. f->entries[i].ival = strtol(s, NULL, 8);
  11324. else
  11325. f->entries[i].ival = strtol(s, NULL, 10);
  11326. if (neg) f->entries[i].ival = -f->entries[i].ival;
  11327. break;
  11328. }
  11329. case STB__CTYPE_string:
  11330. // @TODO
  11331. break;
  11332. }
  11333. }
  11334. static stb_sdict *stb__constant_file_hash;
  11335. stb__Entry *stb__constant_get_entry(char *filename, int line, int type)
  11336. {
  11337. int i;
  11338. stb__FileEntry *f;
  11339. if (stb__constant_file_hash == NULL)
  11340. stb__constant_file_hash = stb_sdict_new(STB_TRUE);
  11341. f = (stb__FileEntry*) stb_sdict_get(stb__constant_file_hash, filename);
  11342. if (f == NULL) {
  11343. char *s = stb__get_sourcefile_path(filename);
  11344. if (s == NULL || !stb_fexists(s)) return 0;
  11345. f = (stb__FileEntry *) malloc(sizeof(*f));
  11346. f->timestamp = stb_ftimestamp(s);
  11347. f->file_data = stb_stringfile(s, &f->file_len);
  11348. f->filename = strdup(s); // cache the full path
  11349. f->entries = NULL;
  11350. f->line_index = 0;
  11351. stb_arr_setlen(f->line_index, f->file_len);
  11352. memset(f->line_index, 0xff, stb_arr_storage(f->line_index));
  11353. } else {
  11354. time_t t = stb_ftimestamp(f->filename);
  11355. if (f->timestamp != t) {
  11356. f->timestamp = t;
  11357. free(f->file_data);
  11358. f->file_data = stb_stringfile(f->filename, &f->file_len);
  11359. stb_arr_setlen(f->line_index, f->file_len);
  11360. for (i=0; i < stb_arr_len(f->entries); ++i)
  11361. stb__constant_parse(f, i);
  11362. }
  11363. }
  11364. if (line >= f->file_len) return 0;
  11365. if (f->line_index[line] >= stb_arr_len(f->entries)) {
  11366. // need a new entry
  11367. int n = stb_arr_len(f->entries);
  11368. stb__Entry e;
  11369. e.line = line;
  11370. if (line < f->file_len)
  11371. f->line_index[line] = n;
  11372. e.type = type;
  11373. stb_arr_push(f->entries, e);
  11374. stb__constant_parse(f, n);
  11375. }
  11376. return f->entries + f->line_index[line];
  11377. }
  11378. double stb__double_constant(char *file, int line, double x)
  11379. {
  11380. stb__Entry *e = stb__constant_get_entry(file, line, STB__CTYPE_float);
  11381. if (!e) return x;
  11382. return e->dval;
  11383. }
  11384. int stb__int_constant(char *file, int line, int x)
  11385. {
  11386. stb__Entry *e = stb__constant_get_entry(file, line, STB__CTYPE_int);
  11387. if (!e) return x;
  11388. return e->ival;
  11389. }
  11390. char * stb__string_constant(char *file, int line, char *x)
  11391. {
  11392. stb__Entry *e = stb__constant_get_entry(file, line, STB__CTYPE_string);
  11393. if (!e) return x;
  11394. return e->sval;
  11395. }
  11396. #endif // STB_DEFINE
  11397. #endif // !STB_DEBUG && !STB_ALWAYS_H
  11398. #ifdef STB_STUA
  11399. //////////////////////////////////////////////////////////////////////////
  11400. //
  11401. // stua: little scripting language
  11402. //
  11403. // define STB_STUA to compile it
  11404. //
  11405. // see http://nothings.org/stb/stb_stua.html for documentation
  11406. //
  11407. // basic parsing model:
  11408. //
  11409. // lexical analysis
  11410. // use stb_lex() to parse tokens; keywords get their own tokens
  11411. //
  11412. // parsing:
  11413. // recursive descent parser. too much of a hassle to make an unambiguous
  11414. // LR(1) grammar, and one-pass generation is clumsier (recursive descent
  11415. // makes it easier to e.g. compile nested functions). on the other hand,
  11416. // dictionary syntax required hackery to get extra lookahead.
  11417. //
  11418. // codegen:
  11419. // output into an evaluation tree, using array indices as 'pointers'
  11420. //
  11421. // run:
  11422. // traverse the tree; support for 'break/continue/return' is tricky
  11423. //
  11424. // garbage collection:
  11425. // stu__mark and sweep; explicit stack with non-stu__compile_global_scope roots
  11426. typedef stb_int32 stua_obj;
  11427. typedef stb_idict stua_dict;
  11428. STB_EXTERN void stua_run_script(char *s);
  11429. STB_EXTERN void stua_uninit(void);
  11430. extern stua_obj stua_globals;
  11431. STB_EXTERN double stua_number(stua_obj z);
  11432. STB_EXTERN stua_obj stua_getnil(void);
  11433. STB_EXTERN stua_obj stua_getfalse(void);
  11434. STB_EXTERN stua_obj stua_gettrue(void);
  11435. STB_EXTERN stua_obj stua_string(char *z);
  11436. STB_EXTERN stua_obj stua_make_number(double d);
  11437. STB_EXTERN stua_obj stua_box(int type, void *data, int size);
  11438. enum
  11439. {
  11440. STUA_op_negate=129,
  11441. STUA_op_shl, STUA_op_ge,
  11442. STUA_op_shr, STUA_op_le,
  11443. STUA_op_shru,
  11444. STUA_op_last
  11445. };
  11446. #define STUA_NO_VALUE 2 // equivalent to a tagged NULL
  11447. STB_EXTERN stua_obj (*stua_overload)(int op, stua_obj a, stua_obj b, stua_obj c);
  11448. STB_EXTERN stua_obj stua_error(char *err, ...);
  11449. STB_EXTERN stua_obj stua_pushroot(stua_obj o);
  11450. STB_EXTERN void stua_poproot ( void );
  11451. #ifdef STB_DEFINE
  11452. // INTERPRETER
  11453. // 31-bit floating point implementation
  11454. // force the (1 << 30) bit (2nd highest bit) to be zero by re-biasing the exponent;
  11455. // then shift and set the bottom bit
  11456. static stua_obj stu__floatp(float *f)
  11457. {
  11458. unsigned int n = *(unsigned int *) f;
  11459. unsigned int e = n & (0xff << 23);
  11460. assert(sizeof(int) == 4 && sizeof(float) == 4);
  11461. if (!e) // zero?
  11462. n = n; // no change
  11463. else if (e < (64 << 23)) // underflow of the packed encoding?
  11464. n = (n & 0x80000000); // signed 0
  11465. else if (e > (190 << 23)) // overflow of the encoding? (or INF or NAN)
  11466. n = (n & 0x80000000) + (127 << 23); // new INF encoding
  11467. else
  11468. n -= 0x20000000;
  11469. // now we need to shuffle the bits so that the spare bit is at the bottom
  11470. assert((n & 0x40000000) == 0);
  11471. return (n & 0x80000000) + (n << 1) + 1;
  11472. }
  11473. static unsigned char stu__getfloat_addend[256];
  11474. static float stu__getfloat(stua_obj v)
  11475. {
  11476. unsigned int n;
  11477. unsigned int e = ((unsigned int) v) >> 24;
  11478. n = (int) v >> 1; // preserve high bit
  11479. n += stu__getfloat_addend[e] << 24;
  11480. return *(float *) &n;
  11481. }
  11482. stua_obj stua_float(float f)
  11483. {
  11484. return stu__floatp(&f);
  11485. }
  11486. static void stu__float_init(void)
  11487. {
  11488. int i;
  11489. stu__getfloat_addend[0] = 0; // do nothing to biased exponent of 0
  11490. for (i=1; i < 127; ++i)
  11491. stu__getfloat_addend[i] = 32; // undo the -0x20000000
  11492. stu__getfloat_addend[127] = 64; // convert packed INF to INF (0x3f -> 0x7f)
  11493. for (i=0; i < 128; ++i) // for signed floats, remove the bit we just shifted down
  11494. stu__getfloat_addend[128+i] = stu__getfloat_addend[i] - 64;
  11495. }
  11496. // Tagged data type implementation
  11497. // TAGS:
  11498. #define stu__int_tag 0 // of 2 bits // 00 int
  11499. #define stu__float_tag 1 // of 1 bit // 01 float
  11500. #define stu__ptr_tag 2 // of 2 bits // 10 boxed
  11501. // 11 float
  11502. #define stu__tag(x) ((x) & 3)
  11503. #define stu__number(x) (stu__tag(x) != stu__ptr_tag)
  11504. #define stu__isint(x) (stu__tag(x) == stu__int_tag)
  11505. #define stu__int(x) ((x) >> 2)
  11506. #define stu__float(x) (stu__getfloat(x))
  11507. #define stu__makeint(v) ((v)*4+stu__int_tag)
  11508. // boxed data, and tag support for boxed data
  11509. enum
  11510. {
  11511. STU___float = 1, STU___int = 2,
  11512. STU___number = 3, STU___string = 4,
  11513. STU___function = 5, STU___dict = 6,
  11514. STU___boolean = 7, STU___error = 8,
  11515. };
  11516. // boxed data
  11517. #define STU__BOX short type, stua_gc
  11518. typedef struct stu__box { STU__BOX; } stu__box;
  11519. stu__box stu__nil = { 0, 1 };
  11520. stu__box stu__true = { STU___boolean, 1, };
  11521. stu__box stu__false = { STU___boolean, 1, };
  11522. #define stu__makeptr(v) ((stua_obj) (v) + stu__ptr_tag)
  11523. #define stua_nil stu__makeptr(&stu__nil)
  11524. #define stua_true stu__makeptr(&stu__true)
  11525. #define stua_false stu__makeptr(&stu__false)
  11526. stua_obj stua_getnil(void) { return stua_nil; }
  11527. stua_obj stua_getfalse(void) { return stua_false; }
  11528. stua_obj stua_gettrue(void) { return stua_true; }
  11529. #define stu__ptr(x) ((stu__box *) ((x) - stu__ptr_tag))
  11530. #define stu__checkt(t,x) ((t) == STU___float ? ((x) & 1) == stu__float_tag : \
  11531. (t) == STU___int ? stu__isint(x) : \
  11532. (t) == STU___number ? stu__number(x) : \
  11533. stu__tag(x) == stu__ptr_tag && stu__ptr(x)->type == (t))
  11534. typedef struct
  11535. {
  11536. STU__BOX;
  11537. void *ptr;
  11538. } stu__wrapper;
  11539. // implementation of a 'function' or function + closure
  11540. typedef struct stu__func
  11541. {
  11542. STU__BOX;
  11543. stua_obj closure_source; // 0 - regular function; 4 - C function
  11544. // if closure, pointer to source function
  11545. union {
  11546. stua_obj closure_data; // partial-application data
  11547. void *store; // pointer to free that holds 'code'
  11548. stua_obj (*func)(stua_dict *context);
  11549. } f;
  11550. // closure ends here
  11551. short *code;
  11552. int num_param;
  11553. stua_obj *param; // list of parameter strings
  11554. } stu__func;
  11555. // apply this to 'short *code' to get at data
  11556. #define stu__const(f) ((stua_obj *) (f))
  11557. static void stu__free_func(stu__func *f)
  11558. {
  11559. if (f->closure_source == 0) free(f->f.store);
  11560. if ((stb_uint) f->closure_source <= 4) free(f->param);
  11561. free(f);
  11562. }
  11563. #define stu__pd(x) ((stua_dict *) stu__ptr(x))
  11564. #define stu__pw(x) ((stu__wrapper *) stu__ptr(x))
  11565. #define stu__pf(x) ((stu__func *) stu__ptr(x))
  11566. // garbage-collection
  11567. static stu__box ** stu__gc_ptrlist;
  11568. static stua_obj * stu__gc_root_stack;
  11569. stua_obj stua_pushroot(stua_obj o) { stb_arr_push(stu__gc_root_stack, o); return o; }
  11570. void stua_poproot ( void ) { stb_arr_pop(stu__gc_root_stack); }
  11571. static stb_sdict *stu__strings;
  11572. static void stu__mark(stua_obj z)
  11573. {
  11574. int i;
  11575. stu__box *p = stu__ptr(z);
  11576. if (p->stua_gc == 1) return; // already marked
  11577. assert(p->stua_gc == 0);
  11578. p->stua_gc = 1;
  11579. switch(p->type) {
  11580. case STU___function: {
  11581. stu__func *f = (stu__func *) p;
  11582. if ((stb_uint) f->closure_source <= 4) {
  11583. if (f->closure_source == 0) {
  11584. for (i=1; i <= f->code[0]; ++i)
  11585. if (!stu__number(((stua_obj *) f->code)[-i]))
  11586. stu__mark(((stua_obj *) f->code)[-i]);
  11587. }
  11588. for (i=0; i < f->num_param; ++i)
  11589. stu__mark(f->param[i]);
  11590. } else {
  11591. stu__mark(f->closure_source);
  11592. stu__mark(f->f.closure_data);
  11593. }
  11594. break;
  11595. }
  11596. case STU___dict: {
  11597. stua_dict *e = (stua_dict *) p;
  11598. for (i=0; i < e->limit; ++i)
  11599. if (e->table[i].k != STB_IEMPTY && e->table[i].k != STB_IDEL) {
  11600. if (!stu__number(e->table[i].k)) stu__mark((int) e->table[i].k);
  11601. if (!stu__number(e->table[i].v)) stu__mark((int) e->table[i].v);
  11602. }
  11603. break;
  11604. }
  11605. }
  11606. }
  11607. static int stu__num_allocs, stu__size_allocs;
  11608. static stua_obj stu__flow_val = stua_nil; // used for break & return
  11609. static void stua_gc(int force)
  11610. {
  11611. int i;
  11612. if (!force && stu__num_allocs == 0 && stu__size_allocs == 0) return;
  11613. stu__num_allocs = stu__size_allocs = 0;
  11614. //printf("[gc]\n");
  11615. // clear marks
  11616. for (i=0; i < stb_arr_len(stu__gc_ptrlist); ++i)
  11617. stu__gc_ptrlist[i]->stua_gc = 0;
  11618. // stu__mark everything reachable
  11619. stu__nil.stua_gc = stu__true.stua_gc = stu__false.stua_gc = 1;
  11620. stu__mark(stua_globals);
  11621. if (!stu__number(stu__flow_val))
  11622. stu__mark(stu__flow_val);
  11623. for (i=0; i < stb_arr_len(stu__gc_root_stack); ++i)
  11624. if (!stu__number(stu__gc_root_stack[i]))
  11625. stu__mark(stu__gc_root_stack[i]);
  11626. // sweep unreachables
  11627. for (i=0; i < stb_arr_len(stu__gc_ptrlist);) {
  11628. stu__box *z = stu__gc_ptrlist[i];
  11629. if (!z->stua_gc) {
  11630. switch (z->type) {
  11631. case STU___dict: stb_idict_destroy((stua_dict *) z); break;
  11632. case STU___error: free(((stu__wrapper *) z)->ptr); break;
  11633. case STU___string: stb_sdict_remove(stu__strings, (char*) ((stu__wrapper *) z)->ptr, NULL); free(z); break;
  11634. case STU___function: stu__free_func((stu__func *) z); break;
  11635. }
  11636. // swap in the last item over this, and repeat
  11637. z = stb_arr_pop(stu__gc_ptrlist);
  11638. stu__gc_ptrlist[i] = z;
  11639. } else
  11640. ++i;
  11641. }
  11642. }
  11643. static void stu__consider_gc(stua_obj x)
  11644. {
  11645. if (stu__size_allocs < 100000) return;
  11646. if (stu__num_allocs < 10 && stu__size_allocs < 1000000) return;
  11647. stb_arr_push(stu__gc_root_stack, x);
  11648. stua_gc(0);
  11649. stb_arr_pop(stu__gc_root_stack);
  11650. }
  11651. static stua_obj stu__makeobj(int type, void *data, int size, int safe_to_gc)
  11652. {
  11653. stua_obj x = stu__makeptr(data);
  11654. ((stu__box *) data)->type = type;
  11655. stb_arr_push(stu__gc_ptrlist, (stu__box *) data);
  11656. stu__num_allocs += 1;
  11657. stu__size_allocs += size;
  11658. if (safe_to_gc) stu__consider_gc(x);
  11659. return x;
  11660. }
  11661. stua_obj stua_box(int type, void *data, int size)
  11662. {
  11663. stu__wrapper *p = (stu__wrapper *) malloc(sizeof(*p));
  11664. p->ptr = data;
  11665. return stu__makeobj(type, p, size, 0);
  11666. }
  11667. // a stu string can be directly compared for equality, because
  11668. // they go into a hash table
  11669. stua_obj stua_string(char *z)
  11670. {
  11671. stu__wrapper *b = (stu__wrapper *) stb_sdict_get(stu__strings, z);
  11672. if (b == NULL) {
  11673. int o = stua_box(STU___string, NULL, strlen(z) + sizeof(*b));
  11674. b = stu__pw(o);
  11675. stb_sdict_add(stu__strings, z, b);
  11676. stb_sdict_getkey(stu__strings, z, (char **) &b->ptr);
  11677. }
  11678. return stu__makeptr(b);
  11679. }
  11680. // stb_obj dictionary is just an stb_idict
  11681. static void stu__set(stua_dict *d, stua_obj k, stua_obj v)
  11682. { if (stb_idict_set(d, k, v)) stu__size_allocs += 8; }
  11683. static stua_obj stu__get(stua_dict *d, stua_obj k, stua_obj res)
  11684. {
  11685. stb_idict_get_flag(d, k, &res);
  11686. return res;
  11687. }
  11688. static stua_obj make_string(char *z, int len)
  11689. {
  11690. stua_obj s;
  11691. char temp[256], *q = (char *) stb_temp(temp, len+1), *p = q;
  11692. while (len > 0) {
  11693. if (*z == '\\') {
  11694. if (z[1] == 'n') *p = '\n';
  11695. else if (z[1] == 'r') *p = '\r';
  11696. else if (z[1] == 't') *p = '\t';
  11697. else *p = z[1];
  11698. p += 1; z += 2; len -= 2;
  11699. } else {
  11700. *p++ = *z++; len -= 1;
  11701. }
  11702. }
  11703. *p = 0;
  11704. s = stua_string(q);
  11705. stb_tempfree(temp, q);
  11706. return s;
  11707. }
  11708. enum token_names
  11709. {
  11710. T__none=128,
  11711. ST_shl = STUA_op_shl, ST_ge = STUA_op_ge,
  11712. ST_shr = STUA_op_shr, ST_le = STUA_op_le,
  11713. ST_shru = STUA_op_shru, STU__negate = STUA_op_negate,
  11714. ST__reset_numbering = STUA_op_last,
  11715. ST_white,
  11716. ST_id, ST_float, ST_decimal, ST_hex, ST_char,ST_string, ST_number,
  11717. // make sure the keywords come _AFTER_ ST_id, so stb_lex prefer them
  11718. ST_if, ST_while, ST_for, ST_eq, ST_nil,
  11719. ST_then, ST_do, ST_in, ST_ne, ST_true,
  11720. ST_else, ST_break, ST_let, ST_and, ST_false,
  11721. ST_elseif, ST_continue, ST_into, ST_or, ST_repeat,
  11722. ST_end, ST_as, ST_return, ST_var, ST_func,
  11723. ST_catch, ST__frame,
  11724. ST__max_terminals,
  11725. STU__defaultparm, STU__seq,
  11726. };
  11727. static stua_dict * stu__globaldict;
  11728. stua_obj stua_globals;
  11729. static enum
  11730. {
  11731. FLOW_normal, FLOW_continue, FLOW_break, FLOW_return, FLOW_error,
  11732. } stu__flow;
  11733. stua_obj stua_error(char *z, ...)
  11734. {
  11735. stua_obj a;
  11736. char temp[4096], *x;
  11737. va_list v; va_start(v,z); vsprintf(temp, z, v); va_end(v);
  11738. x = strdup(temp);
  11739. a = stua_box(STU___error, x, strlen(x));
  11740. stu__flow = FLOW_error;
  11741. stu__flow_val = a;
  11742. return stua_nil;
  11743. }
  11744. double stua_number(stua_obj z)
  11745. {
  11746. return stu__tag(z) == stu__int_tag ? stu__int(z) : stu__float(z);
  11747. }
  11748. stua_obj stua_make_number(double d)
  11749. {
  11750. double e = floor(d);
  11751. if (e == d && e < (1 << 29) && e >= -(1 << 29))
  11752. return stu__makeint((int) e);
  11753. else
  11754. return stua_float((float) d);
  11755. }
  11756. stua_obj (*stua_overload)(int op, stua_obj a, stua_obj b, stua_obj c) = NULL;
  11757. static stua_obj stu__op(int op, stua_obj a, stua_obj b, stua_obj c)
  11758. {
  11759. stua_obj r = STUA_NO_VALUE;
  11760. if (op == '+') {
  11761. if (stu__checkt(STU___string, a) && stu__checkt(STU___string, b)) {
  11762. ;// @TODO: string concatenation
  11763. } else if (stu__checkt(STU___function, a) && stu__checkt(STU___dict, b)) {
  11764. stu__func *f = (stu__func *) malloc(12);
  11765. assert(offsetof(stu__func, code)==12);
  11766. f->closure_source = a;
  11767. f->f.closure_data = b;
  11768. return stu__makeobj(STU___function, f, 16, 1);
  11769. }
  11770. }
  11771. if (stua_overload) r = stua_overload(op,a,b,c);
  11772. if (stu__flow != FLOW_error && r == STUA_NO_VALUE)
  11773. stua_error("Typecheck for operator %d", op), r=stua_nil;
  11774. return r;
  11775. }
  11776. #define STU__EVAL2(a,b) \
  11777. a = stu__eval(stu__f[n+1]); if (stu__flow) break; stua_pushroot(a); \
  11778. b = stu__eval(stu__f[n+2]); stua_poproot(); if (stu__flow) break;
  11779. #define STU__FB(op) \
  11780. STU__EVAL2(a,b) \
  11781. if (stu__tag(a) == stu__int_tag && stu__tag(b) == stu__int_tag) \
  11782. return ((a) op (b)); \
  11783. if (stu__number(a) && stu__number(b)) \
  11784. return stua_make_number(stua_number(a) op stua_number(b)); \
  11785. return stu__op(stu__f[n], a,b, stua_nil)
  11786. #define STU__F(op) \
  11787. STU__EVAL2(a,b) \
  11788. if (stu__number(a) && stu__number(b)) \
  11789. return stua_make_number(stua_number(a) op stua_number(b)); \
  11790. return stu__op(stu__f[n], a,b, stua_nil)
  11791. #define STU__I(op) \
  11792. STU__EVAL2(a,b) \
  11793. if (stu__tag(a) == stu__int_tag && stu__tag(b) == stu__int_tag) \
  11794. return stu__makeint(stu__int(a) op stu__int(b)); \
  11795. return stu__op(stu__f[n], a,b, stua_nil)
  11796. #define STU__C(op) \
  11797. STU__EVAL2(a,b) \
  11798. if (stu__number(a) && stu__number(b)) \
  11799. return (stua_number(a) op stua_number(b)) ? stua_true : stua_false; \
  11800. return stu__op(stu__f[n], a,b, stua_nil)
  11801. #define STU__CE(op) \
  11802. STU__EVAL2(a,b) \
  11803. return (a op b) ? stua_true : stua_false
  11804. static short *stu__f;
  11805. static stua_obj stu__f_obj;
  11806. static stua_dict *stu__c;
  11807. static stua_obj stu__funceval(stua_obj fo, stua_obj co);
  11808. static int stu__cond(stua_obj x)
  11809. {
  11810. if (stu__flow) return 0;
  11811. if (!stu__checkt(STU___boolean, x))
  11812. x = stu__op('!', x, stua_nil, stua_nil);
  11813. if (x == stua_true ) return 1;
  11814. if (x == stua_false) return 0;
  11815. stu__flow = FLOW_error;
  11816. return 0;
  11817. }
  11818. // had to manually eliminate tailcall recursion for debugging complex stuff
  11819. #define TAILCALL(x) n = (x); goto top;
  11820. static stua_obj stu__eval(int n)
  11821. {
  11822. top:
  11823. if (stu__flow >= FLOW_return) return stua_nil; // is this needed?
  11824. if (n < 0) return stu__const(stu__f)[n];
  11825. assert(n != 0 && n != 1);
  11826. switch (stu__f[n]) {
  11827. stua_obj a,b,c;
  11828. case ST_catch: a = stu__eval(stu__f[n+1]);
  11829. if (stu__flow == FLOW_error) { a=stu__flow_val; stu__flow = FLOW_normal; }
  11830. return a;
  11831. case ST_var: b = stu__eval(stu__f[n+2]); if (stu__flow) break;
  11832. stu__set(stu__c, stu__const(stu__f)[stu__f[n+1]], b);
  11833. return b;
  11834. case STU__seq: stu__eval(stu__f[n+1]); if (stu__flow) break;
  11835. TAILCALL(stu__f[n+2]);
  11836. case ST_if: if (!stu__cond(stu__eval(stu__f[n+1]))) return stua_nil;
  11837. TAILCALL(stu__f[n+2]);
  11838. case ST_else: a = stu__cond(stu__eval(stu__f[n+1]));
  11839. TAILCALL(stu__f[n + 2 + !a]);
  11840. #define STU__HANDLE_BREAK \
  11841. if (stu__flow >= FLOW_break) { \
  11842. if (stu__flow == FLOW_break) { \
  11843. a = stu__flow_val; \
  11844. stu__flow = FLOW_normal; \
  11845. stu__flow_val = stua_nil; \
  11846. return a; \
  11847. } \
  11848. return stua_nil; \
  11849. }
  11850. case ST_as: stu__eval(stu__f[n+3]);
  11851. STU__HANDLE_BREAK
  11852. // fallthrough!
  11853. case ST_while: a = stua_nil; stua_pushroot(a);
  11854. while (stu__cond(stu__eval(stu__f[n+1]))) {
  11855. stua_poproot();
  11856. a = stu__eval(stu__f[n+2]);
  11857. STU__HANDLE_BREAK
  11858. stu__flow = FLOW_normal; // clear 'continue' flag
  11859. stua_pushroot(a);
  11860. if (stu__f[n+3]) stu__eval(stu__f[n+3]);
  11861. STU__HANDLE_BREAK
  11862. stu__flow = FLOW_normal; // clear 'continue' flag
  11863. }
  11864. stua_poproot();
  11865. return a;
  11866. case ST_break: stu__flow = FLOW_break; stu__flow_val = stu__eval(stu__f[n+1]); break;
  11867. case ST_continue:stu__flow = FLOW_continue; break;
  11868. case ST_return: stu__flow = FLOW_return; stu__flow_val = stu__eval(stu__f[n+1]); break;
  11869. case ST__frame: return stu__f_obj;
  11870. case '[': STU__EVAL2(a,b);
  11871. if (stu__checkt(STU___dict, a))
  11872. return stu__get(stu__pd(a), b, stua_nil);
  11873. return stu__op(stu__f[n], a, b, stua_nil);
  11874. case '=': a = stu__eval(stu__f[n+2]); if (stu__flow) break;
  11875. n = stu__f[n+1];
  11876. if (stu__f[n] == ST_id) {
  11877. if (!stb_idict_update(stu__c, stu__const(stu__f)[stu__f[n+1]], a))
  11878. if (!stb_idict_update(stu__globaldict, stu__const(stu__f)[stu__f[n+1]], a))
  11879. return stua_error("Assignment to undefined variable");
  11880. } else if (stu__f[n] == '[') {
  11881. stua_pushroot(a);
  11882. b = stu__eval(stu__f[n+1]); if (stu__flow) { stua_poproot(); break; }
  11883. stua_pushroot(b);
  11884. c = stu__eval(stu__f[n+2]); stua_poproot(); stua_poproot();
  11885. if (stu__flow) break;
  11886. if (!stu__checkt(STU___dict, b)) return stua_nil;
  11887. stu__set(stu__pd(b), c, a);
  11888. } else {
  11889. return stu__op(stu__f[n], stu__eval(n), a, stua_nil);
  11890. }
  11891. return a;
  11892. case STU__defaultparm:
  11893. a = stu__eval(stu__f[n+2]);
  11894. stu__flow = FLOW_normal;
  11895. if (stb_idict_add(stu__c, stu__const(stu__f)[stu__f[n+1]], a))
  11896. stu__size_allocs += 8;
  11897. return stua_nil;
  11898. case ST_id: a = stu__get(stu__c, stu__const(stu__f)[stu__f[n+1]], STUA_NO_VALUE); // try local variable
  11899. return a != STUA_NO_VALUE // else try stu__compile_global_scope variable
  11900. ? a : stu__get(stu__globaldict, stu__const(stu__f)[stu__f[n+1]], stua_nil);
  11901. case STU__negate:a = stu__eval(stu__f[n+1]); if (stu__flow) break;
  11902. return stu__isint(a) ? -a : stu__op(stu__f[n], a, stua_nil, stua_nil);
  11903. case '~': a = stu__eval(stu__f[n+1]); if (stu__flow) break;
  11904. return stu__isint(a) ? (~a)&~3 : stu__op(stu__f[n], a, stua_nil, stua_nil);
  11905. case '!': a = stu__eval(stu__f[n+1]); if (stu__flow) break;
  11906. a = stu__cond(a); if (stu__flow) break;
  11907. return a ? stua_true : stua_false;
  11908. case ST_eq: STU__CE(==); case ST_le: STU__C(<=); case '<': STU__C(<);
  11909. case ST_ne: STU__CE(!=); case ST_ge: STU__C(>=); case '>': STU__C(>);
  11910. case '+' : STU__FB(+); case '*': STU__F(*); case '&': STU__I(&); case ST_shl: STU__I(<<);
  11911. case '-' : STU__FB(-); case '/': STU__F(/); case '|': STU__I(|); case ST_shr: STU__I(>>);
  11912. case '%': STU__I(%); case '^': STU__I(^);
  11913. case ST_shru: STU__EVAL2(a,b);
  11914. if (stu__tag(a) == stu__int_tag && stu__tag(b) == stu__int_tag)
  11915. return stu__makeint((unsigned) stu__int(a) >> stu__int(b));
  11916. return stu__op(stu__f[n], a,b, stua_nil);
  11917. case ST_and: a = stu__eval(stu__f[n+1]); b = stu__cond(a); if (stu__flow) break;
  11918. return a ? stu__eval(stu__f[n+2]) : a;
  11919. case ST_or : a = stu__eval(stu__f[n+1]); b = stu__cond(a); if (stu__flow) break;
  11920. return a ? b : stu__eval(stu__f[n+2]);
  11921. case'(':case':': STU__EVAL2(a,b);
  11922. if (!stu__checkt(STU___function, a))
  11923. return stu__op(stu__f[n], a,b, stua_nil);
  11924. if (!stu__checkt(STU___dict, b))
  11925. return stua_nil;
  11926. if (stu__f[n] == ':')
  11927. b = stu__makeobj(STU___dict, stb_idict_copy(stu__pd(b)), stb_idict_memory_usage(stu__pd(b)), 0);
  11928. a = stu__funceval(a,b);
  11929. return a;
  11930. case '{' : {
  11931. stua_dict *d;
  11932. d = stb_idict_new_size(stu__f[n+1] > 40 ? 64 : 16);
  11933. if (d == NULL)
  11934. return stua_nil; // breakpoint fodder
  11935. c = stu__makeobj(STU___dict, d, 32, 1);
  11936. stua_pushroot(c);
  11937. a = stu__f[n+1];
  11938. for (b=0; b < a; ++b) {
  11939. stua_obj x = stua_pushroot(stu__eval(stu__f[n+2 + b*2 + 0]));
  11940. stua_obj y = stu__eval(stu__f[n+2 + b*2 + 1]);
  11941. stua_poproot();
  11942. if (stu__flow) { stua_poproot(); return stua_nil; }
  11943. stu__set(d, x, y);
  11944. }
  11945. stua_poproot();
  11946. return c;
  11947. }
  11948. default: if (stu__f[n] < 0) return stu__const(stu__f)[stu__f[n]];
  11949. assert(0); /* NOTREACHED */ // internal error!
  11950. }
  11951. return stua_nil;
  11952. }
  11953. int stb__stua_nesting;
  11954. static stua_obj stu__funceval(stua_obj fo, stua_obj co)
  11955. {
  11956. stu__func *f = stu__pf(fo);
  11957. stua_dict *context = stu__pd(co);
  11958. int i,j;
  11959. stua_obj p;
  11960. short *tf = stu__f; // save previous function
  11961. stua_dict *tc = stu__c;
  11962. if (stu__flow == FLOW_error) return stua_nil;
  11963. assert(stu__flow == FLOW_normal);
  11964. stua_pushroot(fo);
  11965. stua_pushroot(co);
  11966. stu__consider_gc(stua_nil);
  11967. while ((stb_uint) f->closure_source > 4) {
  11968. // add data from closure to context
  11969. stua_dict *e = (stua_dict *) stu__pd(f->f.closure_data);
  11970. for (i=0; i < e->limit; ++i)
  11971. if (e->table[i].k != STB_IEMPTY && e->table[i].k != STB_IDEL)
  11972. if (stb_idict_add(context, e->table[i].k, e->table[i].v))
  11973. stu__size_allocs += 8;
  11974. // use add so if it's already defined, we don't override it; that way
  11975. // explicit parameters win over applied ones, and most recent applications
  11976. // win over previous ones
  11977. f = stu__pf(f->closure_source);
  11978. }
  11979. for (j=0, i=0; i < f->num_param; ++i)
  11980. // if it doesn't already exist, add it from the numbered parameters
  11981. if (stb_idict_add(context, f->param[i], stu__get(context, stu__int(j), stua_nil)))
  11982. ++j;
  11983. // @TODO: if (stu__get(context, stu__int(f->num_param+1)) != STUA_NO_VALUE) // error: too many parameters
  11984. // @TODO: ditto too few parameters
  11985. if (f->closure_source == 4)
  11986. p = f->f.func(context);
  11987. else {
  11988. stu__f = f->code, stu__c = context;
  11989. stu__f_obj = co;
  11990. ++stb__stua_nesting;
  11991. if (stu__f[1])
  11992. p = stu__eval(stu__f[1]);
  11993. else
  11994. p = stua_nil;
  11995. --stb__stua_nesting;
  11996. stu__f = tf, stu__c = tc; // restore previous function
  11997. if (stu__flow == FLOW_return) {
  11998. stu__flow = FLOW_normal;
  11999. p = stu__flow_val;
  12000. stu__flow_val = stua_nil;
  12001. }
  12002. }
  12003. stua_poproot();
  12004. stua_poproot();
  12005. return p;
  12006. }
  12007. // Parser
  12008. static int stu__tok;
  12009. static stua_obj stu__tokval;
  12010. static char *stu__curbuf, *stu__bufstart;
  12011. static stb_matcher *stu__lex_matcher;
  12012. static unsigned char stu__prec[ST__max_terminals], stu__end[ST__max_terminals];
  12013. static void stu__nexttoken(void)
  12014. {
  12015. int len;
  12016. retry:
  12017. stu__tok = stb_lex(stu__lex_matcher, stu__curbuf, &len);
  12018. if (stu__tok == 0)
  12019. return;
  12020. switch(stu__tok) {
  12021. case ST_white : stu__curbuf += len; goto retry;
  12022. case T__none : stu__tok = *stu__curbuf; break;
  12023. case ST_string: stu__tokval = make_string(stu__curbuf+1, len-2); break;
  12024. case ST_id : stu__tokval = make_string(stu__curbuf, len); break;
  12025. case ST_hex : stu__tokval = stu__makeint(strtol(stu__curbuf+2,NULL,16)); stu__tok = ST_number; break;
  12026. case ST_decimal: stu__tokval = stu__makeint(strtol(stu__curbuf ,NULL,10)); stu__tok = ST_number; break;
  12027. case ST_float : stu__tokval = stua_float((float) atof(stu__curbuf)) ; stu__tok = ST_number; break;
  12028. case ST_char : stu__tokval = stu__curbuf[2] == '\\' ? stu__curbuf[3] : stu__curbuf[2];
  12029. if (stu__curbuf[3] == 't') stu__tokval = '\t';
  12030. if (stu__curbuf[3] == 'n') stu__tokval = '\n';
  12031. if (stu__curbuf[3] == 'r') stu__tokval = '\r';
  12032. stu__tokval = stu__makeint(stu__tokval);
  12033. stu__tok = ST_number;
  12034. break;
  12035. }
  12036. stu__curbuf += len;
  12037. }
  12038. static struct { int stu__tok; char *regex; } stu__lexemes[] =
  12039. {
  12040. ST_white , "([ \t\n\r]|/\\*(.|\n)*\\*/|//[^\r\n]*([\r\n]|$))+",
  12041. ST_id , "[_a-zA-Z][_a-zA-Z0-9]*",
  12042. ST_hex , "0x[0-9a-fA-F]+",
  12043. ST_decimal, "[0-9]+[0-9]*",
  12044. ST_float , "[0-9]+\\.?[0-9]*([eE][-+]?[0-9]+)?",
  12045. ST_float , "\\.[0-9]+([eE][-+]?[0-9]+)?",
  12046. ST_char , "c'(\\\\.|[^\\'])'",
  12047. ST_string , "\"(\\\\.|[^\\\"\n\r])*\"",
  12048. ST_string , "\'(\\\\.|[^\\\'\n\r])*\'",
  12049. #define stua_key4(a,b,c,d) ST_##a, #a, ST_##b, #b, ST_##c, #c, ST_##d, #d,
  12050. stua_key4(if,then,else,elseif) stua_key4(while,do,for,in)
  12051. stua_key4(func,var,let,break) stua_key4(nil,true,false,end)
  12052. stua_key4(return,continue,as,repeat) stua_key4(_frame,catch,catch,catch)
  12053. ST_shl, "<<", ST_and, "&&", ST_eq, "==", ST_ge, ">=",
  12054. ST_shr, ">>", ST_or , "||", ST_ne, "!=", ST_le, "<=",
  12055. ST_shru,">>>", ST_into, "=>",
  12056. T__none, ".",
  12057. };
  12058. typedef struct
  12059. {
  12060. stua_obj *data; // constants being compiled
  12061. short *code; // code being compiled
  12062. stua_dict *locals;
  12063. short *non_local_refs;
  12064. } stu__comp_func;
  12065. static stu__comp_func stu__pfunc;
  12066. static stu__comp_func *func_stack = NULL;
  12067. static void stu__push_func_comp(void)
  12068. {
  12069. stb_arr_push(func_stack, stu__pfunc);
  12070. stu__pfunc.data = NULL;
  12071. stu__pfunc.code = NULL;
  12072. stu__pfunc.locals = stb_idict_new_size(16);
  12073. stu__pfunc.non_local_refs = NULL;
  12074. stb_arr_push(stu__pfunc.code, 0); // number of data items
  12075. stb_arr_push(stu__pfunc.code, 1); // starting execution address
  12076. }
  12077. static void stu__pop_func_comp(void)
  12078. {
  12079. stb_arr_free(stu__pfunc.code);
  12080. stb_arr_free(stu__pfunc.data);
  12081. stb_idict_destroy(stu__pfunc.locals);
  12082. stb_arr_free(stu__pfunc.non_local_refs);
  12083. stu__pfunc = stb_arr_pop(func_stack);
  12084. }
  12085. // if an id is a reference to an outer lexical scope, this
  12086. // function returns the "name" of it, and updates the stack
  12087. // structures to make sure the names are propogated in.
  12088. static int stu__nonlocal_id(stua_obj var_obj)
  12089. {
  12090. stua_obj dummy, var = var_obj;
  12091. int i, n = stb_arr_len(func_stack), j,k;
  12092. if (stb_idict_get_flag(stu__pfunc.locals, var, &dummy)) return 0;
  12093. for (i=n-1; i > 1; --i) {
  12094. if (stb_idict_get_flag(func_stack[i].locals, var, &dummy))
  12095. break;
  12096. }
  12097. if (i <= 1) return 0; // stu__compile_global_scope
  12098. j = i; // need to access variable from j'th frame
  12099. for (i=0; i < stb_arr_len(stu__pfunc.non_local_refs); ++i)
  12100. if (stu__pfunc.non_local_refs[i] == j) return j-n;
  12101. stb_arr_push(stu__pfunc.non_local_refs, j-n);
  12102. // now make sure all the parents propogate it down
  12103. for (k=n-1; k > 1; --k) {
  12104. if (j-k >= 0) return j-n; // comes direct from this parent
  12105. for(i=0; i < stb_arr_len(func_stack[k].non_local_refs); ++i)
  12106. if (func_stack[k].non_local_refs[i] == j-k)
  12107. return j-n;
  12108. stb_arr_push(func_stack[k].non_local_refs, j-k);
  12109. }
  12110. assert (k != 1);
  12111. return j-n;
  12112. }
  12113. static int stu__off(void) { return stb_arr_len(stu__pfunc.code); }
  12114. static void stu__cc(int a)
  12115. {
  12116. assert(a >= -2000 && a < 5000);
  12117. stb_arr_push(stu__pfunc.code, a);
  12118. }
  12119. static int stu__cc1(int a) { stu__cc(a); return stu__off()-1; }
  12120. static int stu__cc2(int a, int b) { stu__cc(a); stu__cc(b); return stu__off()-2; }
  12121. static int stu__cc3(int a, int b, int c) {
  12122. if (a == '=') assert(c != 0);
  12123. stu__cc(a); stu__cc(b); stu__cc(c); return stu__off()-3; }
  12124. 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; }
  12125. static int stu__cdv(stua_obj p)
  12126. {
  12127. int i;
  12128. assert(p != STUA_NO_VALUE);
  12129. for (i=0; i < stb_arr_len(stu__pfunc.data); ++i)
  12130. if (stu__pfunc.data[i] == p)
  12131. break;
  12132. if (i == stb_arr_len(stu__pfunc.data))
  12133. stb_arr_push(stu__pfunc.data, p);
  12134. return ~i;
  12135. }
  12136. static int stu__cdt(void)
  12137. {
  12138. int z = stu__cdv(stu__tokval);
  12139. stu__nexttoken();
  12140. return z;
  12141. }
  12142. static int stu__seq(int a, int b)
  12143. {
  12144. return !a ? b : !b ? a : stu__cc3(STU__seq, a,b);
  12145. }
  12146. static char stu__comp_err_str[1024];
  12147. static int stu__comp_err_line;
  12148. static int stu__err(char *str, ...)
  12149. {
  12150. va_list v;
  12151. char *s = stu__bufstart;
  12152. stu__comp_err_line = 1;
  12153. while (s < stu__curbuf) {
  12154. if (s[0] == '\n' || s[0] == '\r') {
  12155. if (s[0]+s[1] == '\n' + '\r') ++s;
  12156. ++stu__comp_err_line;
  12157. }
  12158. ++s;
  12159. }
  12160. va_start(v, str);
  12161. vsprintf(stu__comp_err_str, str, v);
  12162. va_end(v);
  12163. return 0;
  12164. }
  12165. static int stu__accept(int p)
  12166. {
  12167. if (stu__tok != p) return 0;
  12168. stu__nexttoken();
  12169. return 1;
  12170. }
  12171. static int stu__demand(int p)
  12172. {
  12173. if (stu__accept(p)) return 1;
  12174. return stu__err("Didn't find expected stu__tok");
  12175. }
  12176. static int stu__demandv(int p, stua_obj *val)
  12177. {
  12178. if (stu__tok == p || p==0) {
  12179. *val = stu__tokval;
  12180. stu__nexttoken();
  12181. return 1;
  12182. } else
  12183. return 0;
  12184. }
  12185. static int stu__expr(int p);
  12186. int stu__nexpr(int p) { stu__nexttoken(); return stu__expr(p); }
  12187. static int stu__statements(int once, int as);
  12188. static int stu__parse_if(void) // parse both ST_if and ST_elseif
  12189. {
  12190. int b,c,a;
  12191. a = stu__nexpr(1); if (!a) return 0;
  12192. if (!stu__demand(ST_then)) return stu__err("expecting THEN");
  12193. b = stu__statements(0,0); if (!b) return 0;
  12194. if (b == 1) b = -1;
  12195. if (stu__tok == ST_elseif) {
  12196. return stu__parse_if();
  12197. } else if (stu__accept(ST_else)) {
  12198. c = stu__statements(0,0); if (!c) return 0;
  12199. if (!stu__demand(ST_end)) return stu__err("expecting END after else clause");
  12200. return stu__cc4(ST_else, a, b, c);
  12201. } else {
  12202. if (!stu__demand(ST_end)) return stu__err("expecting END in if statement");
  12203. return stu__cc3(ST_if, a, b);
  12204. }
  12205. }
  12206. int stu__varinit(int z, int in_globals)
  12207. {
  12208. int a,b;
  12209. stu__nexttoken();
  12210. while (stu__demandv(ST_id, &b)) {
  12211. if (!stb_idict_add(stu__pfunc.locals, b, 1))
  12212. if (!in_globals) return stu__err("Redefined variable %s.", stu__pw(b)->ptr);
  12213. if (stu__accept('=')) {
  12214. a = stu__expr(1); if (!a) return 0;
  12215. } else
  12216. a = stu__cdv(stua_nil);
  12217. z = stu__seq(z, stu__cc3(ST_var, stu__cdv(b), a));
  12218. if (!stu__accept(',')) break;
  12219. }
  12220. return z;
  12221. }
  12222. static int stu__compile_unary(int z, int outparm, int require_inparm)
  12223. {
  12224. int op = stu__tok, a, b;
  12225. stu__nexttoken();
  12226. if (outparm) {
  12227. if (require_inparm || (stu__tok && stu__tok != ST_end && stu__tok != ST_else && stu__tok != ST_elseif && stu__tok !=';')) {
  12228. a = stu__expr(1); if (!a) return 0;
  12229. } else
  12230. a = stu__cdv(stua_nil);
  12231. b = stu__cc2(op, a);
  12232. } else
  12233. b = stu__cc1(op);
  12234. return stu__seq(z,b);
  12235. }
  12236. static int stu__assign(void)
  12237. {
  12238. int z;
  12239. stu__accept(ST_let);
  12240. z = stu__expr(1); if (!z) return 0;
  12241. if (stu__accept('=')) {
  12242. int y,p = (z >= 0 ? stu__pfunc.code[z] : 0);
  12243. if (z < 0 || (p != ST_id && p != '[')) return stu__err("Invalid lvalue in assignment");
  12244. y = stu__assign(); if (!y) return 0;
  12245. z = stu__cc3('=', z, y);
  12246. }
  12247. return z;
  12248. }
  12249. static int stu__statements(int once, int stop_while)
  12250. {
  12251. int a,b, c, z=0;
  12252. for(;;) {
  12253. switch (stu__tok) {
  12254. case ST_if : a = stu__parse_if(); if (!a) return 0;
  12255. z = stu__seq(z, a);
  12256. break;
  12257. case ST_while : if (stop_while) return (z ? z:1);
  12258. a = stu__nexpr(1); if (!a) return 0;
  12259. if (stu__accept(ST_as)) c = stu__statements(0,0); else c = 0;
  12260. if (!stu__demand(ST_do)) return stu__err("expecting DO");
  12261. b = stu__statements(0,0); if (!b) return 0;
  12262. if (!stu__demand(ST_end)) return stu__err("expecting END");
  12263. if (b == 1) b = -1;
  12264. z = stu__seq(z, stu__cc4(ST_while, a, b, c));
  12265. break;
  12266. case ST_repeat : stu__nexttoken();
  12267. c = stu__statements(0,1); if (!c) return 0;
  12268. if (!stu__demand(ST_while)) return stu__err("expecting WHILE");
  12269. a = stu__expr(1); if (!a) return 0;
  12270. if (!stu__demand(ST_do)) return stu__err("expecting DO");
  12271. b = stu__statements(0,0); if (!b) return 0;
  12272. if (!stu__demand(ST_end)) return stu__err("expecting END");
  12273. if (b == 1) b = -1;
  12274. z = stu__seq(z, stu__cc4(ST_as, a, b, c));
  12275. break;
  12276. case ST_catch : a = stu__nexpr(1); if (!a) return 0;
  12277. z = stu__seq(z, stu__cc2(ST_catch, a));
  12278. break;
  12279. case ST_var : z = stu__varinit(z,0); break;
  12280. case ST_return : z = stu__compile_unary(z,1,1); break;
  12281. case ST_continue:z = stu__compile_unary(z,0,0); break;
  12282. case ST_break : z = stu__compile_unary(z,1,0); break;
  12283. case ST_into : if (z == 0 && !once) return stu__err("=> cannot be first statement in block");
  12284. a = stu__nexpr(99);
  12285. b = (a >= 0? stu__pfunc.code[a] : 0);
  12286. if (a < 0 || (b != ST_id && b != '[')) return stu__err("Invalid lvalue on right side of =>");
  12287. z = stu__cc3('=', a, z);
  12288. break;
  12289. default : if (stu__end[stu__tok]) return once ? 0 : (z ? z:1);
  12290. a = stu__assign(); if (!a) return 0;
  12291. stu__accept(';');
  12292. if (stu__tok && !stu__end[stu__tok]) {
  12293. if (a < 0)
  12294. return stu__err("Constant has no effect");
  12295. if (stu__pfunc.code[a] != '(' && stu__pfunc.code[a] != '=')
  12296. return stu__err("Expression has no effect");
  12297. }
  12298. z = stu__seq(z, a);
  12299. break;
  12300. }
  12301. if (!z) return 0;
  12302. stu__accept(';');
  12303. if (once && stu__tok != ST_into) return z;
  12304. }
  12305. }
  12306. static int stu__postexpr(int z, int p);
  12307. static int stu__dictdef(int end, int *count)
  12308. {
  12309. int z,n=0,i,flags=0;
  12310. short *dict=NULL;
  12311. stu__nexttoken();
  12312. while (stu__tok != end) {
  12313. if (stu__tok == ST_id) {
  12314. stua_obj id = stu__tokval;
  12315. stu__nexttoken();
  12316. if (stu__tok == '=') {
  12317. flags |= 1;
  12318. stb_arr_push(dict, stu__cdv(id));
  12319. z = stu__nexpr(1); if (!z) return 0;
  12320. } else {
  12321. z = stu__cc2(ST_id, stu__cdv(id));
  12322. z = stu__postexpr(z,1); if (!z) return 0;
  12323. flags |= 2;
  12324. stb_arr_push(dict, stu__cdv(stu__makeint(n++)));
  12325. }
  12326. } else {
  12327. z = stu__expr(1); if (!z) return 0;
  12328. flags |= 2;
  12329. stb_arr_push(dict, stu__cdv(stu__makeint(n++)));
  12330. }
  12331. if (end != ')' && flags == 3) { z=stu__err("can't mix initialized and uninitialized defs"); goto done;}
  12332. stb_arr_push(dict, z);
  12333. if (!stu__accept(',')) break;
  12334. }
  12335. if (!stu__demand(end))
  12336. return stu__err(end == ')' ? "Expecting ) at end of function call"
  12337. : "Expecting } at end of dictionary definition");
  12338. z = stu__cc2('{', stb_arr_len(dict)/2);
  12339. for (i=0; i < stb_arr_len(dict); ++i)
  12340. stu__cc(dict[i]);
  12341. if (count) *count = n;
  12342. done:
  12343. stb_arr_free(dict);
  12344. return z;
  12345. }
  12346. static int stu__comp_id(void)
  12347. {
  12348. int z,d;
  12349. d = stu__nonlocal_id(stu__tokval);
  12350. if (d == 0)
  12351. return z = stu__cc2(ST_id, stu__cdt());
  12352. // access a non-local frame by naming it with the appropriate int
  12353. assert(d < 0);
  12354. z = stu__cdv(d); // relative frame # is the 'variable' in our local frame
  12355. z = stu__cc2(ST_id, z); // now access that dictionary
  12356. return stu__cc3('[', z, stu__cdt()); // now access the variable from that dir
  12357. }
  12358. static stua_obj stu__funcdef(stua_obj *id, stua_obj *func);
  12359. static int stu__expr(int p)
  12360. {
  12361. int z;
  12362. // unary
  12363. switch (stu__tok) {
  12364. case ST_number: z = stu__cdt(); break;
  12365. case ST_string: z = stu__cdt(); break; // @TODO - string concatenation like C
  12366. case ST_id : z = stu__comp_id(); break;
  12367. case ST__frame: z = stu__cc1(ST__frame); stu__nexttoken(); break;
  12368. case ST_func : z = stu__funcdef(NULL,NULL); break;
  12369. case ST_if : z = stu__parse_if(); break;
  12370. case ST_nil : z = stu__cdv(stua_nil); stu__nexttoken(); break;
  12371. case ST_true : z = stu__cdv(stua_true); stu__nexttoken(); break;
  12372. case ST_false : z = stu__cdv(stua_false); stu__nexttoken(); break;
  12373. case '-' : z = stu__nexpr(99); if (z) z=stu__cc2(STU__negate,z); else return z; break;
  12374. case '!' : z = stu__nexpr(99); if (z) z=stu__cc2('!',z); else return z; break;
  12375. case '~' : z = stu__nexpr(99); if (z) z=stu__cc2('~',z); else return z; break;
  12376. case '{' : z = stu__dictdef('}', NULL); break;
  12377. default : return stu__err("Unexpected token");
  12378. case '(' : stu__nexttoken(); z = stu__statements(0,0); if (!stu__demand(')')) return stu__err("Expecting )");
  12379. }
  12380. return stu__postexpr(z,p);
  12381. }
  12382. static int stu__postexpr(int z, int p)
  12383. {
  12384. int q;
  12385. // postfix
  12386. while (stu__tok == '(' || stu__tok == '[' || stu__tok == '.') {
  12387. if (stu__accept('.')) {
  12388. // MUST be followed by a plain identifier! use [] for other stuff
  12389. if (stu__tok != ST_id) return stu__err("Must follow . with plain name; try [] instead");
  12390. z = stu__cc3('[', z, stu__cdv(stu__tokval));
  12391. stu__nexttoken();
  12392. } else if (stu__accept('[')) {
  12393. while (stu__tok != ']') {
  12394. int r = stu__expr(1); if (!r) return 0;
  12395. z = stu__cc3('[', z, r);
  12396. if (!stu__accept(',')) break;
  12397. }
  12398. if (!stu__demand(']')) return stu__err("Expecting ]");
  12399. } else {
  12400. int n, p = stu__dictdef(')', &n); if (!p) return 0;
  12401. #if 0 // this is incorrect!
  12402. if (z > 0 && stu__pfunc.code[z] == ST_id) {
  12403. stua_obj q = stu__get(stu__globaldict, stu__pfunc.data[-stu__pfunc.code[z+1]-1], stua_nil);
  12404. if (stu__checkt(STU___function, q))
  12405. if ((stu__pf(q))->num_param != n)
  12406. return stu__err("Incorrect number of parameters");
  12407. }
  12408. #endif
  12409. z = stu__cc3('(', z, p);
  12410. }
  12411. }
  12412. // binop - this implementation taken from lcc
  12413. for (q=stu__prec[stu__tok]; q >= p; --q) {
  12414. while (stu__prec[stu__tok] == q) {
  12415. int o = stu__tok, y = stu__nexpr(p+1); if (!y) return 0;
  12416. z = stu__cc3(o,z,y);
  12417. }
  12418. }
  12419. return z;
  12420. }
  12421. static stua_obj stu__finish_func(stua_obj *param, int start)
  12422. {
  12423. int n, size;
  12424. stu__func *f = (stu__func *) malloc(sizeof(*f));
  12425. f->closure_source = 0;
  12426. f->num_param = stb_arr_len(param);
  12427. f->param = (int *) stb_copy(param, f->num_param * sizeof(*f->param));
  12428. size = stb_arr_storage(stu__pfunc.code) + stb_arr_storage(stu__pfunc.data) + sizeof(*f) + 8;
  12429. f->f.store = malloc(stb_arr_storage(stu__pfunc.code) + stb_arr_storage(stu__pfunc.data));
  12430. f->code = (short *) ((char *) f->f.store + stb_arr_storage(stu__pfunc.data));
  12431. memcpy(f->code, stu__pfunc.code, stb_arr_storage(stu__pfunc.code));
  12432. f->code[1] = start;
  12433. f->code[0] = stb_arr_len(stu__pfunc.data);
  12434. for (n=0; n < f->code[0]; ++n)
  12435. ((stua_obj *) f->code)[-1-n] = stu__pfunc.data[n];
  12436. return stu__makeobj(STU___function, f, size, 0);
  12437. }
  12438. static int stu__funcdef(stua_obj *id, stua_obj *result)
  12439. {
  12440. int n,z=0,i,q;
  12441. stua_obj *param = NULL;
  12442. short *nonlocal;
  12443. stua_obj v,f=stua_nil;
  12444. assert(stu__tok == ST_func);
  12445. stu__nexttoken();
  12446. if (id) {
  12447. if (!stu__demandv(ST_id, id)) return stu__err("Expecting function name");
  12448. } else
  12449. stu__accept(ST_id);
  12450. if (!stu__demand('(')) return stu__err("Expecting ( for function parameter");
  12451. stu__push_func_comp();
  12452. while (stu__tok != ')') {
  12453. if (!stu__demandv(ST_id, &v)) { z=stu__err("Expecting parameter name"); goto done; }
  12454. stb_idict_add(stu__pfunc.locals, v, 1);
  12455. if (stu__tok == '=') {
  12456. n = stu__nexpr(1); if (!n) { z=0; goto done; }
  12457. z = stu__seq(z, stu__cc3(STU__defaultparm, stu__cdv(v), n));
  12458. } else
  12459. stb_arr_push(param, v);
  12460. if (!stu__accept(',')) break;
  12461. }
  12462. if (!stu__demand(')')) { z=stu__err("Expecting ) at end of parameter list"); goto done; }
  12463. n = stu__statements(0,0); if (!n) { z=0; goto done; }
  12464. if (!stu__demand(ST_end)) { z=stu__err("Expecting END at end of function"); goto done; }
  12465. if (n == 1) n = 0;
  12466. n = stu__seq(z,n);
  12467. f = stu__finish_func(param, n);
  12468. if (result) { *result = f; z=1; stu__pop_func_comp(); }
  12469. else {
  12470. nonlocal = stu__pfunc.non_local_refs;
  12471. stu__pfunc.non_local_refs = NULL;
  12472. stu__pop_func_comp();
  12473. z = stu__cdv(f);
  12474. if (nonlocal) { // build a closure with references to the needed frames
  12475. short *initcode = NULL;
  12476. for (i=0; i < stb_arr_len(nonlocal); ++i) {
  12477. int k = nonlocal[i], p;
  12478. stb_arr_push(initcode, stu__cdv(k));
  12479. if (k == -1) p = stu__cc1(ST__frame);
  12480. else { p = stu__cdv(stu__makeint(k+1)); p = stu__cc2(ST_id, p); }
  12481. stb_arr_push(initcode, p);
  12482. }
  12483. q = stu__cc2('{', stb_arr_len(nonlocal));
  12484. for (i=0; i < stb_arr_len(initcode); ++i)
  12485. stu__cc(initcode[i]);
  12486. z = stu__cc3('+', z, q);
  12487. stb_arr_free(initcode);
  12488. }
  12489. stb_arr_free(nonlocal);
  12490. }
  12491. done:
  12492. stb_arr_free(param);
  12493. if (!z) stu__pop_func_comp();
  12494. return z;
  12495. }
  12496. static int stu__compile_global_scope(void)
  12497. {
  12498. stua_obj o;
  12499. int z=0;
  12500. stu__push_func_comp();
  12501. while (stu__tok != 0) {
  12502. if (stu__tok == ST_func) {
  12503. stua_obj id, f;
  12504. if (!stu__funcdef(&id,&f))
  12505. goto error;
  12506. stu__set(stu__globaldict, id, f);
  12507. } else if (stu__tok == ST_var) {
  12508. z = stu__varinit(z,1); if (!z) goto error;
  12509. } else {
  12510. int y = stu__statements(1,0); if (!y) goto error;
  12511. z = stu__seq(z,y);
  12512. }
  12513. stu__accept(';');
  12514. }
  12515. o = stu__finish_func(NULL, z);
  12516. stu__pop_func_comp();
  12517. o = stu__funceval(o, stua_globals); // initialize stu__globaldict
  12518. if (stu__flow == FLOW_error)
  12519. printf("Error: %s\n", ((stu__wrapper *) stu__ptr(stu__flow_val))->ptr);
  12520. return 1;
  12521. error:
  12522. stu__pop_func_comp();
  12523. return 0;
  12524. }
  12525. stua_obj stu__myprint(stua_dict *context)
  12526. {
  12527. stua_obj x = stu__get(context, stua_string("x"), stua_nil);
  12528. if ((x & 1) == stu__float_tag) printf("%f", stu__getfloat(x));
  12529. else if (stu__tag(x) == stu__int_tag) printf("%d", stu__int(x));
  12530. else {
  12531. stu__wrapper *s = stu__pw(x);
  12532. if (s->type == STU___string || s->type == STU___error)
  12533. printf("%s", s->ptr);
  12534. else if (s->type == STU___dict) printf("{{dictionary}}");
  12535. else if (s->type == STU___function) printf("[[function]]");
  12536. else
  12537. printf("[[ERROR:%s]]", s->ptr);
  12538. }
  12539. return x;
  12540. }
  12541. void stua_init(void)
  12542. {
  12543. if (!stu__globaldict) {
  12544. int i;
  12545. stua_obj s;
  12546. stu__func *f;
  12547. stu__prec[ST_and] = stu__prec[ST_or] = 1;
  12548. stu__prec[ST_eq ] = stu__prec[ST_ne] = stu__prec[ST_le] =
  12549. stu__prec[ST_ge] = stu__prec['>' ] = stu__prec['<'] = 2;
  12550. stu__prec[':'] = 3;
  12551. stu__prec['&'] = stu__prec['|'] = stu__prec['^'] = 4;
  12552. stu__prec['+'] = stu__prec['-'] = 5;
  12553. stu__prec['*'] = stu__prec['/'] = stu__prec['%'] =
  12554. stu__prec[ST_shl]= stu__prec[ST_shr]= stu__prec[ST_shru]= 6;
  12555. stu__end[')'] = stu__end[ST_end] = stu__end[ST_else] = 1;
  12556. stu__end[ST_do] = stu__end[ST_elseif] = 1;
  12557. stu__float_init();
  12558. stu__lex_matcher = stb_lex_matcher();
  12559. for (i=0; i < sizeof(stu__lexemes)/sizeof(stu__lexemes[0]); ++i)
  12560. stb_lex_item(stu__lex_matcher, stu__lexemes[i].regex, stu__lexemes[i].stu__tok);
  12561. stu__globaldict = stb_idict_new_size(64);
  12562. stua_globals = stu__makeobj(STU___dict, stu__globaldict, 0,0);
  12563. stu__strings = stb_sdict_new(0);
  12564. stu__curbuf = stu__bufstart = "func _print(x) end\n"
  12565. "func print()\n var x=0 while _frame[x] != nil as x=x+1 do _print(_frame[x]) end end\n";
  12566. stu__nexttoken();
  12567. if (!stu__compile_global_scope())
  12568. printf("Compile error in line %d: %s\n", stu__comp_err_line, stu__comp_err_str);
  12569. s = stu__get(stu__globaldict, stua_string("_print"), stua_nil);
  12570. if (stu__tag(s) == stu__ptr_tag && stu__ptr(s)->type == STU___function) {
  12571. f = stu__pf(s);
  12572. free(f->f.store);
  12573. f->closure_source = 4;
  12574. f->f.func = stu__myprint;
  12575. f->code = NULL;
  12576. }
  12577. }
  12578. }
  12579. void stua_uninit(void)
  12580. {
  12581. if (stu__globaldict) {
  12582. stb_idict_remove_all(stu__globaldict);
  12583. stb_arr_setlen(stu__gc_root_stack, 0);
  12584. stua_gc(1);
  12585. stb_idict_destroy(stu__globaldict);
  12586. stb_sdict_delete(stu__strings);
  12587. stb_matcher_free(stu__lex_matcher);
  12588. stb_arr_free(stu__gc_ptrlist);
  12589. stb_arr_free(func_stack);
  12590. stb_arr_free(stu__gc_root_stack);
  12591. stu__globaldict = NULL;
  12592. }
  12593. }
  12594. void stua_run_script(char *s)
  12595. {
  12596. stua_init();
  12597. stu__curbuf = stu__bufstart = s;
  12598. stu__nexttoken();
  12599. stu__flow = FLOW_normal;
  12600. if (!stu__compile_global_scope())
  12601. printf("Compile error in line %d: %s\n", stu__comp_err_line, stu__comp_err_str);
  12602. stua_gc(1);
  12603. }
  12604. #endif // STB_DEFINE
  12605. #endif // STB_STUA
  12606. #undef STB_EXTERN
  12607. #endif // STB_INCLUDE_STB_H
  12608. /*
  12609. ------------------------------------------------------------------------------
  12610. This software is available under 2 licenses -- choose whichever you prefer.
  12611. ------------------------------------------------------------------------------
  12612. ALTERNATIVE A - MIT License
  12613. Copyright (c) 2017 Sean Barrett
  12614. Permission is hereby granted, free of charge, to any person obtaining a copy of
  12615. this software and associated documentation files (the "Software"), to deal in
  12616. the Software without restriction, including without limitation the rights to
  12617. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  12618. of the Software, and to permit persons to whom the Software is furnished to do
  12619. so, subject to the following conditions:
  12620. The above copyright notice and this permission notice shall be included in all
  12621. copies or substantial portions of the Software.
  12622. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12623. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12624. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  12625. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  12626. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  12627. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  12628. SOFTWARE.
  12629. ------------------------------------------------------------------------------
  12630. ALTERNATIVE B - Public Domain (www.unlicense.org)
  12631. This is free and unencumbered software released into the public domain.
  12632. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
  12633. software, either in source code form or as a compiled binary, for any purpose,
  12634. commercial or non-commercial, and by any means.
  12635. In jurisdictions that recognize copyright laws, the author or authors of this
  12636. software dedicate any and all copyright interest in the software to the public
  12637. domain. We make this dedication for the benefit of the public at large and to
  12638. the detriment of our heirs and successors. We intend this dedication to be an
  12639. overt act of relinquishment in perpetuity of all present and future rights to
  12640. this software under copyright law.
  12641. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  12642. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12643. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  12644. AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  12645. ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  12646. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  12647. ------------------------------------------------------------------------------
  12648. */