package com.rusefi.tools.tune; import com.opensr5.ini.IniFileModel; import org.jetbrains.annotations.NotNull; import java.io.*; import java.util.Date; import java.util.function.Function; /** * tuner studio project to C data structure converter command line utility *

* 12/27/2014 * Andrey Belomutskiy, (c) 2012-2016 */ @SuppressWarnings("StringConcatenationInsideStringBufferAppend") public class TS2C { public static final Function fileFactory = new Function() { @Override public Reader apply(String fileName) { try { return new FileReader(fileName); } catch (FileNotFoundException e) { throw new RuntimeException(e); } } }; public static String FINGER_PRINT = "/* Generated by " + TS2C.class.getSimpleName() + " on " + new Date() + "*/\n"; /** * @see TS2CRunner */ /* public static void main(String[] args) throws IOException { new TS2C(args); } */ private TS2C(String[] args) throws IOException { System.out.println("This tool reads TS tune file and produces some C code for hardcoded base tunes"); if (args.length != 3 && args.length != 4 && args.length != 5) { System.out.println("Three parameters expected: "); System.out.println(" INPUT_MSQ_FILE NAME LOAD_SECTION_NAME RPM_SECTION_NAME [TABLE_NAME]"); System.out.println("for example"); // section names are needed in order to generate comments about cell content System.out.println(" currenttune.msq veLoadBins veRpmBins veTable"); System.exit(-1); } String msqFileName = args[0]; String loadSectionName = args[1]; String rpmSectionName = args[2]; String tableName = args.length == 3 ? "none" : args[3]; IniFileModel model = IniFileModel.getInstance(); String entityName = tableName.equalsIgnoreCase("none") ? loadSectionName : tableName; String methodName = getMethodName(entityName); BufferedWriter w = new BufferedWriter(new FileWriter("generated_" + methodName + ".cpp")); CurveData loadBins = null; CurveData rpmBins = null; if (!loadSectionName.equalsIgnoreCase("none")) { loadBins = CurveData.processCurve(msqFileName, loadSectionName, model, w); } if (!rpmSectionName.equalsIgnoreCase("none")) { rpmBins = CurveData.processCurve(msqFileName, rpmSectionName, model, w); } if (!tableName.equalsIgnoreCase("none")) { String sb = getTableCSourceCode2(msqFileName, tableName, model, rpmBins, loadBins); w.write(sb); } w.write(FINGER_PRINT); w.write("static void set" + methodName + "() {\n"); w.write("\tMEMCPY(config->" + loadSectionName + ", hardCoded" + loadSectionName + ");\n"); w.write("\tMEMCPY(config->" + rpmSectionName + ", hardCoded" + rpmSectionName + ");\n"); if (!tableName.equalsIgnoreCase("none")) { w.write("\tMEMCPY(config->" + tableName + ", hardCoded" + tableName + ");\n"); } w.write("}\n"); w.close(); } public static String getTableCSourceCode2(String msqFileName, String tableName, IniFileModel model) throws IOException { String xRpmBinsName = model.getXBin(tableName); String yLoadBinsName = model.getYBin(tableName); CurveData xRpmCurve = CurveData.valueOf(msqFileName, xRpmBinsName, model); CurveData yLoadCurve = CurveData.valueOf(msqFileName, yLoadBinsName, model); return getTableCSourceCode2(msqFileName, tableName, model, xRpmCurve, yLoadCurve); } @NotNull public static String getTableCSourceCode2(String msqFileName, String tableName, IniFileModel model, CurveData xRpmCurve, CurveData yLoadBins) throws IOException { TableData table = TableData.readTable(msqFileName, tableName, model); return getTableCSourceCode(tableName, yLoadBins, xRpmCurve, table.floats); } private static String getTableCSourceCode(String tableName, CurveData loadBins, CurveData rpmBins, float[][] table) { StringBuilder sb = new StringBuilder(); sb.append("static const float hardCoded" + tableName + "[" + table.length + "][" + table[0].length + "] = {\n"); writeTable(loadBins, rpmBins, sb, (loadIndex, rpmIndex) -> table[loadIndex][rpmIndex]); sb.append("};\n\n"); return sb.toString(); } @NotNull private static String getMethodName(String methodName) { return methodName.toUpperCase().charAt(0) + methodName.substring(1); } private static void writeTable(CurveData loadBins, CurveData rpmBins, StringBuilder sb, ValueSource valueSource) { sb.append(FINGER_PRINT); for (int loadIndex = 0; loadIndex < loadBins.getRawData().length; loadIndex++) { String line = writeTableLine(loadBins, rpmBins, valueSource, loadIndex); sb.append(line); } } public static void writePlainTable(int rows, int columns, StringBuilder sb, ValueSource valueSource) { for (int row = 0; row < rows; row++) { String line = writePlainTableLine(valueSource, row, columns); sb.append(line); } } /** * @param fileName text file to open * @param magicStringKey magic string content to scroll to * @param factory * @return Reader after the magicStringKey line */ static BufferedReader readAndScroll(String fileName, String magicStringKey, Function factory) throws IOException { Reader reader = factory.apply(fileName); BufferedReader br = new BufferedReader(reader); System.out.println("Reading from " + new File(fileName).getAbsolutePath() + ", scrolling to " + magicStringKey); String line; while ((line = br.readLine()) != null) { if (line.contains(magicStringKey)) { // System.out.println("Found " + line); break; } } return br; } private static String writePlainTableLine(ValueSource valueSource, int loadIndex, int loadSize) { StringBuilder sb = new StringBuilder("{"); for (int rpmIndex = 0; rpmIndex < loadSize; rpmIndex++) { sb.append(String.format("%3.3f", valueSource.getValue(loadIndex, rpmIndex)) + ",\t"); } sb.append("},\n"); return sb.toString(); } private static String writeTableLine(CurveData loadBins, CurveData rpmBins, ValueSource valueSource, int loadIndex) { StringBuilder sb = new StringBuilder("{"); sb.append("/* " + loadIndex + " " + String.format("%3.3f", loadBins.getRawData()[loadIndex]) + "\t*/"); for (int rpmIndex = 0; rpmIndex < rpmBins.getRawData().length; rpmIndex++) { sb.append("/* " + rpmIndex + " " + rpmBins.getRawData()[rpmIndex] + "*/" + String.format("%3.3f", valueSource.getValue(loadIndex, rpmIndex)) + ",\t"); } sb.append("},\n"); return sb.toString(); } @NotNull public static String getCopyMethodBody(String tableReference, IniFileModel model, String tableName) { String xRpmBinsName = model.getXBin(tableName); String yLoadBinsName = model.getYBin(tableName); String x = "\tcopyArray(" + tableReference + "LoadBins, hardCoded" + xRpmBinsName + ");\n" + "\tcopyArray(" + tableReference + "RpmBins, hardCoded" + yLoadBinsName + ");\n" + "\tcopyTable(" + tableReference + "Table, hardCoded" + tableName + ");\n"; return x; } public interface ValueSource { float getValue(int rowIndex, int columnIndex); } }