Off by one error in the interface.

This commit is contained in:
Neil 2022-12-27 13:01:51 -08:00
parent afec7f716d
commit a89873d4b0
3 changed files with 37 additions and 15 deletions

View File

@ -86,6 +86,11 @@ union kjvcite {
#ifndef KJV_OMIT_VERSES /* <!-- verses: For external inclusion. */
struct table_kjvset_bucket;
struct kjvset_table {
struct table_kjvset_bucket *buckets;
uint32_t log_capacity, size, top;
};
struct table_verse_bucket;
struct verse_table {
struct table_verse_bucket *buckets;
@ -98,11 +103,16 @@ struct verse_table {
#ifndef KJV_OMIT_PROTO /* <!-- proto */
#include <stddef.h>
struct kjv { struct verse_table verses; size_t words; };
struct kjv {
struct kjvset_table set;
struct verse_table verses;
size_t total_words, set_words;
};
struct kjv kjv(void);
void kjv_(struct kjv *);
unsigned kjv_words(/*const*/ struct kjv *const kjv, const union kjvcite cite);
const char *kjv_entire_to_string(const struct kjv *const kjv);
int kjv_add(struct kjv *const kjv, const union kjvcite cite);
const char *kjv_to_string(const struct kjv *const kjv);
const char *kjv_set_to_string(const struct kjv *const kjv);
#else /* proto --><!-- !proto */
#undef KJV_OMIT_PROTO
#endif /* !proto --> */

View File

@ -41,13 +41,13 @@ static uint32_t lowbias32_r(uint32_t x) {
return x;
}
static uint32_t kjv_hash(const union kjvcite x) { return lowbias32(x.u32); }
static union kjvcite kjv_unhash(const uint32_t x)
static uint32_t kjvset_hash(const union kjvcite x) { return lowbias32(x.u32); }
static union kjvcite kjvset_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])
static void kjvset_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_NAME kjvset
#define TABLE_KEY union kjvcite
#define TABLE_UINT uint32_t
#define TABLE_INVERSE
@ -55,10 +55,10 @@ static void kjv_to_string(const union kjvcite x, char (*const a)[12])
#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 uint32_t verse_hash(const union kjvcite x) { return kjvset_hash(x); }
static union kjvcite verse_unhash(const uint32_t x) { return kjvset_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); }
char (*const a)[12]) { (void)count; kjvset_to_string(x, a); }
#define TABLE_NAME verse
#define TABLE_KEY union kjvcite
#define TABLE_UINT uint32_t
@ -159,6 +159,7 @@ scan:
void kjv_(struct kjv *const kjv) {
if(!kjv) return;
kjvset_table_(&kjv->set);
verse_table_(&kjv->verses);
}
@ -206,7 +207,7 @@ struct kjv kjv(void) {
case TABLE_ERROR: goto catch;
case TABLE_ABSENT: break;
}
*words = x.words, kjv.words += x.words;
*words = x.words, kjv.total_words += x.words;
}
if(x.error) { fprintf(stderr, "[%u]%s on line %zu\n",
b + 1, kjv_book_string[b], x.line); goto catch; }
@ -222,9 +223,18 @@ finally:
return kjv;
}
unsigned kjv_words(/*const*/ struct kjv *const kjv, const union kjvcite cite) {
return kjv && verse_table_get(&kjv->verses, cite);
int kjv_add(struct kjv *const kjv, const union kjvcite cite) {
if(!kjv) return 0;
switch(kjvset_table_try(&kjv->set, cite)) {
case TABLE_ERROR: return 0;
case TABLE_ABSENT: kjv->set_words += verse_table_get(&kjv->verses, cite);
case TABLE_PRESENT: break;
}
return 1;
}
const char *kjv_entire_to_string(const struct kjv *const kjv)
const char *kjv_to_string(const struct kjv *const kjv)
{ return kjv ? verse_table_to_string(&kjv->verses) : ""; }
const char *kjv_set_to_string(const struct kjv *const kjv)
{ return kjv ? kjvset_table_to_string(&kjv->set) : 0; }

View File

@ -23,7 +23,9 @@ int main(void) {
/*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));
fprintf(stderr, "%zu total words, %s.\n", k.total_words, kjv_to_string(&k));
kjv_add(&k, (union kjvcite){ .book = Genesis, .chapter = 1, .verse = 1 });
fprintf(stderr, "%zu of which: %s.\n", k.set_words, kjv_set_to_string(&k));
kjv_(&k);
return EXIT_SUCCESS;
}