From ed81741d89ac546b627ef6ae560f81fd2c39ec72 Mon Sep 17 00:00:00 2001 From: Neil Date: Thu, 2 Feb 2023 23:13:55 -0800 Subject: [PATCH] substring -> lorem, test lorem_dup --- Makefile | 7 ++--- src/flight.h | 10 +++---- src/helper.h | 6 +---- src/lorem.c | 60 +++++++++++++++++++++++++++++++----------- src/lorem.h | 6 +++-- src/source.h | 1 + src/source.re.c | 10 +++---- test/test_lorem.c | 37 ++++++++++++++++++++++++++ test/test_substrings.c | 20 -------------- 9 files changed, 101 insertions(+), 56 deletions(-) create mode 100644 test/test_lorem.c delete mode 100644 test/test_substrings.c diff --git a/Makefile b/Makefile index 14dfb01..9555a7a 100644 --- a/Makefile +++ b/Makefile @@ -2,6 +2,7 @@ optimize := -ffast-math warnbasic := -Wall -pedantic #-ansi # -std=c99 warnclang := -Wextra -Weverything \ -Wno-comma \ +-Wno-parentheses \ -Wno-logical-op-parentheses \ -Wno-parentheses \ -Wno-documentation-unknown-command \ @@ -29,14 +30,14 @@ else CF += -g endif -projects := bin/test-text bin/test-journal bin/test-source bin/test-kjv bin/kjv bin/flight +projects := bin/test-text bin/test-journal bin/test-source bin/test-kjv bin/test-lorem bin/kjv bin/flight #docs := $(patsubst test/test_%.c, doc/%.md, $(wildcard test/test_*.c)) default: $(projects) # success bin/test-text: build/text.o build/test_text.o -bin/test-strings: build/substrings.o build/test_substrings.o +bin/test-lorem: build/lorem.o build/orcish.o build/test_lorem.o bin/test-journal: build/text.o build/journal.o build/test_journal.o bin/test-source: build/text.o build/journal.o build/source.o build/test_source.o bin/test-kjv: build/text.o build/kjv.o build/test_kjv.o @@ -81,6 +82,6 @@ test: $(projects) done clean: - -rm -rf bin/ build/ + -rm -rf build/ #docs: $(docs) diff --git a/src/flight.h b/src/flight.h index 70bfd34..fcd0605 100644 --- a/src/flight.h +++ b/src/flight.h @@ -23,19 +23,19 @@ static const char *flight_type_string[] = { FLIGHT_TYPE }; #undef X #undef FLIGHT_TYPE -#include "helper.h" +#include "lorem.h" struct glider { - struct substring type, reg, launch; + struct lorem type, reg, launch; enum launch_type how; unsigned height_ft, pilot_min, dual_min, instr_min; - struct substring remarks; + struct lorem remarks; }; struct power { - struct substring type, reg, launch, landing, pilot, copilot; + struct lorem type, reg, launch, landing, pilot, copilot; unsigned dual_min, pilot_min, ifrsim_min, ifr_min; - struct substring remarks; + struct lorem remarks; }; struct flight { diff --git a/src/helper.h b/src/helper.h index 937ab42..7494073 100644 --- a/src/helper.h +++ b/src/helper.h @@ -1,9 +1,5 @@ -#include -#include #include - -/** `printf`-compatible substring. */ -struct substring { const char *sub; size_t size; }; +#include /** Parse unsigned; [`s`,`e`) => `n`. */ static int helper_natural(const char *s, const char *const e, uint32_t *const n) diff --git a/src/lorem.c b/src/lorem.c index 8439d55..dc7089d 100644 --- a/src/lorem.c +++ b/src/lorem.c @@ -1,7 +1,8 @@ /** @license 2023 Neil Edelman, distributed under the terms of the [MIT License](https://opensource.org/licenses/MIT). - Temporary strings duplicated from substrings. + Global stable pool of temporary strings duplicated from substrings. Doesn't + support deletion, only growing. @std C89 */ @@ -9,27 +10,54 @@ #include #include -/*#define ARRAY_NAME block +#define ARRAY_NAME block #define ARRAY_TYPE char * -#include "array.h"*/ +#include "array.h" -#define POOL_NAME char -#define POOL_TYPE char -#include "pool.h" +static struct { + size_t capacity, size; /* Lead block. */ + struct block_array blocks; +} lorem; -static struct char_pool pool; - -const char *lorem_dup(const struct substring sub) { +const char *lorem_dup(const struct lorem sub) { char *string; - if(!sub.sub) { errno = EDOM; return 0; } - if(sub.size == ~(size_t)0) { errno = ERANGE; return 0; } - if(!char_pool_buffer(&pool, sub.size + 1)) return 0; - assert(pool.capacity0 - pool.slots.data[0].size >= sub.size + 1); - string = pool.slots.data[0].slab + pool.slots.data[0].size; + size_t size; + if(!sub.sub) { errno = EDOM; return 0; } /* Null substring. */ + if(sub.size == ~(size_t)0) { errno = ERANGE; return 0; } /* Unlikely. */ + if((size = sub.size + 1) > lorem.capacity - lorem.size) { + size_t c0 = lorem.capacity < 8 ? 8 : lorem.capacity; + char *block = 0, **record = 0; + while(c0 < size) { /* Grow. */ + size_t c1 = c0 + (c0 >> 1) + (c0 >> 3); + if(c0 >= c1) { c0 = ~(size_t)0; break; } /* Unlikely. */ + c0 = c1; + } + if(!(block = malloc(c0)) + || !(record = block_array_new(&lorem.blocks))) { /* Error. */ + free(block); + if(!errno) errno = ERANGE; + return 0; + } + *record = block; + lorem.capacity = c0; + lorem.size = 0; + /*printf("%s size %zu\n", orcify(block), c0);*/ + } + assert(lorem.blocks.size); + string = lorem.blocks.data[lorem.blocks.size - 1] + lorem.size; memcpy(string, sub.sub, sub.size); string[sub.size] = '\0'; - pool.slots.data[0].size += sub.size + 1; + lorem.size += size; return string; } -void lorem_(void) { char_pool_(&pool); } +void lorem_(void) { + size_t i; + for(i = 0; i < lorem.blocks.size; i++) { + char *block = lorem.blocks.data[i]; + /*printf("free %s\n", orcify(block));*/ + free(block); + } + lorem.capacity = lorem.size = 0; + block_array_(&lorem.blocks); +} diff --git a/src/lorem.h b/src/lorem.h index 6704ab1..cf2566f 100644 --- a/src/lorem.h +++ b/src/lorem.h @@ -1,4 +1,6 @@ -#include "helper.h" +#include -const char *lorem_dup(const struct substring sub); +struct lorem { const char *sub; size_t size; }; + +const char *lorem_dup(const struct lorem); void lorem_(void); diff --git a/src/source.h b/src/source.h index 2a56bd8..b92dea2 100644 --- a/src/source.h +++ b/src/source.h @@ -1,6 +1,7 @@ #if defined BASE \ || !defined BASE && !defined GENERIC && !defined PROTO /* */ diff --git a/src/source.re.c b/src/source.re.c index 2b11c7e..015f79f 100644 --- a/src/source.re.c +++ b/src/source.re.c @@ -14,25 +14,25 @@ static int lookup_is_equal(const char *const x, const char *const y) { return !strcmp(x, y); } static uint32_t lookup_hash(const char *const x) { return djb2(x); } -static void lookup_to_string(const char *x, const struct substring desc, +static void lookup_to_string(const char *x, const struct lorem desc, char (*const a)[12]) { (void)desc; sprintf(*a, "%.11s", x); } -static struct substring lookup_default = { 0, 0 }; +static struct lorem lookup_default = { 0, 0 }; #define TABLE_NAME lookup #define TABLE_KEY char * #define TABLE_UINT uint32_t -#define TABLE_VALUE struct substring +#define TABLE_VALUE struct lorem #define TABLE_DEFAULT lookup_default #define TABLE_TO_STRING #include "../src/table.h" -static void source_to_string(const union line64 line, const struct substring *u, +static void source_to_string(const union line64 line, const struct lorem *u, char (*const a)[12]) { (void)u; date32_to_string(line.date, a); } static int source_compare(const union line64 a, const union line64 b) { return a.u64 > b.u64; } #define TREE_NAME source #define TREE_KEY union line64 -#define TREE_VALUE struct substring +#define TREE_VALUE struct lorem #define TREE_COMPARE #define TREE_TO_STRING #include "../src/tree.h" diff --git a/test/test_lorem.c b/test/test_lorem.c new file mode 100644 index 0000000..9222b87 --- /dev/null +++ b/test/test_lorem.c @@ -0,0 +1,37 @@ +#include "../src/lorem.h" +#include +#include + +int main(void) { + int success = EXIT_SUCCESS; + const char lorem[] = "Lorem ipsum dolor sit amet, consectetur adipiscing " + "elit. Aenean tincidunt leo neque. Integer vel bibendum lectus, a " + "vulputate dolor. Vivamus vestibulum quam ut euismod aliquet. Vivamus " + "vel pulvinar felis, eu dictum lorem. Integer scelerisque lobortis " + "orci nec tincidunt. Mauris vulputate ipsum non tempus tincidunt. " + "Pellentesque nec iaculis dolor. Curabitur bibendum pretium dui " + "euismod tincidunt. In cursus, libero et porta placerat, ante ante " + "accumsan lacus, nec sollicitudin ex elit nec lectus. Sed nisi sem, " + "rhoncus sed nulla et, faucibus feugiat eros."; + struct lorem s; + const char *a, *b, *c, *d; + s.sub = lorem + 6, s.size = 5; + if(!(a = lorem_dup(s))) goto catch; + printf("a: <%s>\n", a); + s.sub = lorem + 40, s.size = 20; + if(!(b = lorem_dup(s))) goto catch; + printf("a: <%s>, b: <%s>\n", a, b); + s.sub = lorem + 80, s.size = 60; + if(!(c = lorem_dup(s))) goto catch; + printf("a: <%s>, b: <%s>, c: <%s>\n", a, b, c); + s.sub = lorem + 200, s.size = 10; + if(!(d = lorem_dup(s))) goto catch; + printf("a: <%s>, b: <%s>, c: <%s>, d: <%s>\n", a, b, c, d); + goto finally; +catch: + success = EXIT_FAILURE; + perror("text"); +finally: + lorem_(); + return success; +} diff --git a/test/test_substrings.c b/test/test_substrings.c deleted file mode 100644 index 01fc59d..0000000 --- a/test/test_substrings.c +++ /dev/null @@ -1,20 +0,0 @@ -#include "../src/lorem.h" -#include -#include - -int main(void) { - int success = EXIT_SUCCESS; - const char lorem[] = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean tincidunt leo neque. Integer vel bibendum lectus, a vulputate dolor. Vivamus vestibulum quam ut euismod aliquet. Vivamus vel pulvinar felis, eu dictum lorem. Integer scelerisque lobortis orci nec tincidunt. Mauris vulputate ipsum non tempus tincidunt. Pellentesque nec iaculis dolor. Curabitur bibendum pretium dui euismod tincidunt. In cursus, libero et porta placerat, ante ante accumsan lacus, nec sollicitudin ex elit nec lectus. Sed nisi sem, rhoncus sed nulla et, faucibus feugiat eros."; - struct substring s; - const char *a; - s.sub = lorem + 6, s.size = 5; - if(!(a = lorem_dup(s))) goto catch; - printf("lorem: <%s>\n", a); - goto finally; -catch: - success = EXIT_FAILURE; - perror("text"); -finally: - lorem_(); - return success; -}