test.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635
  1. // Public Domain.
  2. #define _GNU_SOURCE /* Expose declaration of tdestroy() */
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <stdio.h>
  6. #include <unistd.h>
  7. #include <math.h>
  8. #include <search.h> // for other testing
  9. #include <time.h>
  10. #include <float.h> // for float limts of conversion testing
  11. #include "sti.h"
  12. #include "./string.h"
  13. // optional utilities
  14. #include "ini.h"
  15. double getCurrentTime() { // in seconds
  16. double now;
  17. struct timespec ts;
  18. static double offset = 0;
  19. // CLOCK_MONOTONIC_RAW is linux-specific.
  20. clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
  21. now = (double)ts.tv_sec + ((double)ts.tv_nsec / 1000000000.0);
  22. if(offset == 0) offset = now;
  23. return now - offset;
  24. }
  25. char** generate_random_strings(size_t len, size_t block_size);
  26. // temp, will be static later
  27. int flt_r_cvt_str(float f, int base, char* buf, char* charset);
  28. int int_r_cvt(int64_t n, int base, int upper, char* buf) ;
  29. int iprintf(char* fmt, ...);
  30. int isnprintfv(char* out, ptrdiff_t out_sz, char* fmt, void** args);
  31. // static void nothin(void* );
  32. // static void nothin(void* b) { (void)b; }
  33. // static int intcomp(const void* a, const void* b);
  34. // static int intcomp(const void* a, const void* b) {
  35. // int ai = *(uint64_t*)a;
  36. // int bi = *(uint64_t*)b;
  37. // return bi - ai;
  38. // }
  39. //void mergesort_strings(char** arr, int len, int bs, int (*compar)(const void *, const void *));
  40. static int str_sort(const void* a, const void* b) {
  41. char* c = *((char**)a);
  42. char* d = *((char**)b);
  43. return strcmp(c, d);
  44. }
  45. struct trav_data {
  46. char* arr;
  47. char* cpy;
  48. int n;
  49. int bs;
  50. };
  51. static long rb_trav_fn(char* key, void* data, void* user_data) {
  52. struct trav_data* td = (struct trav_data*)user_data;
  53. memcpy(
  54. td->cpy + (td->n * td->bs),
  55. td->arr + ((long)data * td->bs),
  56. td->bs
  57. );
  58. td->n++;
  59. (void)key;
  60. return 0;
  61. }
  62. void bench_sort(int n, int bs) {
  63. double s, e;
  64. char** arr = generate_random_strings(n, bs);
  65. char* arr2 = malloc(bs * n);
  66. char** arr3 = malloc(bs * n);
  67. memcpy(arr2, arr, bs * n);
  68. memcpy(arr3, arr, bs * n);
  69. // qsort(arr3, n, sizeof(*arr2), str_sort);
  70. // qsort(arr2, n, sizeof(*arr2), str_sort);
  71. // qsort(arr, n, sizeof(*arr2), str_sort);
  72. printf("\nN = %d\n", n);
  73. s = getCurrentTime();
  74. // mergesort_strings(arr, n, bs, str_sort);
  75. e = getCurrentTime();
  76. printf(" Merge Sort: %fms\n", (e - s) * 1000);
  77. s = getCurrentTime();
  78. RB(int) rb;
  79. char* cpy = malloc(bs * n);
  80. struct trav_data td = {arr2, cpy, 0, bs};
  81. RB_init(&rb);
  82. for(intptr_t i = 0; i < n; i++)
  83. RB_insert(&rb,
  84. *((char**)(arr2 + i*bs))
  85. , i);
  86. RB_traverse(&rb, rb_trav_fn, &td);
  87. RB_trunc(&rb);
  88. memcpy(arr2, cpy, bs * n);
  89. free(cpy);
  90. e = getCurrentTime();
  91. printf(" RB Traverse: %fms\n", (e - s) * 1000);
  92. s = getCurrentTime();
  93. qsort(arr3, n, bs, str_sort);
  94. e = getCurrentTime();
  95. printf(" libc qsort: %fms\n", (e - s) * 1000);
  96. free(arr);
  97. free(arr2);
  98. free(arr3);
  99. }
  100. int intcmp(void* a_, void* b_) {
  101. int* a = (int*)a_;
  102. int* b = (int*)b_;
  103. return *b - *a;
  104. }
  105. int ini_callback(char* section, char* key, char* value, void* user_data) {
  106. (void)user_data;
  107. if(value)
  108. printf("[%s] '%s' = '%s'\n", section, key, value);
  109. else
  110. printf("[%s] '%s' = NULL\n", section, key);
  111. return 0;
  112. }
  113. int main(int argc, char* argv[]) {
  114. char c;
  115. char test_sets = 0;
  116. char test_vec = 0;
  117. char test_fs = 0;
  118. char test_b_vs_t = 0;
  119. char test_rpn = 0;
  120. char test_iprintf = 0;
  121. char test_Iprintf = 0;
  122. char test_commas = 0;
  123. char test_ring = 0;
  124. char test_sort = 0;
  125. char test_talloc = 0;
  126. char test_heap = 0;
  127. char test_range = 0;
  128. char test_ini = 0;
  129. char test_hash = 0;
  130. char test_utf = 0;
  131. //char* source = readWholeFile("./objtext.txt", NULL);
  132. //objdp_text(source);
  133. // uint32_t* u = utf8_to_utf32("bafoooo", NULL);
  134. // uint32_t* v = utf8_to_utf32("fooaarZZZ", NULL);
  135. // uint32_t* w = malloc(500);
  136. //
  137. // printf("d: %d\n", strcspn32(u, utf8_to_utf32("ba", NULL)));
  138. // // printf("r: %d\n", strspn("foooobar", "fo"));
  139. // uint32_t* x = strchrnul32(w, 'a');
  140. // printf("c: %d\n", );
  141. // for(int i = 0; x[i]; i++) printf("%c", x[i]);
  142. while ((c = getopt (argc, argv, "AtchsSvf1piInrRu")) != -1) {
  143. switch(c) {
  144. case 't': test_talloc = 1; break;
  145. case 's': test_sets = 1; break;
  146. case 'v': test_vec = 1; break;
  147. case 'S': test_sort = 1; break;
  148. case 'f': test_fs = 1; break;
  149. case '1': test_b_vs_t = 1; break;
  150. case 'p': test_rpn = 1; break;
  151. case 'i': test_iprintf = 1; break;
  152. case 'I': test_Iprintf = 1; break;
  153. case 'n': test_ini = 1; break;
  154. case 'c': test_commas = 1; break;
  155. case 'r': test_ring = 1; break;
  156. case 'R': test_range = 1; break;
  157. case 'h': test_heap = 1; break;
  158. case 'A': test_hash = 1; break;
  159. case 'u': test_utf = 1; break;
  160. }
  161. }
  162. if(test_utf) {
  163. unsigned char* t = "abca""\xc6""\x80""czxg""\xc6""\x80""sdf"; // 10
  164. // unsigned char* t = "abca""\xc6""\x80""c"; // 4
  165. // unsigned char* t = "abca""\xc6""\x81""c"; // NULL
  166. unsigned char* x = strrchr8(t, 384);
  167. if(!x) printf("got NULL\n");
  168. else printf("got: %d\n", (int)(x - t));
  169. }
  170. if(test_range) {
  171. }
  172. if(test_hash) {
  173. int fooval = 0xdeadbeef;
  174. int barval = 0xfeedbeef;
  175. int* foovalp;
  176. int testval = 0;;
  177. char* testkey = "foo";
  178. HT(int) foo;
  179. HT(int, int) bar;
  180. HT_init(&foo, 32);
  181. HT_init(&bar, 32);
  182. HT_set(&foo, "foo", fooval);
  183. //HT_set(&foo, testkey, fooval);
  184. HT_get(&foo, "foo", &testval);
  185. printf("foo testval: %x\n", testval);
  186. HT_setn(&bar, 64, barval);
  187. testval = 0;
  188. HT_getn(&bar, 64, &testval);
  189. printf("bar testval: %x\n", testval);
  190. // HT_set(&bar, 500, fooval);
  191. // HT_getp(&bar, 500, &foovalp);
  192. }
  193. if(test_ini) {
  194. ini_read("./initest.ini", ini_callback, (void*)1337);
  195. }
  196. if(test_heap) {
  197. HEAP(char*) h;
  198. HEAP_init(&h, str_sort);
  199. int i = 80;
  200. char* k;
  201. int len = 8000;
  202. char** arr = generate_random_strings(len, 8);
  203. for(i = 0; i < len; i++)
  204. HEAP_insert(&h, &arr[i]);
  205. // heap_insert_(&h, &j, intcmp, 4);
  206. // heap_insert_(&h, &k, intcmp, 4);
  207. // heap_insert_(&h, &l, intcmp, 4);
  208. // heap_insert_(&h, &m, intcmp, 4);
  209. // heap_print_(&h, 4);
  210. printf("\n");
  211. for(i = 0; i < len; i++) {
  212. HEAP_pop(&h, &k);
  213. // heap_print_(&h, 4);
  214. printf("%s\n", k);
  215. }
  216. HEAP_free(&h);
  217. /*
  218. heap_pop_(&h, &k, intcmp, 4);
  219. heap_print_(&h, 4);
  220. printf("\n");
  221. heap_pop_(&h, &k, intcmp, 4);
  222. heap_print_(&h, 4);*/
  223. return 0;
  224. }
  225. if(test_talloc) {
  226. /*
  227. void* a = talloc(NULL, 503);
  228. void* aa = talloc(a, 3);
  229. void* ab = talloc(a, 53);
  230. void* ac = talloc(a, 5);
  231. void* aba = talloc(ab, 45);
  232. void* abb = talloc(ab, 45);
  233. void* abc = talloc(ab, 45);
  234. trealloc(ab, 7435);
  235. tfree(a);*/
  236. return 0;
  237. }
  238. if(test_sort) {
  239. int block_size = 4*16;
  240. bench_sort(10, block_size);
  241. bench_sort(100, block_size);
  242. bench_sort(1000, block_size);
  243. bench_sort(10000, block_size);
  244. bench_sort(100000, block_size);
  245. bench_sort(1000000, block_size);
  246. }
  247. if(test_ring) {
  248. RING(int) r;
  249. RING_INIT(&r, 10);
  250. for(int j = 0; j < 15; j++) {
  251. RING_PUSH(&r, 50 + j);
  252. }
  253. RING_EACH(&r, i, v) {
  254. printf("each: %ld - %d\n", i, v);
  255. }
  256. printf("--\n");
  257. //for(int i = 0; i < 10; i++) {
  258. // printf("%d: %d\n", i, r.data[i]);
  259. //}
  260. // int a = -99;
  261. //RING_POP(&r, a);
  262. //printf("\na: %d, len: %ld\n", a, r.len);
  263. RING_RM(&r, 9);
  264. // int b = -99;
  265. //RING_POP(&r, b);
  266. //printf("\nb: %d, len: %ld\n", b, r.len);
  267. //RING_PUSH(&r, 70);
  268. // int c = -99;
  269. //RING_POP(&r, c);
  270. //printf("\nc: %d, len: %ld\n", c, r.len);
  271. RING_EACH(&r, i, v) {
  272. printf("each: %ld - %d\n", i, v);
  273. }
  274. }
  275. if(test_Iprintf) {
  276. char buffer[256] = "zzzzzzzzzzzz";
  277. size_t n;
  278. int i = 77;
  279. int* pi = &i;
  280. int** ppi = &pi;
  281. double dd = 3.5;
  282. uint64_t nn = *((uint64_t*)&dd);
  283. uint64_t n1, n2;
  284. (void)pi;
  285. (void)ppi;
  286. uint64_t iargs[] = {
  287. 3,
  288. (uint64_t)ppi,
  289. (uint64_t)&n1,
  290. nn,
  291. (uint64_t)&dd,
  292. -500000000,
  293. (uint64_t)"string test",
  294. (uint64_t)&n2,
  295. };
  296. // printf("%d\n", snprintf(buffer, 100, "%ld", 123456l));
  297. n = isnprintfv(buffer, 256, "a %>>.*ld%n b %.3f c %p d %d e %s f-%n-g", (void**)iargs);
  298. printf("\n\n%s\n%ld\n%p\n%ld, %ld\n", buffer, n, (void*)&dd, n1, n2);
  299. }
  300. if(test_iprintf) {
  301. for(int i = 0; i < 24; i++) {
  302. long ii = 5;
  303. uint64_t ijh = 0;
  304. uint64_t ijl = 1;
  305. for(int n = 0; n < i; n++) ii *= 5;
  306. for(int n = 23; n > i; n--) {
  307. uint64_t two, four;
  308. // uint64_t ci = 0, co = 0;
  309. ijh += __builtin_add_overflow(ijl, ijl, &two);
  310. ijh += __builtin_add_overflow(two, two, &four);
  311. ijh += __builtin_add_overflow(four, four, &ijl);
  312. ijh += __builtin_add_overflow(two, ijl, &ijl);
  313. ijh *= 10;
  314. }
  315. printf("% .2d - %.25f - %lu %lu - % .*ld\n", i, 1.0/(2<<i), ijh, ijl, i+1, ii);
  316. }
  317. char buf[100];
  318. uint32_t N = 0x00000001;
  319. float F = *((float*)&N);
  320. float f = F;// -0x1.fffffep+127;
  321. printf("%a\n", f);
  322. uint32_t d = *((uint32_t*)&f);
  323. int n = int_r_cvt(d, 2, 0, buf);
  324. printf("%.*s\n", n, buf);
  325. flt_r_cvt_str(f, 10, buf, "0123456789abcdef");
  326. // printf("%.*s\n", n, buf);
  327. }
  328. if(test_rpn) {
  329. sti_op_prec_rule rules[] = {
  330. {"", 0, STI_OP_ASSOC_NONE, 0},
  331. {"+", 1, STI_OP_ASSOC_LEFT, 2},
  332. {"-", 1, STI_OP_ASSOC_LEFT, 2},
  333. {"*", 2, STI_OP_ASSOC_LEFT, 2},
  334. {"**", 3, STI_OP_ASSOC_LEFT, 2},
  335. {"/", 2, STI_OP_ASSOC_LEFT, 2},
  336. {"(", 8, STI_OP_OPEN_PAREN, 0},
  337. {")", 8, STI_OP_CLOSE_PAREN, 0},
  338. {"[", 9, STI_OP_OPEN_PAREN, 0},
  339. {"]", 9, STI_OP_CLOSE_PAREN, 0},
  340. {NULL, 0, 0, 0},
  341. };
  342. char* infix[] = {
  343. "2",
  344. "*",
  345. "4",
  346. // "1",
  347. // "*",
  348. // "(",
  349. // "2",
  350. // "+",
  351. // "3",
  352. // ")",
  353. // "/",
  354. // "[",
  355. // "4",
  356. // "-",
  357. // "5",
  358. // "]",
  359. // "*",
  360. // "2",
  361. NULL,
  362. };
  363. char** rpn;
  364. size_t len;
  365. infix_to_rpn(rules, infix, &rpn, &len);
  366. printf("answer: %ld \n", rpn_eval_int_str(rpn));
  367. while(*rpn) {
  368. printf(" %s \n", *rpn);
  369. rpn++;
  370. }
  371. }
  372. if(test_sets) {
  373. PointerSet* ps = calloc(1, sizeof(*ps));
  374. PointerSet* ps2 = calloc(1, sizeof(*ps2));
  375. PointerSet_insert(ps, (void*)0x00004);
  376. PointerSet_insert(ps, (void*)0x00002);
  377. PointerSet_insert(ps, (void*)0x00003);
  378. PointerSet_insert(ps, (void*)0x00008);
  379. PointerSet_insert(ps, (void*)0x00008);
  380. PointerSet_insert(ps, (void*)0x00001);
  381. PointerSet_insert(ps2, (void*)0x00003);
  382. PointerSet_insert(ps2, (void*)0x00008);
  383. PointerSet_insert(ps2, (void*)0x00007);
  384. PointerSet_insert(ps2, (void*)0x00002);
  385. PointerSet_insert(ps2, (void*)0x00008);
  386. PointerSet_print(ps);
  387. PointerSet_print(ps2);
  388. PointerSet* ps3 = PointerSet_intersect(ps, ps2);
  389. PointerSet_print(ps3);
  390. PointerSet* ps4 = PointerSet_union(ps, ps2);
  391. PointerSet_print(ps4);
  392. PointerSet* ps5 = PointerSet_difference(ps, ps2);
  393. PointerSet_print(ps5);
  394. PointerSet_union_inplace(ps5, ps3);
  395. PointerSet_print(ps5);
  396. }
  397. if(test_vec) {
  398. printf("vec testing nyi\n");
  399. }
  400. if(test_fs) {
  401. printf("fs testing nyi\n");
  402. }
  403. if(test_b_vs_t) {
  404. double start;
  405. double ttime = 1, btime = 0;
  406. int inc = 2;
  407. int max = 700;
  408. while(ttime > btime) {
  409. // int i = 0;
  410. // int64_t* nums = malloc(max * sizeof(*nums));
  411. // for(i = 0; i < max; i++) nums[i] = frandNorm() * 1000000 + 1;
  412. // int64_tSet set;
  413. // int64_tSet_init(&set);
  414. // PointerSet set;
  415. // HashTable hash;
  416. start = getCurrentTimePerf();
  417. // PointerSet_init(&set);
  418. // for(i = 0; i < max; i++) {
  419. // int64_tSet_insert(&set, nums[i]);
  420. // PointerSet_insert(&set, (void*)nums[i]);
  421. // }
  422. // PointerSet_destroy(&set);
  423. btime = timeSincePerf(start);
  424. printf("set time: %fms\n", btime * 1000);
  425. start = getCurrentTimePerf();
  426. // for(i = 0; i < max; i++) {
  427. // tsearch(&nums[i], &tree, intcomp);
  428. // }
  429. // tdestroy(tree, nothin);
  430. ttime = timeSincePerf(start);
  431. printf("tree time: %fms\n", ttime * 1000);
  432. // max += inc;
  433. }
  434. printf("passed at: %d\n", max - inc);
  435. }
  436. if(test_commas) {
  437. iprintf("%+,d\n", 1);
  438. iprintf("%+,d\n", -12l);
  439. iprintf("%,d\n", -123l);
  440. iprintf("%,d\n", 1234);
  441. iprintf("%,d\n", 12345);
  442. iprintf("%,d\n", 123456);
  443. iprintf("%,d\n", 1234567);
  444. iprintf("%,d\n", 12345678);
  445. iprintf("%,d\n", 123456789);
  446. iprintf("%,d\n", 1234567890);
  447. iprintf("%+,d\n", 12345678901);
  448. iprintf("%,d\n", 123456789012);
  449. iprintf("%,d\n", 1234567890123);
  450. iprintf("%p\n", &c);
  451. }
  452. return 0;
  453. }
  454. char rand_char() {
  455. static char* chars = "QWERTYUIOPASDFGHJKLZXCVBNM";
  456. return chars[rand() % 26];
  457. }
  458. char** generate_random_strings(size_t len, size_t block_size) {
  459. char** out = malloc(len * block_size);
  460. int cl = 0;
  461. for(size_t i = 0; i < len; i++) {
  462. char* k = malloc(5);
  463. TRY_AGAIN:
  464. k[0] = rand_char();
  465. k[1] = rand_char();
  466. k[2] = rand_char();
  467. k[3] = rand_char();
  468. k[4] = 0;
  469. for(int j = 0; j < cl; j++) {
  470. if(0 == strcmp(k, out[j])) goto TRY_AGAIN;
  471. }
  472. *((char**)(out + (i * block_size))) = k;
  473. }
  474. return (char**)out;
  475. }