gen_config should fail with misaligned integers fix #1115
This commit is contained in:
parent
c2e02cc235
commit
a62340b8b9
Binary file not shown.
|
@ -11,6 +11,7 @@
|
|||
<mkdir dir="build/classes"/>
|
||||
<javac
|
||||
source="${javac.source}"
|
||||
debug="true"
|
||||
target="${javac.target}"
|
||||
destdir="build/classes"
|
||||
classpath="lib/junit.jar:lib/annotations.jar:lib/snakeyaml.jar">
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -95,6 +95,19 @@ public class ReaderState {
|
|||
}
|
||||
}
|
||||
|
||||
private void handleEndStruct(List<ConfigurationConsumer> 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<ConfigurationConsumer> 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<ConfigurationConsumer> 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++) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue