rusefi-full/java_tools/configuration_definition/src/com/rusefi/ConfigDefinition.java

323 lines
13 KiB
Java

package com.rusefi;
import com.rusefi.output.*;
import com.rusefi.util.IoUtils;
import com.rusefi.util.LazyFile;
import com.rusefi.util.SystemOut;
import java.io.*;
import java.lang.reflect.Array;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
/**
* (c) Andrey Belomutskiy
* 1/12/15
*/
@SuppressWarnings("StringConcatenationInsideStringBufferAppend")
public class ConfigDefinition {
public static final String EOL = "\n";
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_ROM_INPUT = "-romraider";
public static final String KEY_TS_DESTINATION = "-ts_destination";
private static final String KEY_C_DESTINATION = "-c_destination";
private static final String KEY_C_FSIO_CONSTANTS = "-c_fsio_constants";
private static final String KEY_C_FSIO_GETTERS = "-c_fsio_getters";
private static final String KEY_C_FSIO_NAMES = "-c_fsio_names";
private static final String KEY_C_FSIO_STRING = "-c_fsio_strings";
private static final String KEY_C_DEFINES = "-c_defines";
private static final String KEY_WITH_C_DEFINES = "-with_c_defines";
private static final String KEY_JAVA_DESTINATION = "-java_destination";
private static final String KEY_ROMRAIDER_DESTINATION = "-romraider_destination";
private static final String KEY_FIRING = "-firing_order";
public static final String KEY_PREPEND = "-prepend";
private static final String KEY_SKIP = "-skip";
private static final String KEY_ZERO_INIT = "-initialize_to_zero";
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) throws IOException {
try {
doJob(args);
} catch (Throwable e) {
SystemOut.println(e);
e.printStackTrace();
SystemOut.close();
System.exit(-1);
}
SystemOut.close();
}
private static void doJob(String[] args) throws IOException {
if (args.length < 2) {
SystemOut.println("Please specify\r\n"
+ KEY_DEFINITION + " x\r\n"
+ KEY_TS_DESTINATION + " x\r\n"
+ KEY_C_DESTINATION + " x\r\n"
+ KEY_JAVA_DESTINATION + " x\r\n"
);
return;
}
SystemOut.println("Invoked with " + Arrays.toString(args));
String tsPath = null;
String destCHeaderFileName = null;
String destCDefinesFileName = null;
String destCFsioConstantsFileName = null;
String destCFsioGettersFileName = null;
String namesCFileName = null;
String stringsCFileName = null;
String javaDestinationFileName = null;
String romRaiderDestination = null;
List<String> prependFiles = new ArrayList<>();
String skipRebuildFile = null;
String romRaiderInputFile = null;
CHeaderConsumer.withC_Defines = true;
for (int i = 0; i < args.length - 1; i += 2) {
String key = args[i];
if (key.equals("-tool")) {
ConfigDefinition.TOOL = args[i + 1];
} else if (key.equals(KEY_DEFINITION)) {
definitionInputFile = args[i + 1];
} else if (key.equals(KEY_TS_DESTINATION)) {
tsPath = args[i + 1];
} else if (key.equals(KEY_C_DESTINATION)) {
destCHeaderFileName = args[i + 1];
} else if (key.equals(KEY_C_FSIO_GETTERS)) {
destCFsioGettersFileName = args[i + 1];
} else if (key.equals(KEY_C_FSIO_STRING)) {
stringsCFileName = args[i + 1];
} else if (key.equals(KEY_C_FSIO_NAMES)) {
namesCFileName = args[i + 1];
} else if (key.equals(KEY_C_FSIO_CONSTANTS)) {
destCFsioConstantsFileName = args[i + 1];
} else if (key.equals(KEY_ZERO_INIT)) {
needZeroInit = Boolean.parseBoolean(args[i + 1]);
} else if (key.equals(KEY_WITH_C_DEFINES)) {
CHeaderConsumer.withC_Defines = Boolean.parseBoolean(args[i + 1]);
} else if (key.equals(KEY_C_DEFINES)) {
destCDefinesFileName = args[i + 1];
} else if (key.equals(KEY_JAVA_DESTINATION)) {
javaDestinationFileName = args[i + 1];
} else if (key.equals(KEY_FIRING)) {
String firingEnumFileName = args[i + 1];
SystemOut.println("Reading firing from " + firingEnumFileName);
VariableRegistry.INSTANCE.register("FIRINGORDER", FiringOrderTSLogic.invoke(firingEnumFileName));
} else if (key.equals(KEY_ROMRAIDER_DESTINATION)) {
romRaiderDestination = args[i + 1];
} else if (key.equals(KEY_PREPEND)) {
prependFiles.add(args[i + 1]);
} else if (key.equals(KEY_SKIP)) {
skipRebuildFile = args[i + 1];
} else if (key.equals("-ts_output_name")) {
TSProjectConsumer.TS_FILE_OUTPUT_NAME = args[i + 1];
} else if (key.equals(KEY_ROM_INPUT)) {
romRaiderInputFile = args[i + 1];
}
}
MESSAGE = getGeneratedAutomaticallyTag() + definitionInputFile + " " + new Date();
SystemOut.println("Reading definition from " + definitionInputFile);
String currentMD5 = getDefinitionMD5(definitionInputFile);
if (skipRebuildFile != null) {
boolean nothingToDoHere = needToSkipRebuild(skipRebuildFile, currentMD5);
if (nothingToDoHere) {
SystemOut.println("Nothing to do here according to " + skipRebuildFile + " hash " + currentMD5);
return;
}
}
for (String prependFile : prependFiles)
readPrependValues(prependFile);
BufferedReader definitionReader = new BufferedReader(new InputStreamReader(new FileInputStream(definitionInputFile), IoUtils.CHARSET.name()));
ReaderState state = new ReaderState();
List<ConfigurationConsumer> destinations = new ArrayList<>();
if (destCHeaderFileName != null) {
destinations.add(new CHeaderConsumer(destCHeaderFileName));
}
if (tsPath != null) {
CharArrayWriter tsWriter = new CharArrayWriter();
destinations.add(new TSProjectConsumer(tsWriter, tsPath, state));
}
if (javaDestinationFileName != null) {
destinations.add(new FileJavaFieldsConsumer(state, javaDestinationFileName));
}
if (destCFsioConstantsFileName != null || destCFsioGettersFileName != null) {
destinations.add(new FileFsioSettingsConsumer(state,
destCFsioConstantsFileName,
destCFsioGettersFileName,
namesCFileName,
stringsCFileName));
}
if (destinations.isEmpty())
throw new IllegalArgumentException("No destinations specified");
state.readBufferedReader(definitionReader, destinations);
if (destCDefinesFileName != null)
VariableRegistry.INSTANCE.writeDefinesToFile(destCDefinesFileName);
if (romRaiderDestination != null && romRaiderInputFile != null) {
String inputFileName = romRaiderInputFile + File.separator + ROM_RAIDER_XML_TEMPLATE;
processTextTemplate(inputFileName, romRaiderDestination);
}
if (skipRebuildFile != null) {
SystemOut.println("Writing " + currentMD5 + " to " + skipRebuildFile);
PrintWriter writer = new PrintWriter(new FileWriter(skipRebuildFile));
writer.write(currentMD5);
writer.close();
}
}
private static boolean needToSkipRebuild(String skipRebuildFile, String currentMD5) throws IOException {
if (currentMD5 == null || !(new File(skipRebuildFile).exists()))
return false;
String finishedMD5 = new BufferedReader(new FileReader(skipRebuildFile)).readLine();
return finishedMD5 != null && finishedMD5.equals(currentMD5);
}
private static String getDefinitionMD5(String fullFileName) throws IOException {
File source = new File(fullFileName);
FileInputStream fileInputStream = new FileInputStream(fullFileName);
byte content[] = new byte[(int) source.length()];
if (fileInputStream.read(content) != content.length)
return "";
return getMd5(content);
}
private static void readPrependValues(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(line.substring(ReaderState.DEFINE.length()).trim());
}
}
}
private static void processTextTemplate(String inputFileName, String outputFileName) throws IOException {
SystemOut.println("Reading from " + inputFileName);
SystemOut.println("Writing to " + outputFileName);
VariableRegistry.INSTANCE.put("generator_message", ConfigDefinition.getGeneratedAutomaticallyTag() + new Date());
File inputFile = new File(inputFileName);
BufferedReader fr = new BufferedReader(new FileReader(inputFile));
LazyFile fw = new LazyFile(outputFileName);
String line;
while ((line = fr.readLine()) != null) {
line = VariableRegistry.INSTANCE.applyVariables(line);
fw.write(line + ConfigDefinition.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) {
return "\t/**" + EOL + packComment(comment, "\t") + "\t * offset " + currentOffset + EOL + "\t */" + EOL;
}
public static String packComment(String comment, String linePrefix) {
if (comment == null)
return "";
if (comment.trim().isEmpty())
return "";
String result = "";
for (String line : comment.split("\\\\n")) {
result += linePrefix + " * " + line + EOL;
}
return result;
}
public static int getSize(String s) {
if (VariableRegistry.INSTANCE.intValues.containsKey(s)) {
return VariableRegistry.INSTANCE.intValues.get(s);
}
return Integer.parseInt(s);
}
static 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 (VariableRegistry.isNumeric(line)) {
Integer v = Integer.valueOf(line);
VariableRegistry.INSTANCE.register(name, v);
} else {
VariableRegistry.INSTANCE.register(name, line);
}
}
private static String getMd5(byte[] content) {
try {
// Static getInstance method is called with hashing MD5
MessageDigest md = MessageDigest.getInstance("MD5");
// digest() method is called to calculate message digest
// of an input digest() return array of byte
byte[] messageDigest = md.digest(content);
// Convert byte array into signum representation
BigInteger no = new BigInteger(1, messageDigest);
// Convert message digest into hex value
String hashtext = no.toString(16);
while (hashtext.length() < 32) {
hashtext = "0" + hashtext;
}
return hashtext;
} catch (NoSuchAlgorithmException e) {
// For specifying wrong message digest algorithms
throw new RuntimeException(e);
}
}
}