Reference-counted, deduplicated string store.
1/**
2 * Runs a tests to make sure the text-store works.
3 */
4
5#include <stdio.h>
6#include <string.h>
7#include <textstore.h>
8
9int main() {
10 textstore_t store;
11 if(textstore_init(&store, 64))
12 return 1;
13
14 // A reference counted string handle.
15 char *handle1_expected = "Hello world!";
16 textstore_handle handle1 = textstore_intern(&store, handle1_expected);
17 if (strcmp(textstore_string(&store, handle1), handle1_expected) != 0)
18 return 1;
19
20 char *handle2_expected = "A different string!";
21 textstore_handle handle2 = textstore_intern(&store, handle2_expected);
22 if (strcmp(textstore_string(&store, handle2), handle2_expected))
23 return 1;
24
25 // A handle may become invalidated after all references to it are released.
26 textstore_release(&store, handle1);
27 if (textstore_gc(&store) != 0)
28 return 1;
29
30 // Trying to get the data of an inactive handle should return null.
31 char *invalid_string = textstore_string(&store, handle1);
32 if (invalid_string != NULL)
33 return 1;
34
35 // Interning new strings may re-use previously gc'd handle indexes.
36 // But they are not equal due to their cycle bits.
37 textstore_handle handle3 = textstore_intern(&store, "Hello world.");
38 if (handle1 == handle3)
39 return 1;
40
41 // And trying to access a previously gc'd handle will still return an error,
42 // even if its index is in use.
43 invalid_string = textstore_string(&store, handle1);
44 if (invalid_string != NULL)
45 return 1;
46
47 // Likewise, interning the same string will result in identical handles.
48 textstore_handle handle4 = textstore_intern(&store, "Hello world.");
49 if (handle3 != handle4)
50 return 1;
51
52 // It's also possible to intern strings that aren't null-terminated.
53 textstore_handle handle5 = textstore_intern_len(&store, &(char){'.'}, 1);
54 // But the internally stored string is null-terminated for ecosystem compatibility.
55 if (strcmp(textstore_string(&store, handle5), ".") != 0)
56 return 1;
57
58 {
59 textstore_handle temp_handle;
60 temp_handle = textstore_intern(&store, "blah blah");
61 textstore_release(&store, temp_handle);
62 temp_handle = textstore_intern(&store, "random text");
63 textstore_release(&store, temp_handle);
64 temp_handle = textstore_intern(&store, "text");
65 textstore_release(&store, temp_handle);
66 temp_handle = textstore_intern(&store, "random text2");
67 textstore_release(&store, temp_handle);
68 }
69
70 textstore_handle handle6 = textstore_intern(&store, "All your bases...");
71 textstore_gc(&store);
72 // Even after a GC and the underlying text being invalidated and shifted
73 // about, valid handles can still be used.
74 if (strcmp(textstore_string(&store, handle6), "All your bases...") != 0)
75 return 1;
76
77 textstore_free(&store);
78
79 printf("All tests passed.\n");
80 return 0;
81}