Write output channels with new parser (#4219)
* let the new parser run * s * support for output channels * usages reader uses new parser for output channels * better debugging configuration * bad merge * test it a bit too * more tests * copy/paste the same content from other file * s * fix bugs where even the existing logic tries to write as an enum (?) * jar * print stream always unix * print stream always unix * use typedefs correctly * jar * stub support for multiple of each type * s * s * name some more datas
This commit is contained in:
parent
b43677919f
commit
7e8ae7c8a3
|
@ -56,8 +56,12 @@ const ac_control_s* getLiveDataAddr() {
|
|||
}
|
||||
|
||||
template<>
|
||||
const fan_control_s* getLiveDataAddr() {
|
||||
return &engine->fan1;
|
||||
const fan_control_s* getLiveDataAddr(size_t idx) {
|
||||
switch (idx) {
|
||||
case 0: return &engine->fan1;
|
||||
case 1: return &engine->fan2;
|
||||
default: return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
|
@ -117,8 +121,7 @@ const ignition_state_s* getLiveDataAddr() {
|
|||
}
|
||||
|
||||
template<>
|
||||
const electronic_throttle_s* getLiveDataAddr() {
|
||||
// todo: figure out how to handle two units?
|
||||
const electronic_throttle_s* getLiveDataAddr(size_t) {
|
||||
// return engine->etbControllers[0];
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
struct_no_prefix idle_state_s
|
||||
custom idle_state_e 4 bits, S32, @OFFSET@, [0:2], "not important"
|
||||
idle_state_e idleState
|
||||
custom percent_t 4 bits, F32, @OFFSET@, [0:2], "not important"
|
||||
|
||||
custom percent_t 4 scalar, F32, @OFFSET@, "", 1, 0, 0, 100, 2
|
||||
|
||||
percent_t currentIdlePosition;that's current position with CLT and IAT corrections
|
||||
percent_t baseIdlePosition;current position without adjustments (iacByTpsTaper, afterCrankingIACtaperDuration)
|
||||
percent_t iacByTpsTaper;iacByTpsTaper portion of idle
|
||||
|
|
|
@ -72,10 +72,10 @@ end_struct
|
|||
! actually define a member of 'running_fuel_s' type
|
||||
running_fuel_s running
|
||||
|
||||
custom percent_t 4 bits, F32, @OFFSET@, [0:2], "not important"
|
||||
|
||||
percent_t etbFeedForward;
|
||||
custom percent_t 4 scalar, F32, @OFFSET@, "", 1, 0, 0, 100, 2
|
||||
|
||||
! todo: move these to ETB state, not engine
|
||||
percent_t etbFeedForward
|
||||
percent_t targetFromTable
|
||||
|
||||
! spark-related
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
struct_no_prefix tps_accel_state_s
|
||||
|
||||
custom percent_t 4 bits, F32, @OFFSET@, [0:2], "not important"
|
||||
custom percent_t 4 scalar, F32, @OFFSET@, "", 1, 0, 0, 100, 2
|
||||
|
||||
percent_t tpsFrom;
|
||||
percent_t tpsTo;
|
||||
percent_t deltaTps;
|
||||
percent_t tpsFrom
|
||||
percent_t tpsTo
|
||||
percent_t deltaTps
|
||||
|
||||
floatms_t extraFuel;
|
||||
float valueFromTable;
|
||||
|
|
|
@ -21,10 +21,12 @@ Usages:
|
|||
- name: knock_controller
|
||||
java: KnockController.java
|
||||
folder: controllers/engine_cycle
|
||||
output_name: knock
|
||||
|
||||
- name: high_pressure_fuel_pump
|
||||
java: HighPressureFuelPump.java
|
||||
folder: controllers/engine_cycle
|
||||
output_name: hpfp
|
||||
|
||||
- name: injector_model
|
||||
java: InjectorModel.java
|
||||
|
@ -37,23 +39,28 @@ Usages:
|
|||
- name: boost_control
|
||||
java: BoostControl.java
|
||||
folder: controllers/actuators
|
||||
output_name: boost
|
||||
|
||||
- name: ac_control
|
||||
java: AcControl.java
|
||||
folder: controllers/actuators
|
||||
prepend: integration/rusefi_config.txt
|
||||
output_name: ac
|
||||
|
||||
- name: fan_control
|
||||
java: FanControl.java
|
||||
folder: controllers/actuators
|
||||
output_name: [ "fan1", "fan2" ]
|
||||
|
||||
- name: fuel_pump_control
|
||||
java: FuelPump.java
|
||||
folder: controllers/actuators
|
||||
output_name: fuelPump
|
||||
|
||||
- name: main_relay
|
||||
java: MainRelay.java
|
||||
folder: controllers/actuators
|
||||
output_name: mainRelay
|
||||
|
||||
#todo: handle ETB pid and Idle pid which point at same pid_state.txt
|
||||
# - name: pid_state
|
||||
|
@ -95,3 +102,4 @@ Usages:
|
|||
- name: electronic_throttle
|
||||
java: ElectronicThrottle.java
|
||||
folder: controllers/actuators
|
||||
output_name: [ "etb1", "etb2" ]
|
||||
|
|
Binary file not shown.
|
@ -3,6 +3,10 @@ package com.rusefi.ldmp;
|
|||
import com.devexperts.logging.Logging;
|
||||
import com.rusefi.ConfigDefinition;
|
||||
import com.rusefi.ReaderState;
|
||||
import com.rusefi.RusefiParseErrorStrategy;
|
||||
import com.rusefi.newparse.ParseState;
|
||||
import com.rusefi.newparse.outputs.OutputChannelWriter;
|
||||
import com.rusefi.newparse.parsing.Definition;
|
||||
import com.rusefi.output.*;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
|
@ -74,7 +78,7 @@ public class UsagesReader {
|
|||
JavaSensorsConsumer javaSensorsConsumer = new JavaSensorsConsumer();
|
||||
String tsOutputsDestination = "console/binary/";
|
||||
|
||||
ConfigurationConsumer outputsSections = new OutputsSectionConsumer(tsOutputsDestination + File.separator + "generated/output_channels.ini");
|
||||
OutputChannelWriter outputChannelWriter = new OutputChannelWriter(tsOutputsDestination + File.separator + "generated/output_channels.ini");
|
||||
|
||||
ConfigurationConsumer dataLogConsumer = new DataLogConsumer(tsOutputsDestination + File.separator + "generated/data_logs.ini");
|
||||
|
||||
|
@ -87,11 +91,11 @@ public class UsagesReader {
|
|||
log.info("Starting " + name + " at " + startingPosition);
|
||||
|
||||
ReaderState state = new ReaderState();
|
||||
state.setDefinitionInputFile(folder + File.separator + name + ".txt");
|
||||
String definitionInputFile = folder + File.separator + name + ".txt";
|
||||
state.setDefinitionInputFile(definitionInputFile);
|
||||
state.withC_Defines = withCDefines;
|
||||
|
||||
state.addDestination(javaSensorsConsumer,
|
||||
outputsSections,
|
||||
dataLogConsumer
|
||||
);
|
||||
FragmentDialogConsumer fragmentDialogConsumer = new FragmentDialogConsumer(name);
|
||||
|
@ -102,6 +106,26 @@ public class UsagesReader {
|
|||
state.addJavaDestination("../java_console/models/src/main/java/com/rusefi/config/generated/" + javaName);
|
||||
state.doJob();
|
||||
|
||||
{
|
||||
ParseState parseState = new ParseState(state.enumsReader);
|
||||
|
||||
parseState.setDefinitionPolicy(Definition.OverwritePolicy.NotAllowed);
|
||||
|
||||
if (prepend != null && !prepend.isEmpty()) {
|
||||
RusefiParseErrorStrategy.parseDefinitionFile(parseState.getListener(), prepend);
|
||||
}
|
||||
|
||||
RusefiParseErrorStrategy.parseDefinitionFile(parseState.getListener(), definitionInputFile);
|
||||
|
||||
// if (outputNames.length == 0) {
|
||||
outputChannelWriter.writeOutputChannels(parseState, null);
|
||||
// } else {
|
||||
// for (int i = 0; i < outputNames.length; i++) {
|
||||
// outputChannelWriter.writeOutputChannels(parseState, outputNames[i]);
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
fancyNewStuff.append(fragmentDialogConsumer.getContent());
|
||||
|
||||
fancyNewMenu.append(fragmentDialogConsumer.menuLine());
|
||||
|
|
|
@ -73,4 +73,9 @@ public class ArrayLayout extends Layout {
|
|||
this.prototypeLayout.writeCLayout(ps, this.length);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeOutputChannelLayout(PrintStream ps, StructNamePrefixer prefixer, int offsetAdd) {
|
||||
this.prototypeLayout.writeOutputChannelLayout(ps, prefixer, offsetAdd, this.length);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,4 +89,22 @@ public class BitGroupLayout extends Layout {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeOutputChannelLayout(PrintStream ps, StructNamePrefixer prefixer, int offsetAdd) {
|
||||
int actualOffset = this.offset + offsetAdd;
|
||||
|
||||
for (int i = 0; i < bits.size(); i++) {
|
||||
BitLayout bit = bits.get(i);
|
||||
|
||||
ps.print(prefixer.get(bit.name));
|
||||
ps.print(" = bits, U32, ");
|
||||
ps.print(actualOffset);
|
||||
ps.print(", [");
|
||||
ps.print(i + ":" + i);
|
||||
|
||||
ps.print("]");
|
||||
|
||||
ps.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,4 +72,15 @@ public class EnumLayout extends Layout {
|
|||
this.writeCOffsetHeader(ps, this.options.comment, this.options.units);
|
||||
ps.println("\t" + this.enumType + " " + this.name + "[" + arrayLength[0] + "];");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeOutputChannelLayout(PrintStream ps, StructNamePrefixer prefixer, int offsetAdd) {
|
||||
// Output an enum as a scalar, since there's no TS support for enum output channels
|
||||
ps.print(prefixer.get(name));
|
||||
ps.print(" = scalar, ");
|
||||
ps.print(this.type.tsType);
|
||||
ps.print(", ");
|
||||
ps.print(this.offset + offsetAdd);
|
||||
ps.println(", \"\", 1, 0");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,4 +67,20 @@ public abstract class Layout {
|
|||
public void writeCLayout(PrintStream ps, int[] arrayLength) {
|
||||
throw new IllegalStateException("This type can't be in an array!");
|
||||
}
|
||||
|
||||
public void writeOutputChannelLayout(PrintStream ps, String prefix, int offsetAdd) {
|
||||
StructNamePrefixer prefixer = new StructNamePrefixer();
|
||||
|
||||
if (prefix != null) {
|
||||
prefixer.push(prefix);
|
||||
}
|
||||
|
||||
writeOutputChannelLayout(ps, prefixer, offsetAdd);
|
||||
}
|
||||
|
||||
protected void writeOutputChannelLayout(PrintStream ps, StructNamePrefixer prefixer, int offsetAdd) { }
|
||||
|
||||
protected void writeOutputChannelLayout(PrintStream ps, StructNamePrefixer prefixer, int offsetAdd, int[] arrayLength) {
|
||||
throw new IllegalStateException("This type can't be in an array!");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,4 +147,40 @@ public class ScalarLayout extends Layout {
|
|||
|
||||
ps.println("\t" + cTypeName + " " + this.name + "[" + al + "];");
|
||||
}
|
||||
|
||||
private void writeOutputChannelLayout(PrintStream ps, StructNamePrefixer prefixer, int offsetAdd, String name) {
|
||||
ps.print(prefixer.get(name));
|
||||
//ps.print(" = " + fieldType + ", ");
|
||||
ps.print(" = scalar, ");
|
||||
ps.print(this.type.tsType);
|
||||
ps.print(", ");
|
||||
ps.print(this.offset + offsetAdd);
|
||||
ps.print(", ");
|
||||
ps.print(this.options.units);
|
||||
ps.print(", ");
|
||||
ps.print(FieldOptions.tryRound(this.options.scale));
|
||||
ps.print(", ");
|
||||
ps.print(FieldOptions.tryRound(this.options.offset));
|
||||
|
||||
ps.println();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeOutputChannelLayout(PrintStream ps, StructNamePrefixer prefixer, int offsetAdd) {
|
||||
writeOutputChannelLayout(ps, prefixer, offsetAdd, this.name);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeOutputChannelLayout(PrintStream ps, StructNamePrefixer prefixer, int offsetAdd, int[] arrayLength) {
|
||||
if (arrayLength.length != 1) {
|
||||
throw new IllegalStateException("Output channels don't support multi dimension arrays");
|
||||
}
|
||||
|
||||
int elementOffset = offsetAdd;
|
||||
|
||||
for (int i = 0; i < arrayLength[0]; i++) {
|
||||
writeOutputChannelLayout(ps, prefixer, elementOffset, this.name + (i + 1));
|
||||
elementOffset += type.size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -192,8 +192,22 @@ public class StructLayout extends Layout {
|
|||
|
||||
this.children.forEach(c -> c.writeCLayout(ps));
|
||||
|
||||
ps.println("\t/** total size " + getSize() + "*/");
|
||||
ps.println("};");
|
||||
ps.println("static_assert(sizeof(" + this.typeName + ") == " + getSize() + ");");
|
||||
|
||||
ps.println();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void writeOutputChannelLayout(PrintStream ps, StructNamePrefixer prefixer, int offsetAdd) {
|
||||
if (!this.noPrefix) {
|
||||
prefixer.push(this.name);
|
||||
}
|
||||
|
||||
this.children.forEach(c -> c.writeOutputChannelLayout(ps, prefixer, offsetAdd));
|
||||
|
||||
if (!this.noPrefix) {
|
||||
prefixer.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,12 +8,9 @@ import java.io.FileNotFoundException;
|
|||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
/**
|
||||
* proposed alternative which does not seem to be covered by any unit tests
|
||||
*/
|
||||
public class CStructWriter {
|
||||
public void writeCStructs(ParseState parser, String outputFile) throws FileNotFoundException {
|
||||
writeCStructs(parser, new PrintStream(new FileOutputStream(outputFile)));
|
||||
writeCStructs(parser, new PrintStreamAlwaysUnix(new FileOutputStream(outputFile)));
|
||||
}
|
||||
|
||||
public void writeCStructs(ParseState parser, PrintStream ps) {
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
package com.rusefi.newparse.outputs;
|
||||
|
||||
import com.rusefi.newparse.ParseState;
|
||||
import com.rusefi.newparse.layout.StructLayout;
|
||||
import com.rusefi.newparse.parsing.Struct;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
public class OutputChannelWriter {
|
||||
private final PrintStream ps;
|
||||
|
||||
public OutputChannelWriter(String outputFile) throws FileNotFoundException {
|
||||
this.ps = new PrintStreamAlwaysUnix(new FileOutputStream(outputFile));
|
||||
}
|
||||
|
||||
public OutputChannelWriter(PrintStream ps) {
|
||||
this.ps = ps;
|
||||
}
|
||||
|
||||
private int cumulativeSize = 0;
|
||||
|
||||
public void writeOutputChannels(ParseState parser, String namePrefix) throws FileNotFoundException {
|
||||
// Assume the last struct is the one we want...
|
||||
Struct s = parser.getStructs().get(parser.getStructs().size() - 1);
|
||||
|
||||
StructLayout sl = new StructLayout(0, "root", s);
|
||||
sl.writeOutputChannelLayout(ps, namePrefix, cumulativeSize);
|
||||
|
||||
cumulativeSize += sl.getSize();
|
||||
ps.println("; total TS size = " + cumulativeSize);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.rusefi.newparse.outputs;
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
|
||||
public class PrintStreamAlwaysUnix extends PrintStream {
|
||||
public PrintStreamAlwaysUnix(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
public PrintStreamAlwaysUnix(OutputStream out, boolean autoFlush, String encoding) throws UnsupportedEncodingException {
|
||||
super(out, autoFlush, encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println() {
|
||||
print('\n');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println(String s) {
|
||||
print(s);
|
||||
println();
|
||||
}
|
||||
}
|
|
@ -8,9 +8,6 @@ import java.io.*;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* proposed alternative which does not seem to be covered by any unit tests
|
||||
*/
|
||||
public class TsWriter {
|
||||
// matches strings in the form of @@MY_var_123@@
|
||||
private static final Pattern VAR = Pattern.compile("@@([a-zA-Z0-9_]+?)@@");
|
||||
|
@ -18,7 +15,7 @@ public class TsWriter {
|
|||
private static final Pattern OPTIONAL_LINE = Pattern.compile("@@if_([a-zA-Z0-9_]+)");
|
||||
|
||||
public void writeTunerstudio(ParseState parser, String inputFile, String outputFile) throws IOException {
|
||||
PrintStream ps = new PrintStream(new FileOutputStream(outputFile));
|
||||
PrintStream ps = new PrintStreamAlwaysUnix(new FileOutputStream(outputFile));
|
||||
writeTunerstudio(parser, inputFile, ps);
|
||||
ps.close();
|
||||
}
|
||||
|
|
|
@ -5,14 +5,16 @@ import org.junit.Test;
|
|||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.rusefi.test.newParse.NewParseHelper.parseToOutputChannels;
|
||||
import static com.rusefi.test.newParse.NewParseHelper.parseToTs;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class LayoutTest {
|
||||
@Test
|
||||
public void singleField() throws IOException {
|
||||
String ts = parseToTs("struct_no_prefix myStruct\n" +
|
||||
String input = "struct_no_prefix myStruct\n" +
|
||||
"int8_t xyz;comment;\"units\", 1, 2, 3, 4, 5\n" +
|
||||
"end_struct");
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 4\n" +
|
||||
|
@ -21,15 +23,20 @@ public class LayoutTest {
|
|||
"; unused 3 bytes at offset 1\n" +
|
||||
"; total TS size = 4\n" +
|
||||
"[SettingContextHelp]\n" +
|
||||
"\txyz = \"comment\"\n", ts);
|
||||
"\txyz = \"comment\"\n", parseToTs(input));
|
||||
|
||||
Assert.assertEquals(
|
||||
"xyz = scalar, S08, 0, \"units\", 1, 2\n" +
|
||||
"; total TS size = 4\n"
|
||||
, parseToOutputChannels(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoFieldsSameSize() throws IOException {
|
||||
String ts = parseToTs("struct_no_prefix myStruct\n" +
|
||||
String input = "struct_no_prefix myStruct\n" +
|
||||
"int32_t abc;;\"\", 1, 2, 3, 4, 5\n" +
|
||||
"int32_t xyz;;\"\", 6, 7, 8, 9, 10\n" +
|
||||
"end_struct");
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 8\n" +
|
||||
|
@ -37,15 +44,20 @@ public class LayoutTest {
|
|||
"abc = scalar, S32, 0, \"\", 1, 2, 3, 4, 5\n" +
|
||||
"xyz = scalar, S32, 4, \"\", 6, 7, 8, 9, 10\n" +
|
||||
"; total TS size = 8\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
"[SettingContextHelp]\n", parseToTs(input));
|
||||
|
||||
Assert.assertEquals(
|
||||
"abc = scalar, S32, 0, \"\", 1, 2\n" +
|
||||
"xyz = scalar, S32, 4, \"\", 6, 7\n" +
|
||||
"; total TS size = 8\n", parseToOutputChannels(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoFieldsBigThenSmall() throws IOException {
|
||||
String ts = parseToTs("struct_no_prefix myStruct\n" +
|
||||
String input = "struct_no_prefix myStruct\n" +
|
||||
"int32_t abc;;\"\", 1, 2, 3, 4, 5\n" +
|
||||
"int8_t xyz;;\"\", 6, 7, 8, 9, 10\n" +
|
||||
"end_struct");
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 8\n" +
|
||||
|
@ -54,15 +66,20 @@ public class LayoutTest {
|
|||
"xyz = scalar, S08, 4, \"\", 6, 7, 8, 9, 10\n" +
|
||||
"; unused 3 bytes at offset 5\n" +
|
||||
"; total TS size = 8\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
"[SettingContextHelp]\n", parseToTs(input));
|
||||
|
||||
Assert.assertEquals(
|
||||
"abc = scalar, S32, 0, \"\", 1, 2\n" +
|
||||
"xyz = scalar, S08, 4, \"\", 6, 7\n" +
|
||||
"; total TS size = 8\n", parseToOutputChannels(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoFieldsSmallThenBig() throws IOException {
|
||||
String ts = parseToTs("struct_no_prefix myStruct\n" +
|
||||
String input = "struct_no_prefix myStruct\n" +
|
||||
"int8_t abc;;\"\", 1, 2, 3, 4, 5\n" +
|
||||
"int32_t xyz;;\"\", 6, 7, 8, 9, 10\n" +
|
||||
"end_struct");
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 8\n" +
|
||||
|
@ -71,16 +88,21 @@ public class LayoutTest {
|
|||
"; unused 3 bytes at offset 1\n" +
|
||||
"xyz = scalar, S32, 4, \"\", 6, 7, 8, 9, 10\n" +
|
||||
"; total TS size = 8\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
"[SettingContextHelp]\n", parseToTs(input));
|
||||
|
||||
Assert.assertEquals(
|
||||
"abc = scalar, S08, 0, \"\", 1, 2\n" +
|
||||
"xyz = scalar, S32, 4, \"\", 6, 7\n" +
|
||||
"; total TS size = 8\n", parseToOutputChannels(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void threeFieldsSmallInMisalignment() throws IOException {
|
||||
String ts = parseToTs("struct_no_prefix myStruct\n" +
|
||||
String input = "struct_no_prefix myStruct\n" +
|
||||
"int16_t abc\n" +
|
||||
"int8_t def\n" +
|
||||
"int32_t xyz\n" +
|
||||
"end_struct");
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 8\n" +
|
||||
|
@ -90,15 +112,21 @@ public class LayoutTest {
|
|||
"; unused 1 bytes at offset 3\n" +
|
||||
"xyz = scalar, S32, 4, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; total TS size = 8\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
"[SettingContextHelp]\n", parseToTs(input));
|
||||
|
||||
Assert.assertEquals(
|
||||
"abc = scalar, S16, 0, \"\", 1, 0\n" +
|
||||
"def = scalar, S08, 2, \"\", 1, 0\n" +
|
||||
"xyz = scalar, S32, 4, \"\", 1, 0\n" +
|
||||
"; total TS size = 8\n", parseToOutputChannels(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoFieldsArrayThenBig() throws IOException {
|
||||
String ts = parseToTs("struct_no_prefix myStruct\n" +
|
||||
String input = "struct_no_prefix myStruct\n" +
|
||||
"int8_t[10] abc;;\"\", 1, 2, 3, 4, 5\n" +
|
||||
"int32_t xyz;;\"\", 6, 7, 8, 9, 10\n" +
|
||||
"end_struct");
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 16\n" +
|
||||
|
@ -107,7 +135,21 @@ public class LayoutTest {
|
|||
"; unused 2 bytes at offset 10\n" +
|
||||
"xyz = scalar, S32, 12, \"\", 6, 7, 8, 9, 10\n" +
|
||||
"; total TS size = 16\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
"[SettingContextHelp]\n", parseToTs(input));
|
||||
|
||||
Assert.assertEquals(
|
||||
"abc1 = scalar, S08, 0, \"\", 1, 2\n" +
|
||||
"abc2 = scalar, S08, 1, \"\", 1, 2\n" +
|
||||
"abc3 = scalar, S08, 2, \"\", 1, 2\n" +
|
||||
"abc4 = scalar, S08, 3, \"\", 1, 2\n" +
|
||||
"abc5 = scalar, S08, 4, \"\", 1, 2\n" +
|
||||
"abc6 = scalar, S08, 5, \"\", 1, 2\n" +
|
||||
"abc7 = scalar, S08, 6, \"\", 1, 2\n" +
|
||||
"abc8 = scalar, S08, 7, \"\", 1, 2\n" +
|
||||
"abc9 = scalar, S08, 8, \"\", 1, 2\n" +
|
||||
"abc10 = scalar, S08, 9, \"\", 1, 2\n" +
|
||||
"xyz = scalar, S32, 12, \"\", 6, 7\n" +
|
||||
"; total TS size = 16\n", parseToOutputChannels(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -152,10 +194,9 @@ public class LayoutTest {
|
|||
|
||||
@Test
|
||||
public void arrayIterate() throws IOException {
|
||||
String ts = parseToTs(
|
||||
"struct_no_prefix rootStruct\n" +
|
||||
String input = "struct_no_prefix rootStruct\n" +
|
||||
"int32_t[4 iterate] myArr\n" +
|
||||
"end_struct");
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 16\n" +
|
||||
|
@ -165,7 +206,14 @@ public class LayoutTest {
|
|||
"myArr3 = scalar, S32, 8, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"myArr4 = scalar, S32, 12, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; total TS size = 16\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
"[SettingContextHelp]\n", parseToTs(input));
|
||||
|
||||
Assert.assertEquals(
|
||||
"myArr1 = scalar, S32, 0, \"\", 1, 0\n" +
|
||||
"myArr2 = scalar, S32, 4, \"\", 1, 0\n" +
|
||||
"myArr3 = scalar, S32, 8, \"\", 1, 0\n" +
|
||||
"myArr4 = scalar, S32, 12, \"\", 1, 0\n" +
|
||||
"; total TS size = 16\n", parseToOutputChannels(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -214,11 +262,11 @@ public class LayoutTest {
|
|||
|
||||
@Test
|
||||
public void bits() throws IOException {
|
||||
String ts = parseToTs("struct_no_prefix myStruct\n" +
|
||||
String input = "struct_no_prefix myStruct\n" +
|
||||
"bit first\n" +
|
||||
"bit second\n" +
|
||||
"bit withOpt,\"a\",\"b\"\n" +
|
||||
"end_struct");
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 4\n" +
|
||||
|
@ -227,6 +275,33 @@ public class LayoutTest {
|
|||
"second = bits, U32, 0, [1:1], \"false\", \"true\"\n" +
|
||||
"withOpt = bits, U32, 0, [2:2], \"b\", \"a\"\n" +
|
||||
"; total TS size = 4\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
"[SettingContextHelp]\n", parseToTs(input));
|
||||
|
||||
Assert.assertEquals(
|
||||
"first = bits, U32, 0, [0:0]\n" +
|
||||
"second = bits, U32, 0, [1:1]\n" +
|
||||
"withOpt = bits, U32, 0, [2:2]\n" +
|
||||
"; total TS size = 4\n"
|
||||
, parseToOutputChannels(input));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bigOutputChannels() throws IOException {
|
||||
String input = "struct_no_prefix total\n" +
|
||||
"float afr_type;PID dTime;\"ms\", 1, 0, 0, 3000, 0\n" +
|
||||
"uint8_t afr_typet;@@GAUGE_NAME_FUEL_WALL_CORRECTION@@;\"ms\", 1, 0, 0, 3000, 0\n" +
|
||||
"bit isForcedInduction;isForcedInduction\\nDoes the vehicle have a turbo or supercharger?\n" +
|
||||
"bit enableFan1WithAc;+Turn on this fan when AC is on.\n" +
|
||||
"angle_t m_requested_pump;Computed requested pump \n" +
|
||||
"float tCharge;speed density\n" +
|
||||
"end_struct\n";
|
||||
|
||||
assertEquals("afr_type = scalar, F32, 0, \"ms\", 1, 0\n" +
|
||||
"afr_typet = scalar, U08, 4, \"ms\", 1, 0\n" +
|
||||
"isForcedInduction = bits, U32, 8, [0:0]\n" +
|
||||
"enableFan1WithAc = bits, U32, 8, [1:1]\n" +
|
||||
"m_requested_pump = scalar, F32, 12, \"\", 1, 0\n" +
|
||||
"tCharge = scalar, F32, 16, \"\", 1, 0\n" +
|
||||
"; total TS size = 20\n", parseToOutputChannels(input));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,8 @@ package com.rusefi.test.newParse;
|
|||
import com.rusefi.RusefiParseErrorStrategy;
|
||||
import com.rusefi.newparse.ParseState;
|
||||
import com.rusefi.newparse.outputs.CStructWriter;
|
||||
import com.rusefi.newparse.outputs.OutputChannelWriter;
|
||||
import com.rusefi.newparse.outputs.PrintStreamAlwaysUnix;
|
||||
import com.rusefi.newparse.outputs.TsWriter;
|
||||
|
||||
import java.io.*;
|
||||
|
@ -15,23 +17,6 @@ public class NewParseHelper {
|
|||
return parseState;
|
||||
}
|
||||
|
||||
private static class PrintStreamAlwaysUnix extends PrintStream {
|
||||
public PrintStreamAlwaysUnix(OutputStream out, boolean autoFlush, String encoding) throws UnsupportedEncodingException {
|
||||
super(out, autoFlush, encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println() {
|
||||
print('\n');
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println(String s) {
|
||||
print(s);
|
||||
println();
|
||||
}
|
||||
}
|
||||
|
||||
public static String parseToTs(String input) throws IOException {
|
||||
ParseState state = parse(input);
|
||||
|
||||
|
@ -47,6 +32,20 @@ public class NewParseHelper {
|
|||
return baos.toString(utf8);
|
||||
}
|
||||
|
||||
public static String parseToOutputChannels(String input) throws IOException {
|
||||
ParseState state = parse(input);
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
final String utf8 = StandardCharsets.UTF_8.name();
|
||||
|
||||
PrintStream ps = new PrintStreamAlwaysUnix(baos, true, utf8);
|
||||
|
||||
OutputChannelWriter writer = new OutputChannelWriter(ps);
|
||||
writer.writeOutputChannels(state, null);
|
||||
|
||||
return baos.toString(utf8);
|
||||
}
|
||||
|
||||
public static String parseToC(String input) throws IOException {
|
||||
ParseState state = parse(input);
|
||||
|
||||
|
|
Loading…
Reference in New Issue