cutils.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641
  1. /*
  2. * C utilities
  3. *
  4. * Copyright (c) 2017 Fabrice Bellard
  5. * Copyright (c) 2018 Charlie Gordon
  6. *
  7. * Permission is hereby granted, free of charge, to any person obtaining a copy
  8. * of this software and associated documentation files (the "Software"), to deal
  9. * in the Software without restriction, including without limitation the rights
  10. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  11. * copies of the Software, and to permit persons to whom the Software is
  12. * furnished to do so, subject to the following conditions:
  13. *
  14. * The above copyright notice and this permission notice shall be included in
  15. * all copies or substantial portions of the Software.
  16. *
  17. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  18. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  19. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  20. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  21. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  22. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  23. * THE SOFTWARE.
  24. */
  25. #include <stdlib.h>
  26. #include <stdio.h>
  27. #include <stdarg.h>
  28. #include <string.h>
  29. #include "cutils.h"
  30. void pstrcpy(char *buf, int buf_size, const char *str)
  31. {
  32. int c;
  33. char *q = buf;
  34. if (buf_size <= 0)
  35. return;
  36. for(;;) {
  37. c = *str++;
  38. if (c == 0 || q >= buf + buf_size - 1)
  39. break;
  40. *q++ = c;
  41. }
  42. *q = '\0';
  43. }
  44. /* strcat and truncate. */
  45. char *pstrcat(char *buf, int buf_size, const char *s)
  46. {
  47. int len;
  48. len = strlen(buf);
  49. if (len < buf_size)
  50. pstrcpy(buf + len, buf_size - len, s);
  51. return buf;
  52. }
  53. int strstart(const char *str, const char *val, const char **ptr)
  54. {
  55. const char *p, *q;
  56. p = str;
  57. q = val;
  58. while (*q != '\0') {
  59. if (*p != *q)
  60. return 0;
  61. p++;
  62. q++;
  63. }
  64. if (ptr)
  65. *ptr = p;
  66. return 1;
  67. }
  68. int has_suffix(const char *str, const char *suffix)
  69. {
  70. size_t len = strlen(str);
  71. size_t slen = strlen(suffix);
  72. return (len >= slen && !memcmp(str + len - slen, suffix, slen));
  73. }
  74. /* Dynamic buffer package */
  75. static void *dbuf_default_realloc(void *opaque, void *ptr, size_t size)
  76. {
  77. return realloc(ptr, size);
  78. }
  79. void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func)
  80. {
  81. memset(s, 0, sizeof(*s));
  82. if (!realloc_func)
  83. realloc_func = dbuf_default_realloc;
  84. s->opaque = opaque;
  85. s->realloc_func = realloc_func;
  86. }
  87. void dbuf_init(DynBuf *s)
  88. {
  89. dbuf_init2(s, NULL, NULL);
  90. }
  91. /* Try to allocate 'len' more bytes. return < 0 if error */
  92. int dbuf_claim(DynBuf *s, size_t len)
  93. {
  94. size_t new_size, size;
  95. uint8_t *new_buf;
  96. new_size = s->size + len;
  97. if (new_size < len)
  98. return -1; /* overflow case */
  99. if (new_size > s->allocated_size) {
  100. if (s->error)
  101. return -1;
  102. size = s->allocated_size + (s->allocated_size / 2);
  103. if (size < s->allocated_size)
  104. return -1; /* overflow case */
  105. if (size > new_size)
  106. new_size = size;
  107. new_buf = s->realloc_func(s->opaque, s->buf, new_size);
  108. if (!new_buf) {
  109. s->error = TRUE;
  110. return -1;
  111. }
  112. s->buf = new_buf;
  113. s->allocated_size = new_size;
  114. }
  115. return 0;
  116. }
  117. int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
  118. {
  119. if (unlikely((s->allocated_size - s->size) < len)) {
  120. if (dbuf_claim(s, len))
  121. return -1;
  122. }
  123. memcpy_no_ub(s->buf + s->size, data, len);
  124. s->size += len;
  125. return 0;
  126. }
  127. int dbuf_put_self(DynBuf *s, size_t offset, size_t len)
  128. {
  129. if (unlikely((s->allocated_size - s->size) < len)) {
  130. if (dbuf_claim(s, len))
  131. return -1;
  132. }
  133. memcpy(s->buf + s->size, s->buf + offset, len);
  134. s->size += len;
  135. return 0;
  136. }
  137. int __dbuf_putc(DynBuf *s, uint8_t c)
  138. {
  139. return dbuf_put(s, &c, 1);
  140. }
  141. int __dbuf_put_u16(DynBuf *s, uint16_t val)
  142. {
  143. return dbuf_put(s, (uint8_t *)&val, 2);
  144. }
  145. int __dbuf_put_u32(DynBuf *s, uint32_t val)
  146. {
  147. return dbuf_put(s, (uint8_t *)&val, 4);
  148. }
  149. int __dbuf_put_u64(DynBuf *s, uint64_t val)
  150. {
  151. return dbuf_put(s, (uint8_t *)&val, 8);
  152. }
  153. int dbuf_putstr(DynBuf *s, const char *str)
  154. {
  155. return dbuf_put(s, (const uint8_t *)str, strlen(str));
  156. }
  157. int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
  158. const char *fmt, ...)
  159. {
  160. va_list ap;
  161. char buf[128];
  162. int len;
  163. va_start(ap, fmt);
  164. len = vsnprintf(buf, sizeof(buf), fmt, ap);
  165. va_end(ap);
  166. if (len < 0)
  167. return -1;
  168. if (len < sizeof(buf)) {
  169. /* fast case */
  170. return dbuf_put(s, (uint8_t *)buf, len);
  171. } else {
  172. if (dbuf_claim(s, len + 1))
  173. return -1;
  174. va_start(ap, fmt);
  175. vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size,
  176. fmt, ap);
  177. va_end(ap);
  178. s->size += len;
  179. }
  180. return 0;
  181. }
  182. void dbuf_free(DynBuf *s)
  183. {
  184. /* we test s->buf as a fail safe to avoid crashing if dbuf_free()
  185. is called twice */
  186. if (s->buf) {
  187. s->realloc_func(s->opaque, s->buf, 0);
  188. }
  189. memset(s, 0, sizeof(*s));
  190. }
  191. /* Note: at most 31 bits are encoded. At most UTF8_CHAR_LEN_MAX bytes
  192. are output. */
  193. int unicode_to_utf8(uint8_t *buf, unsigned int c)
  194. {
  195. uint8_t *q = buf;
  196. if (c < 0x80) {
  197. *q++ = c;
  198. } else {
  199. if (c < 0x800) {
  200. *q++ = (c >> 6) | 0xc0;
  201. } else {
  202. if (c < 0x10000) {
  203. *q++ = (c >> 12) | 0xe0;
  204. } else {
  205. if (c < 0x00200000) {
  206. *q++ = (c >> 18) | 0xf0;
  207. } else {
  208. if (c < 0x04000000) {
  209. *q++ = (c >> 24) | 0xf8;
  210. } else if (c < 0x80000000) {
  211. *q++ = (c >> 30) | 0xfc;
  212. *q++ = ((c >> 24) & 0x3f) | 0x80;
  213. } else {
  214. return 0;
  215. }
  216. *q++ = ((c >> 18) & 0x3f) | 0x80;
  217. }
  218. *q++ = ((c >> 12) & 0x3f) | 0x80;
  219. }
  220. *q++ = ((c >> 6) & 0x3f) | 0x80;
  221. }
  222. *q++ = (c & 0x3f) | 0x80;
  223. }
  224. return q - buf;
  225. }
  226. static const unsigned int utf8_min_code[5] = {
  227. 0x80, 0x800, 0x10000, 0x00200000, 0x04000000,
  228. };
  229. static const unsigned char utf8_first_code_mask[5] = {
  230. 0x1f, 0xf, 0x7, 0x3, 0x1,
  231. };
  232. /* return -1 if error. *pp is not updated in this case. max_len must
  233. be >= 1. The maximum length for a UTF8 byte sequence is 6 bytes. */
  234. int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp)
  235. {
  236. int l, c, b, i;
  237. c = *p++;
  238. if (c < 0x80) {
  239. *pp = p;
  240. return c;
  241. }
  242. switch(c) {
  243. case 0xc0: case 0xc1: case 0xc2: case 0xc3:
  244. case 0xc4: case 0xc5: case 0xc6: case 0xc7:
  245. case 0xc8: case 0xc9: case 0xca: case 0xcb:
  246. case 0xcc: case 0xcd: case 0xce: case 0xcf:
  247. case 0xd0: case 0xd1: case 0xd2: case 0xd3:
  248. case 0xd4: case 0xd5: case 0xd6: case 0xd7:
  249. case 0xd8: case 0xd9: case 0xda: case 0xdb:
  250. case 0xdc: case 0xdd: case 0xde: case 0xdf:
  251. l = 1;
  252. break;
  253. case 0xe0: case 0xe1: case 0xe2: case 0xe3:
  254. case 0xe4: case 0xe5: case 0xe6: case 0xe7:
  255. case 0xe8: case 0xe9: case 0xea: case 0xeb:
  256. case 0xec: case 0xed: case 0xee: case 0xef:
  257. l = 2;
  258. break;
  259. case 0xf0: case 0xf1: case 0xf2: case 0xf3:
  260. case 0xf4: case 0xf5: case 0xf6: case 0xf7:
  261. l = 3;
  262. break;
  263. case 0xf8: case 0xf9: case 0xfa: case 0xfb:
  264. l = 4;
  265. break;
  266. case 0xfc: case 0xfd:
  267. l = 5;
  268. break;
  269. default:
  270. return -1;
  271. }
  272. /* check that we have enough characters */
  273. if (l > (max_len - 1))
  274. return -1;
  275. c &= utf8_first_code_mask[l - 1];
  276. for(i = 0; i < l; i++) {
  277. b = *p++;
  278. if (b < 0x80 || b >= 0xc0)
  279. return -1;
  280. c = (c << 6) | (b & 0x3f);
  281. }
  282. if (c < utf8_min_code[l - 1])
  283. return -1;
  284. *pp = p;
  285. return c;
  286. }
  287. #if 0
  288. #if defined(__EMSCRIPTEN__) || defined(__ANDROID__)
  289. static void *rqsort_arg;
  290. static int (*rqsort_cmp)(const void *, const void *, void *);
  291. static int rqsort_cmp2(const void *p1, const void *p2)
  292. {
  293. return rqsort_cmp(p1, p2, rqsort_arg);
  294. }
  295. /* not reentrant, but not needed with emscripten */
  296. void rqsort(void *base, size_t nmemb, size_t size,
  297. int (*cmp)(const void *, const void *, void *),
  298. void *arg)
  299. {
  300. rqsort_arg = arg;
  301. rqsort_cmp = cmp;
  302. qsort(base, nmemb, size, rqsort_cmp2);
  303. }
  304. #endif
  305. #else
  306. typedef void (*exchange_f)(void *a, void *b, size_t size);
  307. typedef int (*cmp_f)(const void *, const void *, void *opaque);
  308. static void exchange_bytes(void *a, void *b, size_t size) {
  309. uint8_t *ap = (uint8_t *)a;
  310. uint8_t *bp = (uint8_t *)b;
  311. while (size-- != 0) {
  312. uint8_t t = *ap;
  313. *ap++ = *bp;
  314. *bp++ = t;
  315. }
  316. }
  317. static void exchange_one_byte(void *a, void *b, size_t size) {
  318. uint8_t *ap = (uint8_t *)a;
  319. uint8_t *bp = (uint8_t *)b;
  320. uint8_t t = *ap;
  321. *ap = *bp;
  322. *bp = t;
  323. }
  324. static void exchange_int16s(void *a, void *b, size_t size) {
  325. uint16_t *ap = (uint16_t *)a;
  326. uint16_t *bp = (uint16_t *)b;
  327. for (size /= sizeof(uint16_t); size-- != 0;) {
  328. uint16_t t = *ap;
  329. *ap++ = *bp;
  330. *bp++ = t;
  331. }
  332. }
  333. static void exchange_one_int16(void *a, void *b, size_t size) {
  334. uint16_t *ap = (uint16_t *)a;
  335. uint16_t *bp = (uint16_t *)b;
  336. uint16_t t = *ap;
  337. *ap = *bp;
  338. *bp = t;
  339. }
  340. static void exchange_int32s(void *a, void *b, size_t size) {
  341. uint32_t *ap = (uint32_t *)a;
  342. uint32_t *bp = (uint32_t *)b;
  343. for (size /= sizeof(uint32_t); size-- != 0;) {
  344. uint32_t t = *ap;
  345. *ap++ = *bp;
  346. *bp++ = t;
  347. }
  348. }
  349. static void exchange_one_int32(void *a, void *b, size_t size) {
  350. uint32_t *ap = (uint32_t *)a;
  351. uint32_t *bp = (uint32_t *)b;
  352. uint32_t t = *ap;
  353. *ap = *bp;
  354. *bp = t;
  355. }
  356. static void exchange_int64s(void *a, void *b, size_t size) {
  357. uint64_t *ap = (uint64_t *)a;
  358. uint64_t *bp = (uint64_t *)b;
  359. for (size /= sizeof(uint64_t); size-- != 0;) {
  360. uint64_t t = *ap;
  361. *ap++ = *bp;
  362. *bp++ = t;
  363. }
  364. }
  365. static void exchange_one_int64(void *a, void *b, size_t size) {
  366. uint64_t *ap = (uint64_t *)a;
  367. uint64_t *bp = (uint64_t *)b;
  368. uint64_t t = *ap;
  369. *ap = *bp;
  370. *bp = t;
  371. }
  372. static void exchange_int128s(void *a, void *b, size_t size) {
  373. uint64_t *ap = (uint64_t *)a;
  374. uint64_t *bp = (uint64_t *)b;
  375. for (size /= sizeof(uint64_t) * 2; size-- != 0; ap += 2, bp += 2) {
  376. uint64_t t = ap[0];
  377. uint64_t u = ap[1];
  378. ap[0] = bp[0];
  379. ap[1] = bp[1];
  380. bp[0] = t;
  381. bp[1] = u;
  382. }
  383. }
  384. static void exchange_one_int128(void *a, void *b, size_t size) {
  385. uint64_t *ap = (uint64_t *)a;
  386. uint64_t *bp = (uint64_t *)b;
  387. uint64_t t = ap[0];
  388. uint64_t u = ap[1];
  389. ap[0] = bp[0];
  390. ap[1] = bp[1];
  391. bp[0] = t;
  392. bp[1] = u;
  393. }
  394. static inline exchange_f exchange_func(const void *base, size_t size) {
  395. switch (((uintptr_t)base | (uintptr_t)size) & 15) {
  396. case 0:
  397. if (size == sizeof(uint64_t) * 2)
  398. return exchange_one_int128;
  399. else
  400. return exchange_int128s;
  401. case 8:
  402. if (size == sizeof(uint64_t))
  403. return exchange_one_int64;
  404. else
  405. return exchange_int64s;
  406. case 4:
  407. case 12:
  408. if (size == sizeof(uint32_t))
  409. return exchange_one_int32;
  410. else
  411. return exchange_int32s;
  412. case 2:
  413. case 6:
  414. case 10:
  415. case 14:
  416. if (size == sizeof(uint16_t))
  417. return exchange_one_int16;
  418. else
  419. return exchange_int16s;
  420. default:
  421. if (size == 1)
  422. return exchange_one_byte;
  423. else
  424. return exchange_bytes;
  425. }
  426. }
  427. static void heapsortx(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
  428. {
  429. uint8_t *basep = (uint8_t *)base;
  430. size_t i, n, c, r;
  431. exchange_f swap = exchange_func(base, size);
  432. if (nmemb > 1) {
  433. i = (nmemb / 2) * size;
  434. n = nmemb * size;
  435. while (i > 0) {
  436. i -= size;
  437. for (r = i; (c = r * 2 + size) < n; r = c) {
  438. if (c < n - size && cmp(basep + c, basep + c + size, opaque) <= 0)
  439. c += size;
  440. if (cmp(basep + r, basep + c, opaque) > 0)
  441. break;
  442. swap(basep + r, basep + c, size);
  443. }
  444. }
  445. for (i = n - size; i > 0; i -= size) {
  446. swap(basep, basep + i, size);
  447. for (r = 0; (c = r * 2 + size) < i; r = c) {
  448. if (c < i - size && cmp(basep + c, basep + c + size, opaque) <= 0)
  449. c += size;
  450. if (cmp(basep + r, basep + c, opaque) > 0)
  451. break;
  452. swap(basep + r, basep + c, size);
  453. }
  454. }
  455. }
  456. }
  457. static inline void *med3(void *a, void *b, void *c, cmp_f cmp, void *opaque)
  458. {
  459. return cmp(a, b, opaque) < 0 ?
  460. (cmp(b, c, opaque) < 0 ? b : (cmp(a, c, opaque) < 0 ? c : a )) :
  461. (cmp(b, c, opaque) > 0 ? b : (cmp(a, c, opaque) < 0 ? a : c ));
  462. }
  463. /* pointer based version with local stack and insertion sort threshhold */
  464. void rqsort(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
  465. {
  466. struct { uint8_t *base; size_t count; int depth; } stack[50], *sp = stack;
  467. uint8_t *ptr, *pi, *pj, *plt, *pgt, *top, *m;
  468. size_t m4, i, lt, gt, span, span2;
  469. int c, depth;
  470. exchange_f swap = exchange_func(base, size);
  471. exchange_f swap_block = exchange_func(base, size | 128);
  472. if (nmemb < 2 || size <= 0)
  473. return;
  474. sp->base = (uint8_t *)base;
  475. sp->count = nmemb;
  476. sp->depth = 0;
  477. sp++;
  478. while (sp > stack) {
  479. sp--;
  480. ptr = sp->base;
  481. nmemb = sp->count;
  482. depth = sp->depth;
  483. while (nmemb > 6) {
  484. if (++depth > 50) {
  485. /* depth check to ensure worst case logarithmic time */
  486. heapsortx(ptr, nmemb, size, cmp, opaque);
  487. nmemb = 0;
  488. break;
  489. }
  490. /* select median of 3 from 1/4, 1/2, 3/4 positions */
  491. /* should use median of 5 or 9? */
  492. m4 = (nmemb >> 2) * size;
  493. m = med3(ptr + m4, ptr + 2 * m4, ptr + 3 * m4, cmp, opaque);
  494. swap(ptr, m, size); /* move the pivot to the start or the array */
  495. i = lt = 1;
  496. pi = plt = ptr + size;
  497. gt = nmemb;
  498. pj = pgt = top = ptr + nmemb * size;
  499. for (;;) {
  500. while (pi < pj && (c = cmp(ptr, pi, opaque)) >= 0) {
  501. if (c == 0) {
  502. swap(plt, pi, size);
  503. lt++;
  504. plt += size;
  505. }
  506. i++;
  507. pi += size;
  508. }
  509. while (pi < (pj -= size) && (c = cmp(ptr, pj, opaque)) <= 0) {
  510. if (c == 0) {
  511. gt--;
  512. pgt -= size;
  513. swap(pgt, pj, size);
  514. }
  515. }
  516. if (pi >= pj)
  517. break;
  518. swap(pi, pj, size);
  519. i++;
  520. pi += size;
  521. }
  522. /* array has 4 parts:
  523. * from 0 to lt excluded: elements identical to pivot
  524. * from lt to pi excluded: elements smaller than pivot
  525. * from pi to gt excluded: elements greater than pivot
  526. * from gt to n excluded: elements identical to pivot
  527. */
  528. /* move elements identical to pivot in the middle of the array: */
  529. /* swap values in ranges [0..lt[ and [i-lt..i[
  530. swapping the smallest span between lt and i-lt is sufficient
  531. */
  532. span = plt - ptr;
  533. span2 = pi - plt;
  534. lt = i - lt;
  535. if (span > span2)
  536. span = span2;
  537. swap_block(ptr, pi - span, span);
  538. /* swap values in ranges [gt..top[ and [i..top-(top-gt)[
  539. swapping the smallest span between top-gt and gt-i is sufficient
  540. */
  541. span = top - pgt;
  542. span2 = pgt - pi;
  543. pgt = top - span2;
  544. gt = nmemb - (gt - i);
  545. if (span > span2)
  546. span = span2;
  547. swap_block(pi, top - span, span);
  548. /* now array has 3 parts:
  549. * from 0 to lt excluded: elements smaller than pivot
  550. * from lt to gt excluded: elements identical to pivot
  551. * from gt to n excluded: elements greater than pivot
  552. */
  553. /* stack the larger segment and keep processing the smaller one
  554. to minimize stack use for pathological distributions */
  555. if (lt > nmemb - gt) {
  556. sp->base = ptr;
  557. sp->count = lt;
  558. sp->depth = depth;
  559. sp++;
  560. ptr = pgt;
  561. nmemb -= gt;
  562. } else {
  563. sp->base = pgt;
  564. sp->count = nmemb - gt;
  565. sp->depth = depth;
  566. sp++;
  567. nmemb = lt;
  568. }
  569. }
  570. /* Use insertion sort for small fragments */
  571. for (pi = ptr + size, top = ptr + nmemb * size; pi < top; pi += size) {
  572. for (pj = pi; pj > ptr && cmp(pj - size, pj, opaque) > 0; pj -= size)
  573. swap(pj, pj - size, size);
  574. }
  575. }
  576. }
  577. #endif