From 2844eeffd5586d1baad92f3f60b2e3e63cfc3008 Mon Sep 17 00:00:00 2001 From: Neil Date: Sat, 18 Mar 2023 20:41:40 -0700 Subject: [PATCH] updating boxes for head/body new; better --- src/array.h | 31 +++++++++++++--- src/journal.h | 2 +- src/journal.re.c | 6 ++-- src/kjvcount.re.c | 6 ++-- src/source.h | 56 ++++++++++------------------- src/source.re.c | 13 +++---- src/table.h | 88 +++++++++++++++++++++++++++------------------- src/text.c | 19 +++++----- src/text.h | 17 ++++----- src/tree.h | 84 ++++++++++++++++++++++++++++--------------- test/test_source.c | 1 - test/test_text.c | 2 +- 12 files changed, 182 insertions(+), 143 deletions(-) diff --git a/src/array.h b/src/array.h index 9b3c0f6..1b03c34 100644 --- a/src/array.h +++ b/src/array.h @@ -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 /* */ +#ifndef ARRAY_BODY /* */ +#ifndef ARRAY_HEAD /* */ + #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 diff --git a/src/journal.h b/src/journal.h index f304035..b328314 100644 --- a/src/journal.h +++ b/src/journal.h @@ -31,7 +31,7 @@ struct day_tree_iterator { struct tree_day_iterator _; }; #if defined PROTO \ || !defined BASE && !defined PRIVATE && !defined PROTO /* */ +#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 /* */ - - -#if defined PROTO \ - || !defined BASE && !defined PRIVATE && !defined PROTO /* */ - -#ifdef BASE -#undef BASE -#endif -#ifdef PRIVATE -#undef PRIVATE -#endif -#ifdef PROTO -#undef PROTO -#endif diff --git a/src/source.re.c b/src/source.re.c index 2659c75..fc189aa 100644 --- a/src/source.re.c +++ b/src/source.re.c @@ -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 #include #include @@ -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, diff --git a/src/table.h b/src/table.h index cc7ce4f..c0b9a31 100644 --- a/src/table.h +++ b/src/table.h @@ -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 /* */ +#ifndef TABLE_HEAD /* */ + #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 /* */ #ifdef TABLE_TRAIT #undef TABLE_TRAIT diff --git a/src/text.c b/src/text.c index 87072e7..5283c8c 100644 --- a/src/text.c +++ b/src/text.c @@ -1,18 +1,22 @@ /** Dynamic contiguous string that is used to load files. */ +#include "text.h" +#include + #define ARRAY_NAME char #define ARRAY_TYPE char +#define ARRAY_BODY #include "../src/array.h" -#define HAVE_CHAR_ARRAY -#include "text.h" -#include + +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); } diff --git a/src/text.h b/src/text.h index 19d8b80..1a18852 100644 --- a/src/text.h +++ b/src/text.h @@ -1,11 +1,8 @@ -#include +#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 *); diff --git a/src/tree.h b/src/tree.h index 7152da6..270044b 100644 --- a/src/tree.h +++ b/src/tree.h @@ -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 /* */ - /* These rules are more lazy than the original so as to not exhibit worst-case behaviour in small trees, as , (lookup is potentially slower after deleting.) In the terminology of @@ -165,14 +161,7 @@ struct PB_(node) { }; /* B-tree branch is a 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 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 tree_key> and + restart the iterator with tree_less> or tree_more> as + appropriate. */ +struct B_(tree_iterator); +struct B_(tree_iterator) { struct PB_(iterator) _; }; + +#endif /* head --> */ +#ifndef TREE_HEAD /* */ + +/** @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 /* */ -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 tree_key> and - restart the iterator with tree_less> or 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 diff --git a/test/test_source.c b/test/test_source.c index c8bda35..3c64710 100644 --- a/test/test_source.c +++ b/test/test_source.c @@ -1,4 +1,3 @@ -#include "../src/journal.h" #include "../src/source.h" #include #include diff --git a/test/test_text.c b/test/test_text.c index bdfbcce..0fbc011 100644 --- a/test/test_text.c +++ b/test/test_text.c @@ -4,7 +4,7 @@ #include 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. */