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.

3305 lines
104 KiB

  1. /* stb_lib.h - v1.00 - http://nothings.org/stb
  2. no warranty is offered or implied; use this code at your own risk
  3. ============================================================================
  4. You MUST
  5. #define STB_LIB_IMPLEMENTATION
  6. in EXACTLY _one_ C or C++ file that includes this header, BEFORE the
  7. include, like this:
  8. #define STB_LIB_IMPLEMENTATION
  9. #include "stblib_files.h"
  10. All other files should just #include "stblib_files.h" without the #define.
  11. ============================================================================
  12. LICENSE
  13. See end of file for license information.
  14. CREDITS
  15. Written by Sean Barrett.
  16. Fixes:
  17. Philipp Wiesemann Robert Nix
  18. r-lyeh blackpawn
  19. github:Mojofreem Ryan Whitworth
  20. Vincent Isambart Mike Sartain
  21. Eugene Opalev Tim Sjostrand
  22. github:infatum Dave Butler
  23. */
  24. #ifndef STB_INCLUDE_STB_LIB_H
  25. #include <stdarg.h>
  26. #if defined(_WIN32) && !defined(__MINGW32__)
  27. #ifndef _CRT_SECURE_NO_WARNINGS
  28. #define _CRT_SECURE_NO_WARNINGS
  29. #endif
  30. #ifndef _CRT_NONSTDC_NO_DEPRECATE
  31. #define _CRT_NONSTDC_NO_DEPRECATE
  32. #endif
  33. #ifndef _CRT_NON_CONFORMING_SWPRINTFS
  34. #define _CRT_NON_CONFORMING_SWPRINTFS
  35. #endif
  36. #if !defined(_MSC_VER) || _MSC_VER > 1700
  37. #include <intrin.h> // _BitScanReverse
  38. #endif
  39. #endif
  40. #include <stdlib.h> // stdlib could have min/max
  41. #include <stdio.h> // need FILE
  42. #include <string.h> // stb_define_hash needs memcpy/memset
  43. #include <time.h> // stb_dirtree
  44. typedef unsigned char stb_uchar;
  45. typedef unsigned char stb_uint8;
  46. typedef unsigned int stb_uint;
  47. typedef unsigned short stb_uint16;
  48. typedef short stb_int16;
  49. typedef signed char stb_int8;
  50. #if defined(STB_USE_LONG_FOR_32_BIT_INT) || defined(STB_LONG32)
  51. typedef unsigned long stb_uint32;
  52. typedef long stb_int32;
  53. #else
  54. typedef unsigned int stb_uint32;
  55. typedef int stb_int32;
  56. #endif
  57. typedef char stb__testsize2_16[sizeof(stb_uint16)==2 ? 1 : -1];
  58. typedef char stb__testsize2_32[sizeof(stb_uint32)==4 ? 1 : -1];
  59. #ifdef _MSC_VER
  60. typedef unsigned __int64 stb_uint64;
  61. typedef __int64 stb_int64;
  62. #define STB_IMM_UINT64(literalui64) (literalui64##ui64)
  63. #else
  64. // ??
  65. typedef unsigned long long stb_uint64;
  66. typedef long long stb_int64;
  67. #define STB_IMM_UINT64(literalui64) (literalui64##ULL)
  68. #endif
  69. typedef char stb__testsize2_64[sizeof(stb_uint64)==8 ? 1 : -1];
  70. #ifdef __cplusplus
  71. #define STB_EXTERN extern "C"
  72. #else
  73. #define STB_EXTERN extern
  74. #endif
  75. // check for well-known debug defines
  76. #if defined(DEBUG) || defined(_DEBUG) || defined(DBG)
  77. #ifndef NDEBUG
  78. #define STB_DEBUG
  79. #endif
  80. #endif
  81. #ifdef STB_DEBUG
  82. #include <assert.h>
  83. #endif
  84. #endif // STB_INCLUDE_STB_LIB_H
  85. #ifdef STB_LIB_IMPLEMENTATION
  86. #include <assert.h>
  87. #include <stdarg.h>
  88. #include <stddef.h>
  89. #include <ctype.h>
  90. #include <math.h>
  91. #ifndef _WIN32
  92. #include <unistd.h>
  93. #else
  94. #include <io.h> // _mktemp
  95. #include <direct.h> // _rmdir
  96. #endif
  97. #include <sys/types.h> // stat()/_stat()
  98. #include <sys/stat.h> // stat()/_stat()
  99. #endif
  100. //////////////////////////////////////////////////////////////////////////////
  101. //
  102. // Miscellany
  103. //
  104. #ifdef _WIN32
  105. #define stb_stricmp(a,b) stricmp(a,b)
  106. #define stb_strnicmp(a,b,n) strnicmp(a,b,n)
  107. #else
  108. #define stb_stricmp(a,b) strcasecmp(a,b)
  109. #define stb_strnicmp(a,b,n) strncasecmp(a,b,n)
  110. #endif
  111. #ifndef STB_INCLUDE_STB_LIB_H
  112. STB_EXTERN void stb_fatal(char *fmt, ...);
  113. STB_EXTERN void stb_swap(void *p, void *q, size_t sz);
  114. STB_EXTERN double stb_linear_remap(double x, double x_min, double x_max,
  115. double out_min, double out_max);
  116. #define stb_arrcount(x) (sizeof(x)/sizeof((x)[0]))
  117. #define stb_lerp(t,a,b) ( (a) + (t) * (float) ((b)-(a)) )
  118. #define stb_unlerp(t,a,b) ( ((t) - (a)) / (float) ((b) - (a)) )
  119. #endif
  120. #ifdef STB_LIB_IMPLEMENTATION
  121. void stb_fatal(char *s, ...)
  122. {
  123. va_list a;
  124. va_start(a,s);
  125. fputs("Fatal error: ", stderr);
  126. vfprintf(stderr, s, a);
  127. va_end(a);
  128. fputs("\n", stderr);
  129. #ifdef STB_DEBUG
  130. #ifdef _MSC_VER
  131. #ifndef _WIN64
  132. __asm int 3; // trap to debugger!
  133. #else
  134. __debugbreak();
  135. #endif
  136. #else
  137. __builtin_trap();
  138. #endif
  139. #endif
  140. exit(1);
  141. }
  142. typedef struct { char d[4]; } stb__4;
  143. typedef struct { char d[8]; } stb__8;
  144. // optimize the small cases, though you shouldn't be calling this for those!
  145. void stb_swap(void *p, void *q, size_t sz)
  146. {
  147. char buffer[256];
  148. if (p == q) return;
  149. if (sz == 4) {
  150. stb__4 temp = * ( stb__4 *) p;
  151. * (stb__4 *) p = * ( stb__4 *) q;
  152. * (stb__4 *) q = temp;
  153. return;
  154. } else if (sz == 8) {
  155. stb__8 temp = * ( stb__8 *) p;
  156. * (stb__8 *) p = * ( stb__8 *) q;
  157. * (stb__8 *) q = temp;
  158. return;
  159. }
  160. while (sz > sizeof(buffer)) {
  161. stb_swap(p, q, sizeof(buffer));
  162. p = (char *) p + sizeof(buffer);
  163. q = (char *) q + sizeof(buffer);
  164. sz -= sizeof(buffer);
  165. }
  166. memcpy(buffer, p , sz);
  167. memcpy(p , q , sz);
  168. memcpy(q , buffer, sz);
  169. }
  170. #ifdef stb_linear_remap
  171. #undef stb_linear_remap
  172. #endif
  173. double stb_linear_remap(double x, double x_min, double x_max,
  174. double out_min, double out_max)
  175. {
  176. return stb_lerp(stb_unlerp(x,x_min,x_max),out_min,out_max);
  177. }
  178. #define stb_linear_remap(t,a,b,c,d) stb_lerp(stb_unlerp(t,a,b),c,d)
  179. #endif // STB_LIB_IMPLEMENTATION
  180. #ifndef STB_INCLUDE_STB_LIB_H
  181. // avoid unnecessary function call, but define function so its address can be taken
  182. #ifndef stb_linear_remap
  183. #define stb_linear_remap(t,a,b,c,d) stb_lerp(stb_unlerp(t,a,b),c,d)
  184. #endif
  185. #endif
  186. //////////////////////////////////////////////////////////////////////////////
  187. //
  188. // cross-platform snprintf because they keep changing that,
  189. // and with old compilers without vararg macros we can't write
  190. // a macro wrapper to fix it up
  191. #ifndef STB_INCLUDE_STB_LIB_H
  192. STB_EXTERN int stb_snprintf(char *s, size_t n, const char *fmt, ...);
  193. STB_EXTERN int stb_vsnprintf(char *s, size_t n, const char *fmt, va_list v);
  194. STB_EXTERN char *stb_sprintf(const char *fmt, ...);
  195. #endif
  196. #ifdef STB_LIB_IMPLEMENTATION
  197. int stb_vsnprintf(char *s, size_t n, const char *fmt, va_list v)
  198. {
  199. int res;
  200. #ifdef _WIN32
  201. // Could use "_vsnprintf_s(s, n, _TRUNCATE, fmt, v)" ?
  202. res = _vsnprintf(s,n,fmt,v);
  203. #else
  204. res = vsnprintf(s,n,fmt,v);
  205. #endif
  206. if (n) s[n-1] = 0;
  207. // Unix returns length output would require, Windows returns negative when truncated.
  208. return (res >= (int) n || res < 0) ? -1 : res;
  209. }
  210. int stb_snprintf(char *s, size_t n, const char *fmt, ...)
  211. {
  212. int res;
  213. va_list v;
  214. va_start(v,fmt);
  215. res = stb_vsnprintf(s, n, fmt, v);
  216. va_end(v);
  217. return res;
  218. }
  219. char *stb_sprintf(const char *fmt, ...)
  220. {
  221. static char buffer[1024];
  222. va_list v;
  223. va_start(v,fmt);
  224. stb_vsnprintf(buffer,1024,fmt,v);
  225. va_end(v);
  226. return buffer;
  227. }
  228. #endif
  229. //////////////////////////////////////////////////////////////////////////////
  230. //
  231. // Windows UTF8 filename handling
  232. //
  233. // Windows stupidly treats 8-bit filenames as some dopey code page,
  234. // rather than utf-8. If we want to use utf8 filenames, we have to
  235. // convert them to WCHAR explicitly and call WCHAR versions of the
  236. // file functions. So, ok, we do.
  237. #ifndef STB_INCLUDE_STB_LIB_H
  238. #ifdef _WIN32
  239. #define stb__fopen(x,y) _wfopen((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y))
  240. #define stb__windows(x,y) x
  241. #else
  242. #define stb__fopen(x,y) fopen(x,y)
  243. #define stb__windows(x,y) y
  244. #endif
  245. typedef unsigned short stb__wchar;
  246. STB_EXTERN stb__wchar * stb_from_utf8(stb__wchar *buffer, char *str, int n);
  247. STB_EXTERN char * stb_to_utf8 (char *buffer, stb__wchar *str, int n);
  248. STB_EXTERN stb__wchar *stb__from_utf8(char *str);
  249. STB_EXTERN stb__wchar *stb__from_utf8_alt(char *str);
  250. STB_EXTERN char *stb__to_utf8(stb__wchar *str);
  251. #endif
  252. #ifdef STB_LIB_IMPLEMENTATION
  253. stb__wchar * stb_from_utf8(stb__wchar *buffer, char *ostr, int n)
  254. {
  255. unsigned char *str = (unsigned char *) ostr;
  256. stb_uint32 c;
  257. int i=0;
  258. --n;
  259. while (*str) {
  260. if (i >= n)
  261. return NULL;
  262. if (!(*str & 0x80))
  263. buffer[i++] = *str++;
  264. else if ((*str & 0xe0) == 0xc0) {
  265. if (*str < 0xc2) return NULL;
  266. c = (*str++ & 0x1f) << 6;
  267. if ((*str & 0xc0) != 0x80) return NULL;
  268. buffer[i++] = c + (*str++ & 0x3f);
  269. } else if ((*str & 0xf0) == 0xe0) {
  270. if (*str == 0xe0 && (str[1] < 0xa0 || str[1] > 0xbf)) return NULL;
  271. if (*str == 0xed && str[1] > 0x9f) return NULL; // str[1] < 0x80 is checked below
  272. c = (*str++ & 0x0f) << 12;
  273. if ((*str & 0xc0) != 0x80) return NULL;
  274. c += (*str++ & 0x3f) << 6;
  275. if ((*str & 0xc0) != 0x80) return NULL;
  276. buffer[i++] = c + (*str++ & 0x3f);
  277. } else if ((*str & 0xf8) == 0xf0) {
  278. if (*str > 0xf4) return NULL;
  279. if (*str == 0xf0 && (str[1] < 0x90 || str[1] > 0xbf)) return NULL;
  280. if (*str == 0xf4 && str[1] > 0x8f) return NULL; // str[1] < 0x80 is checked below
  281. c = (*str++ & 0x07) << 18;
  282. if ((*str & 0xc0) != 0x80) return NULL;
  283. c += (*str++ & 0x3f) << 12;
  284. if ((*str & 0xc0) != 0x80) return NULL;
  285. c += (*str++ & 0x3f) << 6;
  286. if ((*str & 0xc0) != 0x80) return NULL;
  287. c += (*str++ & 0x3f);
  288. // utf-8 encodings of values used in surrogate pairs are invalid
  289. if ((c & 0xFFFFF800) == 0xD800) return NULL;
  290. if (c >= 0x10000) {
  291. c -= 0x10000;
  292. if (i + 2 > n) return NULL;
  293. buffer[i++] = 0xD800 | (0x3ff & (c >> 10));
  294. buffer[i++] = 0xDC00 | (0x3ff & (c ));
  295. }
  296. } else
  297. return NULL;
  298. }
  299. buffer[i] = 0;
  300. return buffer;
  301. }
  302. char * stb_to_utf8(char *buffer, stb__wchar *str, int n)
  303. {
  304. int i=0;
  305. --n;
  306. while (*str) {
  307. if (*str < 0x80) {
  308. if (i+1 > n) return NULL;
  309. buffer[i++] = (char) *str++;
  310. } else if (*str < 0x800) {
  311. if (i+2 > n) return NULL;
  312. buffer[i++] = 0xc0 + (*str >> 6);
  313. buffer[i++] = 0x80 + (*str & 0x3f);
  314. str += 1;
  315. } else if (*str >= 0xd800 && *str < 0xdc00) {
  316. stb_uint32 c;
  317. if (i+4 > n) return NULL;
  318. c = ((str[0] - 0xd800) << 10) + ((str[1]) - 0xdc00) + 0x10000;
  319. buffer[i++] = 0xf0 + (c >> 18);
  320. buffer[i++] = 0x80 + ((c >> 12) & 0x3f);
  321. buffer[i++] = 0x80 + ((c >> 6) & 0x3f);
  322. buffer[i++] = 0x80 + ((c ) & 0x3f);
  323. str += 2;
  324. } else if (*str >= 0xdc00 && *str < 0xe000) {
  325. return NULL;
  326. } else {
  327. if (i+3 > n) return NULL;
  328. buffer[i++] = 0xe0 + (*str >> 12);
  329. buffer[i++] = 0x80 + ((*str >> 6) & 0x3f);
  330. buffer[i++] = 0x80 + ((*str ) & 0x3f);
  331. str += 1;
  332. }
  333. }
  334. buffer[i] = 0;
  335. return buffer;
  336. }
  337. stb__wchar *stb__from_utf8(char *str)
  338. {
  339. static stb__wchar buffer[4096];
  340. return stb_from_utf8(buffer, str, 4096);
  341. }
  342. stb__wchar *stb__from_utf8_alt(char *str)
  343. {
  344. static stb__wchar buffer[4096];
  345. return stb_from_utf8(buffer, str, 4096);
  346. }
  347. char *stb__to_utf8(stb__wchar *str)
  348. {
  349. static char buffer[4096];
  350. return stb_to_utf8(buffer, str, 4096);
  351. }
  352. #endif
  353. //////////////////////////////////////////////////////////////////////////////
  354. //
  355. // qsort Compare Routines
  356. // NOT THREAD SAFE
  357. #ifndef STB_INCLUDE_STB_LIB_H
  358. STB_EXTERN int (*stb_intcmp(int offset))(const void *a, const void *b);
  359. STB_EXTERN int (*stb_qsort_strcmp(int offset))(const void *a, const void *b);
  360. STB_EXTERN int (*stb_qsort_stricmp(int offset))(const void *a, const void *b);
  361. STB_EXTERN int (*stb_floatcmp(int offset))(const void *a, const void *b);
  362. STB_EXTERN int (*stb_doublecmp(int offset))(const void *a, const void *b);
  363. STB_EXTERN int (*stb_ucharcmp(int offset))(const void *a, const void *b);
  364. STB_EXTERN int (*stb_charcmp(int offset))(const void *a, const void *b);
  365. #endif
  366. #ifdef STB_LIB_IMPLEMENTATION
  367. static int stb__intcmpoffset, stb__ucharcmpoffset, stb__strcmpoffset;
  368. static int stb__floatcmpoffset, stb__doublecmpoffset, stb__charcmpoffset;
  369. int stb__intcmp(const void *a, const void *b)
  370. {
  371. const int p = *(const int *) ((const char *) a + stb__intcmpoffset);
  372. const int q = *(const int *) ((const char *) b + stb__intcmpoffset);
  373. return p < q ? -1 : p > q;
  374. }
  375. int stb__ucharcmp(const void *a, const void *b)
  376. {
  377. const int p = *(const unsigned char *) ((const char *) a + stb__ucharcmpoffset);
  378. const int q = *(const unsigned char *) ((const char *) b + stb__ucharcmpoffset);
  379. return p < q ? -1 : p > q;
  380. }
  381. int stb__charcmp(const void *a, const void *b)
  382. {
  383. const int p = *(const char *) ((const char *) a + stb__ucharcmpoffset);
  384. const int q = *(const char *) ((const char *) b + stb__ucharcmpoffset);
  385. return p < q ? -1 : p > q;
  386. }
  387. int stb__floatcmp(const void *a, const void *b)
  388. {
  389. const float p = *(const float *) ((const char *) a + stb__floatcmpoffset);
  390. const float q = *(const float *) ((const char *) b + stb__floatcmpoffset);
  391. return p < q ? -1 : p > q;
  392. }
  393. int stb__doublecmp(const void *a, const void *b)
  394. {
  395. const double p = *(const double *) ((const char *) a + stb__doublecmpoffset);
  396. const double q = *(const double *) ((const char *) b + stb__doublecmpoffset);
  397. return p < q ? -1 : p > q;
  398. }
  399. int stb__qsort_strcmp(const void *a, const void *b)
  400. {
  401. const char *p = *(const char **) ((const char *) a + stb__strcmpoffset);
  402. const char *q = *(const char **) ((const char *) b + stb__strcmpoffset);
  403. return strcmp(p,q);
  404. }
  405. int stb__qsort_stricmp(const void *a, const void *b)
  406. {
  407. const char *p = *(const char **) ((const char *) a + stb__strcmpoffset);
  408. const char *q = *(const char **) ((const char *) b + stb__strcmpoffset);
  409. return stb_stricmp(p,q);
  410. }
  411. int (*stb_intcmp(int offset))(const void *, const void *)
  412. {
  413. stb__intcmpoffset = offset;
  414. return &stb__intcmp;
  415. }
  416. int (*stb_ucharcmp(int offset))(const void *, const void *)
  417. {
  418. stb__ucharcmpoffset = offset;
  419. return &stb__ucharcmp;
  420. }
  421. int (*stb_charcmp(int offset))(const void *, const void *)
  422. {
  423. stb__charcmpoffset = offset;
  424. return &stb__ucharcmp;
  425. }
  426. int (*stb_qsort_strcmp(int offset))(const void *, const void *)
  427. {
  428. stb__strcmpoffset = offset;
  429. return &stb__qsort_strcmp;
  430. }
  431. int (*stb_qsort_stricmp(int offset))(const void *, const void *)
  432. {
  433. stb__strcmpoffset = offset;
  434. return &stb__qsort_stricmp;
  435. }
  436. int (*stb_floatcmp(int offset))(const void *, const void *)
  437. {
  438. stb__floatcmpoffset = offset;
  439. return &stb__floatcmp;
  440. }
  441. int (*stb_doublecmp(int offset))(const void *, const void *)
  442. {
  443. stb__doublecmpoffset = offset;
  444. return &stb__doublecmp;
  445. }
  446. #endif
  447. //////////////////////////////////////////////////////////////////////////////
  448. //
  449. // String Processing
  450. //
  451. #ifndef STB_INCLUDE_STB_LIB_H
  452. #define stb_prefixi(s,t) (0==stb_strnicmp((s),(t),strlen(t)))
  453. enum stb_splitpath_flag
  454. {
  455. STB_PATH = 1,
  456. STB_FILE = 2,
  457. STB_EXT = 4,
  458. STB_PATH_FILE = STB_PATH + STB_FILE,
  459. STB_FILE_EXT = STB_FILE + STB_EXT,
  460. STB_EXT_NO_PERIOD = 8,
  461. };
  462. STB_EXTERN char * stb_skipwhite(char *s);
  463. STB_EXTERN char * stb_trimwhite(char *s);
  464. STB_EXTERN char * stb_skipnewline(char *s);
  465. STB_EXTERN char * stb_strncpy(char *s, char *t, int n);
  466. STB_EXTERN char * stb_substr(char *t, int n);
  467. STB_EXTERN char * stb_duplower(char *s);
  468. STB_EXTERN void stb_tolower (char *s);
  469. STB_EXTERN char * stb_strchr2 (char *s, char p1, char p2);
  470. STB_EXTERN char * stb_strrchr2(char *s, char p1, char p2);
  471. STB_EXTERN char * stb_strtok(char *output, char *src, char *delimit);
  472. STB_EXTERN char * stb_strtok_keep(char *output, char *src, char *delimit);
  473. STB_EXTERN char * stb_strtok_invert(char *output, char *src, char *allowed);
  474. STB_EXTERN char * stb_dupreplace(char *s, char *find, char *replace);
  475. STB_EXTERN void stb_replaceinplace(char *s, char *find, char *replace);
  476. STB_EXTERN char * stb_splitpath(char *output, char *src, int flag);
  477. STB_EXTERN char * stb_splitpathdup(char *src, int flag);
  478. STB_EXTERN char * stb_replacedir(char *output, char *src, char *dir);
  479. STB_EXTERN char * stb_replaceext(char *output, char *src, char *ext);
  480. STB_EXTERN void stb_fixpath(char *path);
  481. STB_EXTERN char * stb_shorten_path_readable(char *path, int max_len);
  482. STB_EXTERN int stb_suffix (char *s, char *t);
  483. STB_EXTERN int stb_suffixi(char *s, char *t);
  484. STB_EXTERN int stb_prefix (char *s, char *t);
  485. STB_EXTERN char * stb_strichr(char *s, char t);
  486. STB_EXTERN char * stb_stristr(char *s, char *t);
  487. STB_EXTERN int stb_prefix_count(char *s, char *t);
  488. STB_EXTERN const char * stb_plural(int n); // "s" or ""
  489. STB_EXTERN size_t stb_strscpy(char *d, const char *s, size_t n);
  490. STB_EXTERN char **stb_tokens(char *src, char *delimit, int *count);
  491. STB_EXTERN char **stb_tokens_nested(char *src, char *delimit, int *count, char *nest_in, char *nest_out);
  492. STB_EXTERN char **stb_tokens_nested_empty(char *src, char *delimit, int *count, char *nest_in, char *nest_out);
  493. STB_EXTERN char **stb_tokens_allowempty(char *src, char *delimit, int *count);
  494. STB_EXTERN char **stb_tokens_stripwhite(char *src, char *delimit, int *count);
  495. STB_EXTERN char **stb_tokens_withdelim(char *src, char *delimit, int *count);
  496. STB_EXTERN char **stb_tokens_quoted(char *src, char *delimit, int *count);
  497. // with 'quoted', allow delimiters to appear inside quotation marks, and don't
  498. // strip whitespace inside them (and we delete the quotation marks unless they
  499. // appear back to back, in which case they're considered escaped)
  500. #endif // STB_INCLUDE_STB_LIB_H
  501. #ifdef STB_LIB_IMPLEMENTATION
  502. #include <ctype.h>
  503. size_t stb_strscpy(char *d, const char *s, size_t n)
  504. {
  505. size_t len = strlen(s);
  506. if (len >= n) {
  507. if (n) d[0] = 0;
  508. return 0;
  509. }
  510. strcpy(d,s);
  511. return len + 1;
  512. }
  513. const char *stb_plural(int n)
  514. {
  515. return n == 1 ? "" : "s";
  516. }
  517. int stb_prefix(char *s, char *t)
  518. {
  519. while (*t)
  520. if (*s++ != *t++)
  521. return 0;
  522. return 1;
  523. }
  524. int stb_prefix_count(char *s, char *t)
  525. {
  526. int c=0;
  527. while (*t) {
  528. if (*s++ != *t++)
  529. break;
  530. ++c;
  531. }
  532. return c;
  533. }
  534. int stb_suffix(char *s, char *t)
  535. {
  536. size_t n = strlen(s);
  537. size_t m = strlen(t);
  538. if (m <= n)
  539. return 0 == strcmp(s+n-m, t);
  540. else
  541. return 0;
  542. }
  543. int stb_suffixi(char *s, char *t)
  544. {
  545. size_t n = strlen(s);
  546. size_t m = strlen(t);
  547. if (m <= n)
  548. return 0 == stb_stricmp(s+n-m, t);
  549. else
  550. return 0;
  551. }
  552. // originally I was using this table so that I could create known sentinel
  553. // values--e.g. change whitetable[0] to be true if I was scanning for whitespace,
  554. // and false if I was scanning for nonwhite. I don't appear to be using that
  555. // functionality anymore (I do for tokentable, though), so just replace it
  556. // with isspace()
  557. char *stb_skipwhite(char *s)
  558. {
  559. while (isspace((unsigned char) *s)) ++s;
  560. return s;
  561. }
  562. char *stb_skipnewline(char *s)
  563. {
  564. if (s[0] == '\r' || s[0] == '\n') {
  565. if (s[0]+s[1] == '\r' + '\n') ++s;
  566. ++s;
  567. }
  568. return s;
  569. }
  570. char *stb_trimwhite(char *s)
  571. {
  572. int i,n;
  573. s = stb_skipwhite(s);
  574. n = (int) strlen(s);
  575. for (i=n-1; i >= 0; --i)
  576. if (!isspace(s[i]))
  577. break;
  578. s[i+1] = 0;
  579. return s;
  580. }
  581. char *stb_strncpy(char *s, char *t, int n)
  582. {
  583. strncpy(s,t,n);
  584. s[n-1] = 0;
  585. return s;
  586. }
  587. char *stb_substr(char *t, int n)
  588. {
  589. char *a;
  590. int z = (int) strlen(t);
  591. if (z < n) n = z;
  592. a = (char *) malloc(n+1);
  593. strncpy(a,t,n);
  594. a[n] = 0;
  595. return a;
  596. }
  597. char *stb_duplower(char *s)
  598. {
  599. char *p = strdup(s), *q = p;
  600. while (*q) {
  601. *q = tolower(*q);
  602. ++q;
  603. }
  604. return p;
  605. }
  606. void stb_tolower(char *s)
  607. {
  608. while (*s) {
  609. *s = tolower(*s);
  610. ++s;
  611. }
  612. }
  613. char *stb_strchr2(char *s, char x, char y)
  614. {
  615. for(; *s; ++s)
  616. if (*s == x || *s == y)
  617. return s;
  618. return NULL;
  619. }
  620. char *stb_strrchr2(char *s, char x, char y)
  621. {
  622. char *r = NULL;
  623. for(; *s; ++s)
  624. if (*s == x || *s == y)
  625. r = s;
  626. return r;
  627. }
  628. char *stb_strichr(char *s, char t)
  629. {
  630. if (tolower(t) == toupper(t))
  631. return strchr(s,t);
  632. return stb_strchr2(s, (char) tolower(t), (char) toupper(t));
  633. }
  634. char *stb_stristr(char *s, char *t)
  635. {
  636. size_t n = strlen(t);
  637. char *z;
  638. if (n==0) return s;
  639. while ((z = stb_strichr(s, *t)) != NULL) {
  640. if (0==stb_strnicmp(z, t, n))
  641. return z;
  642. s = z+1;
  643. }
  644. return NULL;
  645. }
  646. static char *stb_strtok_raw(char *output, char *src, char *delimit, int keep, int invert)
  647. {
  648. if (invert) {
  649. while (*src && strchr(delimit, *src) != NULL) {
  650. *output++ = *src++;
  651. }
  652. } else {
  653. while (*src && strchr(delimit, *src) == NULL) {
  654. *output++ = *src++;
  655. }
  656. }
  657. *output = 0;
  658. if (keep)
  659. return src;
  660. else
  661. return *src ? src+1 : src;
  662. }
  663. char *stb_strtok(char *output, char *src, char *delimit)
  664. {
  665. return stb_strtok_raw(output, src, delimit, 0, 0);
  666. }
  667. char *stb_strtok_keep(char *output, char *src, char *delimit)
  668. {
  669. return stb_strtok_raw(output, src, delimit, 1, 0);
  670. }
  671. char *stb_strtok_invert(char *output, char *src, char *delimit)
  672. {
  673. return stb_strtok_raw(output, src, delimit, 1,1);
  674. }
  675. static char **stb_tokens_raw(char *src_, char *delimit, int *count,
  676. int stripwhite, int allow_empty, char *start, char *end)
  677. {
  678. int nested = 0;
  679. unsigned char *src = (unsigned char *) src_;
  680. static char stb_tokentable[256]; // rely on static initializion to 0
  681. static char stable[256],etable[256];
  682. char *out;
  683. char **result;
  684. int num=0;
  685. unsigned char *s;
  686. s = (unsigned char *) delimit; while (*s) stb_tokentable[*s++] = 1;
  687. if (start) {
  688. s = (unsigned char *) start; while (*s) stable[*s++] = 1;
  689. s = (unsigned char *) end; if (s) while (*s) stable[*s++] = 1;
  690. s = (unsigned char *) end; if (s) while (*s) etable[*s++] = 1;
  691. }
  692. stable[0] = 1;
  693. // two passes through: the first time, counting how many
  694. s = (unsigned char *) src;
  695. while (*s) {
  696. // state: just found delimiter
  697. // skip further delimiters
  698. if (!allow_empty) {
  699. stb_tokentable[0] = 0;
  700. while (stb_tokentable[*s])
  701. ++s;
  702. if (!*s) break;
  703. }
  704. ++num;
  705. // skip further non-delimiters
  706. stb_tokentable[0] = 1;
  707. if (stripwhite == 2) { // quoted strings
  708. while (!stb_tokentable[*s]) {
  709. if (*s != '"')
  710. ++s;
  711. else {
  712. ++s;
  713. if (*s == '"')
  714. ++s; // "" -> ", not start a string
  715. else {
  716. // begin a string
  717. while (*s) {
  718. if (s[0] == '"') {
  719. if (s[1] == '"') s += 2; // "" -> "
  720. else { ++s; break; } // terminating "
  721. } else
  722. ++s;
  723. }
  724. }
  725. }
  726. }
  727. } else
  728. while (nested || !stb_tokentable[*s]) {
  729. if (stable[*s]) {
  730. if (!*s) break;
  731. if (end ? etable[*s] : nested)
  732. --nested;
  733. else
  734. ++nested;
  735. }
  736. ++s;
  737. }
  738. if (allow_empty) {
  739. if (*s) ++s;
  740. }
  741. }
  742. // now num has the actual count... malloc our output structure
  743. // need space for all the strings: strings won't be any longer than
  744. // original input, since for every '\0' there's at least one delimiter
  745. result = (char **) malloc(sizeof(*result) * (num+1) + (s-src+1));
  746. if (result == NULL) return result;
  747. out = (char *) (result + (num+1));
  748. // second pass: copy out the data
  749. s = (unsigned char *) src;
  750. num = 0;
  751. nested = 0;
  752. while (*s) {
  753. char *last_nonwhite;
  754. // state: just found delimiter
  755. // skip further delimiters
  756. if (!allow_empty) {
  757. stb_tokentable[0] = 0;
  758. if (stripwhite)
  759. while (stb_tokentable[*s] || isspace(*s))
  760. ++s;
  761. else
  762. while (stb_tokentable[*s])
  763. ++s;
  764. } else if (stripwhite) {
  765. while (isspace(*s)) ++s;
  766. }
  767. if (!*s) break;
  768. // we're past any leading delimiters and whitespace
  769. result[num] = out;
  770. ++num;
  771. // copy non-delimiters
  772. stb_tokentable[0] = 1;
  773. last_nonwhite = out-1;
  774. if (stripwhite == 2) {
  775. while (!stb_tokentable[*s]) {
  776. if (*s != '"') {
  777. if (!isspace(*s)) last_nonwhite = out;
  778. *out++ = *s++;
  779. } else {
  780. ++s;
  781. if (*s == '"') {
  782. if (!isspace(*s)) last_nonwhite = out;
  783. *out++ = *s++; // "" -> ", not start string
  784. } else {
  785. // begin a quoted string
  786. while (*s) {
  787. if (s[0] == '"') {
  788. if (s[1] == '"') { *out++ = *s; s += 2; }
  789. else { ++s; break; } // terminating "
  790. } else
  791. *out++ = *s++;
  792. }
  793. last_nonwhite = out-1; // all in quotes counts as non-white
  794. }
  795. }
  796. }
  797. } else {
  798. while (nested || !stb_tokentable[*s]) {
  799. if (!isspace(*s)) last_nonwhite = out;
  800. if (stable[*s]) {
  801. if (!*s) break;
  802. if (end ? etable[*s] : nested)
  803. --nested;
  804. else
  805. ++nested;
  806. }
  807. *out++ = *s++;
  808. }
  809. }
  810. if (stripwhite) // rewind to last non-whitespace char
  811. out = last_nonwhite+1;
  812. *out++ = '\0';
  813. if (*s) ++s; // skip delimiter
  814. }
  815. s = (unsigned char *) delimit; while (*s) stb_tokentable[*s++] = 0;
  816. if (start) {
  817. s = (unsigned char *) start; while (*s) stable[*s++] = 1;
  818. s = (unsigned char *) end; if (s) while (*s) stable[*s++] = 1;
  819. s = (unsigned char *) end; if (s) while (*s) etable[*s++] = 1;
  820. }
  821. if (count != NULL) *count = num;
  822. result[num] = 0;
  823. return result;
  824. }
  825. char **stb_tokens(char *src, char *delimit, int *count)
  826. {
  827. return stb_tokens_raw(src,delimit,count,0,0,0,0);
  828. }
  829. char **stb_tokens_nested(char *src, char *delimit, int *count, char *nest_in, char *nest_out)
  830. {
  831. return stb_tokens_raw(src,delimit,count,0,0,nest_in,nest_out);
  832. }
  833. char **stb_tokens_nested_empty(char *src, char *delimit, int *count, char *nest_in, char *nest_out)
  834. {
  835. return stb_tokens_raw(src,delimit,count,0,1,nest_in,nest_out);
  836. }
  837. char **stb_tokens_allowempty(char *src, char *delimit, int *count)
  838. {
  839. return stb_tokens_raw(src,delimit,count,0,1,0,0);
  840. }
  841. char **stb_tokens_stripwhite(char *src, char *delimit, int *count)
  842. {
  843. return stb_tokens_raw(src,delimit,count,1,1,0,0);
  844. }
  845. char **stb_tokens_quoted(char *src, char *delimit, int *count)
  846. {
  847. return stb_tokens_raw(src,delimit,count,2,1,0,0);
  848. }
  849. char *stb_dupreplace(char *src, char *find, char *replace)
  850. {
  851. size_t len_find = strlen(find);
  852. size_t len_replace = strlen(replace);
  853. int count = 0;
  854. char *s,*p,*q;
  855. s = strstr(src, find);
  856. if (s == NULL) return strdup(src);
  857. do {
  858. ++count;
  859. s = strstr(s + len_find, find);
  860. } while (s != NULL);
  861. p = (char *) malloc(strlen(src) + count * (len_replace - len_find) + 1);
  862. if (p == NULL) return p;
  863. q = p;
  864. s = src;
  865. for (;;) {
  866. char *t = strstr(s, find);
  867. if (t == NULL) {
  868. strcpy(q,s);
  869. assert(strlen(p) == strlen(src) + count*(len_replace-len_find));
  870. return p;
  871. }
  872. memcpy(q, s, t-s);
  873. q += t-s;
  874. memcpy(q, replace, len_replace);
  875. q += len_replace;
  876. s = t + len_find;
  877. }
  878. }
  879. void stb_replaceinplace(char *src, char *find, char *replace)
  880. {
  881. size_t len_find = strlen(find);
  882. size_t len_replace = strlen(replace);
  883. int delta;
  884. char *s,*p,*q;
  885. delta = len_replace - len_find;
  886. assert(delta <= 0);
  887. if (delta > 0) return;
  888. p = strstr(src, find);
  889. if (p == NULL) return;
  890. s = q = p;
  891. while (*s) {
  892. memcpy(q, replace, len_replace);
  893. p += len_find;
  894. q += len_replace;
  895. s = strstr(p, find);
  896. if (s == NULL) s = p + strlen(p);
  897. memmove(q, p, s-p);
  898. q += s-p;
  899. p = s;
  900. }
  901. *q = 0;
  902. }
  903. void stb_fixpath(char *path)
  904. {
  905. for(; *path; ++path)
  906. if (*path == '\\')
  907. *path = '/';
  908. }
  909. void stb__add_section(char *buffer, char *data, int curlen, int newlen)
  910. {
  911. if (newlen < curlen) {
  912. int z1 = newlen >> 1, z2 = newlen-z1;
  913. memcpy(buffer, data, z1-1);
  914. buffer[z1-1] = '.';
  915. buffer[z1-0] = '.';
  916. memcpy(buffer+z1+1, data+curlen-z2+1, z2-1);
  917. } else
  918. memcpy(buffer, data, curlen);
  919. }
  920. char * stb_shorten_path_readable(char *path, int len)
  921. {
  922. static char buffer[1024];
  923. int n = strlen(path),n1,n2,r1,r2;
  924. char *s;
  925. if (n <= len) return path;
  926. if (len > 1024) return path;
  927. s = stb_strrchr2(path, '/', '\\');
  928. if (s) {
  929. n1 = s - path + 1;
  930. n2 = n - n1;
  931. ++s;
  932. } else {
  933. n1 = 0;
  934. n2 = n;
  935. s = path;
  936. }
  937. // now we need to reduce r1 and r2 so that they fit in len
  938. if (n1 < len>>1) {
  939. r1 = n1;
  940. r2 = len - r1;
  941. } else if (n2 < len >> 1) {
  942. r2 = n2;
  943. r1 = len - r2;
  944. } else {
  945. r1 = n1 * len / n;
  946. r2 = n2 * len / n;
  947. if (r1 < len>>2) r1 = len>>2, r2 = len-r1;
  948. if (r2 < len>>2) r2 = len>>2, r1 = len-r2;
  949. }
  950. assert(r1 <= n1 && r2 <= n2);
  951. if (n1)
  952. stb__add_section(buffer, path, n1, r1);
  953. stb__add_section(buffer+r1, s, n2, r2);
  954. buffer[len] = 0;
  955. return buffer;
  956. }
  957. static char *stb__splitpath_raw(char *buffer, char *path, int flag)
  958. {
  959. int len=0,x,y, n = (int) strlen(path), f1,f2;
  960. char *s = stb_strrchr2(path, '/', '\\');
  961. char *t = strrchr(path, '.');
  962. if (s && t && t < s) t = NULL;
  963. if (s) ++s;
  964. if (flag == STB_EXT_NO_PERIOD)
  965. flag |= STB_EXT;
  966. if (!(flag & (STB_PATH | STB_FILE | STB_EXT))) return NULL;
  967. f1 = s == NULL ? 0 : s-path; // start of filename
  968. f2 = t == NULL ? n : t-path; // just past end of filename
  969. if (flag & STB_PATH) {
  970. x = 0; if (f1 == 0 && flag == STB_PATH) len=2;
  971. } else if (flag & STB_FILE) {
  972. x = f1;
  973. } else {
  974. x = f2;
  975. if (flag & STB_EXT_NO_PERIOD)
  976. if (buffer[x] == '.')
  977. ++x;
  978. }
  979. if (flag & STB_EXT)
  980. y = n;
  981. else if (flag & STB_FILE)
  982. y = f2;
  983. else
  984. y = f1;
  985. if (buffer == NULL) {
  986. buffer = (char *) malloc(y-x + len + 1);
  987. if (!buffer) return NULL;
  988. }
  989. if (len) { strcpy(buffer, "./"); return buffer; }
  990. strncpy(buffer, path+x, y-x);
  991. buffer[y-x] = 0;
  992. return buffer;
  993. }
  994. char *stb_splitpath(char *output, char *src, int flag)
  995. {
  996. return stb__splitpath_raw(output, src, flag);
  997. }
  998. char *stb_splitpathdup(char *src, int flag)
  999. {
  1000. return stb__splitpath_raw(NULL, src, flag);
  1001. }
  1002. char *stb_replacedir(char *output, char *src, char *dir)
  1003. {
  1004. char buffer[4096];
  1005. stb_splitpath(buffer, src, STB_FILE | STB_EXT);
  1006. if (dir)
  1007. sprintf(output, "%s/%s", dir, buffer);
  1008. else
  1009. strcpy(output, buffer);
  1010. return output;
  1011. }
  1012. char *stb_replaceext(char *output, char *src, char *ext)
  1013. {
  1014. char buffer[4096];
  1015. stb_splitpath(buffer, src, STB_PATH | STB_FILE);
  1016. if (ext)
  1017. sprintf(output, "%s.%s", buffer, ext[0] == '.' ? ext+1 : ext);
  1018. else
  1019. strcpy(output, buffer);
  1020. return output;
  1021. }
  1022. #endif
  1023. //////////////////////////////////////////////////////////////////////////////
  1024. //
  1025. // stb_arr
  1026. //
  1027. // An stb_arr is directly useable as a pointer (use the actual type in your
  1028. // definition), but when it resizes, it returns a new pointer and you can't
  1029. // use the old one, so you have to be careful to copy-in-out as necessary.
  1030. //
  1031. // Use a NULL pointer as a 0-length array.
  1032. //
  1033. // float *my_array = NULL, *temp;
  1034. //
  1035. // // add elements on the end one at a time
  1036. // stb_arr_push(my_array, 0.0f);
  1037. // stb_arr_push(my_array, 1.0f);
  1038. // stb_arr_push(my_array, 2.0f);
  1039. //
  1040. // assert(my_array[1] == 2.0f);
  1041. //
  1042. // // add an uninitialized element at the end, then assign it
  1043. // *stb_arr_add(my_array) = 3.0f;
  1044. //
  1045. // // add three uninitialized elements at the end
  1046. // temp = stb_arr_addn(my_array,3);
  1047. // temp[0] = 4.0f;
  1048. // temp[1] = 5.0f;
  1049. // temp[2] = 6.0f;
  1050. //
  1051. // assert(my_array[5] == 5.0f);
  1052. //
  1053. // // remove the last one
  1054. // stb_arr_pop(my_array);
  1055. //
  1056. // assert(stb_arr_len(my_array) == 6);
  1057. #ifndef STB_INCLUDE_STB_LIB_H
  1058. // simple functions written on top of other functions
  1059. #define stb_arr_empty(a) ( stb_arr_len(a) == 0 )
  1060. #define stb_arr_add(a) ( stb_arr_addn((a),1) )
  1061. #define stb_arr_push(a,v) ( *stb_arr_add(a)=(v) )
  1062. typedef struct
  1063. {
  1064. int len, limit;
  1065. unsigned int signature;
  1066. unsigned int padding; // make it a multiple of 16 so preserve alignment mod 16
  1067. } stb__arr;
  1068. #define stb_arr_signature 0x51bada7b // ends with 0123 in decimal
  1069. // access the header block stored before the data
  1070. #define stb_arrhead(a) /*lint --e(826)*/ (((stb__arr *) (a)) - 1)
  1071. #define stb_arrhead2(a) /*lint --e(826)*/ (((stb__arr *) (a)) - 1)
  1072. #ifdef STB_DEBUG
  1073. #define stb_arr_check(a) assert(!a || stb_arrhead(a)->signature == stb_arr_signature)
  1074. #define stb_arr_check2(a) assert(!a || stb_arrhead2(a)->signature == stb_arr_signature)
  1075. #else
  1076. #define stb_arr_check(a) ((void) 0)
  1077. #define stb_arr_check2(a) ((void) 0)
  1078. #endif
  1079. // ARRAY LENGTH
  1080. // get the array length; special case if pointer is NULL
  1081. #define stb_arr_len(a) (a ? stb_arrhead(a)->len : 0)
  1082. #define stb_arr_len2(a) ((stb__arr *) (a) ? stb_arrhead2(a)->len : 0)
  1083. #define stb_arr_lastn(a) (stb_arr_len(a)-1)
  1084. // check whether a given index is valid -- tests 0 <= i < stb_arr_len(a)
  1085. #define stb_arr_valid(a,i) (a ? (int) (i) < stb_arrhead(a)->len : 0)
  1086. // change the array length so is is exactly N entries long, creating
  1087. // uninitialized entries as needed
  1088. #define stb_arr_setlen(a,n) \
  1089. (stb__arr_setlen((void **) &(a), sizeof(a[0]), (n)))
  1090. // change the array length so that N is a valid index (that is, so
  1091. // it is at least N entries long), creating uninitialized entries as needed
  1092. #define stb_arr_makevalid(a,n) \
  1093. (stb_arr_len(a) < (n)+1 ? stb_arr_setlen(a,(n)+1),(a) : (a))
  1094. // remove the last element of the array, returning it
  1095. #define stb_arr_pop(a) ((stb_arr_check(a), (a))[--stb_arrhead(a)->len])
  1096. // access the last element in the array
  1097. #define stb_arr_last(a) ((stb_arr_check(a), (a))[stb_arr_len(a)-1])
  1098. // is iterator at end of list?
  1099. #define stb_arr_end(a,i) ((i) >= &(a)[stb_arr_len(a)])
  1100. // (internal) change the allocated length of the array
  1101. #define stb_arr__grow(a,n) (stb_arr_check(a), stb_arrhead(a)->len += (n))
  1102. // add N new unitialized elements to the end of the array
  1103. #define stb_arr__addn(a,n) /*lint --e(826)*/ \
  1104. ((stb_arr_len(a)+(n) > stb_arrcurmax(a)) \
  1105. ? (stb__arr_addlen((void **) &(a),sizeof(*a),(n)),0) \
  1106. : ((stb_arr__grow(a,n), 0)))
  1107. // add N new unitialized elements to the end of the array, and return
  1108. // a pointer to the first new one
  1109. #define stb_arr_addn(a,n) (stb_arr__addn((a),n),(a)+stb_arr_len(a)-(n))
  1110. // add N new uninitialized elements starting at index 'i'
  1111. #define stb_arr_insertn(a,i,n) (stb__arr_insertn((void **) &(a), sizeof(*a), i, n))
  1112. // insert an element at i
  1113. #define stb_arr_insert(a,i,v) (stb__arr_insertn((void **) &(a), sizeof(*a), i, 1), ((a)[i] = v))
  1114. // delete N elements from the middle starting at index 'i'
  1115. #define stb_arr_deleten(a,i,n) (stb__arr_deleten((void **) &(a), sizeof(*a), i, n))
  1116. // delete the i'th element
  1117. #define stb_arr_delete(a,i) stb_arr_deleten(a,i,1)
  1118. // delete the i'th element, swapping down from the end
  1119. #define stb_arr_fastdelete(a,i) \
  1120. (stb_swap(&a[i], &a[stb_arrhead(a)->len-1], sizeof(*a)), stb_arr_pop(a))
  1121. // ARRAY STORAGE
  1122. // get the array maximum storage; special case if NULL
  1123. #define stb_arrcurmax(a) (a ? stb_arrhead(a)->limit : 0)
  1124. #define stb_arrcurmax2(a) (a ? stb_arrhead2(a)->limit : 0)
  1125. // set the maxlength of the array to n in anticipation of further growth
  1126. #define stb_arr_setsize(a,n) (stb_arr_check(a), stb__arr_setsize((void **) &(a),sizeof((a)[0]),n))
  1127. // make sure maxlength is large enough for at least N new allocations
  1128. #define stb_arr_atleast(a,n) (stb_arr_len(a)+(n) > stb_arrcurmax(a) \
  1129. ? stb_arr_setsize((a), (n)) : 0)
  1130. // make a copy of a given array (copies contents via 'memcpy'!)
  1131. #define stb_arr_copy(a) stb__arr_copy(a, sizeof((a)[0]))
  1132. // compute the storage needed to store all the elements of the array
  1133. #define stb_arr_storage(a) (stb_arr_len(a) * sizeof((a)[0]))
  1134. #define stb_arr_for(v,arr) for((v)=(arr); (v) < (arr)+stb_arr_len(arr); ++(v))
  1135. // IMPLEMENTATION
  1136. STB_EXTERN void stb_arr_free_(void **p);
  1137. STB_EXTERN void *stb__arr_copy_(void *p, int elem_size);
  1138. STB_EXTERN void stb__arr_setsize_(void **p, int size, int limit);
  1139. STB_EXTERN void stb__arr_setlen_(void **p, int size, int newlen);
  1140. STB_EXTERN void stb__arr_addlen_(void **p, int size, int addlen);
  1141. STB_EXTERN void stb__arr_deleten_(void **p, int size, int loc, int n);
  1142. STB_EXTERN void stb__arr_insertn_(void **p, int size, int loc, int n);
  1143. #define stb_arr_free(p) stb_arr_free_((void **) &(p))
  1144. #ifndef STBLIB_MALLOC_WRAPPER // @Todo
  1145. #define stb__arr_setsize stb__arr_setsize_
  1146. #define stb__arr_setlen stb__arr_setlen_
  1147. #define stb__arr_addlen stb__arr_addlen_
  1148. #define stb__arr_deleten stb__arr_deleten_
  1149. #define stb__arr_insertn stb__arr_insertn_
  1150. #define stb__arr_copy stb__arr_copy_
  1151. #else
  1152. #define stb__arr_addlen(p,s,n) stb__arr_addlen_(p,s,n,__FILE__,__LINE__)
  1153. #define stb__arr_setlen(p,s,n) stb__arr_setlen_(p,s,n,__FILE__,__LINE__)
  1154. #define stb__arr_setsize(p,s,n) stb__arr_setsize_(p,s,n,__FILE__,__LINE__)
  1155. #define stb__arr_deleten(p,s,i,n) stb__arr_deleten_(p,s,i,n,__FILE__,__LINE__)
  1156. #define stb__arr_insertn(p,s,i,n) stb__arr_insertn_(p,s,i,n,__FILE__,__LINE__)
  1157. #define stb__arr_copy(p,s) stb__arr_copy_(p,s,__FILE__,__LINE__)
  1158. #endif
  1159. #endif // STB_INCLUDE_STB_LIB_H
  1160. #ifdef STB_LIB_IMPLEMENTATION
  1161. void stb_arr_malloc(void **target, void *context)
  1162. {
  1163. stb__arr *q = (stb__arr *) malloc(sizeof(*q));
  1164. q->len = q->limit = 0;
  1165. q->signature = stb_arr_signature;
  1166. *target = (void *) (q+1);
  1167. }
  1168. static void * stb__arr_malloc(int size)
  1169. {
  1170. return malloc(size);
  1171. }
  1172. void * stb__arr_copy_(void *p, int elem_size)
  1173. {
  1174. stb__arr *q;
  1175. if (p == NULL) return p;
  1176. q = (stb__arr *) malloc(sizeof(*q) + elem_size * stb_arrhead2(p)->limit);
  1177. stb_arr_check2(p);
  1178. memcpy(q, stb_arrhead2(p), sizeof(*q) + elem_size * stb_arrhead2(p)->len);
  1179. return q+1;
  1180. }
  1181. void stb_arr_free_(void **pp)
  1182. {
  1183. void *p = *pp;
  1184. stb_arr_check2(p);
  1185. if (p) {
  1186. stb__arr *q = stb_arrhead2(p);
  1187. free(q);
  1188. }
  1189. *pp = NULL;
  1190. }
  1191. static void stb__arrsize_(void **pp, int size, int limit, int len)
  1192. {
  1193. void *p = *pp;
  1194. stb__arr *a;
  1195. stb_arr_check2(p);
  1196. if (p == NULL) {
  1197. if (len == 0 && size == 0) return;
  1198. a = (stb__arr *) stb__arr_malloc(sizeof(*a) + size*limit);
  1199. a->limit = limit;
  1200. a->len = len;
  1201. a->signature = stb_arr_signature;
  1202. } else {
  1203. a = stb_arrhead2(p);
  1204. a->len = len;
  1205. if (a->limit < limit) {
  1206. void *p;
  1207. if (a->limit >= 4 && limit < a->limit * 2)
  1208. limit = a->limit * 2;
  1209. p = realloc(a, sizeof(*a) + limit*size);
  1210. if (p) {
  1211. a = (stb__arr *) p;
  1212. a->limit = limit;
  1213. } else {
  1214. // throw an error!
  1215. }
  1216. }
  1217. }
  1218. a->len = a->len < a->limit ? a->len : a->limit;
  1219. *pp = a+1;
  1220. }
  1221. void stb__arr_setsize_(void **pp, int size, int limit)
  1222. {
  1223. void *p = *pp;
  1224. stb_arr_check2(p);
  1225. stb__arrsize_(pp, size, limit, stb_arr_len2(p));
  1226. }
  1227. void stb__arr_setlen_(void **pp, int size, int newlen)
  1228. {
  1229. void *p = *pp;
  1230. stb_arr_check2(p);
  1231. if (stb_arrcurmax2(p) < newlen || p == NULL) {
  1232. stb__arrsize_(pp, size, newlen, newlen);
  1233. } else {
  1234. stb_arrhead2(p)->len = newlen;
  1235. }
  1236. }
  1237. void stb__arr_addlen_(void **p, int size, int addlen)
  1238. {
  1239. stb__arr_setlen_(p, size, stb_arr_len2(*p) + addlen);
  1240. }
  1241. void stb__arr_insertn_(void **pp, int size, int i, int n)
  1242. {
  1243. void *p = *pp;
  1244. if (n) {
  1245. int z;
  1246. if (p == NULL) {
  1247. stb__arr_addlen_(pp, size, n);
  1248. return;
  1249. }
  1250. z = stb_arr_len2(p);
  1251. stb__arr_addlen_(&p, size, n);
  1252. memmove((char *) p + (i+n)*size, (char *) p + i*size, size * (z-i));
  1253. }
  1254. *pp = p;
  1255. }
  1256. void stb__arr_deleten_(void **pp, int size, int i, int n)
  1257. {
  1258. void *p = *pp;
  1259. if (n) {
  1260. memmove((char *) p + i*size, (char *) p + (i+n)*size, size * (stb_arr_len2(p)-(i+n)));
  1261. stb_arrhead2(p)->len -= n;
  1262. }
  1263. *pp = p;
  1264. }
  1265. #endif
  1266. //////////////////////////////////////////////////////////////////////////////
  1267. //
  1268. // Hashing
  1269. //
  1270. // typical use for this is to make a power-of-two hash table.
  1271. //
  1272. // let N = size of table (2^n)
  1273. // let H = stb_hash(str)
  1274. // let S = stb_rehash(H) | 1
  1275. //
  1276. // then hash probe sequence P(i) for i=0..N-1
  1277. // P(i) = (H + S*i) & (N-1)
  1278. //
  1279. // the idea is that H has 32 bits of hash information, but the
  1280. // table has only, say, 2^20 entries so only uses 20 of the bits.
  1281. // then by rehashing the original H we get 2^12 different probe
  1282. // sequences for a given initial probe location. (So it's optimal
  1283. // for 64K tables and its optimality decreases past that.)
  1284. //
  1285. // ok, so I've added something that generates _two separate_
  1286. // 32-bit hashes simultaneously which should scale better to
  1287. // very large tables.
  1288. #ifndef STB_INCLUDE_STB_LIB_H
  1289. STB_EXTERN unsigned int stb_hash(char *str);
  1290. STB_EXTERN unsigned int stb_hashptr(void *p);
  1291. STB_EXTERN unsigned int stb_hashlen(char *str, int len);
  1292. STB_EXTERN unsigned int stb_rehash_improved(unsigned int v);
  1293. STB_EXTERN unsigned int stb_hash_fast(void *p, int len);
  1294. STB_EXTERN unsigned int stb_hash2(char *str, unsigned int *hash2_ptr);
  1295. STB_EXTERN unsigned int stb_hash_number(unsigned int hash);
  1296. #define stb_rehash(x) ((x) + ((x) >> 6) + ((x) >> 19))
  1297. #endif // STB_INCLUDE_STB_LIB_H
  1298. #ifdef STB_LIB_IMPLEMENTATION
  1299. unsigned int stb_hash(char *str)
  1300. {
  1301. unsigned int hash = 0;
  1302. while (*str)
  1303. hash = (hash << 7) + (hash >> 25) + *str++;
  1304. return hash + (hash >> 16);
  1305. }
  1306. unsigned int stb_hashlen(char *str, int len)
  1307. {
  1308. unsigned int hash = 0;
  1309. while (len-- > 0 && *str)
  1310. hash = (hash << 7) + (hash >> 25) + *str++;
  1311. return hash + (hash >> 16);
  1312. }
  1313. unsigned int stb_hashptr(void *p)
  1314. {
  1315. unsigned int x = (unsigned int)(size_t) p;
  1316. // typically lacking in low bits and high bits
  1317. x = stb_rehash(x);
  1318. x += x << 16;
  1319. // pearson's shuffle
  1320. x ^= x << 3;
  1321. x += x >> 5;
  1322. x ^= x << 2;
  1323. x += x >> 15;
  1324. x ^= x << 10;
  1325. return stb_rehash(x);
  1326. }
  1327. unsigned int stb_rehash_improved(unsigned int v)
  1328. {
  1329. return stb_hashptr((void *)(size_t) v);
  1330. }
  1331. unsigned int stb_hash2(char *str, unsigned int *hash2_ptr)
  1332. {
  1333. unsigned int hash1 = 0x3141592c;
  1334. unsigned int hash2 = 0x77f044ed;
  1335. while (*str) {
  1336. hash1 = (hash1 << 7) + (hash1 >> 25) + *str;
  1337. hash2 = (hash2 << 11) + (hash2 >> 21) + *str;
  1338. ++str;
  1339. }
  1340. *hash2_ptr = hash2 + (hash1 >> 16);
  1341. return hash1 + (hash2 >> 16);
  1342. }
  1343. // Paul Hsieh hash
  1344. #define stb__get16_slow(p) ((p)[0] + ((p)[1] << 8))
  1345. #if defined(_MSC_VER)
  1346. #define stb__get16(p) (*((unsigned short *) (p)))
  1347. #else
  1348. #define stb__get16(p) stb__get16_slow(p)
  1349. #endif
  1350. unsigned int stb_hash_fast(void *p, int len)
  1351. {
  1352. unsigned char *q = (unsigned char *) p;
  1353. unsigned int hash = len;
  1354. if (len <= 0 || q == NULL) return 0;
  1355. /* Main loop */
  1356. if (((int)(size_t) q & 1) == 0) {
  1357. for (;len > 3; len -= 4) {
  1358. unsigned int val;
  1359. hash += stb__get16(q);
  1360. val = (stb__get16(q+2) << 11);
  1361. hash = (hash << 16) ^ hash ^ val;
  1362. q += 4;
  1363. hash += hash >> 11;
  1364. }
  1365. } else {
  1366. for (;len > 3; len -= 4) {
  1367. unsigned int val;
  1368. hash += stb__get16_slow(q);
  1369. val = (stb__get16_slow(q+2) << 11);
  1370. hash = (hash << 16) ^ hash ^ val;
  1371. q += 4;
  1372. hash += hash >> 11;
  1373. }
  1374. }
  1375. /* Handle end cases */
  1376. switch (len) {
  1377. case 3: hash += stb__get16_slow(q);
  1378. hash ^= hash << 16;
  1379. hash ^= q[2] << 18;
  1380. hash += hash >> 11;
  1381. break;
  1382. case 2: hash += stb__get16_slow(q);
  1383. hash ^= hash << 11;
  1384. hash += hash >> 17;
  1385. break;
  1386. case 1: hash += q[0];
  1387. hash ^= hash << 10;
  1388. hash += hash >> 1;
  1389. break;
  1390. case 0: break;
  1391. }
  1392. /* Force "avalanching" of final 127 bits */
  1393. hash ^= hash << 3;
  1394. hash += hash >> 5;
  1395. hash ^= hash << 4;
  1396. hash += hash >> 17;
  1397. hash ^= hash << 25;
  1398. hash += hash >> 6;
  1399. return hash;
  1400. }
  1401. unsigned int stb_hash_number(unsigned int hash)
  1402. {
  1403. hash ^= hash << 3;
  1404. hash += hash >> 5;
  1405. hash ^= hash << 4;
  1406. hash += hash >> 17;
  1407. hash ^= hash << 25;
  1408. hash += hash >> 6;
  1409. return hash;
  1410. }
  1411. #endif
  1412. //////////////////////////////////////////////////////////////////////////////
  1413. //
  1414. // Instantiated data structures
  1415. //
  1416. // This is an attempt to implement a templated data structure.
  1417. //
  1418. // Hash table: call stb_define_hash(TYPE,N,KEY,K1,K2,HASH,VALUE)
  1419. // TYPE -- will define a structure type containing the hash table
  1420. // N -- the name, will prefix functions named:
  1421. // N create
  1422. // N destroy
  1423. // N get
  1424. // N set, N add, N update,
  1425. // N remove
  1426. // KEY -- the type of the key. 'x == y' must be valid
  1427. // K1,K2 -- keys never used by the app, used as flags in the hashtable
  1428. // HASH -- a piece of code ending with 'return' that hashes key 'k'
  1429. // VALUE -- the type of the value. 'x = y' must be valid
  1430. //
  1431. // Note that stb_define_hash_base can be used to define more sophisticated
  1432. // hash tables, e.g. those that make copies of the key or use special
  1433. // comparisons (e.g. strcmp).
  1434. #define STB_(prefix,name) stb__##prefix##name
  1435. #define STB__(prefix,name) prefix##name
  1436. #define STB__use(x) x
  1437. #define STB__skip(x)
  1438. #define stb_declare_hash(PREFIX,TYPE,N,KEY,VALUE) \
  1439. typedef struct stb__st_##TYPE TYPE;\
  1440. PREFIX int STB__(N, init)(TYPE *h, int count);\
  1441. PREFIX int STB__(N, memory_usage)(TYPE *h);\
  1442. PREFIX TYPE * STB__(N, create)(void);\
  1443. PREFIX TYPE * STB__(N, copy)(TYPE *h);\
  1444. PREFIX void STB__(N, destroy)(TYPE *h);\
  1445. PREFIX int STB__(N,get_flag)(TYPE *a, KEY k, VALUE *v);\
  1446. PREFIX VALUE STB__(N,get)(TYPE *a, KEY k);\
  1447. PREFIX int STB__(N, set)(TYPE *a, KEY k, VALUE v);\
  1448. PREFIX int STB__(N, add)(TYPE *a, KEY k, VALUE v);\
  1449. PREFIX int STB__(N, update)(TYPE*a,KEY k,VALUE v);\
  1450. PREFIX int STB__(N, remove)(TYPE *a, KEY k, VALUE *v);
  1451. #define STB_nocopy(x) (x)
  1452. #define STB_nodelete(x) 0
  1453. #define STB_nofields
  1454. #define STB_nonullvalue(x)
  1455. #define STB_nullvalue(x) x
  1456. #define STB_safecompare(x) x
  1457. #define STB_nosafe(x)
  1458. #define STB_noprefix
  1459. #ifdef __GNUC__
  1460. #define STB__nogcc(x)
  1461. #else
  1462. #define STB__nogcc(x) x
  1463. #endif
  1464. #define stb_define_hash_base(PREFIX,TYPE,FIELDS,N,NC,LOAD_FACTOR, \
  1465. KEY,EMPTY,DEL,COPY,DISPOSE,SAFE, \
  1466. VCOMPARE,CCOMPARE,HASH, \
  1467. VALUE,HASVNULL,VNULL) \
  1468. \
  1469. typedef struct \
  1470. { \
  1471. KEY k; \
  1472. VALUE v; \
  1473. } STB_(N,_hashpair); \
  1474. \
  1475. STB__nogcc( typedef struct stb__st_##TYPE TYPE; ) \
  1476. struct stb__st_##TYPE { \
  1477. FIELDS \
  1478. STB_(N,_hashpair) *table; \
  1479. unsigned int mask; \
  1480. int count, limit; \
  1481. int deleted; \
  1482. \
  1483. int delete_threshhold; \
  1484. int grow_threshhold; \
  1485. int shrink_threshhold; \
  1486. unsigned char alloced, has_empty, has_del; \
  1487. VALUE ev; VALUE dv; \
  1488. }; \
  1489. \
  1490. static unsigned int STB_(N, hash)(KEY k) \
  1491. { \
  1492. HASH \
  1493. } \
  1494. \
  1495. PREFIX int STB__(N, init)(TYPE *h, int count) \
  1496. { \
  1497. int i; \
  1498. if (count < 4) count = 4; \
  1499. h->limit = count; \
  1500. h->count = 0; \
  1501. h->mask = count-1; \
  1502. h->deleted = 0; \
  1503. h->grow_threshhold = (int) (count * LOAD_FACTOR); \
  1504. h->has_empty = h->has_del = 0; \
  1505. h->alloced = 0; \
  1506. if (count <= 64) \
  1507. h->shrink_threshhold = 0; \
  1508. else \
  1509. h->shrink_threshhold = (int) (count * (LOAD_FACTOR/2.25)); \
  1510. h->delete_threshhold = (int) (count * (1-LOAD_FACTOR)/2); \
  1511. h->table = (STB_(N,_hashpair)*) malloc(sizeof(h->table[0]) * count); \
  1512. if (h->table == NULL) return 0; \
  1513. /* ideally this gets turned into a memset32 automatically */ \
  1514. for (i=0; i < count; ++i) \
  1515. h->table[i].k = EMPTY; \
  1516. return 1; \
  1517. } \
  1518. \
  1519. PREFIX int STB__(N, memory_usage)(TYPE *h) \
  1520. { \
  1521. return sizeof(*h) + h->limit * sizeof(h->table[0]); \
  1522. } \
  1523. \
  1524. PREFIX TYPE * STB__(N, create)(void) \
  1525. { \
  1526. TYPE *h = (TYPE *) malloc(sizeof(*h)); \
  1527. if (h) { \
  1528. if (STB__(N, init)(h, 16)) \
  1529. h->alloced = 1; \
  1530. else { free(h); h=NULL; } \
  1531. } \
  1532. return h; \
  1533. } \
  1534. \
  1535. PREFIX void STB__(N, destroy)(TYPE *a) \
  1536. { \
  1537. int i; \
  1538. for (i=0; i < a->limit; ++i) \
  1539. if (!CCOMPARE(a->table[i].k,EMPTY) && !CCOMPARE(a->table[i].k, DEL)) \
  1540. DISPOSE(a->table[i].k); \
  1541. free(a->table); \
  1542. if (a->alloced) \
  1543. free(a); \
  1544. } \
  1545. \
  1546. static void STB_(N, rehash)(TYPE *a, int count); \
  1547. \
  1548. PREFIX int STB__(N,get_flag)(TYPE *a, KEY k, VALUE *v) \
  1549. { \
  1550. unsigned int h = STB_(N, hash)(k); \
  1551. unsigned int n = h & a->mask, s; \
  1552. if (CCOMPARE(k,EMPTY)){ if (a->has_empty) *v = a->ev; return a->has_empty;}\
  1553. if (CCOMPARE(k,DEL)) { if (a->has_del ) *v = a->dv; return a->has_del; }\
  1554. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  1555. SAFE(if (!CCOMPARE(a->table[n].k,DEL))) \
  1556. if (VCOMPARE(a->table[n].k,k)) { *v = a->table[n].v; return 1; } \
  1557. s = stb_rehash(h) | 1; \
  1558. for(;;) { \
  1559. n = (n + s) & a->mask; \
  1560. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  1561. SAFE(if (CCOMPARE(a->table[n].k,DEL)) continue;) \
  1562. if (VCOMPARE(a->table[n].k,k)) \
  1563. { *v = a->table[n].v; return 1; } \
  1564. } \
  1565. } \
  1566. \
  1567. HASVNULL( \
  1568. PREFIX VALUE STB__(N,get)(TYPE *a, KEY k) \
  1569. { \
  1570. VALUE v; \
  1571. if (STB__(N,get_flag)(a,k,&v)) return v; \
  1572. else return VNULL; \
  1573. } \
  1574. ) \
  1575. \
  1576. PREFIX int STB__(N,getkey)(TYPE *a, KEY k, KEY *kout) \
  1577. { \
  1578. unsigned int h = STB_(N, hash)(k); \
  1579. unsigned int n = h & a->mask, s; \
  1580. if (CCOMPARE(k,EMPTY)||CCOMPARE(k,DEL)) return 0; \
  1581. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  1582. SAFE(if (!CCOMPARE(a->table[n].k,DEL))) \
  1583. if (VCOMPARE(a->table[n].k,k)) { *kout = a->table[n].k; return 1; } \
  1584. s = stb_rehash(h) | 1; \
  1585. for(;;) { \
  1586. n = (n + s) & a->mask; \
  1587. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  1588. SAFE(if (CCOMPARE(a->table[n].k,DEL)) continue;) \
  1589. if (VCOMPARE(a->table[n].k,k)) \
  1590. { *kout = a->table[n].k; return 1; } \
  1591. } \
  1592. } \
  1593. \
  1594. static int STB_(N,addset)(TYPE *a, KEY k, VALUE v, \
  1595. int allow_new, int allow_old, int copy) \
  1596. { \
  1597. unsigned int h = STB_(N, hash)(k); \
  1598. unsigned int n = h & a->mask; \
  1599. int b = -1; \
  1600. if (CCOMPARE(k,EMPTY)) { \
  1601. if (a->has_empty ? allow_old : allow_new) { \
  1602. n=a->has_empty; a->ev = v; a->has_empty = 1; return !n; \
  1603. } else return 0; \
  1604. } \
  1605. if (CCOMPARE(k,DEL)) { \
  1606. if (a->has_del ? allow_old : allow_new) { \
  1607. n=a->has_del; a->dv = v; a->has_del = 1; return !n; \
  1608. } else return 0; \
  1609. } \
  1610. if (!CCOMPARE(a->table[n].k, EMPTY)) { \
  1611. unsigned int s; \
  1612. if (CCOMPARE(a->table[n].k, DEL)) \
  1613. b = n; \
  1614. else if (VCOMPARE(a->table[n].k,k)) { \
  1615. if (allow_old) \
  1616. a->table[n].v = v; \
  1617. return !allow_new; \
  1618. } \
  1619. s = stb_rehash(h) | 1; \
  1620. for(;;) { \
  1621. n = (n + s) & a->mask; \
  1622. if (CCOMPARE(a->table[n].k, EMPTY)) break; \
  1623. if (CCOMPARE(a->table[n].k, DEL)) { \
  1624. if (b < 0) b = n; \
  1625. } else if (VCOMPARE(a->table[n].k,k)) { \
  1626. if (allow_old) \
  1627. a->table[n].v = v; \
  1628. return !allow_new; \
  1629. } \
  1630. } \
  1631. } \
  1632. if (!allow_new) return 0; \
  1633. if (b < 0) b = n; else --a->deleted; \
  1634. a->table[b].k = copy ? COPY(k) : k; \
  1635. a->table[b].v = v; \
  1636. ++a->count; \
  1637. if (a->count > a->grow_threshhold) \
  1638. STB_(N,rehash)(a, a->limit*2); \
  1639. return 1; \
  1640. } \
  1641. \
  1642. PREFIX int STB__(N, set)(TYPE *a, KEY k, VALUE v){return STB_(N,addset)(a,k,v,1,1,1);}\
  1643. PREFIX int STB__(N, add)(TYPE *a, KEY k, VALUE v){return STB_(N,addset)(a,k,v,1,0,1);}\
  1644. PREFIX int STB__(N, update)(TYPE*a,KEY k,VALUE v){return STB_(N,addset)(a,k,v,0,1,1);}\
  1645. \
  1646. PREFIX int STB__(N, remove)(TYPE *a, KEY k, VALUE *v) \
  1647. { \
  1648. unsigned int h = STB_(N, hash)(k); \
  1649. unsigned int n = h & a->mask, s; \
  1650. if (CCOMPARE(k,EMPTY)) { if (a->has_empty) { if(v)*v = a->ev; a->has_empty=0; return 1; } return 0; } \
  1651. if (CCOMPARE(k,DEL)) { if (a->has_del ) { if(v)*v = a->dv; a->has_del =0; return 1; } return 0; } \
  1652. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  1653. if (SAFE(CCOMPARE(a->table[n].k,DEL) || ) !VCOMPARE(a->table[n].k,k)) { \
  1654. s = stb_rehash(h) | 1; \
  1655. for(;;) { \
  1656. n = (n + s) & a->mask; \
  1657. if (CCOMPARE(a->table[n].k,EMPTY)) return 0; \
  1658. SAFE(if (CCOMPARE(a->table[n].k, DEL)) continue;) \
  1659. if (VCOMPARE(a->table[n].k,k)) break; \
  1660. } \
  1661. } \
  1662. DISPOSE(a->table[n].k); \
  1663. a->table[n].k = DEL; \
  1664. --a->count; \
  1665. ++a->deleted; \
  1666. if (v != NULL) \
  1667. *v = a->table[n].v; \
  1668. if (a->count < a->shrink_threshhold) \
  1669. STB_(N, rehash)(a, a->limit >> 1); \
  1670. else if (a->deleted > a->delete_threshhold) \
  1671. STB_(N, rehash)(a, a->limit); \
  1672. return 1; \
  1673. } \
  1674. \
  1675. PREFIX TYPE * STB__(NC, copy)(TYPE *a) \
  1676. { \
  1677. int i; \
  1678. TYPE *h = (TYPE *) malloc(sizeof(*h)); \
  1679. if (!h) return NULL; \
  1680. if (!STB__(N, init)(h, a->limit)) { free(h); return NULL; } \
  1681. h->count = a->count; \
  1682. h->deleted = a->deleted; \
  1683. h->alloced = 1; \
  1684. h->ev = a->ev; h->dv = a->dv; \
  1685. h->has_empty = a->has_empty; h->has_del = a->has_del; \
  1686. memcpy(h->table, a->table, h->limit * sizeof(h->table[0])); \
  1687. for (i=0; i < a->limit; ++i) \
  1688. if (!CCOMPARE(h->table[i].k,EMPTY) && !CCOMPARE(h->table[i].k,DEL)) \
  1689. h->table[i].k = COPY(h->table[i].k); \
  1690. return h; \
  1691. } \
  1692. \
  1693. static void STB_(N, rehash)(TYPE *a, int count) \
  1694. { \
  1695. int i; \
  1696. TYPE b; \
  1697. STB__(N, init)(&b, count); \
  1698. for (i=0; i < a->limit; ++i) \
  1699. if (!CCOMPARE(a->table[i].k,EMPTY) && !CCOMPARE(a->table[i].k,DEL)) \
  1700. STB_(N,addset)(&b, a->table[i].k, a->table[i].v,1,1,0); \
  1701. free(a->table); \
  1702. a->table = b.table; \
  1703. a->mask = b.mask; \
  1704. a->count = b.count; \
  1705. a->limit = b.limit; \
  1706. a->deleted = b.deleted; \
  1707. a->delete_threshhold = b.delete_threshhold; \
  1708. a->grow_threshhold = b.grow_threshhold; \
  1709. a->shrink_threshhold = b.shrink_threshhold; \
  1710. }
  1711. #define STB_equal(a,b) ((a) == (b))
  1712. #define stb_define_hash(TYPE,N,KEY,EMPTY,DEL,HASH,VALUE) \
  1713. stb_define_hash_base(STB_noprefix, TYPE,STB_nofields,N,NC,0.85f, \
  1714. KEY,EMPTY,DEL,STB_nocopy,STB_nodelete,STB_nosafe, \
  1715. STB_equal,STB_equal,HASH, \
  1716. VALUE,STB_nonullvalue,0)
  1717. #define stb_define_hash_vnull(TYPE,N,KEY,EMPTY,DEL,HASH,VALUE,VNULL) \
  1718. stb_define_hash_base(STB_noprefix, TYPE,STB_nofields,N,NC,0.85f, \
  1719. KEY,EMPTY,DEL,STB_nocopy,STB_nodelete,STB_nosafe, \
  1720. STB_equal,STB_equal,HASH, \
  1721. VALUE,STB_nullvalue,VNULL)
  1722. //////////////////////////////////////////////////////////////////////////////
  1723. //
  1724. // stb_ptrmap
  1725. //
  1726. // An stb_ptrmap data structure is an O(1) hash table between pointers. One
  1727. // application is to let you store "extra" data associated with pointers,
  1728. // which is why it was originally called stb_extra.
  1729. #ifndef STB_INCLUDE_STB_LIB_H
  1730. stb_declare_hash(STB_EXTERN, stb_ptrmap, stb_ptrmap_, void *, void *)
  1731. stb_declare_hash(STB_EXTERN, stb_idict, stb_idict_, stb_int32, stb_int32)
  1732. STB_EXTERN void stb_ptrmap_delete(stb_ptrmap *e, void (*free_func)(void *));
  1733. STB_EXTERN stb_ptrmap *stb_ptrmap_new(void);
  1734. STB_EXTERN stb_idict * stb_idict_new_size(unsigned int size);
  1735. STB_EXTERN void stb_idict_remove_all(stb_idict *e);
  1736. #endif // STB_INCLUDE_STB_LIB_H
  1737. #ifdef STB_LIB_IMPLEMENTATION
  1738. #define STB_EMPTY ((void *) 2)
  1739. #define STB_EDEL ((void *) 6)
  1740. stb_define_hash_base(STB_noprefix,stb_ptrmap, STB_nofields, stb_ptrmap_,stb_ptrmap_,0.85f,
  1741. void *,STB_EMPTY,STB_EDEL,STB_nocopy,STB_nodelete,STB_nosafe,
  1742. STB_equal,STB_equal,return stb_hashptr(k);,
  1743. void *,STB_nullvalue,NULL)
  1744. stb_ptrmap *stb_ptrmap_new(void)
  1745. {
  1746. return stb_ptrmap_create();
  1747. }
  1748. void stb_ptrmap_delete(stb_ptrmap *e, void (*free_func)(void *))
  1749. {
  1750. int i;
  1751. if (free_func)
  1752. for (i=0; i < e->limit; ++i)
  1753. if (e->table[i].k != STB_EMPTY && e->table[i].k != STB_EDEL) {
  1754. if (free_func == free)
  1755. free(e->table[i].v); // allow STB_MALLOC_WRAPPER to operate
  1756. else
  1757. free_func(e->table[i].v);
  1758. }
  1759. stb_ptrmap_destroy(e);
  1760. }
  1761. // extra fields needed for stua_dict
  1762. #define STB_IEMPTY ((int) 1)
  1763. #define STB_IDEL ((int) 3)
  1764. stb_define_hash_base(STB_noprefix, stb_idict, STB_nofields, stb_idict_,stb_idict_,0.85f,
  1765. stb_int32,STB_IEMPTY,STB_IDEL,STB_nocopy,STB_nodelete,STB_nosafe,
  1766. STB_equal,STB_equal,
  1767. return stb_rehash_improved(k);,stb_int32,STB_nonullvalue,0)
  1768. stb_idict * stb_idict_new_size(unsigned int size)
  1769. {
  1770. stb_idict *e = (stb_idict *) malloc(sizeof(*e));
  1771. if (e) {
  1772. // round up to power of 2
  1773. while ((size & (size-1)) != 0) // while more than 1 bit is set
  1774. size += (size & ~(size-1)); // add the lowest set bit
  1775. stb_idict_init(e, size);
  1776. e->alloced = 1;
  1777. }
  1778. return e;
  1779. }
  1780. void stb_idict_remove_all(stb_idict *e)
  1781. {
  1782. int n;
  1783. for (n=0; n < e->limit; ++n)
  1784. e->table[n].k = STB_IEMPTY;
  1785. e->has_empty = e->has_del = 0;
  1786. }
  1787. #endif
  1788. //////////////////////////////////////////////////////////////////////////////
  1789. //
  1790. // SDICT: Hash Table for Strings (symbol table)
  1791. //
  1792. // if "use_arena=1", then strings will be copied
  1793. // into blocks and never freed until the sdict is freed;
  1794. // otherwise they're malloc()ed and free()d on the fly.
  1795. // (specify use_arena=1 if you never stb_sdict_remove)
  1796. #ifndef STB_INCLUDE_STB_LIB_H
  1797. stb_declare_hash(STB_EXTERN, stb_sdict, stb_sdict_, char *, void *)
  1798. STB_EXTERN stb_sdict * stb_sdict_new(void);
  1799. STB_EXTERN stb_sdict * stb_sdict_copy(stb_sdict*);
  1800. STB_EXTERN void stb_sdict_delete(stb_sdict *);
  1801. STB_EXTERN void * stb_sdict_change(stb_sdict *, char *str, void *p);
  1802. STB_EXTERN int stb_sdict_count(stb_sdict *d);
  1803. STB_EXTERN int stb_sdict_internal_limit(stb_sdict *d);
  1804. STB_EXTERN char * stb_sdict_internal_key(stb_sdict *d, int n);
  1805. STB_EXTERN void * stb_sdict_internal_value(stb_sdict *d, int n);
  1806. #define stb_sdict_for(d,i,q,z) \
  1807. 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) \
  1808. if (q==NULL||q==(void *) 1);else // reversed makes macro friendly
  1809. #endif // STB_INCLUDE_STB_LIB_H
  1810. #ifdef STB_LIB_IMPLEMENTATION
  1811. // if in same translation unit, for speed, don't call accessors
  1812. #undef stb_sdict_for
  1813. #define stb_sdict_for(d,i,q,z) \
  1814. for(i=0; i < (d)->limit ? (q=(d)->table[i].k,z=(d)->table[i].v,1) : 0; ++i) \
  1815. if (q==NULL||q==(void *) 1);else // reversed makes macro friendly
  1816. //#define STB_DEL ((void *) 1)
  1817. #define STB_SDEL ((char *) 1)
  1818. stb_define_hash_base(STB_noprefix, stb_sdict, STB_nofields, stb_sdict_,stb_sdictinternal_, 0.85f,
  1819. char *, NULL, STB_SDEL, strdup, free,
  1820. STB_safecompare, !strcmp, STB_equal, return stb_hash(k);,
  1821. void *, STB_nullvalue, NULL)
  1822. int stb_sdict_count(stb_sdict *a)
  1823. {
  1824. return a->count;
  1825. }
  1826. int stb_sdict_internal_limit(stb_sdict *a)
  1827. {
  1828. return a->limit;
  1829. }
  1830. char* stb_sdict_internal_key(stb_sdict *a, int n)
  1831. {
  1832. return a->table[n].k;
  1833. }
  1834. void* stb_sdict_internal_value(stb_sdict *a, int n)
  1835. {
  1836. return a->table[n].v;
  1837. }
  1838. stb_sdict * stb_sdict_new(void)
  1839. {
  1840. stb_sdict *d = stb_sdict_create();
  1841. if (d == NULL) return NULL;
  1842. return d;
  1843. }
  1844. stb_sdict* stb_sdict_copy(stb_sdict *old)
  1845. {
  1846. return stb_sdictinternal_copy(old);
  1847. }
  1848. void stb_sdict_delete(stb_sdict *d)
  1849. {
  1850. stb_sdict_destroy(d);
  1851. }
  1852. void * stb_sdict_change(stb_sdict *d, char *str, void *p)
  1853. {
  1854. void *q = stb_sdict_get(d, str);
  1855. stb_sdict_set(d, str, p);
  1856. return q;
  1857. }
  1858. #endif
  1859. //////////////////////////////////////////////////////////////////////////////
  1860. //
  1861. // File Processing
  1862. //
  1863. #ifndef STB_INCLUDE_STB_LIB_H
  1864. #ifdef _MSC_VER
  1865. #define stb_rename(x,y) _wrename((const wchar_t *)stb__from_utf8(x), (const wchar_t *)stb__from_utf8_alt(y))
  1866. #define stb_mktemp _mktemp
  1867. #else
  1868. #define stb_mktemp mktemp
  1869. #define stb_rename rename
  1870. #endif
  1871. #define stb_filec (char *) stb_file
  1872. #define stb_fileu (unsigned char *) stb_file
  1873. STB_EXTERN void * stb_file(char *filename, size_t *length);
  1874. STB_EXTERN size_t stb_filelen(FILE *f);
  1875. STB_EXTERN int stb_filewrite(char *filename, void *data, size_t length);
  1876. STB_EXTERN int stb_filewritestr(char *filename, char *data);
  1877. STB_EXTERN char ** stb_stringfile(char *filename, int *len);
  1878. STB_EXTERN char * stb_fgets(char *buffer, int buflen, FILE *f);
  1879. STB_EXTERN char * stb_fgets_malloc(FILE *f);
  1880. STB_EXTERN int stb_fexists(char *filename);
  1881. STB_EXTERN int stb_fcmp(char *s1, char *s2);
  1882. STB_EXTERN int stb_feq(char *s1, char *s2);
  1883. STB_EXTERN time_t stb_ftimestamp(char *filename);
  1884. STB_EXTERN int stb_fullpath(char *abs, int abs_size, char *rel);
  1885. STB_EXTERN int stb_copyfile(char *src, char *dest);
  1886. STB_EXTERN int stb_fread(void *data, size_t len, size_t count, void *f);
  1887. STB_EXTERN int stb_fwrite(void *data, size_t len, size_t count, void *f);
  1888. #endif // STB_INCLUDE_STB_LIB_H
  1889. #ifdef STB_LIB_IMPLEMENTATION
  1890. #if defined(_MSC_VER) || defined(__MINGW32__)
  1891. #define stb__stat _stat
  1892. #else
  1893. #define stb__stat stat
  1894. #endif
  1895. int stb_fexists(char *filename)
  1896. {
  1897. struct stb__stat buf;
  1898. return stb__windows(
  1899. _wstat((const wchar_t *)stb__from_utf8(filename), &buf),
  1900. stat(filename,&buf)
  1901. ) == 0;
  1902. }
  1903. time_t stb_ftimestamp(char *filename)
  1904. {
  1905. struct stb__stat buf;
  1906. if (stb__windows(
  1907. _wstat((const wchar_t *)stb__from_utf8(filename), &buf),
  1908. stat(filename,&buf)
  1909. ) == 0)
  1910. {
  1911. return buf.st_mtime;
  1912. } else {
  1913. return 0;
  1914. }
  1915. }
  1916. size_t stb_filelen(FILE *f)
  1917. {
  1918. size_t len, pos;
  1919. pos = ftell(f);
  1920. fseek(f, 0, SEEK_END);
  1921. len = ftell(f);
  1922. fseek(f, pos, SEEK_SET);
  1923. return len;
  1924. }
  1925. void *stb_file(char *filename, size_t *length)
  1926. {
  1927. FILE *f = stb__fopen(filename, "rb");
  1928. char *buffer;
  1929. size_t len, len2;
  1930. if (!f) return NULL;
  1931. len = stb_filelen(f);
  1932. buffer = (char *) malloc(len+2); // nul + extra
  1933. len2 = fread(buffer, 1, len, f);
  1934. if (len2 == len) {
  1935. if (length) *length = len;
  1936. buffer[len] = 0;
  1937. } else {
  1938. free(buffer);
  1939. buffer = NULL;
  1940. }
  1941. fclose(f);
  1942. return buffer;
  1943. }
  1944. int stb_filewrite(char *filename, void *data, size_t length)
  1945. {
  1946. FILE *f = stb__fopen(filename, "wb");
  1947. if (f) {
  1948. unsigned char *data_ptr = (unsigned char *) data;
  1949. size_t remaining = length;
  1950. while (remaining > 0) {
  1951. size_t len2 = remaining > 65536 ? 65536 : remaining;
  1952. size_t len3 = fwrite(data_ptr, 1, len2, f);
  1953. if (len2 != len3) {
  1954. fprintf(stderr, "Failed while writing %s\n", filename);
  1955. break;
  1956. }
  1957. remaining -= len2;
  1958. data_ptr += len2;
  1959. }
  1960. fclose(f);
  1961. }
  1962. return f != NULL;
  1963. }
  1964. int stb_filewritestr(char *filename, char *data)
  1965. {
  1966. return stb_filewrite(filename, data, strlen(data));
  1967. }
  1968. char ** stb_stringfile(char *filename, int *plen)
  1969. {
  1970. FILE *f = stb__fopen(filename, "rb");
  1971. char *buffer, **list=NULL, *s;
  1972. size_t len, count, i;
  1973. if (!f) return NULL;
  1974. len = stb_filelen(f);
  1975. buffer = (char *) malloc(len+1);
  1976. len = fread(buffer, 1, len, f);
  1977. buffer[len] = 0;
  1978. fclose(f);
  1979. // two passes through: first time count lines, second time set them
  1980. for (i=0; i < 2; ++i) {
  1981. s = buffer;
  1982. if (i == 1)
  1983. list[0] = s;
  1984. count = 1;
  1985. while (*s) {
  1986. if (*s == '\n' || *s == '\r') {
  1987. // detect if both cr & lf are together
  1988. int crlf = (s[0] + s[1]) == ('\n' + '\r');
  1989. if (i == 1) *s = 0;
  1990. if (crlf) ++s;
  1991. if (s[1]) { // it's not over yet
  1992. if (i == 1) list[count] = s+1;
  1993. ++count;
  1994. }
  1995. }
  1996. ++s;
  1997. }
  1998. if (i == 0) {
  1999. list = (char **) malloc(sizeof(*list) * (count+1) + len+1);
  2000. if (!list) return NULL;
  2001. list[count] = 0;
  2002. // recopy the file so there's just a single allocation to free
  2003. memcpy(&list[count+1], buffer, len+1);
  2004. free(buffer);
  2005. buffer = (char *) &list[count+1];
  2006. if (plen) *plen = count;
  2007. }
  2008. }
  2009. return list;
  2010. }
  2011. char * stb_fgets(char *buffer, int buflen, FILE *f)
  2012. {
  2013. char *p;
  2014. buffer[0] = 0;
  2015. p = fgets(buffer, buflen, f);
  2016. if (p) {
  2017. int n = strlen(p)-1;
  2018. if (n >= 0)
  2019. if (p[n] == '\n')
  2020. p[n] = 0;
  2021. }
  2022. return p;
  2023. }
  2024. char * stb_fgets_malloc(FILE *f)
  2025. {
  2026. // avoid reallocing for small strings
  2027. char quick_buffer[800];
  2028. quick_buffer[sizeof(quick_buffer)-2] = 0;
  2029. if (!fgets(quick_buffer, sizeof(quick_buffer), f))
  2030. return NULL;
  2031. if (quick_buffer[sizeof(quick_buffer)-2] == 0) {
  2032. int n = strlen(quick_buffer);
  2033. if (n > 0 && quick_buffer[n-1] == '\n')
  2034. quick_buffer[n-1] = 0;
  2035. return strdup(quick_buffer);
  2036. } else {
  2037. char *p;
  2038. char *a = strdup(quick_buffer);
  2039. int len = sizeof(quick_buffer)-1;
  2040. while (!feof(f)) {
  2041. if (a[len-1] == '\n') break;
  2042. a = (char *) realloc(a, len*2);
  2043. p = &a[len];
  2044. p[len-2] = 0;
  2045. if (!fgets(p, len, f))
  2046. break;
  2047. if (p[len-2] == 0) {
  2048. len += strlen(p);
  2049. break;
  2050. }
  2051. len = len + (len-1);
  2052. }
  2053. if (a[len-1] == '\n')
  2054. a[len-1] = 0;
  2055. return a;
  2056. }
  2057. }
  2058. int stb_fullpath(char *abs, int abs_size, char *rel)
  2059. {
  2060. #ifdef _MSC_VER
  2061. return _fullpath(abs, rel, abs_size) != NULL;
  2062. #else
  2063. if (rel[0] == '/' || rel[0] == '~') {
  2064. if ((int) strlen(rel) >= abs_size)
  2065. return 0;
  2066. strcpy(abs,rel);
  2067. return 1;
  2068. } else {
  2069. int n;
  2070. getcwd(abs, abs_size);
  2071. n = strlen(abs);
  2072. if (n+(int) strlen(rel)+2 <= abs_size) {
  2073. abs[n] = '/';
  2074. strcpy(abs+n+1, rel);
  2075. return 1;
  2076. } else {
  2077. return 0;
  2078. }
  2079. }
  2080. #endif
  2081. }
  2082. static int stb_fcmp_core(FILE *f, FILE *g)
  2083. {
  2084. char buf1[1024],buf2[1024];
  2085. int n1,n2, res=0;
  2086. while (1) {
  2087. n1 = fread(buf1, 1, sizeof(buf1), f);
  2088. n2 = fread(buf2, 1, sizeof(buf2), g);
  2089. res = memcmp(buf1,buf2,n1 < n2 ? n1 : n2);
  2090. if (res)
  2091. break;
  2092. if (n1 != n2) {
  2093. res = n1 < n2 ? -1 : 1;
  2094. break;
  2095. }
  2096. if (n1 == 0)
  2097. break;
  2098. }
  2099. fclose(f);
  2100. fclose(g);
  2101. return res;
  2102. }
  2103. int stb_fcmp(char *s1, char *s2)
  2104. {
  2105. FILE *f = stb__fopen(s1, "rb");
  2106. FILE *g = stb__fopen(s2, "rb");
  2107. if (f == NULL || g == NULL) {
  2108. if (f) fclose(f);
  2109. if (g) {
  2110. fclose(g);
  2111. return 1;
  2112. }
  2113. return f != NULL;
  2114. }
  2115. return stb_fcmp_core(f,g);
  2116. }
  2117. int stb_feq(char *s1, char *s2)
  2118. {
  2119. FILE *f = stb__fopen(s1, "rb");
  2120. FILE *g = stb__fopen(s2, "rb");
  2121. if (f == NULL || g == NULL) {
  2122. if (f) fclose(f);
  2123. if (g) fclose(g);
  2124. return f == g;
  2125. }
  2126. // feq is faster because it shortcuts if they're different length
  2127. if (stb_filelen(f) != stb_filelen(g)) {
  2128. fclose(f);
  2129. fclose(g);
  2130. return 0;
  2131. }
  2132. return !stb_fcmp_core(f,g);
  2133. }
  2134. int stb_copyfile(char *src, char *dest)
  2135. {
  2136. char raw_buffer[1024];
  2137. char *buffer;
  2138. int buf_size = 65536;
  2139. FILE *f, *g;
  2140. // if file already exists at destination, do nothing
  2141. if (stb_feq(src, dest)) return 1;
  2142. // open file
  2143. f = stb__fopen(src, "rb");
  2144. if (f == NULL) return 0;
  2145. // open file for writing
  2146. g = stb__fopen(dest, "wb");
  2147. if (g == NULL) {
  2148. fclose(f);
  2149. return 0;
  2150. }
  2151. buffer = (char *) malloc(buf_size);
  2152. if (buffer == NULL) {
  2153. buffer = raw_buffer;
  2154. buf_size = sizeof(raw_buffer);
  2155. }
  2156. while (!feof(f)) {
  2157. int n = fread(buffer, 1, buf_size, f);
  2158. if (n != 0)
  2159. fwrite(buffer, 1, n, g);
  2160. }
  2161. fclose(f);
  2162. if (buffer != raw_buffer)
  2163. free(buffer);
  2164. fclose(g);
  2165. return 1;
  2166. }
  2167. #define stb_fgetc(f) ((unsigned char) fgetc(f))
  2168. #if 0
  2169. // strip the trailing '/' or '\\' from a directory so we can refer to it
  2170. // as a file for _stat()
  2171. char *stb_strip_final_slash(char *t)
  2172. {
  2173. if (t[0]) {
  2174. char *z = t + strlen(t) - 1;
  2175. // *z is the last character
  2176. if (*z == '\\' || *z == '/')
  2177. if (z != t+2 || t[1] != ':') // but don't strip it if it's e.g. "c:/"
  2178. *z = 0;
  2179. if (*z == '\\')
  2180. *z = '/'; // canonicalize to make sure it matches db
  2181. }
  2182. return t;
  2183. }
  2184. char *stb_strip_final_slash_regardless(char *t)
  2185. {
  2186. if (t[0]) {
  2187. char *z = t + strlen(t) - 1;
  2188. // *z is the last character
  2189. if (*z == '\\' || *z == '/')
  2190. *z = 0;
  2191. if (*z == '\\')
  2192. *z = '/'; // canonicalize to make sure it matches db
  2193. }
  2194. return t;
  2195. }
  2196. #endif
  2197. #endif
  2198. //////////////////////////////////////////////////////////////////////////////
  2199. //
  2200. // Portable directory reading
  2201. //
  2202. #ifndef STB_INCLUDE_STB_LIB_H
  2203. STB_EXTERN char **stb_readdir_files (char *dir);
  2204. STB_EXTERN char **stb_readdir_files_mask(char *dir, char *wild);
  2205. STB_EXTERN char **stb_readdir_subdirs(char *dir);
  2206. STB_EXTERN char **stb_readdir_subdirs_mask(char *dir, char *wild);
  2207. STB_EXTERN void stb_readdir_free (char **files);
  2208. STB_EXTERN char **stb_readdir_recursive(char *dir, char *filespec);
  2209. STB_EXTERN void stb_delete_directory_recursive(char *dir);
  2210. // forward declare for implementation
  2211. STB_EXTERN int stb_wildmatchi(char *expr, char *candidate);
  2212. #endif // STB_INCLUDE_STB_LIB_H
  2213. #ifdef STB_LIB_IMPLEMENTATION
  2214. #ifdef _MSC_VER
  2215. #include <io.h>
  2216. #else
  2217. #include <unistd.h>
  2218. #include <dirent.h>
  2219. #endif
  2220. void stb_readdir_free(char **files)
  2221. {
  2222. char **f2 = files;
  2223. int i;
  2224. for (i=0; i < stb_arr_len(f2); ++i)
  2225. free(f2[i]);
  2226. stb_arr_free(f2);
  2227. }
  2228. static int isdotdirname(char *name)
  2229. {
  2230. if (name[0] == '.')
  2231. return (name[1] == '.') ? !name[2] : !name[1];
  2232. return 0;
  2233. }
  2234. static char **readdir_raw(char *dir, int return_subdirs, char *mask)
  2235. {
  2236. char **results = NULL;
  2237. char buffer[4096], with_slash[4096];
  2238. size_t n;
  2239. #ifdef _MSC_VER
  2240. stb__wchar *ws;
  2241. struct _wfinddata_t data;
  2242. #ifdef _WIN64
  2243. const intptr_t none = -1;
  2244. intptr_t z;
  2245. #else
  2246. const long none = -1;
  2247. long z;
  2248. #endif
  2249. #else // !_MSC_VER
  2250. const DIR *none = NULL;
  2251. DIR *z;
  2252. #endif
  2253. n = stb_strscpy(buffer,dir,sizeof(buffer));
  2254. if (!n || n >= sizeof(buffer))
  2255. return NULL;
  2256. stb_fixpath(buffer);
  2257. n--;
  2258. if (n > 0 && (buffer[n-1] != '/')) {
  2259. buffer[n++] = '/';
  2260. }
  2261. buffer[n] = 0;
  2262. if (!stb_strscpy(with_slash,buffer,sizeof(with_slash)))
  2263. return NULL;
  2264. #ifdef _MSC_VER
  2265. if (!stb_strscpy(buffer+n,"*.*",sizeof(buffer)-n))
  2266. return NULL;
  2267. ws = stb__from_utf8(buffer);
  2268. z = _wfindfirst((const wchar_t *)ws, &data);
  2269. #else
  2270. z = opendir(dir);
  2271. #endif
  2272. if (z != none) {
  2273. int nonempty = 1;
  2274. #ifndef _MSC_VER
  2275. struct dirent *data = readdir(z);
  2276. nonempty = (data != NULL);
  2277. #endif
  2278. if (nonempty) {
  2279. do {
  2280. int is_subdir;
  2281. #ifdef _MSC_VER
  2282. char *name = stb__to_utf8((stb__wchar *)data.name);
  2283. if (name == NULL) {
  2284. fprintf(stderr, "%s to convert '%S' to %s!\n", "Unable", data.name, "utf8");
  2285. continue;
  2286. }
  2287. is_subdir = !!(data.attrib & _A_SUBDIR);
  2288. #else
  2289. char *name = data->d_name;
  2290. if (!stb_strscpy(buffer+n,name,sizeof(buffer)-n))
  2291. break;
  2292. // Could follow DT_LNK, but would need to check for recursive links.
  2293. is_subdir = !!(data->d_type & DT_DIR);
  2294. #endif
  2295. if (is_subdir == return_subdirs) {
  2296. if (!is_subdir || !isdotdirname(name)) {
  2297. if (!mask || stb_wildmatchi(mask, name)) {
  2298. char buffer[4096],*p=buffer;
  2299. if ( stb_snprintf(buffer, sizeof(buffer), "%s%s", with_slash, name) < 0 )
  2300. break;
  2301. if (buffer[0] == '.' && buffer[1] == '/')
  2302. p = buffer+2;
  2303. stb_arr_push(results, strdup(p));
  2304. }
  2305. }
  2306. }
  2307. }
  2308. #ifdef _MSC_VER
  2309. while (0 == _wfindnext(z, &data));
  2310. #else
  2311. while ((data = readdir(z)) != NULL);
  2312. #endif
  2313. }
  2314. #ifdef _MSC_VER
  2315. _findclose(z);
  2316. #else
  2317. closedir(z);
  2318. #endif
  2319. }
  2320. return results;
  2321. }
  2322. char **stb_readdir_files (char *dir) { return readdir_raw(dir, 0, NULL); }
  2323. char **stb_readdir_subdirs(char *dir) { return readdir_raw(dir, 1, NULL); }
  2324. char **stb_readdir_files_mask(char *dir, char *wild) { return readdir_raw(dir, 0, wild); }
  2325. char **stb_readdir_subdirs_mask(char *dir, char *wild) { return readdir_raw(dir, 1, wild); }
  2326. int stb__rec_max=0x7fffffff;
  2327. static char **stb_readdir_rec(char **sofar, char *dir, char *filespec)
  2328. {
  2329. char **files;
  2330. char ** dirs;
  2331. char **p;
  2332. if (stb_arr_len(sofar) >= stb__rec_max) return sofar;
  2333. files = stb_readdir_files_mask(dir, filespec);
  2334. stb_arr_for(p, files) {
  2335. stb_arr_push(sofar, strdup(*p));
  2336. if (stb_arr_len(sofar) >= stb__rec_max) break;
  2337. }
  2338. stb_readdir_free(files);
  2339. if (stb_arr_len(sofar) >= stb__rec_max) return sofar;
  2340. dirs = stb_readdir_subdirs(dir);
  2341. stb_arr_for(p, dirs)
  2342. sofar = stb_readdir_rec(sofar, *p, filespec);
  2343. stb_readdir_free(dirs);
  2344. return sofar;
  2345. }
  2346. char **stb_readdir_recursive(char *dir, char *filespec)
  2347. {
  2348. return stb_readdir_rec(NULL, dir, filespec);
  2349. }
  2350. void stb_delete_directory_recursive(char *dir)
  2351. {
  2352. char **list = stb_readdir_subdirs(dir);
  2353. int i;
  2354. for (i=0; i < stb_arr_len(list); ++i)
  2355. stb_delete_directory_recursive(list[i]);
  2356. stb_arr_free(list);
  2357. list = stb_readdir_files(dir);
  2358. for (i=0; i < stb_arr_len(list); ++i)
  2359. if (!remove(list[i])) {
  2360. // on windows, try again after making it writeable; don't ALWAYS
  2361. // do this first since that would be slow in the normal case
  2362. #ifdef _MSC_VER
  2363. _chmod(list[i], _S_IWRITE);
  2364. remove(list[i]);
  2365. #endif
  2366. }
  2367. stb_arr_free(list);
  2368. stb__windows(_rmdir,rmdir)(dir);
  2369. }
  2370. #endif
  2371. //////////////////////////////////////////////////////////////////////////////
  2372. //
  2373. // Checksums: CRC-32, ADLER32, SHA-1
  2374. //
  2375. // CRC-32 and ADLER32 allow streaming blocks
  2376. // SHA-1 requires either a complete buffer, max size 2^32 - 73
  2377. // or it can checksum directly from a file, max 2^61
  2378. #ifndef STB_INCLUDE_STB_LIB_H
  2379. #define STB_ADLER32_SEED 1
  2380. #define STB_CRC32_SEED 0 // note that we logical NOT this in the code
  2381. STB_EXTERN stb_uint stb_adler32 (stb_uint adler32, stb_uchar *buffer, stb_uint buflen);
  2382. STB_EXTERN stb_uint stb_crc32_block(stb_uint crc32 , stb_uchar *buffer, stb_uint buflen);
  2383. STB_EXTERN stb_uint stb_crc32 ( stb_uchar *buffer, stb_uint buflen);
  2384. STB_EXTERN void stb_sha1( unsigned char output[20], stb_uchar *buffer, unsigned int len);
  2385. STB_EXTERN int stb_sha1_file(unsigned char output[20], char *file);
  2386. #endif // STB_INCLUDE_STB_LIB_H
  2387. #ifdef STB_LIB_IMPLEMENTATION
  2388. stb_uint stb_crc32_block(stb_uint crc, unsigned char *buffer, stb_uint len)
  2389. {
  2390. static stb_uint crc_table[256];
  2391. stb_uint i,j,s;
  2392. crc = ~crc;
  2393. if (crc_table[1] == 0)
  2394. for(i=0; i < 256; i++) {
  2395. for (s=i, j=0; j < 8; ++j)
  2396. s = (s >> 1) ^ (s & 1 ? 0xedb88320 : 0);
  2397. crc_table[i] = s;
  2398. }
  2399. for (i=0; i < len; ++i)
  2400. crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
  2401. return ~crc;
  2402. }
  2403. stb_uint stb_crc32(unsigned char *buffer, stb_uint len)
  2404. {
  2405. return stb_crc32_block(0, buffer, len);
  2406. }
  2407. stb_uint stb_adler32(stb_uint adler32, stb_uchar *buffer, stb_uint buflen)
  2408. {
  2409. const unsigned long ADLER_MOD = 65521;
  2410. unsigned long s1 = adler32 & 0xffff, s2 = adler32 >> 16;
  2411. unsigned long blocklen, i;
  2412. blocklen = buflen % 5552;
  2413. while (buflen) {
  2414. for (i=0; i + 7 < blocklen; i += 8) {
  2415. s1 += buffer[0], s2 += s1;
  2416. s1 += buffer[1], s2 += s1;
  2417. s1 += buffer[2], s2 += s1;
  2418. s1 += buffer[3], s2 += s1;
  2419. s1 += buffer[4], s2 += s1;
  2420. s1 += buffer[5], s2 += s1;
  2421. s1 += buffer[6], s2 += s1;
  2422. s1 += buffer[7], s2 += s1;
  2423. buffer += 8;
  2424. }
  2425. for (; i < blocklen; ++i)
  2426. s1 += *buffer++, s2 += s1;
  2427. s1 %= ADLER_MOD, s2 %= ADLER_MOD;
  2428. buflen -= blocklen;
  2429. blocklen = 5552;
  2430. }
  2431. return (s2 << 16) + s1;
  2432. }
  2433. #define stb__big32(c) (((c)[0]<<24) + (c)[1]*65536 + (c)[2]*256 + (c)[3])
  2434. static void stb__sha1(stb_uchar *chunk, stb_uint h[5])
  2435. {
  2436. int i;
  2437. stb_uint a,b,c,d,e;
  2438. stb_uint w[80];
  2439. for (i=0; i < 16; ++i)
  2440. w[i] = stb__big32(&chunk[i*4]);
  2441. for (i=16; i < 80; ++i) {
  2442. stb_uint t;
  2443. t = w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16];
  2444. w[i] = (t + t) | (t >> 31);
  2445. }
  2446. a = h[0];
  2447. b = h[1];
  2448. c = h[2];
  2449. d = h[3];
  2450. e = h[4];
  2451. #define STB__SHA1(k,f) \
  2452. { \
  2453. stb_uint temp = (a << 5) + (a >> 27) + (f) + e + (k) + w[i]; \
  2454. e = d; \
  2455. d = c; \
  2456. c = (b << 30) + (b >> 2); \
  2457. b = a; \
  2458. a = temp; \
  2459. }
  2460. i=0;
  2461. for (; i < 20; ++i) STB__SHA1(0x5a827999, d ^ (b & (c ^ d)) );
  2462. for (; i < 40; ++i) STB__SHA1(0x6ed9eba1, b ^ c ^ d );
  2463. for (; i < 60; ++i) STB__SHA1(0x8f1bbcdc, (b & c) + (d & (b ^ c)) );
  2464. for (; i < 80; ++i) STB__SHA1(0xca62c1d6, b ^ c ^ d );
  2465. #undef STB__SHA1
  2466. h[0] += a;
  2467. h[1] += b;
  2468. h[2] += c;
  2469. h[3] += d;
  2470. h[4] += e;
  2471. }
  2472. void stb_sha1(stb_uchar output[20], stb_uchar *buffer, stb_uint len)
  2473. {
  2474. unsigned char final_block[128];
  2475. stb_uint end_start, final_len, j;
  2476. int i;
  2477. stb_uint h[5];
  2478. h[0] = 0x67452301;
  2479. h[1] = 0xefcdab89;
  2480. h[2] = 0x98badcfe;
  2481. h[3] = 0x10325476;
  2482. h[4] = 0xc3d2e1f0;
  2483. // we need to write padding to the last one or two
  2484. // blocks, so build those first into 'final_block'
  2485. // we have to write one special byte, plus the 8-byte length
  2486. // compute the block where the data runs out
  2487. end_start = len & ~63;
  2488. // compute the earliest we can encode the length
  2489. if (((len+9) & ~63) == end_start) {
  2490. // it all fits in one block, so fill a second-to-last block
  2491. end_start -= 64;
  2492. }
  2493. final_len = end_start + 128;
  2494. // now we need to copy the data in
  2495. assert(end_start + 128 >= len+9);
  2496. assert(end_start < len || len < 64-9);
  2497. j = 0;
  2498. if (end_start > len)
  2499. j = (stb_uint) - (int) end_start;
  2500. for (; end_start + j < len; ++j)
  2501. final_block[j] = buffer[end_start + j];
  2502. final_block[j++] = 0x80;
  2503. while (j < 128-5) // 5 byte length, so write 4 extra padding bytes
  2504. final_block[j++] = 0;
  2505. // big-endian size
  2506. final_block[j++] = len >> 29;
  2507. final_block[j++] = len >> 21;
  2508. final_block[j++] = len >> 13;
  2509. final_block[j++] = len >> 5;
  2510. final_block[j++] = len << 3;
  2511. assert(j == 128 && end_start + j == final_len);
  2512. for (j=0; j < final_len; j += 64) { // 512-bit chunks
  2513. if (j+64 >= end_start+64)
  2514. stb__sha1(&final_block[j - end_start], h);
  2515. else
  2516. stb__sha1(&buffer[j], h);
  2517. }
  2518. for (i=0; i < 5; ++i) {
  2519. output[i*4 + 0] = h[i] >> 24;
  2520. output[i*4 + 1] = h[i] >> 16;
  2521. output[i*4 + 2] = h[i] >> 8;
  2522. output[i*4 + 3] = h[i] >> 0;
  2523. }
  2524. }
  2525. int stb_sha1_file(stb_uchar output[20], char *file)
  2526. {
  2527. int i;
  2528. stb_uint64 length=0;
  2529. unsigned char buffer[128];
  2530. FILE *f = stb__fopen(file, "rb");
  2531. stb_uint h[5];
  2532. if (f == NULL) return 0; // file not found
  2533. h[0] = 0x67452301;
  2534. h[1] = 0xefcdab89;
  2535. h[2] = 0x98badcfe;
  2536. h[3] = 0x10325476;
  2537. h[4] = 0xc3d2e1f0;
  2538. for(;;) {
  2539. int n = fread(buffer, 1, 64, f);
  2540. if (n == 64) {
  2541. stb__sha1(buffer, h);
  2542. length += n;
  2543. } else {
  2544. int block = 64;
  2545. length += n;
  2546. buffer[n++] = 0x80;
  2547. // if there isn't enough room for the length, double the block
  2548. if (n + 8 > 64)
  2549. block = 128;
  2550. // pad to end
  2551. memset(buffer+n, 0, block-8-n);
  2552. i = block - 8;
  2553. buffer[i++] = (stb_uchar) (length >> 53);
  2554. buffer[i++] = (stb_uchar) (length >> 45);
  2555. buffer[i++] = (stb_uchar) (length >> 37);
  2556. buffer[i++] = (stb_uchar) (length >> 29);
  2557. buffer[i++] = (stb_uchar) (length >> 21);
  2558. buffer[i++] = (stb_uchar) (length >> 13);
  2559. buffer[i++] = (stb_uchar) (length >> 5);
  2560. buffer[i++] = (stb_uchar) (length << 3);
  2561. assert(i == block);
  2562. stb__sha1(buffer, h);
  2563. if (block == 128)
  2564. stb__sha1(buffer+64, h);
  2565. else
  2566. assert(block == 64);
  2567. break;
  2568. }
  2569. }
  2570. fclose(f);
  2571. for (i=0; i < 5; ++i) {
  2572. output[i*4 + 0] = h[i] >> 24;
  2573. output[i*4 + 1] = h[i] >> 16;
  2574. output[i*4 + 2] = h[i] >> 8;
  2575. output[i*4 + 3] = h[i] >> 0;
  2576. }
  2577. return 1;
  2578. }
  2579. #endif // STB_LIB_IMPLEMENTATION
  2580. //////////////////////////////////////////////////////////////////////////////
  2581. //
  2582. // Random Numbers via Meresenne Twister or LCG
  2583. //
  2584. #ifndef STB_INCLUDE_STB_LIB_H
  2585. STB_EXTERN unsigned long stb_srandLCG(unsigned long seed);
  2586. STB_EXTERN unsigned long stb_randLCG(void);
  2587. STB_EXTERN double stb_frandLCG(void);
  2588. STB_EXTERN void stb_srand(unsigned long seed);
  2589. STB_EXTERN unsigned long stb_rand(void);
  2590. STB_EXTERN double stb_frand(void);
  2591. STB_EXTERN void stb_shuffle(void *p, size_t n, size_t sz,
  2592. unsigned long seed);
  2593. STB_EXTERN void stb_reverse(void *p, size_t n, size_t sz);
  2594. STB_EXTERN unsigned long stb_randLCG_explicit(unsigned long seed);
  2595. #endif // STB_INCLUDE_STB_LIB_H
  2596. #ifdef STB_LIB_IMPLEMENTATION
  2597. unsigned long stb_randLCG_explicit(unsigned long seed)
  2598. {
  2599. return seed * 2147001325 + 715136305;
  2600. }
  2601. static unsigned long stb__rand_seed=0;
  2602. unsigned long stb_srandLCG(unsigned long seed)
  2603. {
  2604. unsigned long previous = stb__rand_seed;
  2605. stb__rand_seed = seed;
  2606. return previous;
  2607. }
  2608. unsigned long stb_randLCG(void)
  2609. {
  2610. stb__rand_seed = stb__rand_seed * 2147001325 + 715136305; // BCPL generator
  2611. // shuffle non-random bits to the middle, and xor to decorrelate with seed
  2612. return 0x31415926 ^ ((stb__rand_seed >> 16) + (stb__rand_seed << 16));
  2613. }
  2614. double stb_frandLCG(void)
  2615. {
  2616. return stb_randLCG() / ((double) (1 << 16) * (1 << 16));
  2617. }
  2618. void stb_shuffle(void *p, size_t n, size_t sz, unsigned long seed)
  2619. {
  2620. char *a;
  2621. unsigned long old_seed;
  2622. int i;
  2623. if (seed)
  2624. old_seed = stb_srandLCG(seed);
  2625. a = (char *) p + (n-1) * sz;
  2626. for (i=n; i > 1; --i) {
  2627. int j = stb_randLCG() % i;
  2628. stb_swap(a, (char *) p + j * sz, sz);
  2629. a -= sz;
  2630. }
  2631. if (seed)
  2632. stb_srandLCG(old_seed);
  2633. }
  2634. void stb_reverse(void *p, size_t n, size_t sz)
  2635. {
  2636. int i,j = n-1;
  2637. for (i=0; i < j; ++i,--j) {
  2638. stb_swap((char *) p + i * sz, (char *) p + j * sz, sz);
  2639. }
  2640. }
  2641. // public domain Mersenne Twister by Michael Brundage
  2642. #define STB__MT_LEN 624
  2643. int stb__mt_index = STB__MT_LEN*sizeof(unsigned long)+1;
  2644. unsigned long stb__mt_buffer[STB__MT_LEN];
  2645. void stb_srand(unsigned long seed)
  2646. {
  2647. int i;
  2648. unsigned long old = stb_srandLCG(seed);
  2649. for (i = 0; i < STB__MT_LEN; i++)
  2650. stb__mt_buffer[i] = stb_randLCG();
  2651. stb_srandLCG(old);
  2652. stb__mt_index = STB__MT_LEN*sizeof(unsigned long);
  2653. }
  2654. #define STB__MT_IA 397
  2655. #define STB__MT_IB (STB__MT_LEN - STB__MT_IA)
  2656. #define STB__UPPER_MASK 0x80000000
  2657. #define STB__LOWER_MASK 0x7FFFFFFF
  2658. #define STB__MATRIX_A 0x9908B0DF
  2659. #define STB__TWIST(b,i,j) ((b)[i] & STB__UPPER_MASK) | ((b)[j] & STB__LOWER_MASK)
  2660. #define STB__MAGIC(s) (((s)&1)*STB__MATRIX_A)
  2661. unsigned long stb_rand()
  2662. {
  2663. unsigned long * b = stb__mt_buffer;
  2664. int idx = stb__mt_index;
  2665. unsigned long s,r;
  2666. int i;
  2667. if (idx >= STB__MT_LEN*sizeof(unsigned long)) {
  2668. if (idx > STB__MT_LEN*sizeof(unsigned long))
  2669. stb_srand(0);
  2670. idx = 0;
  2671. i = 0;
  2672. for (; i < STB__MT_IB; i++) {
  2673. s = STB__TWIST(b, i, i+1);
  2674. b[i] = b[i + STB__MT_IA] ^ (s >> 1) ^ STB__MAGIC(s);
  2675. }
  2676. for (; i < STB__MT_LEN-1; i++) {
  2677. s = STB__TWIST(b, i, i+1);
  2678. b[i] = b[i - STB__MT_IB] ^ (s >> 1) ^ STB__MAGIC(s);
  2679. }
  2680. s = STB__TWIST(b, STB__MT_LEN-1, 0);
  2681. b[STB__MT_LEN-1] = b[STB__MT_IA-1] ^ (s >> 1) ^ STB__MAGIC(s);
  2682. }
  2683. stb__mt_index = idx + sizeof(unsigned long);
  2684. r = *(unsigned long *)((unsigned char *)b + idx);
  2685. r ^= (r >> 11);
  2686. r ^= (r << 7) & 0x9D2C5680;
  2687. r ^= (r << 15) & 0xEFC60000;
  2688. r ^= (r >> 18);
  2689. return r;
  2690. }
  2691. double stb_frand(void)
  2692. {
  2693. return stb_rand() / ((double) (1 << 16) * (1 << 16));
  2694. }
  2695. #endif
  2696. //////////////////////////////////////////////////////////////////////////////
  2697. //
  2698. // wildcards and regexping
  2699. //
  2700. #ifndef STB_INCLUDE_STB_LIB_H
  2701. STB_EXTERN int stb_wildmatch (char *expr, char *candidate);
  2702. STB_EXTERN int stb_wildmatchi(char *expr, char *candidate);
  2703. STB_EXTERN int stb_wildfind (char *expr, char *candidate);
  2704. STB_EXTERN int stb_wildfindi (char *expr, char *candidate);
  2705. #endif // STB_INCLUDE_STB_LIB_H
  2706. #ifdef STB_LIB_IMPLEMENTATION
  2707. static int stb__match_qstring(char *candidate, char *qstring, int qlen, int insensitive)
  2708. {
  2709. int i;
  2710. if (insensitive) {
  2711. for (i=0; i < qlen; ++i)
  2712. if (qstring[i] == '?') {
  2713. if (!candidate[i]) return 0;
  2714. } else
  2715. if (tolower(qstring[i]) != tolower(candidate[i]))
  2716. return 0;
  2717. } else {
  2718. for (i=0; i < qlen; ++i)
  2719. if (qstring[i] == '?') {
  2720. if (!candidate[i]) return 0;
  2721. } else
  2722. if (qstring[i] != candidate[i])
  2723. return 0;
  2724. }
  2725. return 1;
  2726. }
  2727. static int stb__find_qstring(char *candidate, char *qstring, int qlen, int insensitive)
  2728. {
  2729. char c;
  2730. int offset=0;
  2731. while (*qstring == '?') {
  2732. ++qstring;
  2733. --qlen;
  2734. ++candidate;
  2735. if (qlen == 0) return 0;
  2736. if (*candidate == 0) return -1;
  2737. }
  2738. c = *qstring++;
  2739. --qlen;
  2740. if (insensitive) c = tolower(c);
  2741. while (candidate[offset]) {
  2742. if (c == (insensitive ? tolower(candidate[offset]) : candidate[offset]))
  2743. if (stb__match_qstring(candidate+offset+1, qstring, qlen, insensitive))
  2744. return offset;
  2745. ++offset;
  2746. }
  2747. return -1;
  2748. }
  2749. int stb__wildmatch_raw2(char *expr, char *candidate, int search, int insensitive)
  2750. {
  2751. int where=0;
  2752. int start = -1;
  2753. if (!search) {
  2754. // parse to first '*'
  2755. if (*expr != '*')
  2756. start = 0;
  2757. while (*expr != '*') {
  2758. if (!*expr)
  2759. return *candidate == 0 ? 0 : -1;
  2760. if (*expr == '?') {
  2761. if (!*candidate) return -1;
  2762. } else {
  2763. if (insensitive) {
  2764. if (tolower(*candidate) != tolower(*expr))
  2765. return -1;
  2766. } else
  2767. if (*candidate != *expr)
  2768. return -1;
  2769. }
  2770. ++candidate, ++expr, ++where;
  2771. }
  2772. } else {
  2773. // 0-length search string
  2774. if (!*expr)
  2775. return 0;
  2776. }
  2777. assert(search || *expr == '*');
  2778. if (!search)
  2779. ++expr;
  2780. // implicit '*' at this point
  2781. while (*expr) {
  2782. int o=0;
  2783. // combine redundant * characters
  2784. while (expr[0] == '*') ++expr;
  2785. // ok, at this point, expr[-1] == '*',
  2786. // and expr[0] != '*'
  2787. if (!expr[0]) return start >= 0 ? start : 0;
  2788. // now find next '*'
  2789. o = 0;
  2790. while (expr[o] != '*') {
  2791. if (expr[o] == 0)
  2792. break;
  2793. ++o;
  2794. }
  2795. // if no '*', scan to end, then match at end
  2796. if (expr[o] == 0 && !search) {
  2797. int z;
  2798. for (z=0; z < o; ++z)
  2799. if (candidate[z] == 0)
  2800. return -1;
  2801. while (candidate[z])
  2802. ++z;
  2803. // ok, now check if they match
  2804. if (stb__match_qstring(candidate+z-o, expr, o, insensitive))
  2805. return start >= 0 ? start : 0;
  2806. return -1;
  2807. } else {
  2808. // if yes '*', then do stb__find_qmatch on the intervening chars
  2809. int n = stb__find_qstring(candidate, expr, o, insensitive);
  2810. if (n < 0)
  2811. return -1;
  2812. if (start < 0)
  2813. start = where + n;
  2814. expr += o;
  2815. candidate += n+o;
  2816. }
  2817. if (*expr == 0) {
  2818. assert(search);
  2819. return start;
  2820. }
  2821. assert(*expr == '*');
  2822. ++expr;
  2823. }
  2824. return start >= 0 ? start : 0;
  2825. }
  2826. int stb__wildmatch_raw(char *expr, char *candidate, int search, int insensitive)
  2827. {
  2828. char buffer[256];
  2829. // handle multiple search strings
  2830. char *s = strchr(expr, ';');
  2831. char *last = expr;
  2832. while (s) {
  2833. int z;
  2834. // need to allow for non-writeable strings... assume they're small
  2835. if (s - last < 256) {
  2836. stb_strncpy(buffer, last, s-last+1);
  2837. z = stb__wildmatch_raw2(buffer, candidate, search, insensitive);
  2838. } else {
  2839. *s = 0;
  2840. z = stb__wildmatch_raw2(last, candidate, search, insensitive);
  2841. *s = ';';
  2842. }
  2843. if (z >= 0) return z;
  2844. last = s+1;
  2845. s = strchr(last, ';');
  2846. }
  2847. return stb__wildmatch_raw2(last, candidate, search, insensitive);
  2848. }
  2849. int stb_wildmatch(char *expr, char *candidate)
  2850. {
  2851. return stb__wildmatch_raw(expr, candidate, 0,0) >= 0;
  2852. }
  2853. int stb_wildmatchi(char *expr, char *candidate)
  2854. {
  2855. return stb__wildmatch_raw(expr, candidate, 0,1) >= 0;
  2856. }
  2857. int stb_wildfind(char *expr, char *candidate)
  2858. {
  2859. return stb__wildmatch_raw(expr, candidate, 1,0);
  2860. }
  2861. int stb_wildfindi(char *expr, char *candidate)
  2862. {
  2863. return stb__wildmatch_raw(expr, candidate, 1,1);
  2864. }
  2865. #undef STB_LIB_IMPLEMENTATION
  2866. #endif // STB_LIB_IMPLEMENTATION
  2867. #ifndef STB_INCLUDE_STB_LIB_H
  2868. #define STB_INCLUDE_STB_LIB_H
  2869. #undef STB_EXTERN
  2870. #endif
  2871. /*
  2872. ------------------------------------------------------------------------------
  2873. This software is available under 2 licenses -- choose whichever you prefer.
  2874. ------------------------------------------------------------------------------
  2875. ALTERNATIVE A - MIT License
  2876. Copyright (c) 2017 Sean Barrett
  2877. Permission is hereby granted, free of charge, to any person obtaining a copy of
  2878. this software and associated documentation files (the "Software"), to deal in
  2879. the Software without restriction, including without limitation the rights to
  2880. use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
  2881. of the Software, and to permit persons to whom the Software is furnished to do
  2882. so, subject to the following conditions:
  2883. The above copyright notice and this permission notice shall be included in all
  2884. copies or substantial portions of the Software.
  2885. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  2886. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  2887. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  2888. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  2889. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  2890. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  2891. SOFTWARE.
  2892. ------------------------------------------------------------------------------
  2893. ALTERNATIVE B - Public Domain (www.unlicense.org)
  2894. This is free and unencumbered software released into the public domain.
  2895. Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
  2896. software, either in source code form or as a compiled binary, for any purpose,
  2897. commercial or non-commercial, and by any means.
  2898. In jurisdictions that recognize copyright laws, the author or authors of this
  2899. software dedicate any and all copyright interest in the software to the public
  2900. domain. We make this dedication for the benefit of the public at large and to
  2901. the detriment of our heirs and successors. We intend this dedication to be an
  2902. overt act of relinquishment in perpetuity of all present and future rights to
  2903. this software under copyright law.
  2904. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  2905. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  2906. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  2907. AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  2908. ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  2909. WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  2910. ------------------------------------------------------------------------------
  2911. */