aboutsummaryrefslogtreecommitdiffstats
path: root/core/module.c
diff options
context:
space:
mode:
authoreunhhu <[email protected]>2026-09-29 18:04:10 +0100
committereunhhu <[email protected]>2026-09-29 18:04:10 +0100
commite710b93588782135365f01bb8351edb3bf4f95ac (patch)
tree9e4b810ad77761693dc8416eec5eb1bf55139194 /core/module.c
parent685cafa8f976fdd94168cfc933ad5389f8b4c617 (diff)
downloadpure-e710b93588782135365f01bb8351edb3bf4f95ac.tar.gz
pure-e710b93588782135365f01bb8351edb3bf4f95ac.zip
Refuse a module whose output names its fields otherwise while sends wait
Replacing a module, or starting one over a store, kept an output's waiting sends when the module had the output with as many fields of the same types. Their names were not compared, and the stored links kept the types alone: an output whose two numbers swapped places read debit 10, credit 20 as credit 10, debit 20, replaced and started again (review 004, F3). A send's bytes mean its fields' names and types in order; now both are compared, in memory and in the store, whose links (PLK4) keep each field's name. Links kept before (PLK3) have the types alone, as before; the next save writes PLK4. test-module's output_meaning: the swapped module is refused, replacing and starting, while a send waits; trimmed, it replaces and its sends go on; and the store then refuses the module before.
Diffstat (limited to 'core/module.c')
-rw-r--r--core/module.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/core/module.c b/core/module.c
index 574d6af..c65ef80 100644
--- a/core/module.c
+++ b/core/module.c
@@ -3246,9 +3246,10 @@ PURE_COLD static PureResult keep_list(PureList **out, PureList *from, const Pure
* again, and the next event or save publishes the module's states; a state
* the module drops stays stored as it was. Starting an app opens its module
* over none. */
-/* Outputs of old that module has by name and with the same fields keep their
- * sends and numbers; one it lacks or changed refuses the module while sends
- * are left on it (CONFLICT), and otherwise keeps its number for later. */
+/* Outputs of old that module has by name and with the same fields (their
+ * names and types, in order: what a send's bytes mean) keep their sends and
+ * numbers; one it lacks or changed refuses the module while sends are left
+ * on it (CONFLICT), and otherwise keeps its number for later. */
PURE_COLD static PureResult remap_outputs(PureApp *app, const PureModule *old, const PureModule *module, bool apply) {
int map[PURE_MODULE_INPUTS];
for (uint32_t i = 0; i < old->inputs; ++i) {
@@ -3257,8 +3258,11 @@ PURE_COLD static PureResult remap_outputs(PureApp *app, const PureModule *old, c
int to = pure_module_input(module, old->input_names[i]);
bool same = to >= 0 && module->input[to].kind == PURE_KIND_OUTPUT &&
module->input[to].field_count == old->input[i].field_count;
- for (uint32_t f = 0; same && f < old->input[i].field_count; ++f)
- same = module->field[module->input[to].field_start + f].type == old->field[old->input[i].field_start + f].type;
+ for (uint32_t f = 0; same && f < old->input[i].field_count; ++f) {
+ const PureField *now = &module->field[module->input[to].field_start + f],
+ *was = &old->field[old->input[i].field_start + f];
+ same = now->type == was->type && !strcmp(now->name, was->name);
+ }
map[i] = same ? to : -1;
size_t length = strlen(old->input_names[i]);
for (size_t s = 0, count = app->outbox ? pure_list_count(app->outbox) : 0; !same && s < count; ++s) {