callback is to much steps; have verse tree

This commit is contained in:
Neil 2023-03-12 20:43:27 -07:00
parent d137919d13
commit 4db31489c2
7 changed files with 67 additions and 45 deletions

View File

@ -35,7 +35,7 @@ struct journal { struct day_tree days; struct text backing; };
struct journal_iterator { struct day_tree_iterator _; };
struct journal journal(void);
void journal_(struct journal *);
/*int journal_is_valid(const struct journal *);*/
int journal_is_empty(const struct journal *);
const char *journal_to_string(const struct journal *);
struct journal_iterator journal_iterator(struct journal *const j);
int journal_next(struct journal_iterator *, union date32 *, const char **);

View File

@ -1,4 +1,9 @@
/** Reading all journal entries in yyyy/mm/dd.txt.
/** @license 2022 Neil Edelman, distributed under the terms of the
[GNU General Public License 3](https://opensource.org/licenses/GPL-3.0).
Reading all journal entries yyyy-mm-dd in yyyy/mm/dd.txt to a tree.
[re2c](https://re2c.org/) is a convince (and fast) for "looks like" functions,
telling the recursion to go into a directory.
@std GNU, C11, assumes reverse order unions. */
#define BASE
@ -13,6 +18,7 @@
#include <sys/stat.h> /* umask (POSIX) */
#include <dirent.h> /* opendir readdir closedir */
/* Day tree-map from date to pointer; is backed by a huge array of text. */
void date32_to_string(const union date32 d, char (*const a)[12]) {
sprintf(*a, "%" PRIu32 "-%2.2" PRIu32 "-%2.2" PRIu32,
d.year % 10000, d.month % 100, d.day % 100);
@ -24,11 +30,11 @@ static void day_to_string(const union date32 d, const char *const*const entry,
#define TREE_NAME day
#define TREE_KEY union date32
#define TREE_VALUE const char *
#define TREE_COMPARE
#define TREE_TO_STRING
#define TREE_COMPARE /* <fn:day_compare> custom comparison. */
#define TREE_TO_STRING /* <fn:day_to_string> printing day. */
#include "../src/tree.h"
/* Temporary filename arrangement. */
/* Temporary filename arrangement in directory. */
#if INT_MAX >= 100000000000
#error int_to_string requires truncation on this compiler.
#endif
@ -109,7 +115,8 @@ void journal_(struct journal *const j) {
text_(&j->backing);
}
/** @return A completed journal out of "journal". */
/** @return A completed journal out of "journal". Any reading errors and
`errno` will be set, it will be idle. */
struct journal journal(void) {
const char *const dir_journal = "journal";
struct journal j = {0};
@ -221,14 +228,14 @@ recatch:
journal_(&j);
finally:
if(dir) { if(closedir(dir)) { dir = 0; goto recatch; } dir = 0; }
int_array_(&years), int_array_(&months), int_array_(&days);
int_array_(&years), int_array_(&months), int_array_(&days); /* Temporary. */
return j;
}
/** @return `j` read in some data? */
/*int journal_is_valid(const struct journal *const j) {
return j && j->days.root.node && j->backing.a.data;
}*/
int journal_is_empty(const struct journal *const j) {
return !j || !j->days.root.node || !j->backing.a.data;
}
/** @return `j` as a string. */
const char *journal_to_string(const struct journal *const j)

View File

@ -110,7 +110,7 @@ struct kjv {
};
struct kjv kjv(void);
void kjv_(struct kjv *);
int kjv_is_valid(const struct kjv *const kjv);
int kjv_is_empty(const struct kjv *const kjv);
/* Only used in test. */
int kjv_add(struct kjv *const kjv, const union kjvcite cite);
const char *kjv_to_string(const struct kjv *const kjv);

View File

@ -213,20 +213,15 @@ catch:
recatch:
kjv_(&kjv);
finally:
printf("kjv: %s.\n", kjv_to_string(&kjv));
printf("kjv: closedir errno %d\n", errno);
if(dir) { if(closedir(dir)) { dir = 0; goto recatch; } dir = 0; }
printf("kjv: is_in_kjv errno %d\n", errno);
if(is_in_kjv && (is_in_kjv = 0, chdir("..") == -1)) goto recatch;
printf("kjv: ~text(backing) errno %d\n", errno);
text_(&backing);
printf("kjv: %p errno %d\n", (void *)&kjv, errno);
return kjv;
}
/** Has loaded properly? Otherwise, probably `errno` is set. */
int kjv_is_valid(const struct kjv *const kjv)
{ return kjv && kjv->verses.buckets; }
int kjv_is_empty(const struct kjv *const kjv)
{ return !kjv || !kjv->verses.buckets; }
/** Adds `cite` to `kjv` if not present. Only used in test.
@return Is the kjv still valid. */

View File

@ -17,7 +17,7 @@ struct pair pair(const char *const a, const char *const b) {
return p;
}
/** Doesn't check anything.
/** Doesn't check if the number is actually in [0, 9].
@return Whether it was able to parse unsigned `p` to `n`. */
int pair_to_natural(const char *s, const char *const e, uint32_t *const n) {
uint32_t accum = 0;
@ -49,6 +49,7 @@ int pair_hours_to_minutes(const char *h0, const char *const h1,
? (*n = hours * 60 + minutes * 6, 1) : 0;
}
/** @return The content of `x` is the same as `y`. */
int pair_is_equal(struct pair x, struct pair y) {
assert(x.a <= x.b && y.a <= y.b);
if(!x.a) return !y.a;
@ -58,6 +59,8 @@ int pair_is_equal(struct pair x, struct pair y) {
return 1;
}
/** @return Exact match between a pair `x` (start-end pointers) and a string
`y` (null-terminated). */
int pair_is_string(struct pair x, const char *y) {
assert(x.a <= x.b);
if(!x.a) return !y;
@ -66,7 +69,7 @@ int pair_is_string(struct pair x, const char *y) {
return !*y;
}
/** djb2 <http://www.cse.yorku.ca/~oz/hash.html> */
/** @return A djb2 <http://www.cse.yorku.ca/~oz/hash.html> hash of `p`. */
uint32_t pair_djb2(struct pair p) {
uint32_t hash = 5381, c;
while(p.a < p.b) {

View File

@ -13,16 +13,20 @@
#include <assert.h>
#include <limits.h>
/* Callback is stupid; separate into tree with line and verse, and then more
processing. */
typedef int (*scan_callback)(struct kjv *, union line64, union kjvcite,
uint32_t);
/*!conditions:re2c*/
static int scan(union date32 date, const char *const buffer,
struct kjv *const kj) {
const scan_callback callback, struct kjv *const kj) {
const char *YYCURSOR, *YYMARKER, *yyt1, *yyt2, *yyt3, *s0, *s1, *t0, *t1;
enum kjv_book book = Revelation;
uint32_t chapter = 0, verse = 0, verse_end = 0;
enum YYCONDTYPE condition = yycline;
size_t line = 1;
char datestr[12] = {0};
const char *why = "unexpected";
assert(buffer && kj);
YYCURSOR = YYMARKER = yyt1 = buffer;
@ -150,25 +154,13 @@ static int scan(union date32 date, const char *const buffer,
continue;
}
<book> engage => skip {
char citestr[12];
if(!chapter || !verse) { why = "missing information"; goto catch; }
if(verse_end && verse_end <= verse)
{ why = "interval error"; goto catch; }
union kjvcite cite
= { .book = book, .chapter = chapter, .verse = verse };
if(!datestr[0]) date32_to_string(date, &datestr); /* Only once. */
kjvcite_to_string(cite, &citestr);
for( ; ; verse++, cite.verse++) {
if(!kjv_add(kj, cite)) { why = "add to set"; goto catch; }
if(!verse_end || verse_end <= verse) break;
}
printf("%s\t%zu\t%zu\t%zu\t# ",
datestr, kj->words.verse, kj->words.set, kj->words.cumulative);
if(verse_end) {
printf("%s-%" PRIu32 "\n", citestr, verse_end);
} else {
printf("%s\n", citestr);
}
if(!callback(kj, date, cite, verse_end))
{ why = "add to set"; goto catch; }
book = Revelation, chapter = 0, verse = 0, verse_end = 0;
continue;
}
@ -176,32 +168,56 @@ static int scan(union date32 date, const char *const buffer,
assert(0); /* Never gets here. */
catch:
if(!errno) errno = EILSEQ;
date32_to_string(date, &datestr);
fprintf(stderr, "%s\n"
"%s line %zu: %s.\n", buffer, datestr, line, why);
{
char datestr[12];
date32_to_string(date, &datestr);
fprintf(stderr, "%s\n"
"%s line %zu: %s.\n", buffer, datestr, line, why);
}
return 0;
}
static int add_to_set(struct kjv *const kj, const union line64 line,
union kjvcite cite, const uint32_t verse_end) {
char citestr[12], datestr[12];
const struct source *src = source_lookup(&s, line);
assert(src); if(!src->name.a) { errno = EDOM; goto catch; }
kjvcite_to_string(cite, &citestr);
for( ; ; cite.verse++) {
if(!kjv_add(kj, cite)) return 0;
if(!verse_end || verse_end <= cite.verse) break;
}
date32_to_string(date, &datestr);
printf("%s\t%zu\t%zu\t%zu\t# ",
datestr, kj->words.verse, kj->words.set, kj->words.cumulative);
if(verse_end) {
printf("%s-%" PRIu32 "\n", citestr, verse_end);
} else {
printf("%s\n", citestr);
}
return 1;
}
int main(void) {
int success = EXIT_SUCCESS;
const char *reason = "unknown";
errno = 0;
struct journal j;
struct journal_iterator it;
printf("1. kjv\n");
struct kjv bible = kjv();
if(errno) { printf("kjv?\n"); goto catch; }
if(kjv_is_empty(&bible)) { reason = "kjv failed to load"; goto catch; }
union date32 k;
const char *v;
printf("2. journal\n");
j = journal();
if(errno) goto catch;
if(journal_is_empty(&j)) { reason = "journal failed to load"; goto catch; }
fprintf(stderr, "Journal: %s.\n", journal_to_string(&j));
printf("set term postscript eps enhanced\n"
"set output \"kjv.eps\"\n"
"$Data <<EOD\n"
"# date\tverse\tset\tcumulative / %zu\n", bible.words.total);
it = journal_iterator(&j);
while(journal_next(&it, &k, &v)) if(!scan(k, v, &bible)) goto catch;
while(journal_next(&it, &k, &v))
if(!scan(k, v, &add_to_set, &bible)) goto catch;
printf("EOD\n"
"set monochrome\n"
"set xdata time\n"
@ -220,6 +236,7 @@ int main(void) {
catch:
success = EXIT_FAILURE;
perror("journal");
fprintf(stderr, "Details: %s.\n", reason);
finally:
kjv_(&bible);
journal_(&j);

View File

@ -10,7 +10,7 @@ int main(void) {
errno = 0; /* `errno` is not set correctly to 0 in some debug situations. */
struct kjv k = kjv();
fprintf(stderr, "%zu total words, %s.\n", k.words.total, kjv_to_string(&k));
if(!kjv_is_valid(&k)) goto catch;
if(kjv_is_empty(&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 });