Off by one error in the interface.
This commit is contained in:
parent
afec7f716d
commit
a89873d4b0
16
src/kjv.h
16
src/kjv.h
@ -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 --> */
|
||||
|
@ -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; }
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user