updating boxes for head/body new; better

This commit is contained in:
Neil 2023-03-18 20:41:40 -07:00
parent a52d8ce0ba
commit 2844eeffd5
12 changed files with 182 additions and 143 deletions

View File

@ -31,6 +31,13 @@
`ARRAY_EXPECT_TRAIT` and then subsequently including the name in
`ARRAY_TRAIT`.
@param[ARRAY_HEAD, ARRAY_BODY]
These go together to allow exporting non-static data between compilation units
by separating the `ARRAY_HEAD`, which is intended to go in the header, with
`ARRAY_NAME` and `ARRAY_TYPE`, and `ARRAY_BODY` functions. [All static
functions will have `s_` prepended for ease of creating a public thunk
functions, which most likely will conflict with static functions.]
@std C89 */
#if !defined(ARRAY_NAME) || !defined(ARRAY_TYPE)
@ -46,6 +53,9 @@
|| defined(ARRAY_TRAIT) && !defined(ARRAY_HAS_TO_STRING))
#error Test requires to string.
#endif
#if defined ARRAY_HEAD && defined ARRAY_BODY
#error Can not be ARRAY_HEAD and ARRAY_BODY.
#endif
#ifndef ARRAY_H /* <!-- idempotent */
#define ARRAY_H
@ -76,6 +86,8 @@
#define ARRAY_MIN_CAPACITY 3 /* > 1 */
#endif /* !min --> */
#ifndef ARRAY_BODY /* <!-- head */
/** A valid tag type set by `ARRAY_TYPE`. */
typedef ARRAY_TYPE PA_(type);
@ -88,6 +100,13 @@ struct A_(array) { PA_(type) *data; size_t size, capacity; };
/* `a` non-null; `i >= elements` empty; insert-delete on left like C++. */
struct PA_(iterator) { struct A_(array) *a; size_t i; };
/** May become invalid after a topological change to any items previous. */
struct A_(array_iterator);
struct A_(array_iterator) { struct PA_(iterator) _; };
#endif /* head --> */
#ifndef ARRAY_HEAD /* <!-- body */
/** @return Iterator at end of (non-null) valid `a`. */
static struct PA_(iterator) PA_(iterator)(struct A_(array) *const a) {
struct PA_(iterator) it;
@ -126,10 +145,6 @@ static PA_(type) *PA_(at)(const struct A_(array) *a, const size_t idx)
static void PA_(tell_size)(struct A_(array) *a, const size_t size)
{ assert(a); a->size = size; }
/** May become invalid after a topological change to any items previous. */
struct A_(array_iterator);
struct A_(array_iterator) { struct PA_(iterator) _; };
/** Zeroed data (not all-bits-zero) is initialized.
@return An idle array. @order \Theta(1) @allow */
static struct A_(array) A_(array)(void)
@ -321,6 +336,8 @@ static void PA_(unused_base)(void) {
}
static void PA_(unused_base_coda)(void) { PA_(unused_base)(); }
#endif /* body --> */
#endif /* base code --> */
@ -392,6 +409,12 @@ static void PAT_(to_string)(const PA_(type) *e, char (*const a)[12])
#ifdef ARRAY_TEST
#undef ARRAY_TEST
#endif
#ifdef ARRAY_BODY
#undef ARRAY_BODY
#endif
#ifdef ARRAY_HEAD
#undef ARRAY_HEAD
#endif
#endif /* done --> */
#ifdef ARRAY_TRAIT
#undef ARRAY_TRAIT

View File

@ -31,7 +31,7 @@ struct day_tree_iterator { struct tree_day_iterator _; };
#if defined PROTO \
|| !defined BASE && !defined PRIVATE && !defined PROTO /* <!-- proto */
#include "text.h"
struct journal { struct day_tree days; struct text backing; };
struct journal { struct day_tree days; struct char_array backing; };
struct journal_iterator { struct day_tree_iterator _; };
struct journal journal(void);
void journal_(struct journal *);

View File

@ -198,7 +198,7 @@ struct journal journal(void) {
}
/* Because it's in a flat array, the pointers are not stable
while we are loading it, and we need to store the offsets. */
*v.offset = (uintptr_t)(contents - j.backing.a.data);
*v.offset = (uintptr_t)(contents - j.backing.data);
}
d = 0, int_array_clear(&days);
if(chdir("..") == -1) goto catch;
@ -214,7 +214,7 @@ struct journal journal(void) {
while(day_tree_next(&it)) {
v.text = day_tree_value(&it);
/*printf("[%zu]...", *v.offset);*/
*v.text = j.backing.a.data + *v.offset;
*v.text = j.backing.data + *v.offset;
/*printf("<%.32s>\n", *v.text);*/
}
/*fprintf(stderr, "Journal has entries: %s\n",
@ -234,7 +234,7 @@ finally:
/** @return `j` read in some data? */
int journal_is_empty(const struct journal *const j) {
return !j || !j->days.root.node || !j->backing.a.data;
return !j || !j->days.root.node || !j->backing.data;
}
/** @return `j` as a string. */

View File

@ -160,7 +160,7 @@ void kjvcount_(struct kjvcount *const count) {
<fn:kjvcount_is_empty> to tell. */
struct kjvcount kjvcount(void) {
const char *const dir_kjv = "kjv";
struct text backing = text();
struct char_array backing = text();
struct kjvcount count = {0};
DIR *dir = 0;
struct dirent *de = 0;
@ -183,7 +183,7 @@ struct kjvcount kjvcount(void) {
if(!(unstable_backing = text_append_file(&backing, de->d_name)))
goto catch;
build[b].is = 1;
build[b].offset = (size_t)(unstable_backing - backing.a.data);
build[b].offset = (size_t)(unstable_backing - backing.data);
}
if(closedir(dir) == -1) { dir = 0; goto catch; } dir = 0;
@ -192,7 +192,7 @@ struct kjvcount kjvcount(void) {
struct lex x;
if(!build[b].is) { fprintf(stderr, "Missing book [%u]%s.\n",
b + 1, kjv_book_string[b]); errno = EDOM; goto catch; }
x = lex(backing.a.data + build[b].offset);
x = lex(backing.data + build[b].offset);
while(lex_next_verse(&x)) {
const union kjvcite cite
= { .book = b, .chapter = x.chapter, .verse = x.verse };

View File

@ -1,36 +1,29 @@
#if defined BASE \
|| !defined BASE && !defined PRIVATE && !defined PROTO /* <!-- base */
#include "pair.h"
#include "pair.h" /* pair */
struct source { struct pair name, desc; };
#endif /* base --> */
#define ARRAY_NAME sourcelist
#define ARRAY_TYPE struct source
#define ARRAY_HEAD
#include "../src/array.h"
#if defined PRIVATE \
|| !defined BASE && !defined PRIVATE && !defined PROTO /* <!-- private */
#include <stddef.h> /* size_t */
#include <stdint.h> /* uint32_t */
struct tree_source_node;
struct tree_source_tree { struct tree_source_node *node; unsigned height; };
struct source_tree { struct tree_source_tree root; };
struct tree_source_ref { struct tree_source_node *node; unsigned height, idx; };
struct tree_source_iterator {
struct tree_source_tree *root; struct tree_source_ref ref; int seen;
};
struct source_tree_iterator { struct tree_source_iterator _; };
#define TABLE_NAME sourcemap
#define TABLE_KEY struct pair
#define TABLE_UINT uint32_t
#define TABLE_VALUE size_t
#define TABLE_HEAD
#include "../src/table.h"
struct sourcelist_array { struct source *data; size_t size, capacity; };
#include "../src/journal.h" /* line64 */
struct sourcemap_bucket;
struct sourcemap_table {
struct sourcemap_bucket *buckets;
uint32_t log_capacity, size, top;
};
#define TREE_NAME source
#define TREE_KEY union line64
#define TREE_VALUE size_t
#define TREE_HEAD
#include "../src/tree.h"
#endif /* private --> */
#if defined PROTO \
|| !defined BASE && !defined PRIVATE && !defined PROTO /* <!-- proto */
#include <stddef.h>
struct sources {
struct sourcelist_array list;
struct sourcemap_table map;
@ -42,14 +35,3 @@ void sources_(struct sources *);
int sources_is_empty(const struct sources *);
const char *sources_to_string(const struct sources *);
const struct source *source_lookup(struct sources *s, const union line64 range);
#endif /* proto --> */
#ifdef BASE
#undef BASE
#endif
#ifdef PRIVATE
#undef PRIVATE
#endif
#ifdef PROTO
#undef PROTO
#endif

View File

@ -1,9 +1,7 @@
/** @license 2023 Neil Edelman, distributed under the terms of the
[MIT License](https://opensource.org/licenses/MIT).
@std C11 */
#define BASE
#include "../src/source.h" /* base */
#include "../src/journal.h"
#include "../src/source.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
@ -22,6 +20,7 @@ static void sourcelist_to_string(const struct source *const s,
#define ARRAY_NAME sourcelist
#define ARRAY_TYPE struct source
#define ARRAY_TO_STRING
#define ARRAY_BODY
#include "../src/array.h"
@ -35,8 +34,9 @@ static uint32_t sourcemap_hash(const struct pair p) { return pair_djb2(p); }
#define TABLE_KEY struct pair
#define TABLE_UINT uint32_t
#define TABLE_VALUE size_t /* Index into source list. */
#define TABLE_DEFAULT 0
#define TABLE_DEFAULT 0 /* Default set at zero. */
#define TABLE_TO_STRING
#define TABLE_BODY
#include "../src/table.h"
@ -51,13 +51,10 @@ static int source_compare(const union line64 a, const union line64 b)
#define TREE_COMPARE
#define TREE_TO_STRING
#define TREE_DEFAULT 0
#define TREE_BODY
#include "../src/tree.h"
#define PROTO
#include "../src/source.h" /* proto */
/*!conditions:re2c*/
static int scan(union date32 date, const char *const buffer,

View File

@ -41,6 +41,11 @@
`TABLE_EXPECT_TRAIT` and then subsequently including the name in
`TABLE_TRAIT`.
@param[TABLE_HEAD, TABLE_BODY]
These go together to allow exporting non-static data between compilation units
by separating the `TABLE_BODY` refers to `TABLE_HEAD`, and identical
`TABLE_NAME`, `TABLE_KEY`, `TABLE_UNHASH`, `TABLE_VALUE`, and `TABLE_UINT`.
@fixme Remove entry as public struct, this should be entirely private.
@fixme Why not have two `to_string` arguments on map? It's C, after all. This
would be useful in some practical cases.
@ -56,6 +61,9 @@
|| defined(TABLE_TRAIT) && !defined(TABLE_HAS_TO_STRING))
#error Test requires to string.
#endif
#if defined TABLE_HEAD && defined TABLE_BODY
#error Can not be TABLE_HEAD and TABLE_BODY.
#endif
#ifndef TABLE_H /* <!-- idempotent */
#define TABLE_H
@ -99,6 +107,9 @@ static const char *const table_result_str[] = { TABLE_RESULT };
#ifndef TABLE_UINT
#define TABLE_UINT size_t
#endif
#ifndef TABLE_BODY /* <!-- head */
/** <typedef:<PN>hash_fn> returns this hash type by `TABLE_UINT`, which must be
be an unsigned integer. Places a simplifying limit on the maximum number of
elements of half the cardinality. */
@ -160,6 +171,39 @@ struct PN_(bucket) {
#endif
};
/** Returns true if the `replace` replaces the `original`.
(Shouldn't it be entry?) */
typedef int (*PN_(policy_fn))(PN_(key) original, PN_(key) replace);
/** To initialize, see <fn:<N>table>, `TABLE_IDLE`, `{0}` (`C99`,) or being
`static`. The fields should be treated as read-only; any modification is
liable to cause the table to go into an invalid state.
![States.](../doc/table/states.png) */
struct N_(table) { /* "Padding size," good. */
struct PN_(bucket) *buckets; /* @ has zero/one key specified by `next`. */
/* `size <= capacity`; size is not needed but convenient and allows
short-circuiting. Top is an index of the stack, potentially lazy: MSB
stores whether this is a step ahead (which would make it less, the stack
grows from the bottom,) otherwise it is right at the top, */
PN_(uint) log_capacity, size, top;
};
/* In no particular order, usually, but deterministic up to topology changes. */
struct PN_(iterator) { struct N_(table) *table; PN_(uint) i; };
/** ![States](../doc/table/it.png)
Adding, deleting, successfully looking up entries, or any modification of the
table's topology invalidates the iterator.
Iteration usually not in any particular order. The asymptotic runtime of
iterating though the whole table is proportional to the capacity. */
struct N_(table_iterator);
struct N_(table_iterator) { struct PN_(iterator) _; };
#endif /* head --> */
#ifndef TABLE_HEAD /* <!-- body */
/** Gets the key of an occupied `bucket`. */
static PN_(key) PN_(bucket_key)(const struct PN_(bucket) *const bucket) {
assert(bucket && bucket->next != TABLE_NULL);
@ -182,24 +226,6 @@ static PN_(value) PN_(bucket_value)(const struct PN_(bucket) *const bucket) {
#endif
}
/** Returns true if the `replace` replaces the `original`.
(Shouldn't it be entry?) */
typedef int (*PN_(policy_fn))(PN_(key) original, PN_(key) replace);
/** To initialize, see <fn:<N>table>, `TABLE_IDLE`, `{0}` (`C99`,) or being
`static`. The fields should be treated as read-only; any modification is
liable to cause the table to go into an invalid state.
![States.](../doc/table/states.png) */
struct N_(table) { /* "Padding size," good. */
struct PN_(bucket) *buckets; /* @ has zero/one key specified by `next`. */
/* `size <= capacity`; size is not needed but convenient and allows
short-circuiting. Top is an index of the stack, potentially lazy: MSB
stores whether this is a step ahead (which would make it less, the stack
grows from the bottom,) otherwise it is right at the top, */
PN_(uint) log_capacity, size, top;
};
/** The capacity of a non-idle `table` is always a power-of-two. */
static PN_(uint) PN_(capacity)(const struct N_(table) *const table)
{ return assert(table && table->buckets && table->log_capacity >= 3),
@ -487,8 +513,6 @@ static enum table_result PN_(put_key)(struct N_(table) *const table,
return result;
}
/* In no particular order, usually, but deterministic up to topology changes. */
struct PN_(iterator) { struct N_(table) *table; PN_(uint) i; };
/** @return Before `table`. */
static struct PN_(iterator) PN_(iterator)(struct N_(table) *const table)
{ struct PN_(iterator) it; it.table = table, it.i = 0, it.i--; return it; }
@ -539,15 +563,6 @@ static int PN_(remove)(struct PN_(iterator) *const it) {
return 1;
}
/** ![States](../doc/table/it.png)
Adding, deleting, successfully looking up entries, or any modification of the
table's topology invalidates the iterator.
Iteration usually not in any particular order. The asymptotic runtime of
iterating though the whole table is proportional to the capacity. */
struct N_(table_iterator);
struct N_(table_iterator) { struct PN_(iterator) _; };
/** Zeroed data (not all-bits-zero) is initialized. @return An idle array.
@order \Theta(1) @allow */
static struct N_(table) N_(table)(void) {
@ -790,6 +805,8 @@ static void PN_(unused_base)(void) {
}
static void PN_(unused_base_coda)(void) { PN_(unused_base)(); }
#endif /* body --> */
#endif /* base code --> */
@ -802,13 +819,6 @@ static void PN_(unused_base_coda)(void) { PN_(unused_base)(); }
#define NT_(n) N_(n)
#endif /* !trait --> */
/* #ifdef TABLE_TRAIT
#define N_D_(n, m) TABLE_CAT(N_(n), TABLE_CAT(TABLE_TRAIT, m))
#else
#define N_D_(n, m) TABLE_CAT(N_(n), m)
#endif
#define PN_D_(n, m) TABLE_CAT(table, N_D_(n, m)) */
#ifdef TABLE_TO_STRING /* <!-- to string trait */
/** Thunk `b` -> `a`. */
@ -897,6 +907,12 @@ static void PN_D_(unused, default_coda)(void) { PN_D_(unused, default)(); }
#ifdef TABLE_TEST
#undef TABLE_TEST
#endif
#ifdef TABLE_BODY
#undef TABLE_BODY
#endif
#ifdef TABLE_HEAD
#undef TABLE_HEAD
#endif
#endif /* done --> */
#ifdef TABLE_TRAIT
#undef TABLE_TRAIT

View File

@ -1,18 +1,22 @@
/** Dynamic contiguous string that is used to load files. */
#include "text.h"
#include <stdio.h>
#define ARRAY_NAME char
#define ARRAY_TYPE char
#define ARRAY_BODY
#include "../src/array.h"
#define HAVE_CHAR_ARRAY
#include "text.h"
#include <stdio.h>
struct char_array text(void) { return char_array(); }
void text_(struct char_array *const text) { char_array_(text); }
/** Append a text file, `fn`, to `c`, and add a '\0'.
@return The start of the appended file or null on error. A partial read is a
failure. @throws[fopen, fread, malloc]
@throws[EISEQ] The text file has embedded nulls.
@throws[ERANGE] If the standard library does not follow POSIX. */
static char *append_file(struct char_array *text, const char *const fn) {
@throws[ERANGE] If the standard library does not follow POSIX? */
char *text_append_file(struct char_array *text, const char *const fn) {
FILE *fp = 0;
const size_t granularity = 1024;
size_t nread, start;
@ -40,8 +44,3 @@ finally:
if(fp) fclose(fp);
return success ? text->data + start : 0;
}
struct text text(void) { struct text text; text.a = char_array(); return text; }
void text_(struct text *const text) { char_array_(&text->a); }
char *text_append_file(struct text *text, const char *const fn)
{ return append_file(&text->a, fn); }

View File

@ -1,11 +1,8 @@
#include <stddef.h>
#define ARRAY_NAME char
#define ARRAY_TYPE char
#define ARRAY_HEAD
#include "../src/array.h"
#ifndef HAVE_CHAR_ARRAY
struct char_array { char *data; size_t size, capacity; };
#endif
struct text { struct char_array a; };
struct text text(void);
void text_(struct text *);
char *text_append_file(struct text *, const char *);
struct char_array text(void);
void text_(struct char_array *);
char *text_append_file(struct char_array *, const char *);

View File

@ -44,6 +44,11 @@
Named traits are obtained by including `tree.h` multiple times with
`TREE_EXPECT_TRAIT` and then subsequently including the name in `TREE_TRAIT`.
@param[TREE_HEAD, TREE_BODY]
These go together to allow exporting non-static data between compilation units
by separating the `TABLE_BODY` refers to `TABLE_HEAD`, and identical
`TREE_NAME`, `TREE_KEY`, `TREE_VALUE`, and `TREE_ORDER`.
@fixme merge, difference
@std C89 */
@ -58,6 +63,9 @@
|| defined(TREE_TRAIT) && !defined(TREE_HAS_TO_STRING))
#error Test requires to string.
#endif
#if defined TREE_HEAD && defined TREE_BODY
#error Can not be TREE_HEAD and TREE_BODY.
#endif
#ifndef TREE_H /* <!-- idempotent */
#define TREE_H
@ -114,6 +122,8 @@ struct tree_node_count { size_t branches, leaves; };
#define TREE_KEY unsigned
#endif
#ifndef TREE_BODY /* <!-- head */
/** Ordered type used by <typedef:<PB>compare_fn>; defaults to `unsigned`. */
typedef TREE_KEY PB_(key);
@ -123,20 +133,6 @@ typedef TREE_KEY PB_(key);
typedef TREE_VALUE PB_(value);
#endif
/** Returns a positive result if `a` is out-of-order with respect to `b`,
inducing a strict weak order. This is compatible, but less strict then the
comparators from `bsearch` and `qsort`; it only needs to divide entries into
two instead of three categories. */
typedef int (*PB_(compare_fn))(const PB_(key) a, const PB_(key) b);
#ifndef TREE_COMPARE /* <!-- !cmp */
/** The default `TREE_COMPARE` on `a` and `b` is integer comparison that
results in ascending order, `a > b`. Use `TREE_COMPARE` to supply one's own.
@implements <typedef:<PB>compare_fn> */
static int B_(compare)(const PB_(key) a, const PB_(key) b)
{ return a > b; }
#define TREE_COMPARE &PB_(default_compare)
#endif /* !cmp --> */
/* These rules are more lazy than the original so as to not exhibit worst-case
behaviour in small trees, as <Johnson, Shasha, 1993, Free-at-Empty>, (lookup
is potentially slower after deleting.) In the terminology of
@ -165,14 +161,7 @@ struct PB_(node) {
};
/* B-tree branch is a <tag:<PB>node> and links to `size + 1` nodes. */
struct PB_(branch) { struct PB_(node) base, *child[TREE_ORDER]; };
/** @return Downcasts `as_leaf` to a branch. */
static struct PB_(branch) *PB_(as_branch)(struct PB_(node) *const as_leaf)
{ return (struct PB_(branch) *)(void *)
((char *)as_leaf - offsetof(struct PB_(branch), base)); }
/** @return Downcasts `as_node` to a branch. */
static const struct PB_(branch) *PB_(as_branch_c)(const struct PB_(node) *
const as_node) { return (const struct PB_(branch) *)(const void *)
((const char *)as_node - offsetof(struct PB_(branch), base)); }
/* Node plus height is a [sub]-tree. */
struct PB_(tree) { struct PB_(node) *node; unsigned height; };
/** To initialize it to an idle state, see <fn:<B>tree>, `{0}` (`C99`), or
@ -189,6 +178,42 @@ struct PB_(ref) {
struct PB_(node) *node; /* If null, others ignored. */
unsigned height, idx; /* `idx < node.size` means valid. */
};
struct PB_(iterator) { struct PB_(tree) *root; struct PB_(ref) ref; };
/** Adding, deleting, or changes in the topology of the tree invalidate the
iterator. To modify the tree while iterating, take the <fn:<B>tree_key> and
restart the iterator with <fn:<B>tree_less> or <fn:<B>tree_more> as
appropriate. */
struct B_(tree_iterator);
struct B_(tree_iterator) { struct PB_(iterator) _; };
#endif /* head --> */
#ifndef TREE_HEAD /* <!-- body */
/** Returns a positive result if `a` is out-of-order with respect to `b`,
inducing a strict weak order. This is compatible, but less strict then the
comparators from `bsearch` and `qsort`; it only needs to divide entries into
two instead of three categories. */
typedef int (*PB_(compare_fn))(const PB_(key) a, const PB_(key) b);
#ifndef TREE_COMPARE /* <!-- !cmp */
/** The default `TREE_COMPARE` on `a` and `b` is integer comparison that
results in ascending order, `a > b`. Use `TREE_COMPARE` to supply one's own.
@implements <typedef:<PB>compare_fn> */
static int B_(compare)(const PB_(key) a, const PB_(key) b)
{ return a > b; }
#define TREE_COMPARE &PB_(default_compare)
#endif /* !cmp --> */
/** @return Downcasts `as_leaf` to a branch. */
static struct PB_(branch) *PB_(as_branch)(struct PB_(node) *const as_leaf)
{ return (struct PB_(branch) *)(void *)
((char *)as_leaf - offsetof(struct PB_(branch), base)); }
/** @return Downcasts `as_node` to a branch. */
static const struct PB_(branch) *PB_(as_branch_c)(const struct PB_(node) *
const as_node) { return (const struct PB_(branch) *)(const void *)
((const char *)as_node - offsetof(struct PB_(branch), base)); }
#ifdef TREE_VALUE /* <!-- value */
/** Gets the value of `ref`. */
static PB_(value) *PB_(ref_to_valuep)(const struct PB_(ref) ref)
@ -200,7 +225,6 @@ static PB_(value) *PB_(ref_to_valuep)(const struct PB_(ref) ref)
{ return ref.node ? ref.node->key + ref.idx : 0; }
#endif /* !value --> */
struct PB_(iterator) { struct PB_(tree) *root; struct PB_(ref) ref; };
/** Iterator for `tree` in empty state. */
static struct PB_(iterator) PB_(iterator)(struct B_(tree) *const tree) {
struct PB_(iterator) it;
@ -1480,12 +1504,6 @@ finally:
}
/** Adding, deleting, or changes in the topology of the tree invalidate the
iterator. To modify the tree while iterating, take the <fn:<B>tree_key> and
restart the iterator with <fn:<B>tree_less> or <fn:<B>tree_more> as
appropriate. */
struct B_(tree_iterator);
struct B_(tree_iterator) { struct PB_(iterator) _; };
/** @return Cursor at null in valid `tree`. @order \Theta(1) @allow */
static struct B_(tree_iterator) B_(tree_iterator)(struct B_(tree) *const tree)
{ struct B_(tree_iterator) it; it._ = PB_(iterator)(tree); return it; }
@ -1565,6 +1583,8 @@ static void PB_(unused_base_coda)(void) { PB_(unused_base)(); }
#define BOX_MAJOR_NAME tree
#define BOX_MINOR_NAME TREE_NAME
#endif /* body --> */
#endif /* base code --> */
@ -1660,6 +1680,12 @@ static void PB_D_(unused, default_coda)(void) { PB_D_(unused, default)(); }
#ifdef TREE_TEST
#undef TREE_TEST
#endif
#ifdef TREE_BODY
#undef TREE_BODY
#endif
#ifdef TREE_HEAD
#undef TREE_HEAD
#endif
#endif /* done --> */
#ifdef TREE_TRAIT
#undef TREE_TRAIT

View File

@ -1,4 +1,3 @@
#include "../src/journal.h"
#include "../src/source.h"
#include <stdio.h>
#include <stdlib.h>

View File

@ -4,7 +4,7 @@
#include <errno.h>
int main(void) {
struct text t = text();
struct char_array t = text();
char *content;
int success = EXIT_SUCCESS;
errno = 0; /* `errno` is not set correctly to 0 in some debug situations. */