diff --git a/firmware/integration/rusefi_config.txt b/firmware/integration/rusefi_config.txt index 306ca97a29..b5a2e538c0 100644 --- a/firmware/integration/rusefi_config.txt +++ b/firmware/integration/rusefi_config.txt @@ -1991,6 +1991,3 @@ end_struct ! we need to improve this further - at the moment we need too many boards to prepend 'false' #define show_test_presets true #define show_Frankenso_presets true - - -! poke \ No newline at end of file diff --git a/java_tools/ConfigDefinition.jar b/java_tools/ConfigDefinition.jar index be3a9b9e93..f30d4c0e5e 100644 Binary files a/java_tools/ConfigDefinition.jar and b/java_tools/ConfigDefinition.jar differ diff --git a/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigField.java b/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigField.java index 080aa27b3a..4eca468951 100644 --- a/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigField.java +++ b/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigField.java @@ -14,9 +14,10 @@ import java.util.regex.Pattern; * 1/15/15 */ public class ConfigField { - public static final ConfigField VOID = new ConfigField(null, "", null, null, null, 1, null, false, false, null,null, -1, null, null); + public static final ConfigField VOID = new ConfigField(null, "", null, null, null, new int[0], null, false, false, null,null, -1, null, null); + + private static final String typePattern = "([\\w\\d_]+)(\\[([\\w\\d]+)(\\sx\\s([\\w\\d]+))?(\\s([\\w\\d]+))?\\])?"; - private static final String typePattern = "([\\w\\d_]+)(\\[([\\w\\d]+)(\\s([\\w\\d]+))?\\])?"; private static final String namePattern = "[[\\w\\d\\s<>_]]+"; private static final String commentPattern = ";([^;]*)"; @@ -35,7 +36,7 @@ public class ConfigField { private final String comment; public final String arraySizeVariableName; private final String type; - private final int arraySize; + private final int[] arraySizes; private final String tsInfo; private final boolean isIterate; @@ -55,7 +56,7 @@ public class ConfigField { String comment, String arraySizeAsText, String type, - int arraySize, + int[] arraySizes, String tsInfo, boolean isIterate, boolean fsioVisible, @@ -81,13 +82,13 @@ public class ConfigField { Objects.requireNonNull(type); this.type = type; this.arraySizeVariableName = arraySizeAsText; - this.arraySize = arraySize; + this.arraySizes = arraySizes; this.tsInfo = tsInfo == null ? null : state.variableRegistry.applyVariables(tsInfo); this.isIterate = isIterate; } public boolean isArray() { - return arraySizeVariableName != null || arraySize != 1; + return arraySizeVariableName != null || arraySizes.length != 0; } public String getTrueName() { @@ -136,7 +137,7 @@ public class ConfigField { if (!matcher.matches()) return null; - String nameString = matcher.group(6).trim(); + String nameString = matcher.group(8).trim(); String[] nameTokens = nameString.split("\\s"); String name = nameTokens[nameTokens.length - 1]; @@ -152,23 +153,29 @@ public class ConfigField { break; } - String comment = matcher.group(8); + String comment = matcher.group(10); String type = matcher.group(1); - int arraySize; + int[] arraySizes; String arraySizeAsText; - if (matcher.group(3) != null) { + if (matcher.group(5) != null) { + arraySizeAsText = matcher.group(3) + "][" + matcher.group(5); + arraySizes = new int[2]; + arraySizes[0] = ConfigDefinition.getSize(state.variableRegistry, matcher.group(3)); + arraySizes[1] = ConfigDefinition.getSize(state.variableRegistry, matcher.group(5)); + } else if (matcher.group(3) != null) { arraySizeAsText = matcher.group(3); - arraySize = ConfigDefinition.getSize(state.variableRegistry, arraySizeAsText); + arraySizes = new int[1]; + arraySizes[0] = ConfigDefinition.getSize(state.variableRegistry, arraySizeAsText); } else { - arraySize = 1; + arraySizes = new int[0]; arraySizeAsText = null; } - String tsInfo = matcher.group(10); + String tsInfo = matcher.group(12); - boolean isIterate = "iterate".equalsIgnoreCase(matcher.group(5)); + boolean isIterate = "iterate".equalsIgnoreCase(matcher.group(7)); - ConfigField field = new ConfigField(state, name, comment, arraySizeAsText, type, arraySize, + ConfigField field = new ConfigField(state, name, comment, arraySizeAsText, type, arraySizes, tsInfo, isIterate, isFsioVisible, autoscaleSpec, null, -1, null, null); SystemOut.println("type " + type); SystemOut.println("name " + name); @@ -187,7 +194,11 @@ public class ConfigField { return 0; if (isBit()) return 4; - return getElementSize() * arraySize; + int size = getElementSize(); + for (int s : arraySizes) { + size *= s; + } + return size; } @Override @@ -195,7 +206,7 @@ public class ConfigField { return "ConfigField{" + "name='" + name + '\'' + ", type='" + type + '\'' + - ", arraySize=" + arraySize + + ", arraySizes=" + arraySizes + '}'; } @@ -206,8 +217,8 @@ public class ConfigField { return comment.charAt(0) == TS_COMMENT_TAG ? comment.substring(1) : comment; } - public int getArraySize() { - return arraySize; + public int[] getArraySizes() { + return arraySizes; } public String getComment() { diff --git a/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigStructure.java b/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigStructure.java index c94444d0ff..bb0ca598cd 100644 --- a/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigStructure.java +++ b/java_tools/configuration_definition/src/main/java/com/rusefi/ConfigStructure.java @@ -73,9 +73,16 @@ public class ConfigStructure { int fillSize = totalSize % 4 == 0 ? 0 : 4 - (totalSize % 4); if (fillSize != 0) { + int[] fillSizeArray; + if (fillSize != 1) { + fillSizeArray = new int[1]; + fillSizeArray[0] = fillSize; + } else { + fillSizeArray = new int[0]; + } ConfigField fill = new ConfigField(state, ALIGNMENT_FILL_AT + totalSize, "need 4 byte alignment", "" + fillSize, - TypesHelper.UINT8_T, fillSize, "\"units\", 1, 0, -20, 100, 0", false, false, null, null, -1, null, null); + TypesHelper.UINT8_T, fillSizeArray, "\"units\", 1, 0, -20, 100, 0", false, false, null, null, -1, null, null); addBoth(fill); } totalSize += fillSize; @@ -109,7 +116,7 @@ public class ConfigStructure { return; int sizeAtStartOfPadding = cFields.size(); while (readingBitState.get() < 32) { - ConfigField bitField = new ConfigField(readerState, "unusedBit_" + sizeAtStartOfPadding + "_" + readingBitState.get(), "", null, BOOLEAN_T, 0, null, false, false, null, null, -1, null, null); + ConfigField bitField = new ConfigField(readerState, "unusedBit_" + sizeAtStartOfPadding + "_" + readingBitState.get(), "", null, BOOLEAN_T, new int[0], null, false, false, null, null, -1, null, null); addBitField(bitField); } readingBitState.reset(); diff --git a/java_tools/configuration_definition/src/main/java/com/rusefi/ReaderState.java b/java_tools/configuration_definition/src/main/java/com/rusefi/ReaderState.java index 403d78b18b..3168e5fd9c 100644 --- a/java_tools/configuration_definition/src/main/java/com/rusefi/ReaderState.java +++ b/java_tools/configuration_definition/src/main/java/com/rusefi/ReaderState.java @@ -52,7 +52,7 @@ public class ReaderState { String trueName = bitNameParts.length > 1 ? bitNameParts[1].replaceAll("\"", "") : null; String falseName = bitNameParts.length > 2 ? bitNameParts[2].replaceAll("\"", "") : null; - ConfigField bitField = new ConfigField(state, bitNameParts[0], comment, null, BOOLEAN_T, 0, null, false, false, null, null, -1, trueName, falseName); + ConfigField bitField = new ConfigField(state, bitNameParts[0], comment, null, BOOLEAN_T, new int[0], null, false, false, null, null, -1, trueName, falseName); if (state.stack.isEmpty()) throw new IllegalStateException("Parent structure expected"); ConfigStructure structure = state.stack.peek(); @@ -246,7 +246,8 @@ public class ReaderState { if (cf == null) { if (ConfigField.isPreprocessorDirective(state, line)) { cf = new ConfigField(state, "", line, null, - ConfigField.DIRECTIVE_T, 0, null, false, false, null, null, 0, null, null); + ConfigField.DIRECTIVE_T, new int[0], null, false, false, null, null, 0, + null, null); } else { throw new IllegalStateException("Cannot parse line [" + line + "]"); } @@ -267,9 +268,9 @@ public class ReaderState { if (cf.isIterate()) { structure.addC(cf); - for (int i = 1; i <= cf.getArraySize(); i++) { + for (int i = 1; i <= cf.getArraySizes()[0]; i++) { ConfigField element = new ConfigField(state, cf.getName() + i, cf.getComment(), null, - cf.getType(), 1, cf.getTsInfo(), false, false, null, cf.getName(), i, null, null); + cf.getType(), new int[0], cf.getTsInfo(), false, false, null, cf.getName(), i, null, null); structure.addTs(element); } } else if (cf.isDirective()) { diff --git a/java_tools/configuration_definition/src/main/java/com/rusefi/output/JavaFieldsConsumer.java b/java_tools/configuration_definition/src/main/java/com/rusefi/output/JavaFieldsConsumer.java index c280d2aee1..2327268857 100644 --- a/java_tools/configuration_definition/src/main/java/com/rusefi/output/JavaFieldsConsumer.java +++ b/java_tools/configuration_definition/src/main/java/com/rusefi/output/JavaFieldsConsumer.java @@ -68,7 +68,7 @@ public abstract class JavaFieldsConsumer implements ConfigurationConsumer { return tsPosition; } - if (configField.getArraySize() != 1) { + if (configField.getArraySizes().length != 0) { // todo: array support } else if (TypesHelper.isFloat(configField.getType())) { writeJavaFieldName(nameWithPrefix, tsPosition); @@ -101,7 +101,7 @@ public abstract class JavaFieldsConsumer implements ConfigurationConsumer { javaFieldsWriter.write(");" + EOL); } - tsPosition += configField.getArraySize() * configField.getElementSize(); + tsPosition += configField.getSize(next); return tsPosition; } diff --git a/java_tools/configuration_definition/src/main/java/com/rusefi/output/TSProjectConsumer.java b/java_tools/configuration_definition/src/main/java/com/rusefi/output/TSProjectConsumer.java index 4096a88ab2..d6bd3c889a 100644 --- a/java_tools/configuration_definition/src/main/java/com/rusefi/output/TSProjectConsumer.java +++ b/java_tools/configuration_definition/src/main/java/com/rusefi/output/TSProjectConsumer.java @@ -80,23 +80,32 @@ public class TSProjectConsumer implements ConfigurationConsumer { tsPosition += configField.getState().tsCustomSize.get(configField.getType()); } else if (configField.getTsInfo() == null) { throw new IllegalArgumentException("Need TS info for " + configField.getName() + " at "+ prefix); - } else if (configField.getArraySize() == 0) { - // write nothing for empty array - // TS does not like those - } else if (configField.getArraySize() != 1) { - tsHeader.write(nameWithPrefix + " = array, "); - tsHeader.write(TypesHelper.convertToTs(configField.getType()) + ","); - tsHeader.write(" " + tsPosition + ","); - tsHeader.write(" [" + configField.getArraySize() + "],"); - tsHeader.write(" " + handleTsInfo(configField.getTsInfo(), 1)); - - tsPosition += configField.getArraySize() * configField.getElementSize(); - } else { + } else if (configField.getArraySizes().length == 0) { tsHeader.write(nameWithPrefix + " = scalar, "); tsHeader.write(TypesHelper.convertToTs(configField.getType()) + ","); tsHeader.write(" " + tsPosition + ","); tsHeader.write(" " + handleTsInfo(configField.getTsInfo(), 1)); - tsPosition += configField.getArraySize() * configField.getElementSize(); + tsPosition += configField.getSize(next); + } else if (configField.getSize(next) == 0) { + // write nothing for empty array + // TS does not like those + } else { + tsHeader.write(nameWithPrefix + " = array, "); + tsHeader.write(TypesHelper.convertToTs(configField.getType()) + ","); + tsHeader.write(" " + tsPosition + ","); + tsHeader.write(" ["); + boolean first = true; + for (int size : configField.getArraySizes()) { + if (first) { + first = false; + } else { + tsHeader.write("x"); + } + tsHeader.write(Integer.toString(size)); + } + tsHeader.write("], " + handleTsInfo(configField.getTsInfo(), 1)); + + tsPosition += configField.getSize(next); } tsHeader.write(EOL); return tsPosition; diff --git a/java_tools/configuration_definition/src/main/java/com/rusefi/test/ConfigFieldParserTest.java b/java_tools/configuration_definition/src/main/java/com/rusefi/test/ConfigFieldParserTest.java index 5432c9f1dc..d6751312ed 100644 --- a/java_tools/configuration_definition/src/main/java/com/rusefi/test/ConfigFieldParserTest.java +++ b/java_tools/configuration_definition/src/main/java/com/rusefi/test/ConfigFieldParserTest.java @@ -25,12 +25,27 @@ public class ConfigFieldParserTest { { ConfigField cf = ConfigField.parse(state, "uint8_t[8] field"); assertEquals(cf.getType(), "uint8_t"); - assertEquals(cf.getArraySize(), 8); + assertEquals(cf.getArraySizes().length, 1); + assertEquals(cf.getArraySizes()[0], 8); assertEquals(cf.getSize(null), 8); assertFalse("isIterate", cf.isIterate()); } } + @Test + public void testByte3dArray() { + ReaderState state = new ReaderState(); + { + ConfigField cf = ConfigField.parse(state, "uint8_t[8 x 16] field"); + assertEquals(cf.getType(), "uint8_t"); + assertEquals(cf.getArraySizes().length, 2); + assertEquals(cf.getArraySizes()[0], 8); + assertEquals(cf.getArraySizes()[1], 16); + assertEquals(cf.getSize(null), 128); + assertFalse("isIterate", cf.isIterate()); + } + } + @Test public void testFloatMsAlias() throws IOException { String test = "struct pid_s\n" + @@ -382,25 +397,26 @@ public class ConfigFieldParserTest { { ConfigField cf = ConfigField.parse(state, "int[3 iterate] field"); assertEquals(cf.getType(), "int"); - assertEquals(cf.getArraySize(), 3); + assertEquals(cf.getArraySizes().length, 1); + assertEquals(cf.getArraySizes()[0], 3); assertTrue("isIterate", cf.isIterate()); } { ConfigField cf = ConfigField.parse(state, "int16_t crankingRpm;This,. value controls what RPM values we consider 'cranking' (any RPM below 'crankingRpm')\\nAnything above 'crankingRpm' would be 'running'"); assertEquals(cf.getName(), "crankingRpm"); - assertEquals(cf.getArraySize(), 1); + assertEquals(cf.getArraySizes().length, 0); assertEquals(cf.getType(), "int16_t"); } { ConfigField cf = ConfigField.parse(state, "MAP_sensor_config_s map"); assertEquals(cf.getName(), "map"); - assertEquals(cf.getArraySize(), 1); + assertEquals(cf.getArraySizes().length, 0); assertEquals(cf.getType(), "MAP_sensor_config_s"); } { ConfigField cf = ConfigField.parse(state, "MAP_sensor_config_s map;@see hasMapSensor\\n@see isMapAveragingEnabled"); assertEquals(cf.getName(), "map"); - assertEquals(cf.getArraySize(), 1); + assertEquals(cf.getArraySizes().length, 0); assertEquals(cf.getType(), "MAP_sensor_config_s"); assertEquals(cf.getComment(), "@see hasMapSensor\\n@see isMapAveragingEnabled"); }