C11 is slightly useful for some things.

This commit is contained in:
Neil 2022-12-14 21:26:47 -08:00
parent ad991396d8
commit 2807b5704d
1 changed files with 19 additions and 17 deletions

View File

@ -246,8 +246,9 @@ static uint32_t lowbias32_r(uint32_t x) {
}
union kjvcite {
/* Overkill, but no initializing unused bits, 12 + 13 + 7 = 32. */
struct { unsigned verse : 12, chapter : 13, book : 7; };
uint32_t u32;
struct { unsigned verse : 8, chapter : 8, book : 7; };
};
static uint32_t kjv_hash(const union kjvcite x) { return lowbias32(x.u32); }
@ -260,12 +261,12 @@ 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); }
static uint32_t words_hash(const union kjvcite x) { return kjv_hash(x); }
static union kjvcite words_unhash(const uint32_t x) { return kjv_unhash(x); }
static void words_to_string(const union kjvcite x, char (*const a)[12])
static uint32_t kjvword_hash(const union kjvcite x) { return kjv_hash(x); }
static union kjvcite kjvword_unhash(const uint32_t x) { return kjv_unhash(x); }
static void kjvword_to_string(const union kjvcite x, char (*const a)[12])
{ kjv_to_string(x, a); }
#define TABLE_NAME words
#define TABLE_NAME kjvword
#define TABLE_KEY union kjvcite
#define TABLE_UINT uint32_t
#define TABLE_VALUE unsigned
@ -289,7 +290,7 @@ static void kjvset_to_string(const union kjvcite x, char (*const a)[12])
int main(void) {
const char *const dir_name = "KJV";
struct char_array kjv[KJV_BOOK_SIZE] = { 0 };
struct words_table words = { 0 };
struct kjvword_table words = { 0 };
int success = EXIT_SUCCESS;
DIR *dir = 0;
struct dirent *de = 0;
@ -314,18 +315,18 @@ int main(void) {
}
closedir(dir), de = 0, dir = 0;
/* Parse number of words. */
/* Parse number of words in each verse. */
for(i = 0; i < KJV_BOOK_SIZE; i++) {
struct lex x = lex(kjv[i].data);
if(!x.cursor) { fprintf(stderr, "Missing book [%u]%s.\n",
i + 1, kjv_book_string[i]); errno = EDOM; goto catch; }
printf("[%u]%s: cumulative %zu.\n",
i + 1, kjv_book_string[i], cum_words);
/*printf("[%u]%s: cumulative %zu.\n",
i + 1, kjv_book_string[i], cum_words);*/
while(lex_next_verse(&x)) {
const union kjvcite c
= { .verse = x.verse, .chapter = x.chapter, .book = i };
unsigned *w;
switch(words_table_assign(&words, c, &w)) {
switch(kjvword_table_assign(&words, c, &w)) {
case TABLE_PRESENT: fprintf(stderr, "[%u]%s %u:%u duplicated.\n",
i + 1, kjv_book_string[i], x.chapter, x.verse); errno = EDOM;
case TABLE_ERROR: goto catch;
@ -336,19 +337,18 @@ int main(void) {
if(x.error) { fprintf(stderr, "[%u]%s on line %zu\n",
i + 1, kjv_book_string[i], x.line); goto catch; }
}
printf("words: %s\n", words_table_to_string(&words));
printf("kjv: %zu words\n", cum_words);
printf("words: %s\n", kjvword_table_to_string(&words));
printf("kjv: %zu total words\n", cum_words);
{
union kjvcite c;
struct words_table_iterator it = words_table_begin(&words);
struct kjvword_table_iterator it = kjvword_table_begin(&words);
unsigned *w;
while(words_table_next(&it, &c, &w))
while(kjvword_table_next(&it, &c, &w))
printf("%s %u:%u -> %u\n",
kjv_book_string[c.book], c.chapter, c.verse, *w);
c.u32 = 0; /* Unnecessary? */
c.book = Genesis, c.chapter = 1, c.verse = 1;
printf("1:1:1 -> %u\n", words_table_get(&words, c));
c = (union kjvcite){ .book = Genesis, .chapter = 1, .verse = 1 };
printf("1:1:1 -> %u\n", kjvword_table_get(&words, c));
}
goto finally;
catch:
@ -356,6 +356,8 @@ catch:
perror(de ? de->d_name : dir_name);
if(dir && closedir(dir)) perror(dir_name);
finally:
/*kjvset_table_();*/
kjvword_table_(&words);
for(i = 0; i < KJV_BOOK_SIZE; i++) char_array_(kjv + i);
return success;
}