Have to have some kind of persistent data.
This commit is contained in:
parent
f00ed7f1bf
commit
0236cab5d5
|
@ -11,6 +11,7 @@
|
||||||
#include <unistd.h> /* chdir (POSIX) (because I'm lazy) */
|
#include <unistd.h> /* chdir (POSIX) (because I'm lazy) */
|
||||||
|
|
||||||
|
|
||||||
|
/* Dynamic contiguous string that is used to load files. */
|
||||||
|
|
||||||
#define ARRAY_NAME char
|
#define ARRAY_NAME char
|
||||||
#define ARRAY_TYPE char
|
#define ARRAY_TYPE char
|
||||||
|
@ -46,7 +47,8 @@ finally:
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** [`s`,`e`) => `n` */
|
|
||||||
|
/** Helper to parse unsigned; [`s`,`e`) => `n`. */
|
||||||
static int parse_natural(const char *s, const char *const e, unsigned *const n) {
|
static int parse_natural(const char *s, const char *const e, unsigned *const n) {
|
||||||
unsigned accum = 0;
|
unsigned accum = 0;
|
||||||
while(s < e) {
|
while(s < e) {
|
||||||
|
@ -60,6 +62,7 @@ static int parse_natural(const char *s, const char *const e, unsigned *const n)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Enumerate books. */
|
||||||
|
|
||||||
#define BOOKS \
|
#define BOOKS \
|
||||||
X(Genesis),\
|
X(Genesis),\
|
||||||
|
@ -139,6 +142,10 @@ static const char *kjv_book_string[] = { BOOKS };
|
||||||
#undef X
|
#undef X
|
||||||
#undef BOOKS
|
#undef BOOKS
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse filename of books. This works with
|
||||||
|
<https://github.com/scrollmapper/bible_databases/tree/master/txt/KJV> */
|
||||||
|
|
||||||
/*!re2c /**/
|
/*!re2c /**/
|
||||||
re2c:yyfill:enable = 0;
|
re2c:yyfill:enable = 0;
|
||||||
re2c:define:YYCTYPE = char;
|
re2c:define:YYCTYPE = char;
|
||||||
|
@ -160,6 +167,9 @@ static int kjv_filename(const char *fn, unsigned *const book_no) {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Parse book contents. */
|
||||||
|
|
||||||
struct lex {
|
struct lex {
|
||||||
size_t line;
|
size_t line;
|
||||||
const char *cursor;
|
const char *cursor;
|
||||||
|
@ -192,23 +202,29 @@ static int lex_next_verse(struct lex *const lex) {
|
||||||
lex->error = 0;
|
lex->error = 0;
|
||||||
scan:
|
scan:
|
||||||
/*!re2c /**/
|
/*!re2c /**/
|
||||||
<*> * { printf("catch\n"); return errno = EILSEQ, lex->error = 1, 0; }
|
<*> * { return errno = EILSEQ, lex->error = 1, 0; }
|
||||||
<line> [^[\]\n\x00]* "\n" { printf("comment\n"); lex->line++; goto scan; }
|
<line> [^[\]\n\x00]* "\n" { lex->line++; goto scan; }
|
||||||
<line> "\x00" { printf("eof\n"); return 0; }
|
<line> "\x00" { return 0; }
|
||||||
<line> "[" @s0 natural @s1 ":" @t0 natural @t1 "]" => verse {
|
<line> "[" @s0 natural @s1 ":" @t0 natural @t1 "]" => verse {
|
||||||
if(!parse_natural(s0, s1, &lex->chapter)
|
if(!parse_natural(s0, s1, &lex->chapter)
|
||||||
|| !parse_natural(t0, t1, &lex->verse))
|
|| !parse_natural(t0, t1, &lex->verse))
|
||||||
return errno = EILSEQ, lex->error = 1, 0;
|
return errno = EILSEQ, lex->error = 1, 0;
|
||||||
lex->words = 0;
|
lex->words = 0;
|
||||||
printf("%u:%u", lex->chapter, lex->verse);
|
/*printf("%u:%u", lex->chapter, lex->verse);*/
|
||||||
goto scan;
|
goto scan;
|
||||||
}
|
}
|
||||||
<verse> whitespace+ { goto scan; }
|
<verse> whitespace+ { goto scan; }
|
||||||
<verse> @s0 word @s1 { lex->words++; goto scan; }
|
<verse> @s0 word @s1 { lex->words++; goto scan; }
|
||||||
<verse> "\n" { printf(" -> %u\n", lex->words); lex->line++; return 1; }
|
<verse> "\n" { /*printf(" -> %u\n", lex->words);*/ lex->line++; return 1; }
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Reversible hash map to store data on bible. */
|
||||||
|
|
||||||
|
/* */
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
const char *const dir_name = "KJV";
|
const char *const dir_name = "KJV";
|
||||||
struct char_array kjv[KJV_BOOK_SIZE] = { 0 };
|
struct char_array kjv[KJV_BOOK_SIZE] = { 0 };
|
||||||
|
@ -226,8 +242,8 @@ int main(void) {
|
||||||
unsigned ordinal;
|
unsigned ordinal;
|
||||||
enum kjv_book b;
|
enum kjv_book b;
|
||||||
if(!kjv_filename(de->d_name, &ordinal)) /* Extract ordinal. */
|
if(!kjv_filename(de->d_name, &ordinal)) /* Extract ordinal. */
|
||||||
{ fprintf(stderr, "Ignored <%s>.\n", de->d_name); continue; }
|
{ /*fprintf(stderr, "Ignored <%s>.\n", de->d_name);*/ 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(kjv[b = ordinal - 1].data) /* Convert to zero-based. */
|
if(kjv[b = ordinal - 1].data) /* Convert to zero-based. */
|
||||||
|
@ -239,11 +255,12 @@ int main(void) {
|
||||||
/* Parse. */
|
/* Parse. */
|
||||||
for(i = 0; i < KJV_BOOK_SIZE; i++) {
|
for(i = 0; i < KJV_BOOK_SIZE; i++) {
|
||||||
struct lex x = lex(kjv[i].data);
|
struct lex x = lex(kjv[i].data);
|
||||||
if(!x.cursor) { fprintf(stderr, "Missing book %s.\n",
|
if(!x.cursor) { fprintf(stderr, "Missing book [%u]%s.\n",
|
||||||
kjv_book_string[i]); errno = EDOM; goto catch; }
|
i + 1, kjv_book_string[i]); errno = EDOM; goto catch; }
|
||||||
printf("%s: cumulative %zu.\n", kjv_book_string[i], words);
|
printf("[%u]%s: cumulative %zu.\n", i + 1, kjv_book_string[i], words);
|
||||||
while(lex_next_verse(&x)) words += x.words;
|
while(lex_next_verse(&x)) words += x.words;
|
||||||
if(x.error) goto catch;
|
if(x.error) { fprintf(stderr, "[%u]%s on line %zu\n",
|
||||||
|
i + 1, kjv_book_string[i], x.line); goto catch; }
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("kjv: %zu words\n", words);
|
printf("kjv: %zu words\n", words);
|
||||||
|
|
Loading…
Reference in New Issue