From f5820190cd43f9adf21d5f9253de4dbff66cf1cb Mon Sep 17 00:00:00 2001 From: andreika-git Date: Thu, 5 Nov 2020 14:59:47 +0200 Subject: [PATCH] add #if/#else/#endif support to gen_config (#1928) Co-authored-by: Andrei --- .../src/com/rusefi/ConfigField.java | 12 +++++++++++ .../src/com/rusefi/ConfigStructure.java | 10 +++++++++- .../src/com/rusefi/ReaderState.java | 13 ++++++++++-- .../com/rusefi/output/JavaFieldsConsumer.java | 5 +++++ .../com/rusefi/output/TSProjectConsumer.java | 20 +++++++++++++++++++ 5 files changed, 57 insertions(+), 3 deletions(-) diff --git a/java_tools/configuration_definition/src/com/rusefi/ConfigField.java b/java_tools/configuration_definition/src/com/rusefi/ConfigField.java index 77973fad24..69c47283cb 100644 --- a/java_tools/configuration_definition/src/com/rusefi/ConfigField.java +++ b/java_tools/configuration_definition/src/com/rusefi/ConfigField.java @@ -21,10 +21,13 @@ public class ConfigField { private static final Pattern FIELD = Pattern.compile(typePattern + "\\s(" + namePattern + ")(" + commentPattern + ")?(;(.*))?"); + private static final Pattern DIRECTIVE = Pattern.compile("#(if\\s" + namePattern + "|else|elif\\s\" + namePattern + \"|endif)"); + public static final char TS_COMMENT_TAG = '+'; public static final String ENUM_SUFFIX = "_enum"; public static final String VOID_NAME = ""; public static final String BOOLEAN_T = "boolean"; + public static final String DIRECTIVE_T = "directive"; private final String name; private final String comment; @@ -103,6 +106,10 @@ public class ConfigField { return BOOLEAN_T.equalsIgnoreCase(type); } + public boolean isDirective() { + return DIRECTIVE_T.equalsIgnoreCase(type); + } + private boolean isVoid() { return name.equals(VOID_NAME); } @@ -152,6 +159,11 @@ public class ConfigField { return field; } + public static boolean isPreprocessorDirective(ReaderState state, String line) { + Matcher matcher = DIRECTIVE.matcher(line); + return matcher.matches(); + } + public int getSize(ConfigField next) { if (isBit() && next.isBit()) return 0; diff --git a/java_tools/configuration_definition/src/com/rusefi/ConfigStructure.java b/java_tools/configuration_definition/src/com/rusefi/ConfigStructure.java index 9cb7a45b47..9049cfceda 100644 --- a/java_tools/configuration_definition/src/com/rusefi/ConfigStructure.java +++ b/java_tools/configuration_definition/src/com/rusefi/ConfigStructure.java @@ -29,6 +29,8 @@ public class ConfigStructure { public final BitState readingBitState = new BitState(); + private ConfigField cPrevField = ConfigField.VOID; + public ConfigStructure(String name, String comment, boolean withPrefix, boolean withConstructor) { this.name = name; this.comment = comment; @@ -75,12 +77,18 @@ public class ConfigStructure { } public void addBoth(ConfigField cf) { - cFields.add(cf); + addC(cf); tsFields.add(cf); } public void addC(ConfigField cf) { + // skip duplicate names + if (cf.getName().equals(cPrevField.getName())) + return; + cFields.add(cf); + + cPrevField = cf; } public void addTs(ConfigField cf) { diff --git a/java_tools/configuration_definition/src/com/rusefi/ReaderState.java b/java_tools/configuration_definition/src/com/rusefi/ReaderState.java index 2394015a5d..01ee69947e 100644 --- a/java_tools/configuration_definition/src/com/rusefi/ReaderState.java +++ b/java_tools/configuration_definition/src/com/rusefi/ReaderState.java @@ -227,8 +227,15 @@ public class ReaderState { private static void processField(ReaderState state, String line) { ConfigField cf = ConfigField.parse(state, line); - if (cf == null) - throw new IllegalStateException("Cannot parse line [" + line + "]"); + + if (cf == null) { + if (ConfigField.isPreprocessorDirective(state, line)) { + cf = new ConfigField(state, "", line, null, + ConfigField.DIRECTIVE_T, 0, null, false, false, null, 0, null, null); + } else { + throw new IllegalStateException("Cannot parse line [" + line + "]"); + } + } if (state.stack.isEmpty()) throw new IllegalStateException(cf.getName() + ": Not enclosed in a struct"); @@ -250,6 +257,8 @@ public class ReaderState { cf.getType(), 1, cf.getTsInfo(), false, false, cf.getName(), i, null, null); structure.addTs(element); } + } else if (cf.isDirective()) { + structure.addTs(cf); } else { structure.addBoth(cf); } diff --git a/java_tools/configuration_definition/src/com/rusefi/output/JavaFieldsConsumer.java b/java_tools/configuration_definition/src/com/rusefi/output/JavaFieldsConsumer.java index af5917b355..abc06ca0cd 100644 --- a/java_tools/configuration_definition/src/com/rusefi/output/JavaFieldsConsumer.java +++ b/java_tools/configuration_definition/src/com/rusefi/output/JavaFieldsConsumer.java @@ -37,12 +37,17 @@ public abstract class JavaFieldsConsumer implements ConfigurationConsumer { private int writeJavaFields(List tsFields, String prefix, int tsPosition) throws IOException { BitState bitState = new BitState(); + ConfigField prev = ConfigField.VOID; for (int i = 0; i < tsFields.size(); i++) { ConfigField next = i == tsFields.size() - 1 ? ConfigField.VOID : tsFields.get(i + 1); ConfigField cf = tsFields.get(i); + // skip duplicate names + if (cf.getName().equals(prev.getName()) || cf.isDirective()) + continue; tsPosition = writeOneField(cf, prefix, tsPosition, next, bitState.get()); bitState.incrementBitIndex(cf, next); + prev = cf; } return tsPosition; } diff --git a/java_tools/configuration_definition/src/com/rusefi/output/TSProjectConsumer.java b/java_tools/configuration_definition/src/com/rusefi/output/TSProjectConsumer.java index b5c43db423..4f6fb98847 100644 --- a/java_tools/configuration_definition/src/com/rusefi/output/TSProjectConsumer.java +++ b/java_tools/configuration_definition/src/com/rusefi/output/TSProjectConsumer.java @@ -36,6 +36,12 @@ public class TSProjectConsumer implements ConfigurationConsumer { private int writeTunerStudio(ConfigField configField, String prefix, Writer tsHeader, int tsPosition, ConfigField next, int bitIndex) throws IOException { String nameWithPrefix = prefix + configField.getName(); + if (configField.isDirective() && configField.getComment() != null) { + tsHeader.write(configField.getComment()); + tsHeader.write(EOL); + return tsPosition; + } + if (configField.getComment() != null && configField.getComment().startsWith(ConfigField.TS_COMMENT_TAG + "")) { settingContextHelp.append("\t" + nameWithPrefix + " = \"" + configField.getCommentContent() + "\"" + EOL); } @@ -119,9 +125,23 @@ public class TSProjectConsumer implements ConfigurationConsumer { private int writeTunerStudio(ConfigStructure configStructure, String prefix, Writer tsHeader, int tsPosition) throws IOException { BitState bitState = new BitState(); + ConfigField prev = ConfigField.VOID; + int prevTsPosition = tsPosition; for (int i = 0; i < configStructure.tsFields.size(); i++) { ConfigField next = i == configStructure.tsFields.size() - 1 ? ConfigField.VOID : configStructure.tsFields.get(i + 1); ConfigField cf = configStructure.tsFields.get(i); + + // if duplicate names, use previous position + if (cf.getName().equals(prev.getName())) { + tsPosition = prevTsPosition; + } + + // Update 'prev' state needed for duplicate names recognition + if (!cf.isDirective()) { + prevTsPosition = tsPosition; + prev = cf; + } + tsPosition = writeTunerStudio(cf, prefix, tsHeader, tsPosition, next, bitState.get()); bitState.incrementBitIndex(cf, next);