Fixed the off-by-one.
This commit is contained in:
parent
a89873d4b0
commit
a795b70859
@ -110,6 +110,7 @@ struct kjv {
|
|||||||
};
|
};
|
||||||
struct kjv kjv(void);
|
struct kjv kjv(void);
|
||||||
void kjv_(struct kjv *);
|
void kjv_(struct kjv *);
|
||||||
|
int kjv_is_valid(const struct kjv *const kjv);
|
||||||
int kjv_add(struct kjv *const kjv, const union kjvcite cite);
|
int kjv_add(struct kjv *const kjv, const union kjvcite cite);
|
||||||
const char *kjv_to_string(const struct kjv *const kjv);
|
const char *kjv_to_string(const struct kjv *const kjv);
|
||||||
const char *kjv_set_to_string(const struct kjv *const kjv);
|
const char *kjv_set_to_string(const struct kjv *const kjv);
|
||||||
|
@ -46,7 +46,7 @@ static union kjvcite kjvset_unhash(const uint32_t x)
|
|||||||
{ union kjvcite k; k.u32 = lowbias32_r(x); return k; }
|
{ union kjvcite k; k.u32 = lowbias32_r(x); return k; }
|
||||||
static void kjvset_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],
|
{ sprintf(*a, "%.4s%u:%u", kjv_book_string[x.book],
|
||||||
(x.chapter + 1) % 1000, (x.verse + 1) % 1000); }
|
x.chapter % 1000, x.verse % 1000); }
|
||||||
#define TABLE_NAME kjvset
|
#define TABLE_NAME kjvset
|
||||||
#define TABLE_KEY union kjvcite
|
#define TABLE_KEY union kjvcite
|
||||||
#define TABLE_UINT uint32_t
|
#define TABLE_UINT uint32_t
|
||||||
@ -157,12 +157,14 @@ scan:
|
|||||||
#define KJV_OMIT_VERSES
|
#define KJV_OMIT_VERSES
|
||||||
#include "../src/kjv.h" /* Just the kjv and prototypes. */
|
#include "../src/kjv.h" /* Just the kjv and prototypes. */
|
||||||
|
|
||||||
|
/** Frees `kjv`. */
|
||||||
void kjv_(struct kjv *const kjv) {
|
void kjv_(struct kjv *const kjv) {
|
||||||
if(!kjv) return;
|
if(!kjv) return;
|
||||||
kjvset_table_(&kjv->set);
|
kjvset_table_(&kjv->set);
|
||||||
verse_table_(&kjv->verses);
|
verse_table_(&kjv->verses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Loads 66 files from the "kjv/" directory. */
|
||||||
struct kjv kjv(void) {
|
struct kjv kjv(void) {
|
||||||
const char *const dir_kjv = "kjv";
|
const char *const dir_kjv = "kjv";
|
||||||
struct text backing;
|
struct text backing;
|
||||||
@ -177,17 +179,17 @@ struct kjv kjv(void) {
|
|||||||
if(chdir(dir_kjv) == -1 || !(dir = opendir("."))) goto catch;
|
if(chdir(dir_kjv) == -1 || !(dir = opendir("."))) goto catch;
|
||||||
while((de = readdir(dir))) {
|
while((de = readdir(dir))) {
|
||||||
unsigned ordinal;
|
unsigned ordinal;
|
||||||
char *unstable_book;
|
char *unstable_backing;
|
||||||
if(!looks_like_book_fn(de->d_name, &ordinal)) continue;
|
if(!looks_like_book_fn(de->d_name, &ordinal)) continue;
|
||||||
/*fprintf(stderr, "<%s> ordinal: %u\n", de->d_name, ordinal);*/
|
/*fprintf(stderr, "<%s> ordinal: %u\n", de->d_name, ordinal);*/
|
||||||
if(ordinal < 1 || ordinal > KJV_BOOK_SIZE)
|
if(ordinal < 1 || ordinal > KJV_BOOK_SIZE)
|
||||||
{ errno = ERANGE; goto catch; } /* Not in range. */
|
{ errno = ERANGE; goto catch; } /* Not in range. */
|
||||||
if(build[b = ordinal - 1].is) /* Convert to zero-based. */
|
if(build[b = ordinal - 1].is) /* Convert to zero-based. */
|
||||||
{ errno = EDOM; goto catch; } /* Is duplicate. */
|
{ errno = EDOM; goto catch; } /* Is duplicate. */
|
||||||
if(!(unstable_book = text_append_file(&backing, de->d_name)))
|
if(!(unstable_backing = text_append_file(&backing, de->d_name)))
|
||||||
goto catch;
|
goto catch;
|
||||||
build[b].is = 1;
|
build[b].is = 1;
|
||||||
build[b].offset = (size_t)(unstable_book - backing.a.data);
|
build[b].offset = (size_t)(unstable_backing - backing.a.data);
|
||||||
}
|
}
|
||||||
if(attempted_closedir = 1, closedir(dir) == -1) goto catch; dir = 0;
|
if(attempted_closedir = 1, closedir(dir) == -1) goto catch; dir = 0;
|
||||||
|
|
||||||
@ -215,7 +217,6 @@ struct kjv kjv(void) {
|
|||||||
goto finally;
|
goto finally;
|
||||||
catch:
|
catch:
|
||||||
if(de) fprintf(stderr, "While reading %s.\n", de->d_name);
|
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);
|
if(dir && !attempted_closedir && closedir(dir) == -1) perror(dir_kjv);
|
||||||
kjv_(&kjv);
|
kjv_(&kjv);
|
||||||
finally:
|
finally:
|
||||||
@ -223,6 +224,11 @@ finally:
|
|||||||
return kjv;
|
return kjv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Has loaded properly? Otherwise, probably `errno` is set. */
|
||||||
|
int kjv_is_valid(const struct kjv *const kjv)
|
||||||
|
{ return kjv && kjv->verses.buckets; }
|
||||||
|
|
||||||
|
/** Adds `cite` to `kjv` if not present. @return Is the kjv still valid. */
|
||||||
int kjv_add(struct kjv *const kjv, const union kjvcite cite) {
|
int kjv_add(struct kjv *const kjv, const union kjvcite cite) {
|
||||||
if(!kjv) return 0;
|
if(!kjv) return 0;
|
||||||
switch(kjvset_table_try(&kjv->set, cite)) {
|
switch(kjvset_table_try(&kjv->set, cite)) {
|
||||||
|
@ -4,28 +4,18 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
int success = EXIT_SUCCESS;
|
||||||
struct kjv k = kjv();
|
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.total_words, kjv_to_string(&k));
|
fprintf(stderr, "%zu total words, %s.\n", k.total_words, kjv_to_string(&k));
|
||||||
|
if(!kjv_is_valid(&k)) goto catch;
|
||||||
|
kjv_add(&k, (union kjvcite){ .book = Genesis, .chapter = 1, .verse = 1 });
|
||||||
|
kjv_add(&k, (union kjvcite){ .book = Genesis, .chapter = 1, .verse = 2 });
|
||||||
kjv_add(&k, (union kjvcite){ .book = Genesis, .chapter = 1, .verse = 1 });
|
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));
|
fprintf(stderr, "%zu of which: %s.\n", k.set_words, kjv_set_to_string(&k));
|
||||||
|
goto finally;
|
||||||
|
catch:
|
||||||
|
success = EXIT_FAILURE, perror("kjv");
|
||||||
|
finally:
|
||||||
kjv_(&k);
|
kjv_(&k);
|
||||||
return EXIT_SUCCESS;
|
return success;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user