From afec7f716d18d808390f5583e49aa3a07b32f8e4 Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 27 Dec 2022 12:28:04 -0800 Subject: [PATCH] KJV updated to test. --- Makefile | 2 +- src/kjv.h | 30 ++++++++- src/kjv.re_c.c | 158 ++++++++++++++++++++++++------------------------ test/test_kjv.c | 29 +++++++++ 4 files changed, 136 insertions(+), 83 deletions(-) create mode 100644 test/test_kjv.c diff --git a/Makefile b/Makefile index 40d2d20..94f9486 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ default: $(projects) # success bin/text: build/text.o build/test_text.o -bin/kjv: build/text.o build/kjv.o +bin/kjv: build/text.o build/kjv.o build/test_kjv.o bin/%: # linking test $@ diff --git a/src/kjv.h b/src/kjv.h index 7778d6a..0341d4b 100644 --- a/src/kjv.h +++ b/src/kjv.h @@ -1,3 +1,4 @@ +#ifndef KJV_OMIT_BASE /* */ + + +#ifndef KJV_OMIT_VERSES /* */ + + +#ifndef KJV_OMIT_PROTO /* */ diff --git a/src/kjv.re_c.c b/src/kjv.re_c.c index cd67b5a..27dd251 100644 --- a/src/kjv.re_c.c +++ b/src/kjv.re_c.c @@ -8,13 +8,65 @@ @std C11 */ #include "../src/text.h" -#include "../src/kjv.h" -#include +#define KJV_OMIT_VERSES +#define KJV_OMIT_PROTO +#include "../src/kjv.h" /* Just the base data. */ #include -#include +#include #include +#include #include /* opendir readdir closedir */ #include /* chdir (POSIX) (because I'm lazy) */ +/* #include No; overkill. */ + + +/* Reversible hash map. */ +/** + on `x`. */ +static uint32_t lowbias32(uint32_t x) { + x ^= x >> 16; + x *= 0x7feb352dU; + x ^= x >> 15; + x *= 0x846ca68bU; + x ^= x >> 16; + return x; +} +/* Inverts `x`. */ +static uint32_t lowbias32_r(uint32_t x) { + x ^= x >> 16; + x *= 0x43021123U; + x ^= x >> 15 ^ x >> 30; + x *= 0x1d69e2a5U; + x ^= x >> 16; + return x; +} + +static uint32_t kjv_hash(const union kjvcite x) { return lowbias32(x.u32); } +static union kjvcite kjv_unhash(const uint32_t x) + { union kjvcite k; k.u32 = lowbias32_r(x); return k; } +static void kjv_to_string(const union kjvcite x, char (*const a)[12]) + { sprintf(*a, "%.4s%u:%u", kjv_book_string[x.book], + (x.chapter + 1) % 1000, (x.verse + 1) % 1000); } +#define TABLE_NAME kjv +#define TABLE_KEY union kjvcite +#define TABLE_UINT uint32_t +#define TABLE_INVERSE +#define TABLE_TO_STRING +#include "../src/table.h" + +/* Derived information on verse word count. */ +static uint32_t verse_hash(const union kjvcite x) { return kjv_hash(x); } +static union kjvcite verse_unhash(const uint32_t x) { return kjv_unhash(x); } +static void verse_to_string(const union kjvcite x, const unsigned count, + char (*const a)[12]) { (void)count; kjv_to_string(x, a); } +#define TABLE_NAME verse +#define TABLE_KEY union kjvcite +#define TABLE_UINT uint32_t +#define TABLE_VALUE unsigned /* Count words. */ +#define TABLE_INVERSE +#define TABLE_DEFAULT 0 +#define TABLE_TO_STRING +#include "../src/table.h" /** Helper to parse unsigned; [`s`,`e`) => `n`. */ @@ -101,69 +153,24 @@ scan: } -/* Reversible hash map. */ -#include /* C99 */ -/** - on `x`. */ -static uint32_t lowbias32(uint32_t x) { - x ^= x >> 16; - x *= 0x7feb352dU; - x ^= x >> 15; - x *= 0x846ca68bU; - x ^= x >> 16; - return x; -} -/* Inverts `x`. */ -static uint32_t lowbias32_r(uint32_t x) { - x ^= x >> 16; - x *= 0x43021123U; - x ^= x >> 15 ^ x >> 30; - x *= 0x1d69e2a5U; - x ^= x >> 16; - return x; +#define KJV_OMIT_BASE +#define KJV_OMIT_VERSES +#include "../src/kjv.h" /* Just the kjv and prototypes. */ + +void kjv_(struct kjv *const kjv) { + if(!kjv) return; + verse_table_(&kjv->verses); } -static uint32_t kjv_hash(const union kjvcite x) { return lowbias32(x.u32); } -static union kjvcite kjv_unhash(const uint32_t x) - { union kjvcite k; k.u32 = lowbias32_r(x); return k; } -static void kjv_to_string(const union kjvcite x, char (*const a)[12]) - { sprintf(*a, "%.4s%u:%u", kjv_book_string[x.book], - (x.chapter + 1) % 1000, (x.verse + 1) % 1000); } -#define TABLE_NAME kjv -#define TABLE_KEY union kjvcite -#define TABLE_UINT uint32_t -#define TABLE_INVERSE -#define TABLE_TO_STRING -#include "../src/table.h" - -/* Derived information on verse word count. */ -static uint32_t verse_hash(const union kjvcite x) { return kjv_hash(x); } -static union kjvcite verse_unhash(const uint32_t x) { return kjv_unhash(x); } -static void verse_to_string(const union kjvcite x, const unsigned count, - char (*const a)[12]) { (void)count; kjv_to_string(x, a); } -#define TABLE_NAME verse -#define TABLE_KEY union kjvcite -#define TABLE_UINT uint32_t -#define TABLE_VALUE unsigned /* Count words. */ -#define TABLE_INVERSE -#define TABLE_DEFAULT 0 -#define TABLE_TO_STRING -#include "../src/table.h" - - -int main(void) { +struct kjv kjv(void) { const char *const dir_kjv = "kjv"; - struct { - struct text backing; - struct verse_table verses; - size_t words; - } kjv = { 0 }; + struct text backing; + struct kjv kjv = { 0 }; DIR *dir = 0; struct dirent *de = 0; struct { size_t offset; int is; } build[KJV_BOOK_SIZE] = { 0 }; enum kjv_book b = 0; - int success = EXIT_SUCCESS, attempted_closedir = 0; - errno = 0; + int attempted_closedir = 0; /* For all files in directory KJV with <#>*.txt, read into backing. */ if(chdir(dir_kjv) == -1 || !(dir = opendir("."))) goto catch; @@ -176,10 +183,10 @@ int main(void) { { errno = ERANGE; goto catch; } /* Not in range. */ if(build[b = ordinal - 1].is) /* Convert to zero-based. */ { errno = EDOM; goto catch; } /* Is duplicate. */ - if(!(unstable_book = text_append_file(&kjv.backing, de->d_name))) + if(!(unstable_book = text_append_file(&backing, de->d_name))) goto catch; build[b].is = 1; - build[b].offset = (size_t)(unstable_book - kjv.backing.a.data); + build[b].offset = (size_t)(unstable_book - backing.a.data); } if(attempted_closedir = 1, closedir(dir) == -1) goto catch; dir = 0; @@ -188,7 +195,7 @@ int main(void) { struct lex x; if(!build[b].is) { fprintf(stderr, "Missing book [%u]%s.\n", b + 1, kjv_book_string[b]); errno = EDOM; goto catch; } - x = lex(kjv.backing.a.data + build[b].offset); + x = lex(backing.a.data + build[b].offset); while(lex_next_verse(&x)) { const union kjvcite cite = { .book = b, .chapter = x.chapter, .verse = x.verse }; @@ -204,27 +211,20 @@ int main(void) { if(x.error) { fprintf(stderr, "[%u]%s on line %zu\n", b + 1, kjv_book_string[b], x.line); goto catch; } } - - printf("words: %s\n", verse_table_to_string(&kjv.verses)); - printf("kjv: %zu total words\n", kjv.words); - { - union kjvcite c; - struct verse_table_iterator it = verse_table_begin(&kjv.verses); - unsigned *w; - while(verse_table_next(&it, &c, &w)) - printf("%s %u:%u -> %u\n", - kjv_book_string[c.book], c.chapter, c.verse, *w); - c = (union kjvcite){ .book = Genesis, .chapter = 1, .verse = 1 }; - printf("1:1:1 -> %u\n", verse_table_get(&kjv.verses, c)); - } goto finally; catch: - success = EXIT_FAILURE; if(de) fprintf(stderr, "While reading %s.\n", de->d_name); perror(de ? de->d_name : dir_kjv); if(dir && !attempted_closedir && closedir(dir) == -1) perror(dir_kjv); + kjv_(&kjv); finally: - verse_table_(&kjv.verses); - text_(&kjv.backing); - return success; + text_(&backing); + return kjv; } + +unsigned kjv_words(/*const*/ struct kjv *const kjv, const union kjvcite cite) { + return kjv && verse_table_get(&kjv->verses, cite); +} + +const char *kjv_entire_to_string(const struct kjv *const kjv) + { return kjv ? verse_table_to_string(&kjv->verses) : ""; } diff --git a/test/test_kjv.c b/test/test_kjv.c new file mode 100644 index 0000000..78d1168 --- /dev/null +++ b/test/test_kjv.c @@ -0,0 +1,29 @@ +#include "../src/kjv.h" +#include +#include /* C99 */ +#include + +int main(void) { + struct kjv k = kjv(); + union kjvcite c; + /*struct verse_table_iterator it = verse_table_begin(&kjv.verses);*/ + unsigned *verses; + /* printf("%%{\n" + "#include \"../src/kjv.h\"\n" + "%%}\n" + "struct kjvverse { uint32_t name; unsigned words; };\n" + "%%%%\n"); I don't even think this is possible 1.44 bits/key. */ + + /*while(verse_table_next(&it, &c, &verses)) + printf("%" PRIu32 ", %u\n", c.u32, *verses);*/ + /*printf("%s %u:%u -> %u\n", + kjv_book_string[c.book], c.chapter, c.verse, *verses);*/ + /*c = (union kjvcite){ .book = Genesis, .chapter = 1, .verse = 1 }; + printf("1:1:1 -> %u\n", verse_table_get(&kjv.verses, c));*/ + /*c = (union kjvcite){ .book = Genesis, .chapter = 1, .verse = 1 }; + printf("1:1:1 -> %u\n", verse_table_get(&kjv.verses, c));*/ + + fprintf(stderr, "%zu total words, %s\n", k.words, kjv_entire_to_string(&k)); + kjv_(&k); + return EXIT_SUCCESS; +}