Skip to content

Commit

Permalink
Be extra explicit with include guards.
Browse files Browse the repository at this point in the history
I believe that this is only a problem for Arduino because Arduino brings
in header files that are not actually #included. This solution is a
little bit of a hack because it should not be necessary to add this
extra #ifndef, but it solves the problem and it should be mostly
harmless for users that do not target Arduino.
  • Loading branch information
petervdonovan committed Nov 11, 2023
1 parent 6c3a1b8 commit 9b7d3fb
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 4 deletions.
2 changes: 1 addition & 1 deletion core/src/main/java/org/lflang/generator/c/CGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -948,7 +948,7 @@ private void generateReactorClass(TypeParameterizedReactor tpr) throws IOExcepti
CodeBuilder header = new CodeBuilder();
CodeBuilder src = new CodeBuilder();
final String headerName = CUtil.getName(tpr) + ".h";
var guardMacro = headerName.toUpperCase().replace(".", "_");
var guardMacro = CUtil.internalIncludeGuard(tpr);
header.pr("#ifndef " + guardMacro);
header.pr("#define " + guardMacro);
generateReactorClassHeaders(tpr, headerName, header, src);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ private static String generateHeaderFile(
GenerateAuxiliaryStructs generator,
String topLevelPreamble) {
CodeBuilder builder = new CodeBuilder();
appendIncludeGuard(builder, tpr);
appendIncludeGuards(builder, tpr);
builder.pr(topLevelPreamble);
appendPoundIncludes(builder);
tpr.doDefines(builder);
Expand All @@ -64,14 +64,20 @@ private static String generateHeaderFile(
for (Reaction reaction : tpr.reactor().getReactions()) {
appendSignature(builder, types, reaction, tpr);
}
builder.pr("#endif");
closeIncludeGuards(builder);
return builder.getCode();
}

private static void appendIncludeGuard(CodeBuilder builder, TypeParameterizedReactor r) {
private static void appendIncludeGuards(CodeBuilder builder, TypeParameterizedReactor r) {
String macro = CUtil.getName(r) + "_H";
builder.pr("#ifndef " + macro);
builder.pr("#define " + macro);
builder.pr("#ifndef " + CUtil.internalIncludeGuard(r));
}

private static void closeIncludeGuards(CodeBuilder builder) {
builder.pr("#endif");
builder.pr("#endif");
}

private static void appendPoundIncludes(CodeBuilder builder) {
Expand Down
8 changes: 8 additions & 0 deletions core/src/main/java/org/lflang/generator/c/CUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,14 @@ public static String getName(TypeParameterizedReactor reactor) {
return name;
}

/**
* Return the name used in the internal (non-user-facing) include guard for the given reactor.
*/
public static String internalIncludeGuard(TypeParameterizedReactor tpr) {
final String headerName = CUtil.getName(tpr) + ".h";
return headerName.toUpperCase().replace(".", "_");
}

/**
* Return a reference to the specified port.
*
Expand Down
35 changes: 35 additions & 0 deletions test/C/src/arduino/DualReactorBlink.lf
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
target C {
platform: {
name: "arduino",
board: "arduino:avr:mega"
}
}

reactor Blinker {
input in_port:bool

reaction(startup) {=
pinMode(LED_BUILTIN, OUTPUT);
=}

reaction(in_port) {=
digitalWrite(LED_BUILTIN, in_port->value ? HIGH : LOW);
=}
}

reactor Timer {
timer t1(0, 500 msec)
state on_off:bool = false
output out_port:bool

reaction (t1) -> out_port {=
self->on_off = !self->on_off;
lf_set(out_port, self->on_off);
=}
}

main reactor {
the_blinker = new Blinker()
the_timer = new Timer()
the_timer.out_port -> the_blinker.in_port;
}

0 comments on commit 9b7d3fb

Please sign in to comment.