diff --git a/core/src/main/java/org/lflang/generator/c/CTriggerObjectsGenerator.java b/core/src/main/java/org/lflang/generator/c/CTriggerObjectsGenerator.java index ebef8e5933..5ff6a65200 100644 --- a/core/src/main/java/org/lflang/generator/c/CTriggerObjectsGenerator.java +++ b/core/src/main/java/org/lflang/generator/c/CTriggerObjectsGenerator.java @@ -1087,6 +1087,60 @@ private static String deferredAllocationForEffectsOnInputs(ReactorInstance react return code.toString(); } + /** + * Set the parent pointer and reactor name. If the reactor is in a bank, the name will be the + * instance name with [index] appended. + * + * @param reactor The reactor instance. + */ + private static String deferredSetParentAndName(ReactorInstance reactor) { + var code = new CodeBuilder(); + if (reactor.isBank()) { + // First, generate code to determine the size of the memory needed for the name. + code.pr("char* format = \"%s[%d]\";"); + code.pr( + "int length = snprintf(NULL, 0, format, \"" + + reactor.getName() + + "\", " + + CUtil.bankIndexName(reactor) + + ");\n"); + code.pr( + CUtil.reactorRef(reactor) + + "->base.name = (char*)lf_allocate(length + 1, sizeof(char)," + + " (allocation_record_t**)&((self_base_t*)" + + CUtil.reactorRef(reactor) + + ")->allocations);"); + code.pr( + "if(" + + CUtil.reactorRef(reactor) + + "->base.name != NULL) {"); // Will be NULL if lf_allocate fails. + code.indent(); + code.pr( + "snprintf(" + + CUtil.reactorRef(reactor) + + "->base.name, length + 1, format, \"" + + reactor.getName() + + "\", " + + CUtil.bankIndexName(reactor) + + ");"); + code.unindent(); + code.pr("}"); + } else { + code.pr(CUtil.reactorRef(reactor) + "->base.name = \"" + reactor.getName() + "\";"); + } + ReactorInstance parent = reactor.getParent(); + if (parent == null) { + code.pr(CUtil.reactorRef(reactor) + "->base.parent = (self_base_t*)NULL;"); + } else { + code.pr( + CUtil.reactorRef(reactor) + + "->base.parent = (self_base_t*)" + + CUtil.reactorRef(parent) + + ";"); + } + return code.toString(); + } + /** * Perform initialization functions that must be performed after all reactor runtime instances * have been created. This function creates nested loops over nested banks. @@ -1104,6 +1158,9 @@ private static String deferredInitialize( // over bank members for the reactor's parent. code.startScopedBlock(reactor); + // Set the parent pointer and name for the reactor. + code.pr(deferredSetParentAndName(reactor)); + // If the child has a multiport that is an effect of some reaction in its container, // then we have to generate code to allocate memory for arrays pointing to // its data. If the child is a bank, then memory is allocated for the entire diff --git a/core/src/main/resources/lib/c/reactor-c b/core/src/main/resources/lib/c/reactor-c index 03137a0295..c2437e1f94 160000 --- a/core/src/main/resources/lib/c/reactor-c +++ b/core/src/main/resources/lib/c/reactor-c @@ -1 +1 @@ -Subproject commit 03137a029588e5eec364f3f1d6c2ab99a22f66de +Subproject commit c2437e1f948a5d4f2bc487137c3ccb02ca89f631 diff --git a/test/C/src/ReactorName.lf b/test/C/src/ReactorName.lf new file mode 100644 index 0000000000..0fa130168f --- /dev/null +++ b/test/C/src/ReactorName.lf @@ -0,0 +1,58 @@ +target C { + build-type: debug +} + +preamble {= + #include +=} + +reactor A(parent_bank_index: size_t = 0) { + reaction(startup) {= + const char* name = lf_reactor_full_name(self); + lf_print("name: %s", name); + char buffer[20]; + snprintf(buffer, 20, "ReactorName.b[%zu].a", self->parent_bank_index); + if (strcmp(buffer, name) != 0) { + lf_print_error_and_exit("full name does not match"); + } + name = lf_reactor_name(self); + if (strcmp("a", name) != 0) { + lf_print_error_and_exit("name does not match"); + } + =} +} + +reactor B(bank_index: size_t = 0) { + a = new A(parent_bank_index=bank_index) + + reaction(startup) {= + const char* name = lf_reactor_full_name(self); + lf_print("name: %s", name); + char buffer[20]; + snprintf(buffer, 20, "ReactorName.b[%zu]", self->bank_index); + if (strcmp(buffer, name) != 0) { + lf_print_error_and_exit("full name does not match"); + } + name = lf_reactor_name(self); + snprintf(buffer, 20, "b[%zu]", self->bank_index); + if (strcmp(buffer, name) != 0) { + lf_print_error_and_exit("name does not match"); + } + =} +} + +main reactor { + b = new[3] B() + + reaction(startup) {= + const char* name = lf_reactor_full_name(self); + lf_print("name: %s", name); + if (strcmp("ReactorName", name) != 0) { + lf_print_error_and_exit("full name does not match"); + } + name = lf_reactor_name(self); + if (strcmp("ReactorName", name) != 0) { + lf_print_error_and_exit("name does not match"); + } + =} +}