updated tv, movie, rem, book, etc

This commit is contained in:
Neil 2023-05-07 21:44:14 -07:00
parent 54dde7c057
commit 2d11f84bd9
4 changed files with 233 additions and 120 deletions

View File

@ -49,6 +49,8 @@ int main(void) {
catch:
perror(intent);
finally:
/* fixme: ~scan should be idempotent but it's not on disabling ASLR, which
debug mode is in. */
scan_(&scn);
journal_(&jrnl);
return intent ? EXIT_FAILURE : EXIT_SUCCESS;

View File

@ -14,6 +14,11 @@ struct kvpair { struct pair key, value; };
#define ARRAY_TYPE struct kvpair
#define ARRAY_HEAD
#include "../src/array.h"
#define TREE_NAME linekvpair
#define TREE_KEY union line64
#define TREE_VALUE struct kvpair
#define TREE_HEAD
#include "../src/tree.h"
/* Place array. */
struct place { struct pair name; double x, y; };
@ -96,10 +101,6 @@ struct scan {
struct pairmap_table map;
struct linemap_tree dates;
} sources, documents;
struct {
struct kvpair_array array;
struct linemap_tree dates;
} contacts;
struct {
struct place_array array;
struct pairmap_table map;
@ -115,7 +116,7 @@ struct scan {
struct pairmap_table map;
struct linemap_tree dates;
} edits;
//struct kvpair_tree contacts;?
struct linekvpair_tree contacts, books, tvs, movies, ideas;
struct glider_tree gliders;
struct flight_tree flights;
struct kjv_tree kjvs;

View File

@ -41,6 +41,20 @@ static void kvpair_to_string(const struct kvpair *const s,
#define ARRAY_TO_STRING
#define ARRAY_BODY
#include "../src/array.h"
static void linekvpair_to_string(const union line64 line,
const struct kvpair *const kv,
char (*const a)[12]) { (void)kv; date32_to_string(line.date, a); }
static int linekvpair_compare(const union line64 a, const union line64 b)
{ return a.u64 > b.u64; }
#define TREE_NAME linekvpair
#define TREE_KEY union line64
#define TREE_VALUE struct kvpair
#define TREE_COMPARE
#define TREE_TO_STRING
#define TREE_DEFAULT {{0,0},{0,0}}
#define TREE_BODY
#include "../src/tree.h"
/* Array of places. */
static void place_to_string(const struct place *const p,
@ -124,8 +138,9 @@ static int scan_day(struct scan *const scan, union date32 date,
struct score *new_score = 0;
struct glider *new_glider = 0;
struct flight *new_flight = 0;
enum kjv_book book = Revelation;
uint32_t chapter = 0, verse = 0, verse_end = 0;
struct {
enum kjv_book book; uint32_t chapter, verse, verse_end;
} kjv = { Revelation, 0, 0, 0 };
assert(scan && date.u32 && buffer);
YYCURSOR = YYMARKER = yyt1 = buffer;
@ -186,7 +201,12 @@ static int scan_day(struct scan *const scan, union date32 date,
/* ^"[" ... */
<bracket> * { fail = "bracket unrecognized"; goto catch; }
<bracket> "document: " :=> document
<bracket> "rem: " :=> remark //change to "rem"
<bracket> "rem: " :=> remark
<bracket> "contact: " :=> contact
<bracket> "book: " :=> book
<bracket> "tv: " :=> tv
<bracket> "movie: " :=> movie
<bracket> "idea: " :=> idea
<document> * { fail = "document title"; goto catch; }
<document> @s0 bralabel @s1 "]" => future {
@ -228,6 +248,86 @@ static int scan_day(struct scan *const scan, union date32 date,
continue;
}
<contact> * { fail = "contact unrecognized"; goto catch; }
<contact> @s0 bralabel @s1 "]" => future {
const union line64 key = { { (uint32_t)line, date } };
struct kvpair *pair;
switch(linekvpair_tree_bulk_assign(&scan->contacts, key, &pair)) {
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
case TREE_ABSENT: break;
}
pair->key.a = s0, pair->key.b = s1;
pair->value.a = pair->value.b = 0;
assert(!future), future = &pair->value;
fprintf(stderr, "%s[%zu]: new contact <<%.*s>>.\n",
datestr, line, (int)(s1 - s0), s0);
continue;
}
<book> * { fail = "book unrecognized"; goto catch; }
<book> @s0 bralabel @s1 "]" => future {
const union line64 key = { { (uint32_t)line, date } };
struct kvpair *pair;
switch(linekvpair_tree_bulk_assign(&scan->books, key, &pair)) {
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
case TREE_ABSENT: break;
}
pair->key.a = s0, pair->key.b = s1;
pair->value.a = pair->value.b = 0;
assert(!future), future = &pair->value;
fprintf(stderr, "%s[%zu]: new book <<%.*s>>.\n",
datestr, line, (int)(s1 - s0), s0);
continue;
}
<tv> * { fail = "tv unrecognized"; goto catch; }
<tv> @s0 bralabel @s1 "]" => future {
const union line64 key = { { (uint32_t)line, date } };
struct kvpair *pair;
switch(linekvpair_tree_bulk_assign(&scan->tvs, key, &pair)) {
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
case TREE_ABSENT: break;
}
pair->key.a = s0, pair->key.b = s1;
pair->value.a = pair->value.b = 0;
assert(!future), future = &pair->value;
fprintf(stderr, "%s[%zu]: new tv <<%.*s>>.\n",
datestr, line, (int)(s1 - s0), s0);
continue;
}
<movie> * { fail = "movie unrecognized"; goto catch; }
<movie> @s0 bralabel @s1 "]" => future {
const union line64 key = { { (uint32_t)line, date } };
struct kvpair *pair;
switch(linekvpair_tree_bulk_assign(&scan->contacts, key, &pair)) {
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
case TREE_ABSENT: break;
}
pair->key.a = s0, pair->key.b = s1;
pair->value.a = pair->value.b = 0;
assert(!future), future = &pair->value;
fprintf(stderr, "%s[%zu]: new movie <<%.*s>>.\n",
datestr, line, (int)(s1 - s0), s0);
continue;
}
<idea> * { fail = "idea unrecognized"; goto catch; }
<idea> @s0 bralabel @s1 "]" => future {
const union line64 key = { { (uint32_t)line, date } };
struct kvpair *pair;
switch(linekvpair_tree_bulk_assign(&scan->contacts, key, &pair)) {
case TREE_PRESENT: fail = "duplicate"; case TREE_ERROR: goto catch;
case TREE_ABSENT: break;
}
pair->key.a = s0, pair->key.b = s1;
pair->value.a = pair->value.b = 0;
assert(!future), future = &pair->value;
fprintf(stderr, "%s[%zu]: new idea <<%.*s>>.\n",
datestr, line, (int)(s1 - s0), s0);
continue;
}
<place> * { fail = "place unrecognized"; goto catch; }
<place> @s0 parlabel @s1 / "\n" => skip { also_place: {
const struct pair keyword = pair(s0, s1);
@ -523,107 +623,95 @@ static int scan_day(struct scan *const scan, union date32 date,
/* Books in KJV. */
<line> "Genesis" / kjvlookat => book { book = Genesis; continue; }
<line> "Exodus" / kjvlookat => book { book = Exodus; continue; }
<line> "Leviticus" / kjvlookat => book { book = Leviticus; continue; }
<line> "Numbers" / kjvlookat => book { book = Numbers; continue; }
<line> "Deuteronomy" / kjvlookat => book
{ book = Deuteronomy; continue; }
<line> "Joshua" / kjvlookat => book { book = Joshua; continue; }
<line> "Judges" / kjvlookat => book { book = Judges; continue; }
<line> "Ruth" / kjvlookat => book { book = Ruth; continue; }
<line> first "Samuel" / kjvlookat => book { book = ISamuel; continue; }
<line> second "Samuel" / kjvlookat => book
{ book = IISamuel; continue; }
<line> first "Kings" / kjvlookat => book { book = IKings; continue; }
<line> second "Kings" / kjvlookat => book { book = IIKings; continue; }
<line> first "Chronicles" / kjvlookat
=> book { book = IChronicles; continue; }
<line> second "Chronicles" / kjvlookat
=> book { book = IIChronicles; continue; }
<line> "Ezra" / kjvlookat => book { book = Ezra; continue; }
<line> "Nehemiah" / kjvlookat => book { book = Nehemiah; continue; }
<line> "Esther" / kjvlookat => book { book = Esther; continue; }
<line> "Job" / kjvlookat => book { book = Job; continue; }
<line> "Psalms" / kjvlookat => book { book = Psalms; continue; }
<line> "Proverbs" / kjvlookat => book { book = Proverbs; continue; }
<line> "Ecclesiastes" / kjvlookat
=> book { book = Ecclesiastes; continue; }
<line> "Song of Solomon" / kjvlookat
=> book { book = Song_of_Solomon; continue; }
<line> "Isaiah" / kjvlookat => book { book = Isaiah; continue; }
<line> "Jeremiah" / kjvlookat => book { book = Jeremiah; continue; }
<line> "Lamentations" / kjvlookat
=> book { book = Lamentations; continue; }
<line> "Ezekiel" / kjvlookat => book { book = Ezekiel; continue; }
<line> "Daniel" / kjvlookat => book { book = Daniel; continue; }
<line> "Hosea" / kjvlookat => book { book = Hosea; continue; }
<line> "Joel" / kjvlookat => book { book = Joel; continue; }
<line> "Amos" / kjvlookat => book { book = Amos; continue; }
<line> "Obadiah" / kjvlookat => book { book = Obadiah; continue; }
<line> "Jonah" / kjvlookat => book { book = Jonah; continue; }
<line> "Micah" / kjvlookat => book { book = Micah; continue; }
<line> "Nahum" / kjvlookat => book { book = Nahum; continue; }
<line> "Habakkuk" / kjvlookat => book { book = Habakkuk; continue; }
<line> "Zephaniah" / kjvlookat => book { book = Zephaniah; continue; }
<line> "Haggai" / kjvlookat => book { book = Haggai; continue; }
<line> "Zechariah" / kjvlookat => book { book = Zechariah; continue; }
<line> "Malachi" / kjvlookat => book { book = Malachi; continue; }
<line> "Matthew" / kjvlookat => book { book = Matthew; continue; }
<line> "Mark" / kjvlookat => book { book = Mark; continue; }
<line> "Luke" / kjvlookat => book { book = Luke; continue; }
<line> "John" / kjvlookat => book { book = John; continue; }
<line> "Acts" / kjvlookat => book { book = Acts; continue; }
<line> "Romans" / kjvlookat => book { book = Romans; continue; }
<line> first "Corinthians" / kjvlookat
=> book { book = ICorinthians; continue; }
<line> second "Corinthians" / kjvlookat
=> book { book = IICorinthians; continue; }
<line> "Galatians" / kjvlookat => book { book = Galatians; continue; }
<line> "Ephesians" / kjvlookat => book { book = Ephesians; continue; }
<line> "Philippians" / kjvlookat => book
{ book = Philippians; continue; }
<line> "Colossians" / kjvlookat => book { book = Colossians; continue; }
<line> first "Thessalonians" / kjvlookat
=> book { book = IThessalonians; continue; }
<line> second "Thessalonians" / kjvlookat
=> book { book = IIThessalonians; continue; }
<line> first "Timothy" / kjvlookat => book
{ book = ITimothy; continue; }
<line> second "Timothy" / kjvlookat => book
{ book = IITimothy; continue; }
<line> "Titus" / kjvlookat => book { book = Titus; continue; }
<line> "Philemon" / kjvlookat => book { book = Philemon; continue; }
<line> "Hebrews" / kjvlookat => book { book = Hebrews; continue; }
<line> "James" / kjvlookat => book { book = James; continue; }
<line> first "Peter" / kjvlookat => book { book = IPeter; continue; }
<line> second "Peter" / kjvlookat => book { book = IIPeter; continue; }
<line> first "John" / kjvlookat => book { book = IJohn; continue; }
<line> second "John" / kjvlookat => book { book = IIJohn; continue; }
<line> third "John" / kjvlookat => book { book = IIIJohn; continue; }
<line> "Jude" / kjvlookat => book { book = Jude; continue; }
<line> "Revelation" / kjvlookat => book { book = Revelation; continue; }
<book> * { fail = "kjv unrecognized"; goto catch; }
<line> "Genesis" / kjvlookat => kjvbook { kjv.book = Genesis; continue; }
<line> "Exodus" / kjvlookat => kjvbook { kjv.book = Exodus; continue; }
<line> "Leviticus" / kjvlookat => kjvbook { kjv.book = Leviticus; continue; }
<line> "Numbers" / kjvlookat => kjvbook { kjv.book = Numbers; continue; }
<line> "Deuteronomy" / kjvlookat => kjvbook { kjv.book = Deuteronomy; continue; }
<line> "Joshua" / kjvlookat => kjvbook { kjv.book = Joshua; continue; }
<line> "Judges" / kjvlookat => kjvbook { kjv.book = Judges; continue; }
<line> "Ruth" / kjvlookat => kjvbook { kjv.book = Ruth; continue; }
<line> first "Samuel" / kjvlookat => kjvbook { kjv.book = ISamuel; continue; }
<line> second "Samuel" / kjvlookat => kjvbook { kjv.book = IISamuel; continue; }
<line> first "Kings" / kjvlookat => kjvbook { kjv.book = IKings; continue; }
<line> second "Kings" / kjvlookat => kjvbook { kjv.book = IIKings; continue; }
<line> first "Chronicles" / kjvlookat => kjvbook { kjv.book = IChronicles; continue; }
<line> second "Chronicles" / kjvlookat => kjvbook { kjv.book = IIChronicles; continue; }
<line> "Ezra" / kjvlookat => kjvbook { kjv.book = Ezra; continue; }
<line> "Nehemiah" / kjvlookat => kjvbook { kjv.book = Nehemiah; continue; }
<line> "Esther" / kjvlookat => kjvbook { kjv.book = Esther; continue; }
<line> "Job" / kjvlookat => kjvbook { kjv.book = Job; continue; }
<line> "Psalms" / kjvlookat => kjvbook { kjv.book = Psalms; continue; }
<line> "Proverbs" / kjvlookat => kjvbook { kjv.book = Proverbs; continue; }
<line> "Ecclesiastes" / kjvlookat => kjvbook
{ kjv.book = Ecclesiastes; continue; }
<line> "Song of Solomon" / kjvlookat => kjvbook
{ kjv.book = Song_of_Solomon; continue; }
<line> "Isaiah" / kjvlookat => kjvbook { kjv.book = Isaiah; continue; }
<line> "Jeremiah" / kjvlookat => kjvbook { kjv.book = Jeremiah; continue; }
<line> "Lamentations" / kjvlookat => kjvbook { kjv.book = Lamentations; continue; }
<line> "Ezekiel" / kjvlookat => kjvbook { kjv.book = Ezekiel; continue; }
<line> "Daniel" / kjvlookat => kjvbook { kjv.book = Daniel; continue; }
<line> "Hosea" / kjvlookat => kjvbook { kjv.book = Hosea; continue; }
<line> "Joel" / kjvlookat => kjvbook { kjv.book = Joel; continue; }
<line> "Amos" / kjvlookat => kjvbook { kjv.book = Amos; continue; }
<line> "Obadiah" / kjvlookat => kjvbook { kjv.book = Obadiah; continue; }
<line> "Jonah" / kjvlookat => kjvbook { kjv.book = Jonah; continue; }
<line> "Micah" / kjvlookat => kjvbook { kjv.book = Micah; continue; }
<line> "Nahum" / kjvlookat => kjvbook { kjv.book = Nahum; continue; }
<line> "Habakkuk" / kjvlookat => kjvbook { kjv.book = Habakkuk; continue; }
<line> "Zephaniah" / kjvlookat => kjvbook { kjv.book = Zephaniah; continue; }
<line> "Haggai" / kjvlookat => kjvbook { kjv.book = Haggai; continue; }
<line> "Zechariah" / kjvlookat => kjvbook { kjv.book = Zechariah; continue; }
<line> "Malachi" / kjvlookat => kjvbook { kjv.book = Malachi; continue; }
<line> "Matthew" / kjvlookat => kjvbook { kjv.book = Matthew; continue; }
<line> "Mark" / kjvlookat => kjvbook { kjv.book = Mark; continue; }
<line> "Luke" / kjvlookat => kjvbook { kjv.book = Luke; continue; }
<line> "John" / kjvlookat => kjvbook { kjv.book = John; continue; }
<line> "Acts" / kjvlookat => kjvbook { kjv.book = Acts; continue; }
<line> "Romans" / kjvlookat => kjvbook { kjv.book = Romans; continue; }
<line> first "Corinthians" / kjvlookat => kjvbook { kjv.book = ICorinthians; continue; }
<line> second "Corinthians" / kjvlookat => kjvbook { kjv.book = IICorinthians; continue; }
<line> "Galatians" / kjvlookat => kjvbook { kjv.book = Galatians; continue; }
<line> "Ephesians" / kjvlookat => kjvbook { kjv.book = Ephesians; continue; }
<line> "Philippians" / kjvlookat => kjvbook { kjv.book = Philippians; continue; }
<line> "Colossians" / kjvlookat => kjvbook { kjv.book = Colossians; continue; }
<line> first "Thessalonians" / kjvlookat => kjvbook { kjv.book = IThessalonians; continue; }
<line> second "Thessalonians" / kjvlookat => kjvbook { kjv.book = IIThessalonians; continue; }
<line> first "Timothy" / kjvlookat => kjvbook { kjv.book = ITimothy; continue; }
<line> second "Timothy" / kjvlookat => kjvbook { kjv.book = IITimothy; continue; }
<line> "Titus" / kjvlookat => kjvbook { kjv.book = Titus; continue; }
<line> "Philemon" / kjvlookat => kjvbook { kjv.book = Philemon; continue; }
<line> "Hebrews" / kjvlookat => kjvbook { kjv.book = Hebrews; continue; }
<line> "James" / kjvlookat => kjvbook { kjv.book = James; continue; }
<line> first "Peter" / kjvlookat => kjvbook { kjv.book = IPeter; continue; }
<line> second "Peter" / kjvlookat => kjvbook { kjv.book = IIPeter; continue; }
<line> first "John" / kjvlookat => kjvbook { kjv.book = IJohn; continue; }
<line> second "John" / kjvlookat => kjvbook { kjv.book = IIJohn; continue; }
<line> third "John" / kjvlookat => kjvbook { kjv.book = IIIJohn; continue; }
<line> "Jude" / kjvlookat => kjvbook { kjv.book = Jude; continue; }
<line> "Revelation" / kjvlookat => kjvbook { kjv.book = Revelation; continue; }
<kjvbook> * { fail = "kjv unrecognized"; goto catch; }
/* 19:15a, just ignore the a. */
<book> " " @s0 natural @s1 ":" @t0 natural @t1 [ab]? {
if(chapter || verse || verse_end)
<kjvbook> " " @s0 natural @s1 ":" @t0 natural @t1 [ab]? {
if(kjv.chapter || kjv.verse || kjv.verse_end)
{ fail = "kjv reference"; goto catch; }
if(!pair_to_natural(s0, s1, &chapter)
|| !pair_to_natural(t0, t1, &verse))
if(!pair_to_natural(s0, s1, &kjv.chapter)
|| !pair_to_natural(t0, t1, &kjv.verse))
{ fail = "kjv reference numerical error"; goto catch; }
continue;
}
<book> "-" @s0 natural @s1 [ab]? { /* Verse range. */
if(!chapter || !verse || verse_end)
<kjvbook> "-" @s0 natural @s1 [ab]? { /* Verse range. */
if(!kjv.chapter || !kjv.verse || kjv.verse_end)
{ fail = "kjv range unrecognized"; goto catch; }
if(!pair_to_natural(s0, s1, &verse_end))
if(!pair_to_natural(s0, s1, &kjv.verse_end))
{ fail = "kjv range numerical error"; goto catch; }
continue;
}
<book> " -- " => skip {
if(!chapter || !verse)
<kjvbook> " -- " => skip {
if(!kjv.chapter || !kjv.verse)
{ fail = "kjv missing information"; goto catch; }
if(verse_end && verse_end <= verse)
if(kjv.verse_end && kjv.verse_end <= kjv.verse)
{ fail = "kjv interval error"; goto catch; }
const union line64 key = {{ (uint32_t)line, date }};
struct kjvrange *value;
@ -631,17 +719,18 @@ static int scan_day(struct scan *const scan, union date32 date,
case TREE_PRESENT: fail = "kjv duplicate key";
case TREE_ERROR: goto catch;
case TREE_ABSENT:
value->start.book = book;
value->start.chapter = chapter;
value->start.verse = verse;
value->verse_end = verse_end;
value->start.book = kjv.book;
value->start.chapter = kjv.chapter;
value->start.verse = kjv.verse;
value->verse_end = kjv.verse_end;
break;
}
fprintf(stderr, "%s[%zu]: KJV %s %" PRIu32 ":%" PRIu32,
datestr, line, kjv_book_string[book], chapter, verse);
if(verse_end) fprintf(stderr, "-%u", verse_end);
fprintf(stderr, "%s[%zu]: KJV %s %" PRIu32 ":%" PRIu32, datestr,
line, kjv_book_string[kjv.book], kjv.chapter, kjv.verse);
if(kjv.verse_end) fprintf(stderr, "-%u", kjv.verse_end);
fprintf(stderr, "\n");
book = Revelation, chapter = 0, verse = 0, verse_end = 0;
kjv.book = Revelation, kjv.chapter = 0, kjv.verse = 0,
kjv.verse_end = 0;
continue;
}
@ -688,16 +777,26 @@ static int scan_day(struct scan *const scan, union date32 date,
catch:
if(!errno) errno = EILSEQ;
date32_to_string(date, &datestr);
fprintf(stderr, "%s line %zu: %s" /*" condition %d"*/ ".\n",
fprintf(stderr, "%s line %zu fail: %s" /*" condition %d"*/ ".\n",
datestr, line, fail/*, condition*/);
return 0;
}
void scan_(struct scan *const scan) {
fprintf(stderr, "fixme: ~scan should be idempotent <<\n"); // now it is?
if(!scan) return;
// printing it made it so?
fprintf(stderr, "~scan kjv %s\n", kjv_tree_to_string(&scan->kjvs));
kjv_tree_(&scan->kjvs);
fprintf(stderr, "~scan finished kjv\n");
flight_tree_(&scan->flights);
glider_tree_(&scan->gliders);
linekvpair_tree_(&scan->ideas);
linekvpair_tree_(&scan->movies);
linekvpair_tree_(&scan->tvs);
linekvpair_tree_(&scan->books);
linekvpair_tree_(&scan->contacts);
fprintf(stderr, "~scan finished linekvpair\n");
linemap_tree_(&scan->scores.dates);
pair_map_table_(&scan->scores.map);
@ -718,6 +817,7 @@ void scan_(struct scan *const scan) {
linemap_tree_(&scan->sources.dates);
pair_map_table_(&scan->sources.map);
kvpair_array_(&scan->sources.array);
fprintf(stderr, "~scan finish >>\n");
}
/** @param[jrnl] Must be constant throughout the use of the returned value. */
@ -759,14 +859,22 @@ struct scan scan(struct journal *const jrnl) {
/* Scans make trees bulk-loaded; fix to real tree. */
if(!linemap_tree_bulk_finish(&scan.sources.dates)
|| !linemap_tree_bulk_finish(&scan.documents.dates)
|| !linemap_tree_bulk_finish(&scan.places.dates)
|| !linemap_tree_bulk_finish(&scan.scores.dates)
|| !linemap_tree_bulk_finish(&scan.edits.dates)
|| !linekvpair_tree_bulk_finish(&scan.contacts)
|| !linekvpair_tree_bulk_finish(&scan.books)
|| !linekvpair_tree_bulk_finish(&scan.tvs)
|| !linekvpair_tree_bulk_finish(&scan.movies)
|| !linekvpair_tree_bulk_finish(&scan.ideas)
|| !glider_tree_bulk_finish(&scan.gliders)
|| !flight_tree_bulk_finish(&scan.flights)
|| !kjv_tree_bulk_finish(&scan.kjvs)) goto catch;
goto finally;
catch:
fprintf(stderr, "Scan failed.\n");
scan_(&scan);
finally:
return scan;

View File

@ -33,8 +33,8 @@
tree, <Sedgewick, 2008, LLRB>. The above illustration is 5.
@param[TREE_DEFAULT]
Default trait; a name that satisfies `C` naming conventions when mangled and a
<typedef:<PB>value> used in <fn:<B>tree<D>get>.
Default trait which must be set to a <typedef:<PB>value>, used in
<fn:<B>tree<D>get>.
@param[TREE_TO_STRING]
To string trait `<STR>` contained in <src/to_string.h>. Require
@ -42,7 +42,8 @@
@param[TREE_EXPECT_TRAIT, TREE_TRAIT]
Named traits are obtained by including `tree.h` multiple times with
`TREE_EXPECT_TRAIT` and then subsequently including the name in `TREE_TRAIT`.
`TREE_EXPECT_TRAIT` and then subsequently including the name that satisfies
`C` naming conventions when mangled in `TREE_TRAIT`.
@param[TREE_HEAD, TREE_BODY]
These go together to allow exporting non-static data between compilation units
@ -514,7 +515,8 @@ static void B_(tree_)(struct B_(tree) *const tree) {
}
/** Clears `tree`, which can be null, idle, empty, or full. If it is empty or
full, it remains active. @order \O(|`tree`|) @allow */
full, it remains active, (all except one node are freed.)
@order \O(|`tree`|) @allow */
static void B_(tree_clear)(struct B_(tree) *const tree) { PB_(clear)(tree); }
/** Private: counts a sub-tree, `tree`. */
@ -582,12 +584,12 @@ static PB_(key) B_(tree_more_or)(const struct B_(tree) *const tree,
}
#ifdef TREE_VALUE /* <!-- map */
/** Packs `key` on the right side of `tree` without doing the usual
restructuring. All other topology modification functions should be avoided
until followed by <fn:<B>tree_bulk_finish>.
/** Only if `TREE_VALUE` is set; the set version is <fn:<B>tree_try>. Packs
`key` on the right side of `tree` without doing the usual restructuring. All
other topology modification functions should be avoided until followed by
<fn:<B>tree_bulk_finish>.
@param[value] A pointer to the key's value which is set by the function on
returning true. A null pointer in this parameter causes the value to go
uninitialized. This parameter is not there if one didn't specify `TREE_VALUE`.
returning true. Can be null.
@return One of <tag:tree_result>: `TREE_ERROR` and `errno` will be set,
`TREE_PRESENT` if the key is already (the highest) in the tree, and
`TREE_ABSENT`, added, the `value` (if applicable) is uninitialized.
@ -598,8 +600,8 @@ static enum tree_result B_(tree_bulk_assign)(struct B_(tree) *const tree,
#elif defined TREE_VALUE /* map --><!-- null: For braces matching. */
}
#else /* null --><!-- set */
/** Packs `key` on the right side of `tree`. See <fn:<B>tree_assign>, which is
the map version. @allow */
/** Only if `TREE_VALUE` is not set; see <fn:<B>tree_assign>, which is
the map version. Packs `key` on the right side of `tree`. @allow */
static enum tree_result B_(tree_bulk_try)(struct B_(tree) *const tree,
PB_(key) key) {
#endif
@ -1636,7 +1638,7 @@ static void PBT_(to_string)(const struct PB_(ref) *const r,
#define PB_D_(n, m) TREE_CAT(tree, B_D_(n, m))
#endif
/* `TREE_DEFAULT` is a valid <tag:<PB>value>. */
static const PB_(value) PB_D_(default, value) = (TREE_DEFAULT);
static const PB_(value) PB_D_(default, value) = TREE_DEFAULT;
/** This is functionally identical to <fn:<B>tree_get_or>, but a with a trait
specifying a constant default value.
@return The value associated with `key` in `tree`, (which can be null.) If