generate java enum from C enum? generate both C and java from yaml? #2102
This commit is contained in:
parent
5fdc884e71
commit
94bfeec588
|
@ -29,11 +29,9 @@ import java.util.zip.CRC32;
|
|||
*/
|
||||
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
|
||||
public class ConfigDefinition {
|
||||
public static final String EOL = "\n";
|
||||
private static final String SIGNATURE_HASH = "SIGNATURE_HASH";
|
||||
public static String MESSAGE;
|
||||
|
||||
public static String TOOL = "(unknown script)";
|
||||
private static final String ROM_RAIDER_XML_TEMPLATE = "rusefi_template.xml";
|
||||
public static final String KEY_DEFINITION = "-definition";
|
||||
private static final String KEY_ROMRAIDER_INPUT = "-romraider";
|
||||
|
@ -66,10 +64,6 @@ public class ConfigDefinition {
|
|||
public static boolean needZeroInit = true;
|
||||
public static String definitionInputFile = null;
|
||||
|
||||
public static String getGeneratedAutomaticallyTag() {
|
||||
return LazyFile.LAZY_FILE_TAG + "ConfigDefinition.jar based on " + TOOL + " ";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
doJob(args);
|
||||
|
@ -127,7 +121,7 @@ public class ConfigDefinition {
|
|||
String key = args[i];
|
||||
switch (key) {
|
||||
case "-tool":
|
||||
ConfigDefinition.TOOL = args[i + 1];
|
||||
ToolUtil.TOOL = args[i + 1];
|
||||
break;
|
||||
case KEY_DEFINITION:
|
||||
definitionInputFile = args[i + 1];
|
||||
|
@ -240,12 +234,12 @@ public class ConfigDefinition {
|
|||
|
||||
handleFiringOrder(firingEnumFileName, state.variableRegistry);
|
||||
|
||||
MESSAGE = getGeneratedAutomaticallyTag() + definitionInputFile + " " + new Date();
|
||||
MESSAGE = ToolUtil.getGeneratedAutomaticallyTag() + definitionInputFile + " " + new Date();
|
||||
|
||||
SystemOut.println("Reading definition from " + definitionInputFile);
|
||||
|
||||
for (String prependFile : prependFiles)
|
||||
readPrependValues(state.variableRegistry, prependFile);
|
||||
state.variableRegistry.readPrependValues(prependFile);
|
||||
|
||||
if (yamlFiles != null) {
|
||||
processYamls(state.variableRegistry, yamlFiles, state);
|
||||
|
@ -267,8 +261,8 @@ public class ConfigDefinition {
|
|||
parseState.setDefinitionPolicy(Definition.OverwritePolicy.IgnoreNew);
|
||||
|
||||
//for (String prependFile : prependFiles) {
|
||||
// TODO: fix signature define file parsing
|
||||
//parseFile(listener, prependFile);
|
||||
// TODO: fix signature define file parsing
|
||||
//parseFile(listener, prependFile);
|
||||
//}
|
||||
}
|
||||
|
||||
|
@ -299,7 +293,7 @@ public class ConfigDefinition {
|
|||
VariableRegistry tmpRegistry = new VariableRegistry();
|
||||
// store the CRC32 as a built-in variable
|
||||
tmpRegistry.register(SIGNATURE_HASH, "" + crc32);
|
||||
readPrependValues(tmpRegistry, signaturePrependFile);
|
||||
tmpRegistry.readPrependValues(signaturePrependFile);
|
||||
destinations.add(new SignatureConsumer(signatureDestination, tmpRegistry));
|
||||
}
|
||||
if (needToUpdateOtherFiles) {
|
||||
|
@ -329,7 +323,7 @@ public class ConfigDefinition {
|
|||
|
||||
|
||||
if (destCDefinesFileName != null && needToUpdateOtherFiles)
|
||||
state.variableRegistry.writeDefinesToFile(destCDefinesFileName);
|
||||
writeDefinesToFile(state.variableRegistry, destCDefinesFileName);
|
||||
|
||||
if (romRaiderDestination != null && romRaiderInputFile != null && needToUpdateOtherFiles) {
|
||||
processTextTemplate(state, romRaiderInputFile, romRaiderDestination);
|
||||
|
@ -376,22 +370,6 @@ public class ConfigDefinition {
|
|||
return needToUpdateTsFiles;
|
||||
}
|
||||
|
||||
public static void readPrependValues(VariableRegistry registry, String prependFile) throws IOException {
|
||||
BufferedReader definitionReader = new BufferedReader(new FileReader(prependFile));
|
||||
String line;
|
||||
while ((line = definitionReader.readLine()) != null) {
|
||||
line = trimLine(line);
|
||||
/**
|
||||
* we should ignore empty lines and comments
|
||||
*/
|
||||
if (ReaderState.isEmptyDefinitionLine(line))
|
||||
continue;
|
||||
if (startsWithToken(line, ReaderState.DEFINE)) {
|
||||
processDefine(registry, line.substring(ReaderState.DEFINE.length()).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void processYamls(VariableRegistry registry, File[] yamlFiles, ReaderState state) throws IOException {
|
||||
ArrayList<Map<String, Object>> listPins = new ArrayList<>();
|
||||
for (File yamlFile : yamlFiles) {
|
||||
|
@ -524,7 +502,7 @@ public class ConfigDefinition {
|
|||
SystemOut.println("Reading from " + inputFileName);
|
||||
SystemOut.println("Writing to " + outputFileName);
|
||||
|
||||
state.variableRegistry.put("generator_message", ConfigDefinition.getGeneratedAutomaticallyTag() + new Date());
|
||||
state.variableRegistry.put("generator_message", ToolUtil.getGeneratedAutomaticallyTag() + new Date());
|
||||
|
||||
File inputFile = new File(inputFileName);
|
||||
|
||||
|
@ -534,30 +512,19 @@ public class ConfigDefinition {
|
|||
String line;
|
||||
while ((line = fr.readLine()) != null) {
|
||||
line = state.variableRegistry.applyVariables(line);
|
||||
fw.write(line + ConfigDefinition.EOL);
|
||||
fw.write(line + ToolUtil.EOL);
|
||||
}
|
||||
fw.close();
|
||||
}
|
||||
|
||||
static String trimLine(String line) {
|
||||
line = line.trim();
|
||||
line = line.replaceAll("\\s+", " ");
|
||||
return line;
|
||||
}
|
||||
|
||||
static boolean startsWithToken(String line, String token) {
|
||||
return line.startsWith(token + " ") || line.startsWith(token + "\t");
|
||||
}
|
||||
|
||||
|
||||
public static String getComment(String comment, int currentOffset, String units) {
|
||||
String start = "\t/**";
|
||||
String packedComment = packComment(comment, "\t");
|
||||
String unitsComment = units.isEmpty() ? "" : "\t" + units + EOL;
|
||||
return start + EOL +
|
||||
String unitsComment = units.isEmpty() ? "" : "\t" + units + ToolUtil.EOL;
|
||||
return start + ToolUtil.EOL +
|
||||
packedComment +
|
||||
unitsComment +
|
||||
"\t * offset " + currentOffset + EOL + "\t */" + EOL;
|
||||
"\t * offset " + currentOffset + ToolUtil.EOL + "\t */" + ToolUtil.EOL;
|
||||
}
|
||||
|
||||
public static String packComment(String comment, String linePrefix) {
|
||||
|
@ -567,7 +534,7 @@ public class ConfigDefinition {
|
|||
return "";
|
||||
String result = "";
|
||||
for (String line : comment.split("\\\\n")) {
|
||||
result += linePrefix + " * " + line + EOL;
|
||||
result += linePrefix + " * " + line + ToolUtil.EOL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
@ -579,28 +546,6 @@ public class ConfigDefinition {
|
|||
return Integer.parseInt(s);
|
||||
}
|
||||
|
||||
static void processDefine(VariableRegistry registry, String line) {
|
||||
int index = line.indexOf(' ');
|
||||
String name;
|
||||
if (index == -1) {
|
||||
name = line;
|
||||
line = "";
|
||||
} else {
|
||||
name = line.substring(0, index);
|
||||
line = line.substring(index).trim();
|
||||
}
|
||||
if (VariableRegistry.isNumeric(line)) {
|
||||
int v = Integer.parseInt(line);
|
||||
registry.register(name, v);
|
||||
} else {
|
||||
if (line.contains(" ") && !VariableRegistry.isQuoted(line, '\"') && !VariableRegistry.isQuoted(line, '\'')) {
|
||||
throw new IllegalStateException("Unexpected space in unquoted " + line);
|
||||
}
|
||||
|
||||
registry.register(name, line);
|
||||
}
|
||||
}
|
||||
|
||||
private static long getCrc32(String fileName) throws IOException {
|
||||
File file = new File(fileName);
|
||||
byte[] fileContent = Files.readAllBytes(file.toPath());
|
||||
|
@ -614,6 +559,16 @@ public class ConfigDefinition {
|
|||
return c.getValue();
|
||||
}
|
||||
|
||||
public static void writeDefinesToFile(VariableRegistry variableRegistry, String fileName) throws IOException {
|
||||
|
||||
SystemOut.println("Writing to " + fileName);
|
||||
LazyFile cHeader = new LazyFile(fileName);
|
||||
|
||||
cHeader.write("//\n// " + ToolUtil.getGeneratedAutomaticallyTag() + definitionInputFile + "\n//\n\n");
|
||||
cHeader.write(variableRegistry.getDefinesSection());
|
||||
cHeader.close();
|
||||
}
|
||||
|
||||
public static class RusefiParseErrorStrategy extends DefaultErrorStrategy {
|
||||
private boolean hadError = false;
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ public class ConfigField {
|
|||
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";
|
||||
|
|
|
@ -21,13 +21,11 @@ import static com.rusefi.ConfigField.BOOLEAN_T;
|
|||
*/
|
||||
public class ReaderState {
|
||||
public static final String BIT = "bit";
|
||||
public static final String DEFINE = "#define";
|
||||
private static final String CUSTOM = "custom";
|
||||
private static final String END_STRUCT = "end_struct";
|
||||
private static final String STRUCT_NO_PREFIX = "struct_no_prefix ";
|
||||
private static final String STRUCT = "struct ";
|
||||
private static final String DEFINE_CONSTRUCTOR = "define_constructor";
|
||||
public static final char MULT_TOKEN = '*';
|
||||
public final Stack<ConfigStructure> stack = new Stack<>();
|
||||
public final Map<String, Integer> tsCustomSize = new HashMap<>();
|
||||
public final Map<String, String> tsCustomLine = new HashMap<>();
|
||||
|
@ -61,14 +59,6 @@ public class ReaderState {
|
|||
structure.addBitField(bitField);
|
||||
}
|
||||
|
||||
static boolean isEmptyDefinitionLine(String line) {
|
||||
/**
|
||||
* historically somehow '!' was the start of comment line
|
||||
* '//' is the later added alternative.
|
||||
*/
|
||||
return line.length() == 0 || line.startsWith("!") || line.startsWith("//");
|
||||
}
|
||||
|
||||
public void read(Reader reader) throws IOException {
|
||||
Map<String, EnumsReader.EnumState> newEnums = EnumsReader.readStatic(reader);
|
||||
|
||||
|
@ -129,7 +119,7 @@ public class ReaderState {
|
|||
customSize = customSize.replaceAll("x", "*");
|
||||
line = variableRegistry.applyVariables(line);
|
||||
|
||||
int multPosition = customSize.indexOf(MULT_TOKEN);
|
||||
int multPosition = customSize.indexOf(VariableRegistry.MULT_TOKEN);
|
||||
if (multPosition != -1) {
|
||||
String firstPart = customSize.substring(0, multPosition).trim();
|
||||
int first;
|
||||
|
@ -169,11 +159,11 @@ public class ReaderState {
|
|||
String line;
|
||||
while ((line = definitionReader.readLine()) != null) {
|
||||
lineIndex++;
|
||||
line = ConfigDefinition.trimLine(line);
|
||||
line = ToolUtil.trimLine(line);
|
||||
/**
|
||||
* we should ignore empty lines and comments
|
||||
*/
|
||||
if (isEmptyDefinitionLine(line))
|
||||
if (ToolUtil.isEmptyDefinitionLine(line))
|
||||
continue;
|
||||
|
||||
if (line.startsWith(STRUCT)) {
|
||||
|
@ -186,15 +176,15 @@ public class ReaderState {
|
|||
} else if (line.startsWith(BIT)) {
|
||||
handleBitLine(this, line);
|
||||
|
||||
} else if (ConfigDefinition.startsWithToken(line, CUSTOM)) {
|
||||
} else if (ToolUtil.startsWithToken(line, CUSTOM)) {
|
||||
handleCustomLine(line);
|
||||
|
||||
} else if (ConfigDefinition.startsWithToken(line, DEFINE)) {
|
||||
} else if (ToolUtil.startsWithToken(line, VariableRegistry.DEFINE)) {
|
||||
/**
|
||||
* for example
|
||||
* #define CLT_CURVE_SIZE 16
|
||||
*/
|
||||
ConfigDefinition.processDefine(variableRegistry, line.substring(DEFINE.length()).trim());
|
||||
variableRegistry.processDefine(line.substring(VariableRegistry.DEFINE.length()).trim());
|
||||
} else {
|
||||
if (stack.isEmpty())
|
||||
throw new IllegalStateException("Expected to be within structure at line " + lineIndex + ": " + line);
|
||||
|
|
|
@ -2,7 +2,7 @@ package com.rusefi.output;
|
|||
|
||||
import com.rusefi.*;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
import static com.rusefi.ToolUtil.EOL;
|
||||
|
||||
public abstract class BaseCHeaderConsumer implements ConfigurationConsumer {
|
||||
private static final String BOOLEAN_TYPE = "bool";
|
||||
|
|
|
@ -6,7 +6,7 @@ import com.rusefi.util.SystemOut;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
import static com.rusefi.ToolUtil.EOL;
|
||||
|
||||
/**
|
||||
* Configuration consumer which writes C header file
|
||||
|
|
|
@ -2,12 +2,13 @@ package com.rusefi.output;
|
|||
|
||||
import com.rusefi.ConfigDefinition;
|
||||
import com.rusefi.ReaderState;
|
||||
import com.rusefi.ToolUtil;
|
||||
import com.rusefi.util.LazyFile;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
import static com.rusefi.ToolUtil.EOL;
|
||||
|
||||
public class FileFsioSettingsConsumer extends FsioSettingsConsumer {
|
||||
private final LazyFile enumFile;
|
||||
|
@ -30,7 +31,7 @@ public class FileFsioSettingsConsumer extends FsioSettingsConsumer {
|
|||
@Override
|
||||
public void startFile() {
|
||||
for (LazyFile file : Arrays.asList(enumFile, gettersFile, stringsFile, namesFile)) {
|
||||
file.write("// this file " + ConfigDefinition.MESSAGE + ConfigDefinition.EOL + EOL);
|
||||
file.write("// this file " + ConfigDefinition.MESSAGE + ToolUtil.EOL + EOL);
|
||||
file.write("// by " + getClass() + EOL);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,13 @@ package com.rusefi.output;
|
|||
|
||||
import com.rusefi.ConfigDefinition;
|
||||
import com.rusefi.ReaderState;
|
||||
import com.rusefi.ToolUtil;
|
||||
import com.rusefi.util.LazyFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
import static com.rusefi.ToolUtil.EOL;
|
||||
|
||||
/**
|
||||
* This class generates java representation of rusEfi data structures used by rusEfi console
|
||||
|
@ -27,11 +28,11 @@ public class FileJavaFieldsConsumer extends JavaFieldsConsumer {
|
|||
|
||||
@Override
|
||||
public void startFile() {
|
||||
javaFields.write("package " + JAVA_PACKAGE + ";" + ConfigDefinition.EOL + ConfigDefinition.EOL);
|
||||
javaFields.write("// this file " + ConfigDefinition.MESSAGE + ConfigDefinition.EOL + EOL);
|
||||
javaFields.write("package " + JAVA_PACKAGE + ";" + ToolUtil.EOL + ToolUtil.EOL);
|
||||
javaFields.write("// this file " + ConfigDefinition.MESSAGE + ToolUtil.EOL + EOL);
|
||||
javaFields.write("// by " + getClass() + EOL);
|
||||
javaFields.write("import com.rusefi.config.*;" + EOL + EOL);
|
||||
javaFields.write("public class " + className + " {" + ConfigDefinition.EOL);
|
||||
javaFields.write("public class " + className + " {" + ToolUtil.EOL);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -42,7 +43,7 @@ public class FileJavaFieldsConsumer extends JavaFieldsConsumer {
|
|||
allFields.append("\t};" + EOL);
|
||||
javaFields.write(allFields.toString());
|
||||
|
||||
javaFields.write("}" + ConfigDefinition.EOL);
|
||||
javaFields.write("}" + ToolUtil.EOL);
|
||||
javaFields.close();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
import static com.rusefi.ToolUtil.EOL;
|
||||
|
||||
public abstract class JavaFieldsConsumer implements ConfigurationConsumer {
|
||||
// todo: why is this field 'static'?
|
||||
|
@ -74,7 +74,7 @@ public abstract class JavaFieldsConsumer implements ConfigurationConsumer {
|
|||
writeJavaFieldName(nameWithPrefix, tsPosition);
|
||||
javaFieldsWriter.write("FieldType.FLOAT);" + EOL);
|
||||
} else {
|
||||
String enumOptions = state.variableRegistry.get(configField.getType() + ConfigField.ENUM_SUFFIX);
|
||||
String enumOptions = state.variableRegistry.get(configField.getType() + VariableRegistry.ENUM_SUFFIX);
|
||||
|
||||
if (enumOptions != null && !javaEnums.contains(configField.getType())) {
|
||||
javaEnums.add(configField.getType());
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
package com.rusefi.output;
|
||||
|
||||
import com.rusefi.*;
|
||||
import com.rusefi.util.LazyFile;
|
||||
import com.rusefi.util.SystemOut;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
|
||||
/**
|
||||
* Configuration consumer which writes Signature header file
|
||||
*/
|
||||
|
@ -27,7 +24,7 @@ public class SignatureConsumer implements ConfigurationConsumer {
|
|||
|
||||
@Override
|
||||
public void handleEndStruct(ConfigStructure structure) throws IOException {
|
||||
registry.writeDefinesToFile(destHeader);
|
||||
ConfigDefinition.writeDefinesToFile(registry, destHeader);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -9,7 +9,7 @@ import com.rusefi.util.SystemOut;
|
|||
import java.io.*;
|
||||
|
||||
import static com.rusefi.util.IoUtils.CHARSET;
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
import static com.rusefi.ToolUtil.EOL;
|
||||
|
||||
public class TSProjectConsumer implements ConfigurationConsumer {
|
||||
private static final String TS_FILE_INPUT_NAME = "rusefi.input";
|
||||
|
@ -167,17 +167,17 @@ public class TSProjectConsumer implements ConfigurationConsumer {
|
|||
protected void writeContent(String fieldsSection, TsFileContent tsContent, Output tsHeader) throws IOException {
|
||||
tsHeader.write(tsContent.getPrefix());
|
||||
|
||||
tsHeader.write("; " + CONFIG_DEFINITION_START + ConfigDefinition.EOL);
|
||||
tsHeader.write("; this section " + ConfigDefinition.MESSAGE + ConfigDefinition.EOL + ConfigDefinition.EOL);
|
||||
tsHeader.write("pageSize = " + totalTsSize + ConfigDefinition.EOL);
|
||||
tsHeader.write("page = 1" + ConfigDefinition.EOL);
|
||||
tsHeader.write("; " + CONFIG_DEFINITION_START + ToolUtil.EOL);
|
||||
tsHeader.write("; this section " + ConfigDefinition.MESSAGE + ToolUtil.EOL + ToolUtil.EOL);
|
||||
tsHeader.write("pageSize = " + totalTsSize + ToolUtil.EOL);
|
||||
tsHeader.write("page = 1" + ToolUtil.EOL);
|
||||
tsHeader.write(fieldsSection);
|
||||
if (settingContextHelp.length() > 0) {
|
||||
tsHeader.write("[" + SETTING_CONTEXT_HELP + "]" + ConfigDefinition.EOL);
|
||||
tsHeader.write(settingContextHelp.toString() + ConfigDefinition.EOL + ConfigDefinition.EOL);
|
||||
tsHeader.write("; " + SETTING_CONTEXT_HELP_END + ConfigDefinition.EOL);
|
||||
tsHeader.write("[" + SETTING_CONTEXT_HELP + "]" + ToolUtil.EOL);
|
||||
tsHeader.write(settingContextHelp.toString() + ToolUtil.EOL + ToolUtil.EOL);
|
||||
tsHeader.write("; " + SETTING_CONTEXT_HELP_END + ToolUtil.EOL);
|
||||
}
|
||||
tsHeader.write("; " + CONFIG_DEFINITION_END + ConfigDefinition.EOL);
|
||||
tsHeader.write("; " + CONFIG_DEFINITION_END + ToolUtil.EOL);
|
||||
tsHeader.write(tsContent.getPostfix());
|
||||
tsHeader.close();
|
||||
}
|
||||
|
@ -218,10 +218,10 @@ public class TSProjectConsumer implements ConfigurationConsumer {
|
|||
line = state.variableRegistry.applyVariables(line);
|
||||
|
||||
if (isBeforeStartTag)
|
||||
prefix.append(line + ConfigDefinition.EOL);
|
||||
prefix.append(line + ToolUtil.EOL);
|
||||
|
||||
if (isAfterEndTag)
|
||||
postfix.append(state.variableRegistry.applyVariables(line) + ConfigDefinition.EOL);
|
||||
postfix.append(state.variableRegistry.applyVariables(line) + ToolUtil.EOL);
|
||||
}
|
||||
r.close();
|
||||
return new TsFileContent(prefix.toString(), postfix.toString());
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.rusefi.test;
|
||||
|
||||
import com.rusefi.ConfigDefinition;
|
||||
import com.rusefi.EnumsReader;
|
||||
import com.rusefi.VariableRegistry;
|
||||
import org.junit.Test;
|
||||
|
@ -21,7 +20,7 @@ public class ConfigDefinitionTest {
|
|||
|
||||
VariableRegistry variableRegistry = new VariableRegistry();
|
||||
|
||||
ConfigDefinition.readPrependValues(variableRegistry, FIRMWARE + File.separator + "integration/rusefi_config.txt");
|
||||
variableRegistry.readPrependValues(FIRMWARE + File.separator + "integration/rusefi_config.txt");
|
||||
|
||||
|
||||
String sb = variableRegistry.getEnumOptionsForTunerStudio(enumsReader, "engine_type_e");
|
||||
|
|
|
@ -118,7 +118,7 @@ public class ConfigFieldParserTest {
|
|||
@Test(expected = IllegalStateException.class)
|
||||
public void invalidDefine() throws IOException {
|
||||
String test = "struct pid_s\n" +
|
||||
ReaderState.DEFINE + " show show_Hellen121vag_presets true\n" +
|
||||
VariableRegistry.DEFINE + " show show_Hellen121vag_presets true\n" +
|
||||
"end_struct\n" +
|
||||
"";
|
||||
BufferedReader reader = new BufferedReader(new StringReader(test));
|
||||
|
|
Binary file not shown.
|
@ -14,8 +14,8 @@ public class EnumsReader {
|
|||
protected final Map<String, EnumState> enums = new TreeMap<>();
|
||||
|
||||
@NotNull
|
||||
static List<Value> getSortedByOrder(Map<String, Value> brain_pin_e) {
|
||||
Set<Value> byOrdinal = new TreeSet<>(Comparator.comparingInt(Value::getIntValue));
|
||||
static List<Value> getSortedByOrder(VariableRegistry registry, Map<String, Value> brain_pin_e) {
|
||||
Set<Value> byOrdinal = new TreeSet<>(Comparator.comparingInt(value -> value.getIntValueMaybeResolve(registry)));
|
||||
byOrdinal.addAll(brain_pin_e.values());
|
||||
return new ArrayList<>(byOrdinal);
|
||||
}
|
||||
|
|
|
@ -11,10 +11,12 @@ class InvokeReader {
|
|||
private final static String KEY_INPUT_PATH = "-enumInputPath";
|
||||
private final static String KEY_OUTPUT = "-outputPath";
|
||||
private final static String KEY_OUTPUT_FILE = "-generatedFile";
|
||||
private static final String KEY_DEFINITION = "-definition";
|
||||
public static String fileSuffix = "enums";
|
||||
|
||||
private String[] args;
|
||||
private String outputPath;
|
||||
private List<String> definitionInputFiles = new ArrayList<>();
|
||||
private List<String> inputFiles = new ArrayList<>();
|
||||
private String inputPath = ".";
|
||||
|
||||
|
@ -34,6 +36,10 @@ class InvokeReader {
|
|||
return inputPath;
|
||||
}
|
||||
|
||||
public List<String> getDefinitionInputFiles() {
|
||||
return definitionInputFiles;
|
||||
}
|
||||
|
||||
public String getOutputPath() {
|
||||
return outputPath;
|
||||
}
|
||||
|
@ -46,15 +52,23 @@ class InvokeReader {
|
|||
outputPath = null;
|
||||
for (int i = 0; i < args.length - 1; i += 2) {
|
||||
String key = args[i];
|
||||
if (key.equals(KEY_INPUT_PATH)) {
|
||||
inputPath = Objects.requireNonNull(args[i + 1], KEY_INPUT_PATH);
|
||||
} else if (key.equals(EnumToString.KEY_ENUM_INPUT_FILE)) {
|
||||
String headerInputFile = args[i + 1];
|
||||
inputFiles.add(headerInputFile);
|
||||
} else if (key.equals(KEY_OUTPUT_FILE)) {
|
||||
fileSuffix = args[i + 1];
|
||||
} else if (key.equals(KEY_OUTPUT)) {
|
||||
outputPath = args[i + 1];
|
||||
switch (key) {
|
||||
case KEY_DEFINITION:
|
||||
definitionInputFiles.add(args[i + 1]);
|
||||
break;
|
||||
case KEY_INPUT_PATH:
|
||||
inputPath = Objects.requireNonNull(args[i + 1], KEY_INPUT_PATH);
|
||||
break;
|
||||
case EnumToString.KEY_ENUM_INPUT_FILE:
|
||||
String headerInputFile = args[i + 1];
|
||||
inputFiles.add(headerInputFile);
|
||||
break;
|
||||
case KEY_OUTPUT_FILE:
|
||||
fileSuffix = args[i + 1];
|
||||
break;
|
||||
case KEY_OUTPUT:
|
||||
outputPath = args[i + 1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
|
|
|
@ -18,6 +18,10 @@ public class ToJavaEnum {
|
|||
|
||||
EnumsReader enumsReader = new EnumsReader();
|
||||
|
||||
VariableRegistry registry = new VariableRegistry();
|
||||
for (String fileName : invokeReader.getDefinitionInputFiles())
|
||||
registry.readPrependValues(fileName);
|
||||
|
||||
for (String inputFile : invokeReader.getInputFiles()) {
|
||||
File f = new File(invokeReader.getInputPath() + File.separator + inputFile);
|
||||
SystemOut.println("Reading enums from " + f);
|
||||
|
@ -26,7 +30,7 @@ public class ToJavaEnum {
|
|||
}
|
||||
|
||||
for (Map.Entry<String /*enum name*/, EnumsReader.EnumState> e : enumsReader.getEnums().entrySet()) {
|
||||
String java = generate(e.getKey(), e.getValue());
|
||||
String java = generate(registry, e.getKey(), e.getValue());
|
||||
|
||||
String fullFileName = outputPath + File.separator + e.getKey() + ".java";
|
||||
BufferedWriter br = new BufferedWriter(new FileWriter(fullFileName));
|
||||
|
@ -35,12 +39,12 @@ public class ToJavaEnum {
|
|||
}
|
||||
}
|
||||
|
||||
public static String generate(String key, EnumsReader.EnumState enumState) {
|
||||
public static String generate(VariableRegistry registry, String key, EnumsReader.EnumState enumState) {
|
||||
StringBuilder sb = new StringBuilder("package com.rusefi.enums;\n");
|
||||
sb.append("//auto-generated by ToJavaEnum.java\n\n\n\n");
|
||||
sb.append("public enum " + key + " {\n");
|
||||
|
||||
List<Value> sorted = EnumsReader.getSortedByOrder(enumState.values);
|
||||
List<Value> sorted = EnumsReader.getSortedByOrder(registry, enumState.values);
|
||||
|
||||
for (Value value : sorted) {
|
||||
sb.append("\t" + value.getName() + ",\n");
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package com.rusefi;
|
||||
|
||||
import com.rusefi.util.LazyFile;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
|
||||
public class ToolUtil {
|
||||
public static final String EOL = "\n";
|
||||
public static String TOOL = "(unknown script)";
|
||||
|
||||
static String getJarFileName() {
|
||||
try {
|
||||
|
||||
// Get path of the JAR file
|
||||
String jarPath = VariableRegistry.class
|
||||
.getProtectionDomain()
|
||||
.getCodeSource()
|
||||
.getLocation()
|
||||
.toURI()
|
||||
.getPath();
|
||||
System.out.println("JAR Path : " + jarPath);
|
||||
|
||||
// Get name of the JAR file
|
||||
return jarPath.substring(jarPath.lastIndexOf("/") + 1);
|
||||
} catch (URISyntaxException e) {
|
||||
return "(unknown jar)";
|
||||
}
|
||||
}
|
||||
|
||||
public static String getGeneratedAutomaticallyTag() {
|
||||
return LazyFile.LAZY_FILE_TAG + getJarFileName() + " based on " + TOOL + " ";
|
||||
}
|
||||
|
||||
static boolean isEmptyDefinitionLine(String line) {
|
||||
/**
|
||||
* historically somehow '!' was the start of comment line
|
||||
* '//' is the later added alternative.
|
||||
*/
|
||||
return line.length() == 0 || line.startsWith("!") || line.startsWith("//");
|
||||
}
|
||||
|
||||
static boolean startsWithToken(String line, String token) {
|
||||
return line.startsWith(token + " ") || line.startsWith(token + "\t");
|
||||
}
|
||||
|
||||
static String trimLine(String line) {
|
||||
line = line.trim();
|
||||
line = line.replaceAll("\\s+", " ");
|
||||
return line;
|
||||
}
|
||||
}
|
|
@ -1,18 +1,19 @@
|
|||
package com.rusefi;
|
||||
|
||||
import com.rusefi.enum_reader.Value;
|
||||
import com.rusefi.util.LazyFile;
|
||||
import com.rusefi.util.SystemOut;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.io.Reader;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.rusefi.ConfigDefinition.EOL;
|
||||
import static com.rusefi.ReaderState.MULT_TOKEN;
|
||||
|
||||
/**
|
||||
* 3/30/2015
|
||||
*/
|
||||
|
@ -20,9 +21,11 @@ public class VariableRegistry {
|
|||
public static final String _16_HEX_SUFFIX = "_16_hex";
|
||||
public static final String _HEX_SUFFIX = "_hex";
|
||||
public static final String CHAR_SUFFIX = "_char";
|
||||
public static final String ENUM_SUFFIX = "_enum";
|
||||
public static final char MULT_TOKEN = '*';
|
||||
public static final String DEFINE = "#define";
|
||||
private static final String HEX_PREFIX = "0x";
|
||||
private final TreeMap<String, String> data = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
public static final VariableRegistry INSTANCE = new VariableRegistry();
|
||||
|
||||
// todo: smarter regex! See TsWriter.VAR which is a bit better but still not perfect
|
||||
// todo: https://github.com/rusefi/rusefi/issues/3053 ?
|
||||
|
@ -33,7 +36,46 @@ public class VariableRegistry {
|
|||
private final Map<String, String> cAllDefinitions = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
private final Map<String, String> javaDefinitions = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
|
||||
public VariableRegistry() {
|
||||
public void readPrependValues(String prependFile) throws IOException {
|
||||
readPrependValues(new FileReader(prependFile));
|
||||
}
|
||||
|
||||
public void readPrependValues(Reader fileReader) throws IOException {
|
||||
BufferedReader definitionReader = new BufferedReader(fileReader);
|
||||
String line;
|
||||
while ((line = definitionReader.readLine()) != null) {
|
||||
line = ToolUtil.trimLine(line);
|
||||
/**
|
||||
* we should ignore empty lines and comments
|
||||
*/
|
||||
if (ToolUtil.isEmptyDefinitionLine(line))
|
||||
continue;
|
||||
if (ToolUtil.startsWithToken(line, DEFINE)) {
|
||||
processDefine(line.substring(DEFINE.length()).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void processDefine(String line) {
|
||||
int index = line.indexOf(' ');
|
||||
String name;
|
||||
if (index == -1) {
|
||||
name = line;
|
||||
line = "";
|
||||
} else {
|
||||
name = line.substring(0, index);
|
||||
line = line.substring(index).trim();
|
||||
}
|
||||
if (isNumeric(line)) {
|
||||
int v = Integer.parseInt(line);
|
||||
register(name, v);
|
||||
} else {
|
||||
if (line.contains(" ") && !isQuoted(line, '\"') && !isQuoted(line, '\'')) {
|
||||
throw new IllegalStateException("Unexpected space in unquoted " + line);
|
||||
}
|
||||
|
||||
register(name, line);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -129,7 +171,7 @@ public class VariableRegistry {
|
|||
if (!value.contains("\n")) {
|
||||
// multi-lines are not supported in C headers
|
||||
if (!var.endsWith(_16_HEX_SUFFIX) && !var.endsWith(_HEX_SUFFIX)) {
|
||||
cAllDefinitions.put(var, "#define " + var + " " + value + EOL);
|
||||
cAllDefinitions.put(var, "#define " + var + " " + value + ToolUtil.EOL);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
|
@ -149,7 +191,7 @@ public class VariableRegistry {
|
|||
if (value.trim().startsWith(HEX_PREFIX)) {
|
||||
int intValue = Integer.parseInt(value.trim().substring(HEX_PREFIX.length()), 16);
|
||||
intValues.put(var, intValue);
|
||||
javaDefinitions.put(var, "\tpublic static final int " + var + " = " + value + ";" + EOL);
|
||||
javaDefinitions.put(var, "\tpublic static final int " + var + " = " + value + ";" + ToolUtil.EOL);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -158,18 +200,18 @@ public class VariableRegistry {
|
|||
SystemOut.println("key [" + var + "] value: " + intValue);
|
||||
intValues.put(var, intValue);
|
||||
if (!var.endsWith(_HEX_SUFFIX)) {
|
||||
javaDefinitions.put(var, "\tpublic static final int " + var + " = " + intValue + ";" + EOL);
|
||||
javaDefinitions.put(var, "\tpublic static final int " + var + " = " + intValue + ";" + ToolUtil.EOL);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
SystemOut.println("Not an integer: " + value);
|
||||
|
||||
if (!var.trim().endsWith(ConfigField.ENUM_SUFFIX)) {
|
||||
if (!var.trim().endsWith(ENUM_SUFFIX)) {
|
||||
if (isQuoted(value, '"')) {
|
||||
// quoted and not with enum suffix means plain string define statement
|
||||
javaDefinitions.put(var, "\tpublic static final String " + var + " = " + value + ";" + EOL);
|
||||
javaDefinitions.put(var, "\tpublic static final String " + var + " = " + value + ";" + ToolUtil.EOL);
|
||||
} else if (isQuoted(value, '\'')) {
|
||||
// quoted and not with enum suffix means plain string define statement
|
||||
javaDefinitions.put(var, "\tpublic static final char " + var + " = " + value + ";" + EOL);
|
||||
javaDefinitions.put(var, "\tpublic static final char " + var + " = " + value + ";" + ToolUtil.EOL);
|
||||
char charValue = value.charAt(1);
|
||||
registerHex(var + CHAR_SUFFIX, charValue);
|
||||
doRegister(var + CHAR_SUFFIX, Character.toString(charValue));
|
||||
|
@ -205,16 +247,6 @@ public class VariableRegistry {
|
|||
register(name + _16_HEX_SUFFIX, _16_hex);
|
||||
}
|
||||
|
||||
public void writeDefinesToFile(String fileName) throws IOException {
|
||||
|
||||
SystemOut.println("Writing to " + fileName);
|
||||
LazyFile cHeader = new LazyFile(fileName);
|
||||
|
||||
cHeader.write("//\n// " + ConfigDefinition.getGeneratedAutomaticallyTag() + ConfigDefinition.definitionInputFile + "\n//\n\n");
|
||||
cHeader.write(getDefinesSection());
|
||||
cHeader.close();
|
||||
}
|
||||
|
||||
public String getDefinesSection() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String value : cAllDefinitions.values())
|
|
@ -1,5 +1,7 @@
|
|||
package com.rusefi.enum_reader;
|
||||
|
||||
import com.rusefi.VariableRegistry;
|
||||
|
||||
public class Value implements Comparable<Value> {
|
||||
private final String name;
|
||||
private final String value;
|
||||
|
@ -33,4 +35,13 @@ public class Value implements Comparable<Value> {
|
|||
", value='" + value + '\'' +
|
||||
'}';
|
||||
}
|
||||
|
||||
public int getIntValueMaybeResolve(VariableRegistry registry) {
|
||||
try {
|
||||
return getIntValue();
|
||||
} catch (NumberFormatException e) {
|
||||
String resolvedValue = registry.get(value);
|
||||
return Integer.parseInt(resolvedValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,12 +118,13 @@ public class EnumToStringTest {
|
|||
EnumsReader.EnumState brain_pin_e = enumsReader.getEnums().get("brain_pin_e");
|
||||
assertEquals(2, brain_pin_e.values.get("GPIO_HEX").getIntValue());
|
||||
|
||||
List<Value> listByOrdinal = EnumsReader.getSortedByOrder(brain_pin_e.values);
|
||||
VariableRegistry registry = new VariableRegistry();
|
||||
List<Value> listByOrdinal = EnumsReader.getSortedByOrder(registry, brain_pin_e.values);
|
||||
assertEquals(0, listByOrdinal.get(0).getIntValue());
|
||||
|
||||
for (Map.Entry<String /*enum name*/, EnumsReader.EnumState> e : enumsReader.getEnums().entrySet()) {
|
||||
|
||||
String a = new ToJavaEnum().generate(e.getKey(), e.getValue());
|
||||
String a = ToJavaEnum.generate(registry, e.getKey(), e.getValue());
|
||||
|
||||
assertEquals("package com.rusefi.enums;\n" +
|
||||
"//auto-generated by ToJavaEnum.java\n" +
|
||||
|
@ -178,4 +179,28 @@ public class EnumToStringTest {
|
|||
" return NULL;\n" +
|
||||
"}\n", enumToString.getCppFileContent());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithInput() throws IOException {
|
||||
final StringReader reader = new StringReader(
|
||||
"typedef enum {\n" +
|
||||
"\tGPIO_UNASSIGNED = XXXX,\n" +
|
||||
"}brain_pin_e; // hello");
|
||||
|
||||
VariableRegistry registry = new VariableRegistry();
|
||||
registry.readPrependValues(new StringReader("#define XXXX 12"));
|
||||
|
||||
EnumsReader enumsReader = new EnumsReader().read(reader);
|
||||
for (Map.Entry<String /*enum name*/, EnumsReader.EnumState> e : enumsReader.getEnums().entrySet()) {
|
||||
String java = ToJavaEnum.generate(registry, e.getKey(), e.getValue());
|
||||
assertEquals("package com.rusefi.enums;\n" +
|
||||
"//auto-generated by ToJavaEnum.java\n" +
|
||||
"\n" +
|
||||
"\n" +
|
||||
"\n" +
|
||||
"public enum brain_pin_e {\n" +
|
||||
"\tGPIO_UNASSIGNED,\n" +
|
||||
"}\n", java);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue