diff --git a/java_tools/ConfigDefinition.jar b/java_tools/ConfigDefinition.jar index 0dc5a1260a..29ee78d137 100644 Binary files a/java_tools/ConfigDefinition.jar and b/java_tools/ConfigDefinition.jar differ diff --git a/java_tools/configuration_definition/build.xml b/java_tools/configuration_definition/build.xml index 180224c105..b9fc4b5cc5 100644 --- a/java_tools/configuration_definition/build.xml +++ b/java_tools/configuration_definition/build.xml @@ -11,6 +11,7 @@ diff --git a/java_tools/configuration_definition/src/com/rusefi/ConfigStructure.java b/java_tools/configuration_definition/src/com/rusefi/ConfigStructure.java index 751c52ddb7..d6135c9158 100644 --- a/java_tools/configuration_definition/src/com/rusefi/ConfigStructure.java +++ b/java_tools/configuration_definition/src/com/rusefi/ConfigStructure.java @@ -54,6 +54,7 @@ public class ConfigStructure { * we make alignment decision based on C fields since we expect iteration and non-iteration fields * to match in size */ + totalSize = 0; for (int i = 0; i < cFields.size(); i++) { ConfigField cf = cFields.get(i); ConfigField next = i == cFields.size() - 1 ? ConfigField.VOID : cFields.get(i + 1); @@ -64,7 +65,7 @@ public class ConfigStructure { int fillSize = totalSize % 4 == 0 ? 0 : 4 - (totalSize % 4); if (fillSize != 0) { - ConfigField fill = new ConfigField(state, "alignmentFill", "need 4 byte alignment", + ConfigField fill = new ConfigField(state, "alignmentFill_at_" + totalSize, "need 4 byte alignment", "" + fillSize, TypesHelper.UINT8_T, fillSize, null, false, false, null, -1); addBoth(fill); diff --git a/java_tools/configuration_definition/src/com/rusefi/ReaderState.java b/java_tools/configuration_definition/src/com/rusefi/ReaderState.java index 17fe286d4d..84dcd26997 100644 --- a/java_tools/configuration_definition/src/com/rusefi/ReaderState.java +++ b/java_tools/configuration_definition/src/com/rusefi/ReaderState.java @@ -95,6 +95,19 @@ public class ReaderState { } } + private void handleEndStruct(List consumers) throws IOException { + if (stack.isEmpty()) + throw new IllegalStateException("Unexpected end_struct"); + ConfigStructure structure = stack.pop(); + SystemOut.println("Ending structure " + structure.getName()); + structure.addAlignmentFill(this); + + structures.put(structure.getName(), structure); + + for (ConfigurationConsumer consumer : consumers) + consumer.handleEndStruct(structure); + } + public void readBufferedReader(BufferedReader definitionReader, List consumers) throws IOException { for (ConfigurationConsumer consumer : consumers) consumer.startFile(); @@ -114,7 +127,7 @@ public class ReaderState { handleStartStructure(this, line.substring(STRUCT_NO_PREFIX.length()), false); } else if (line.startsWith(END_STRUCT)) { addBitPadding(); - handleEndStruct(this, consumers); + this.handleEndStruct(consumers); } else if (line.startsWith(BIT)) { handleBitLine(this, line); @@ -128,6 +141,8 @@ public class ReaderState { */ ConfigDefinition.processDefine(line.substring(DEFINE.length()).trim()); } else { + if (stack.isEmpty()) + throw new IllegalStateException("Expected to be within structure"); addBitPadding(); processField(this, line); } @@ -172,19 +187,6 @@ public class ReaderState { SystemOut.println("Starting structure " + structure.getName()); } - private static void handleEndStruct(ReaderState state, List consumers) throws IOException { - if (state.stack.isEmpty()) - throw new IllegalStateException("Unexpected end_struct"); - ConfigStructure structure = state.stack.pop(); - SystemOut.println("Ending structure " + structure.getName()); - structure.addAlignmentFill(state); - - state.structures.put(structure.getName(), structure); - - for (ConfigurationConsumer consumer : consumers) - consumer.handleEndStruct(structure); - } - private static void processField(ReaderState state, String line) { ConfigField cf = ConfigField.parse(state, line); @@ -195,6 +197,15 @@ public class ReaderState { throw new IllegalStateException(cf.getName() + ": Not enclosed in a struct"); ConfigStructure structure = state.stack.peek(); + Integer getPrimitiveSize = TypesHelper.getPrimitiveSize(cf.getType()); + if (getPrimitiveSize != null && getPrimitiveSize % 4 == 0) { + SystemOut.println("Need to align before " + cf.getName()); + structure.addAlignmentFill(state); + } else { + // adding a structure instance - had to be aligned + // todo? structure.addAlignmentFill(state); + } + if (cf.isIterate()) { structure.addC(cf); for (int i = 1; i <= cf.getArraySize(); i++) { diff --git a/java_tools/configuration_definition/src/com/rusefi/TypesHelper.java b/java_tools/configuration_definition/src/com/rusefi/TypesHelper.java index 8fa5d238b5..f10fe2d16e 100644 --- a/java_tools/configuration_definition/src/com/rusefi/TypesHelper.java +++ b/java_tools/configuration_definition/src/com/rusefi/TypesHelper.java @@ -24,6 +24,13 @@ public class TypesHelper { return state.structures.get(type).totalSize; if (state != null && state.tsCustomSize.containsKey(type)) return state.tsCustomSize.get(type); + Integer primitiveSize = getPrimitiveSize(type); + if (primitiveSize != null) + return primitiveSize; + throw new IllegalArgumentException("Unknown type " + type); + } + + public static Integer getPrimitiveSize(String type) { if (isPrimitive1byte(type)) return 1; if (isPrimitive2byte(type)) { @@ -32,7 +39,7 @@ public class TypesHelper { if (isPrimitive4byte(type)) { return 4; } - throw new IllegalArgumentException("Unknown type " + type); + return null; } public static boolean isPrimitive(String type) { diff --git a/java_tools/configuration_definition/src/com/rusefi/test/ConfigFieldParserTest.java b/java_tools/configuration_definition/src/com/rusefi/test/ConfigFieldParserTest.java index 83c47f4f67..b71c29e17b 100644 --- a/java_tools/configuration_definition/src/com/rusefi/test/ConfigFieldParserTest.java +++ b/java_tools/configuration_definition/src/com/rusefi/test/ConfigFieldParserTest.java @@ -2,6 +2,7 @@ package com.rusefi.test; import com.rusefi.ConfigField; import com.rusefi.ReaderState; +import com.rusefi.TypesHelper; import com.rusefi.VariableRegistry; import com.rusefi.output.FsioSettingsConsumer; import com.rusefi.output.JavaFieldsConsumer; @@ -9,7 +10,6 @@ import org.junit.Test; import java.io.BufferedReader; import java.io.IOException; -import java.io.Reader; import java.io.StringReader; import java.util.Arrays; @@ -33,6 +33,24 @@ public class ConfigFieldParserTest { } } + @Test + public void alignFourByteTypes() throws IOException { + // we expect padding before each 4 byte field + String test = "struct pid_s\n" + + "\tint16_t periodMs1;PID dTime;\"ms\", 1, 0, 0, 3000, 0\n" + + "\tint periodSec;PID dTime;\"ms\", 1, 0, 0, 3000, 0\n" + + "\tint16_t periodMs2;PID dTime;\"ms\", 1, 0, 0, 3000, 0\n" + + "\tint periodSec2;PID dTime;\"ms\", 1, 0, 0, 3000, 0\n" + + "end_struct\n"; + ReaderState state = new ReaderState(); + BufferedReader reader = new BufferedReader(new StringReader(test)); + + JavaFieldsConsumer javaFieldsConsumer = createTestJavaConsumer(state); + state.readBufferedReader(reader, Arrays.asList(javaFieldsConsumer)); + + assertEquals(16, TypesHelper.getElementSize(state, "pid_s")); + } + @Test public void testFsioVisible() throws IOException { { @@ -57,19 +75,9 @@ public class ConfigFieldParserTest { "end_struct\n" + "" + ""; - Reader inputString = new StringReader(test); - BufferedReader reader = new BufferedReader(inputString); - - JavaFieldsConsumer javaFieldsConsumer = new JavaFieldsConsumer(state) { - @Override - public void startFile() { - } - - @Override - public void endFile() { - } - }; + BufferedReader reader = new BufferedReader(new StringReader(test)); + JavaFieldsConsumer javaFieldsConsumer = createTestJavaConsumer(state); FsioSettingsConsumer fsioSettingsConsumer = new FsioSettingsConsumer(state) { @Override @@ -154,6 +162,18 @@ public class ConfigFieldParserTest { } } + private JavaFieldsConsumer createTestJavaConsumer(ReaderState state) { + return new JavaFieldsConsumer(state) { + @Override + public void startFile() { + } + + @Override + public void endFile() { + } + }; + } + @Test public void testParseLine() { ReaderState state = new ReaderState();