We have to move either forward or backwards with newparse #4441
This commit is contained in:
parent
e6ca0a42ba
commit
752a10ee05
Binary file not shown.
|
@ -452,78 +452,6 @@ public class ParseState implements DefinitionsState {
|
|||
|
||||
@Override
|
||||
public void exitArrayField(RusefiConfigGrammarParser.ArrayFieldContext ctx) {
|
||||
String type = ctx.identifier(0).getText();
|
||||
String name = ctx.identifier(1).getText();
|
||||
int[] length = this.arrayDim;
|
||||
// check if the iterate token is present
|
||||
boolean iterate = ctx.Iterate() != null;
|
||||
boolean autoscale = ctx.Autoscale() != null;
|
||||
|
||||
if (iterate && length.length != 1) {
|
||||
throw new IllegalStateException("Cannot iterate multi dimensional array: " + name);
|
||||
}
|
||||
|
||||
// First check if this is an array of structs
|
||||
if (structs.containsKey(type)) {
|
||||
// iterate required for structs
|
||||
assert(iterate);
|
||||
|
||||
scope.structFields.add(new ArrayField<>(new StructField(structs.get(type), name), length, iterate));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check first if we have a typedef for this type
|
||||
Typedef typedef = typedefs.get(type);
|
||||
|
||||
FieldOptions options;
|
||||
if (typedef != null) {
|
||||
if (typedef instanceof ScalarTypedef) {
|
||||
ScalarTypedef scTypedef = (ScalarTypedef) typedef;
|
||||
// Copy the typedef's options list - we don't want to edit it
|
||||
options = scTypedef.options.copy();
|
||||
// Switch to the "real" type, that is the typedef's type
|
||||
type = scTypedef.type.cType;
|
||||
} else if (typedef instanceof EnumTypedef) {
|
||||
EnumTypedef bTypedef = (EnumTypedef) typedef;
|
||||
|
||||
options = new FieldOptions();
|
||||
handleFieldOptionsList(options, ctx.fieldOptionsList());
|
||||
|
||||
EnumField prototype = new EnumField(bTypedef.type, type, name, bTypedef.endBit, bTypedef.values, options);
|
||||
|
||||
scope.structFields.add(new ArrayField<>(prototype, length, iterate));
|
||||
return;
|
||||
} else if (typedef instanceof StringTypedef) {
|
||||
StringTypedef sTypedef = (StringTypedef) typedef;
|
||||
|
||||
// iterate required for strings
|
||||
assert(iterate);
|
||||
|
||||
options = new FieldOptions();
|
||||
handleFieldOptionsList(options, ctx.fieldOptionsList());
|
||||
|
||||
StringField prototype = new StringField(name, sTypedef.size, options.comment);
|
||||
scope.structFields.add(new ArrayField<>(prototype, length, iterate));
|
||||
return;
|
||||
} else {
|
||||
throw new RuntimeException("didn't understand type " + type + " for element " + name);
|
||||
}
|
||||
} else {
|
||||
// If no typedef found, it MUST be a native type
|
||||
if (!Type.findByCtype(type).isPresent()) {
|
||||
throw new RuntimeException("didn't understand type " + type + " for element " + name);
|
||||
}
|
||||
|
||||
// no typedef found, create new options list
|
||||
options = new FieldOptions();
|
||||
}
|
||||
|
||||
// Merge the read-in options list with the default from the typedef (if exists)
|
||||
handleFieldOptionsList(options, ctx.fieldOptionsList());
|
||||
|
||||
ScalarField prototype = new ScalarField(Type.findByCtype(type).get(), name, options, autoscale);
|
||||
|
||||
scope.structFields.add(new ArrayField<>(prototype, length, iterate));
|
||||
}
|
||||
|
||||
private int[] arrayDim = null;
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
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 CStructWriter {
|
||||
public void writeCStructs(ParseState parser, String outputFile) throws FileNotFoundException {
|
||||
writeCStructs(parser, new PrintStreamAlwaysUnix(new FileOutputStream(outputFile)));
|
||||
}
|
||||
|
||||
public void writeCStructs(ParseState parser, PrintStream ps) {
|
||||
ps.println(
|
||||
"// begin\n" +
|
||||
"#pragma once\n" +
|
||||
"#include \"rusefi_types.h\""
|
||||
);
|
||||
|
||||
for (Struct s : parser.getStructs()) {
|
||||
StructLayout sl = new StructLayout(0, "root", s);
|
||||
sl.writeCLayoutRoot(ps);
|
||||
}
|
||||
|
||||
ps.println("// end");
|
||||
|
||||
ps.close();
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
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;
|
||||
|
||||
/**
|
||||
* As of Nov 2022 this implementation is not used in prod :(
|
||||
*/
|
||||
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) {
|
||||
// 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);
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
package com.rusefi.newparse.outputs;
|
||||
|
||||
import com.rusefi.newparse.ParseState;
|
||||
import com.rusefi.newparse.layout.StructLayout;
|
||||
import com.rusefi.newparse.parsing.Definition;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* As of Nov 2022 this implementation is not used in prod :(
|
||||
*/
|
||||
public class TsWriter {
|
||||
// matches strings in the form of @@MY_var_123@@
|
||||
private static final Pattern VAR = Pattern.compile("@@([a-zA-Z0-9_]+?)@@");
|
||||
|
||||
private static final Pattern OPTIONAL_LINE = Pattern.compile("@@if_([a-zA-Z0-9_]+)");
|
||||
|
||||
// TODO: We have to move either forward or backwards with newparse #4441
|
||||
public void writeTunerstudio(ParseState parser, String inputFile, String outputFile) throws IOException {
|
||||
PrintStream ps = new PrintStreamAlwaysUnix(new FileOutputStream(outputFile));
|
||||
writeTunerstudio(parser, inputFile, ps);
|
||||
ps.close();
|
||||
}
|
||||
|
||||
public void writeTunerstudio(ParseState parser, String inputFile, PrintStream ps) throws IOException {
|
||||
BufferedReader is = new BufferedReader(new FileReader(inputFile));
|
||||
|
||||
while (is.ready()) {
|
||||
String line = is.readLine();
|
||||
|
||||
if (line.contains("CONFIG_DEFINITION_START")) {
|
||||
writeLayoutAndComments(parser, ps);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Check if this line has a "skip me" suffix
|
||||
Matcher match = OPTIONAL_LINE.matcher(line);
|
||||
if (match.find()) {
|
||||
String varName = match.group(1);
|
||||
|
||||
Definition def = parser.findDefinition(varName);
|
||||
|
||||
if (def == null || def.toString().equals("false")) {
|
||||
// Definition was missing or false, skip this line
|
||||
continue;
|
||||
}
|
||||
|
||||
// Delete that part of the line
|
||||
line = line.replace(match.group(0), "");
|
||||
}
|
||||
|
||||
// Don't strip surrounding quotes of the FIRST replace of the line - only do it in nested replacements
|
||||
boolean isNested = false;
|
||||
|
||||
// While there is a line to replace, do it
|
||||
while (line.contains("@@")) {
|
||||
match = VAR.matcher(line);
|
||||
|
||||
if (!match.find()) {
|
||||
throw new RuntimeException("Failed to resolve definition in line: " + line);
|
||||
}
|
||||
|
||||
String varName = match.group(1);
|
||||
Definition def = parser.findDefinition(varName);
|
||||
|
||||
String replacement = def != null ? def.toString() : "MISSING DEFINITION";
|
||||
|
||||
// Strip off any quotes from the resolved string - we may be trying to concatenate inside a string literal where quotes aren't allowed
|
||||
while (isNested && replacement.startsWith("\"") && replacement.endsWith("\"")) {
|
||||
replacement = replacement.substring(1, replacement.length() - 1);
|
||||
}
|
||||
|
||||
line = line.replaceAll(match.group(0), replacement);
|
||||
|
||||
if (!isNested) {
|
||||
isNested = true;
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: remove extra whitespace from the line
|
||||
|
||||
// Copy the line to the output stream
|
||||
ps.println(line);
|
||||
}
|
||||
|
||||
is.close();
|
||||
}
|
||||
|
||||
public void writeLayoutAndComments(ParseState parser, PrintStream ps) {
|
||||
StructLayout root = new StructLayout(0, "root", parser.getLastStruct());
|
||||
TsMetadata meta = new TsMetadata();
|
||||
|
||||
// Print configuration layout
|
||||
int size = root.getSize();
|
||||
ps.println("pageSize = " + size);
|
||||
ps.println("page = 1");
|
||||
root.writeTunerstudioLayout(ps, meta);
|
||||
ps.println("; total TS size = " + size);
|
||||
|
||||
// Print context help
|
||||
ps.println("[SettingContextHelp]");
|
||||
meta.writeComments(ps);
|
||||
}
|
||||
}
|
|
@ -2,22 +2,17 @@ package com.rusefi.test;
|
|||
|
||||
import com.rusefi.BitState;
|
||||
import com.rusefi.ReaderStateImpl;
|
||||
import com.rusefi.newparse.outputs.OutputChannelWriter;
|
||||
import com.rusefi.output.DataLogConsumer;
|
||||
import com.rusefi.output.GaugeConsumer;
|
||||
import com.rusefi.output.GetOutputValueConsumer;
|
||||
import com.rusefi.output.OutputsSectionConsumer;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.rusefi.test.newParse.NewParseHelper.parseToOutputChannels;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
public class OutputsTest {
|
||||
@Test
|
||||
public void generateSomething() throws IOException {
|
||||
public void generateSomething() {
|
||||
ReaderStateImpl state = new ReaderStateImpl();
|
||||
state.getVariableRegistry().register("GAUGE_NAME_FUEL_WALL_CORRECTION", "wall");
|
||||
String test = "struct total\n" +
|
||||
|
@ -29,15 +24,6 @@ public class OutputsTest {
|
|||
"float tCharge;speed density\n" +
|
||||
"end_struct\n";
|
||||
|
||||
String expected = "root_afr_type = scalar, F32, 0, \"ms\", 1, 0\n" +
|
||||
"root_afr_typet = scalar, U08, 4, \"ms\", 1, 0\n" +
|
||||
"root_isForcedInduction = bits, U32, 8, [0:0]\n" +
|
||||
"root_enableFan1WithAc = bits, U32, 8, [1:1]\n" +
|
||||
"root_m_requested_pump = scalar, F32, 12, \"\", 1, 0\n" +
|
||||
"root_tCharge = scalar, F32, 16, \"\", 1, 0\n" +
|
||||
"; total TS size = 20\n";
|
||||
assertEquals(expected, parseToOutputChannels(test));
|
||||
|
||||
String expectedLegacy = "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" +
|
||||
|
@ -59,9 +45,6 @@ public class OutputsTest {
|
|||
runOriginalImplementation(test);
|
||||
}
|
||||
|
||||
/**
|
||||
* while we have {@link OutputChannelWriter} here we use the current 'legacy' implementation
|
||||
*/
|
||||
private static OutputsSectionConsumer runOriginalImplementation(String test) {
|
||||
ReaderStateImpl state = new ReaderStateImpl();
|
||||
|
||||
|
|
|
@ -1,307 +0,0 @@
|
|||
package com.rusefi.test.newParse;
|
||||
|
||||
import org.junit.Assert;
|
||||
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 input = "struct_no_prefix myStruct\n" +
|
||||
"int8_t xyz;comment;\"units\", 1, 2, 3, 4, 5\n" +
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 4\n" +
|
||||
"page = 1\n" +
|
||||
"xyz = scalar, S08, 0, \"units\", 1, 2, 3, 4, 5\n" +
|
||||
"; unused 3 bytes at offset 1\n" +
|
||||
"; total TS size = 4\n" +
|
||||
"[SettingContextHelp]\n" +
|
||||
"\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 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";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 8\n" +
|
||||
"page = 1\n" +
|
||||
"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", 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 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";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 8\n" +
|
||||
"page = 1\n" +
|
||||
"abc = scalar, S32, 0, \"\", 1, 2, 3, 4, 5\n" +
|
||||
"xyz = scalar, S08, 4, \"\", 6, 7, 8, 9, 10\n" +
|
||||
"; unused 3 bytes at offset 5\n" +
|
||||
"; total TS size = 8\n" +
|
||||
"[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 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";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 8\n" +
|
||||
"page = 1\n" +
|
||||
"abc = scalar, S08, 0, \"\", 1, 2, 3, 4, 5\n" +
|
||||
"; unused 3 bytes at offset 1\n" +
|
||||
"xyz = scalar, S32, 4, \"\", 6, 7, 8, 9, 10\n" +
|
||||
"; total TS size = 8\n" +
|
||||
"[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 input = "struct_no_prefix myStruct\n" +
|
||||
"int16_t abc\n" +
|
||||
"int8_t def\n" +
|
||||
"int32_t xyz\n" +
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 8\n" +
|
||||
"page = 1\n" +
|
||||
"abc = scalar, S16, 0, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"def = scalar, S08, 2, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; unused 1 bytes at offset 3\n" +
|
||||
"xyz = scalar, S32, 4, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; total TS size = 8\n" +
|
||||
"[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 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";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 16\n" +
|
||||
"page = 1\n" +
|
||||
"abc = array, S08, 0, [10], \"\", 1, 2, 3, 4, 5\n" +
|
||||
"; unused 2 bytes at offset 10\n" +
|
||||
"xyz = scalar, S32, 12, \"\", 6, 7, 8, 9, 10\n" +
|
||||
"; total TS size = 16\n" +
|
||||
"[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
|
||||
public void singleFieldMultiDimArray() throws IOException {
|
||||
String ts = parseToTs("struct_no_prefix myStruct\n" +
|
||||
"int8_t[10 x 5] abc;;\"\", 1, 2, 3, 4, 5\n" +
|
||||
"end_struct");
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 52\n" +
|
||||
"page = 1\n" +
|
||||
"abc = array, S08, 0, [10x5], \"\", 1, 2, 3, 4, 5\n" +
|
||||
"; unused 2 bytes at offset 50\n" +
|
||||
"; total TS size = 52\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void structs() throws IOException {
|
||||
String ts = parseToTs(
|
||||
"struct s1\n" +
|
||||
"int32_t abc\n" +
|
||||
"uint8_t def\n" +
|
||||
"end_struct\n" +
|
||||
"struct_no_prefix rootStruct\n" +
|
||||
"s1 a\n" +
|
||||
"s1 b\n" +
|
||||
"end_struct");
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 16\n" +
|
||||
"page = 1\n" +
|
||||
"a_abc = scalar, S32, 0, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"a_def = scalar, U08, 4, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; unused 3 bytes at offset 5\n" +
|
||||
"b_abc = scalar, S32, 8, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"b_def = scalar, U08, 12, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; unused 3 bytes at offset 13\n" +
|
||||
"; total TS size = 16\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayIterate() throws IOException {
|
||||
String input = "struct_no_prefix rootStruct\n" +
|
||||
"int32_t[4 iterate] myArr\n" +
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 16\n" +
|
||||
"page = 1\n" +
|
||||
"myArr1 = scalar, S32, 0, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"myArr2 = scalar, S32, 4, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"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", 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
|
||||
public void arrayZeroLength() throws IOException {
|
||||
String ts = parseToTs(
|
||||
"struct_no_prefix rootStruct\n" +
|
||||
"int32_t[0] myArr\n" +
|
||||
"end_struct");
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 0\n" +
|
||||
"page = 1\n" +
|
||||
"; total TS size = 0\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayOfStructsIterate() throws IOException {
|
||||
String ts = parseToTs(
|
||||
"struct s1\n" +
|
||||
"uint8_t var1\n" +
|
||||
"uint16_t var2\n" +
|
||||
"end_struct\n" +
|
||||
"struct_no_prefix rootStruct\n" +
|
||||
"s1[4 iterate] arr\n" +
|
||||
"end_struct");
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 16\n" +
|
||||
"page = 1\n" +
|
||||
"arr1_var1 = scalar, U08, 0, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; unused 1 bytes at offset 1\n" +
|
||||
"arr1_var2 = scalar, U16, 2, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"arr2_var1 = scalar, U08, 4, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; unused 1 bytes at offset 5\n" +
|
||||
"arr2_var2 = scalar, U16, 6, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"arr3_var1 = scalar, U08, 8, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; unused 1 bytes at offset 9\n" +
|
||||
"arr3_var2 = scalar, U16, 10, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"arr4_var1 = scalar, U08, 12, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; unused 1 bytes at offset 13\n" +
|
||||
"arr4_var2 = scalar, U16, 14, \"\", 1, 0, 0, 0, 0\n" +
|
||||
"; total TS size = 16\n" +
|
||||
"[SettingContextHelp]\n", ts);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bits() throws IOException {
|
||||
String input = "struct_no_prefix myStruct\n" +
|
||||
"bit first\n" +
|
||||
"bit second\n" +
|
||||
"bit withOpt,\"a\",\"b\"\n" +
|
||||
"end_struct";
|
||||
|
||||
Assert.assertEquals(
|
||||
"pageSize = 4\n" +
|
||||
"page = 1\n" +
|
||||
"first = bits, U32, 0, [0:0], \"false\", \"true\"\n" +
|
||||
"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", 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));
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
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.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
public class NewParseHelper {
|
||||
public static ParseState parse(String input) throws IOException {
|
||||
ParseState parseState = new ParseState();
|
||||
RusefiParseErrorStrategy.parseDefinitionString(parseState.getListener(), input);
|
||||
return parseState;
|
||||
}
|
||||
|
||||
// TODO: We have to move either forward or backwards with newparse #4441
|
||||
public static String parseToTs(String input) throws IOException {
|
||||
ParseState state = parse(input);
|
||||
|
||||
TsWriter writer = new TsWriter();
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
final String utf8 = StandardCharsets.UTF_8.name();
|
||||
|
||||
PrintStream ps = new PrintStreamAlwaysUnix(baos, true, utf8);
|
||||
|
||||
writer.writeLayoutAndComments(state, ps);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// TODO: We have to move either forward or backwards with newparse #4441
|
||||
public static String parseToC(String input) throws IOException {
|
||||
ParseState state = parse(input);
|
||||
|
||||
CStructWriter writer = new CStructWriter();
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
final String utf8 = StandardCharsets.UTF_8.name();
|
||||
|
||||
PrintStream ps = new PrintStreamAlwaysUnix(baos, true, utf8);
|
||||
|
||||
writer.writeCStructs(state, ps);
|
||||
|
||||
return baos.toString(utf8);
|
||||
}
|
||||
}
|
|
@ -1,147 +0,0 @@
|
|||
package com.rusefi.test.newParse;
|
||||
|
||||
import com.rusefi.RusefiParseErrorStrategy;
|
||||
import com.rusefi.newparse.ParseState;
|
||||
import com.rusefi.newparse.parsing.Definition;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.rusefi.test.newParse.NewParseHelper.parse;
|
||||
|
||||
|
||||
public class ParseDefinitionsTest {
|
||||
@Test
|
||||
public void basicIntegerDefinition() throws IOException {
|
||||
ParseState state = parse("#define foo 123");
|
||||
|
||||
Assert.assertNull(state.findDefinition("notFoo"));
|
||||
|
||||
Definition def = state.findDefinition("foo");
|
||||
Assert.assertTrue(def.isNumeric());
|
||||
Assert.assertEquals(123, def.asDouble(), 1e-5);
|
||||
|
||||
Definition defHex = state.findDefinition("foo_16_hex");
|
||||
Assert.assertFalse(defHex.isNumeric());
|
||||
Assert.assertEquals("\\x00\\x7b", defHex.value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicDoubleDefinition() throws IOException {
|
||||
ParseState state = parse("#define foo 123.5");
|
||||
|
||||
Definition def = state.findDefinition("foo");
|
||||
|
||||
Assert.assertTrue(def.isNumeric());
|
||||
Assert.assertEquals(123.5, def.asDouble(), 1e-5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void basicStringDefinition() throws IOException {
|
||||
ParseState state = parse("#define foo \"fooValue\"");
|
||||
|
||||
Definition def = state.findDefinition("foo");
|
||||
|
||||
Assert.assertFalse(def.isNumeric());
|
||||
Assert.assertTrue(def.value instanceof String);
|
||||
Assert.assertEquals("\"fooValue\"", def.value);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void definitionWithNumexprValue() throws IOException {
|
||||
ParseState state = parse("#define foo 5 + 8 * 2 + 3");
|
||||
|
||||
Definition def = state.findDefinition("foo");
|
||||
|
||||
Assert.assertTrue(def.isNumeric());
|
||||
Assert.assertEquals(24, def.asDouble(), 1e-5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void definitionWithAnotherDefinition() throws IOException {
|
||||
ParseState state = parse(
|
||||
"#define val1 20\n" +
|
||||
"#define val2 val1 + 1\n" +
|
||||
"#define val3 3 * @@val2@@");
|
||||
|
||||
Definition def1 = state.findDefinition("val1");
|
||||
Assert.assertTrue(def1.isNumeric());
|
||||
Assert.assertEquals(20, def1.asDouble(), 1e-5);
|
||||
|
||||
Definition def2 = state.findDefinition("val2");
|
||||
Assert.assertTrue(def2.isNumeric());
|
||||
Assert.assertEquals(21, def2.asDouble(), 1e-5);
|
||||
|
||||
Definition def3 = state.findDefinition("val3");
|
||||
Assert.assertTrue(def3.isNumeric());
|
||||
Assert.assertEquals(63, def3.asDouble(), 1e-5);
|
||||
}
|
||||
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void definitionEvalMissingDefinition() throws IOException {
|
||||
parse(
|
||||
"#define val1 20\n" +
|
||||
"#define val2 val1 + 1\n" +
|
||||
"#define val3 3 * valgggggg"
|
||||
);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void definitionEvalNonNumeric() throws IOException {
|
||||
parse(
|
||||
"#define val1 \"foo\"\n" +
|
||||
"#define val2 val1 + 1"
|
||||
);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void definitionOverwritePolicyReplace() throws IOException {
|
||||
ParseState state = new ParseState();
|
||||
state.setDefinitionPolicy(Definition.OverwritePolicy.Replace);
|
||||
RusefiParseErrorStrategy.parseDefinitionString(state.getListener(), "#define val 20");
|
||||
|
||||
Definition def = state.findDefinition("val");
|
||||
Assert.assertEquals(20, def.asDouble(), 1e-5);
|
||||
|
||||
// Now parse another definition with the same name
|
||||
RusefiParseErrorStrategy.parseDefinitionString(state.getListener(), "#define val 40");
|
||||
|
||||
// Should get back the new definition, not the old one
|
||||
Definition def2 = state.findDefinition("val");
|
||||
Assert.assertTrue(def != def2);
|
||||
Assert.assertEquals(40, def2.asDouble(), 1e-5);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void definitionOverwritePolicyIgnoreNew() throws IOException {
|
||||
ParseState state = new ParseState();
|
||||
state.setDefinitionPolicy(Definition.OverwritePolicy.IgnoreNew);
|
||||
RusefiParseErrorStrategy.parseDefinitionString(state.getListener(), "#define val 20");
|
||||
|
||||
Definition def = state.findDefinition("val");
|
||||
Assert.assertEquals(20, def.asDouble(), 1e-5);
|
||||
|
||||
// Now parse another definition with the same name
|
||||
state.setDefinitionPolicy(Definition.OverwritePolicy.IgnoreNew);
|
||||
RusefiParseErrorStrategy.parseDefinitionString(state.getListener(), "#define val 40");
|
||||
|
||||
// New one ignored, still returns the same old one.
|
||||
Assert.assertEquals(def, state.findDefinition("val"));
|
||||
Assert.assertEquals(20, def.asDouble(), 1e-5);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void definitionOverwritePolicyNotAllowed() throws IOException {
|
||||
ParseState state = new ParseState();
|
||||
state.setDefinitionPolicy(Definition.OverwritePolicy.NotAllowed);
|
||||
RusefiParseErrorStrategy.parseDefinitionString(state.getListener(), "#define val 20");
|
||||
|
||||
Definition def = state.findDefinition("val");
|
||||
Assert.assertEquals(20, def.asDouble(), 1e-5);
|
||||
|
||||
// Now parse another definition with the same name, this should throw
|
||||
RusefiParseErrorStrategy.parseDefinitionString(state.getListener(), "#define val 40");
|
||||
}
|
||||
}
|
|
@ -1,342 +0,0 @@
|
|||
package com.rusefi.test.newParse;
|
||||
|
||||
import com.rusefi.newparse.ParseState;
|
||||
import com.rusefi.newparse.parsing.*;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
import static com.rusefi.test.newParse.NewParseHelper.parse;
|
||||
|
||||
public class ParseStructTest {
|
||||
@Test
|
||||
public void structEmpty() throws IOException {
|
||||
ParseState state = parse(
|
||||
"struct myStruct\n\n" +
|
||||
"end_struct\n"
|
||||
);
|
||||
|
||||
// Parsed exactly one struct
|
||||
Assert.assertEquals(1, state.getStructs().size());
|
||||
|
||||
Struct myStruct = state.getStructs().get(0);
|
||||
|
||||
// It's a real struct!
|
||||
Assert.assertNotNull(myStruct);
|
||||
|
||||
// Check that it was parsed correctly
|
||||
Assert.assertEquals("myStruct", myStruct.name);
|
||||
Assert.assertEquals(0, myStruct.fields.size());
|
||||
Assert.assertEquals(false, myStruct.noPrefix);
|
||||
|
||||
Assert.assertEquals(state.getStructs().get(0), state.getLastStruct());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void structEmptyNoPrefix() throws IOException {
|
||||
ParseState state = parse(
|
||||
"struct_no_prefix myStruct\n\n" +
|
||||
"end_struct\n"
|
||||
);
|
||||
|
||||
Struct myStruct = state.getStructs().get(0);
|
||||
|
||||
// Check that this one is marked as no prefix
|
||||
Assert.assertEquals(true, myStruct.noPrefix);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void structMultiple() throws IOException {
|
||||
ParseState state = parse(
|
||||
"struct myStruct1\n\n" +
|
||||
"end_struct\n" +
|
||||
"struct myStruct2\n\n" +
|
||||
"end_struct\n"
|
||||
);
|
||||
|
||||
// Now there are two structs!
|
||||
Assert.assertEquals(2, state.getStructs().size());
|
||||
|
||||
Assert.assertEquals("myStruct1", state.getStructs().get(0).name);
|
||||
Assert.assertEquals("myStruct2", state.getStructs().get(1).name);
|
||||
|
||||
// Check that get last struct returns the last one
|
||||
Assert.assertEquals(state.getStructs().get(1), state.getLastStruct());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void structNested() throws IOException {
|
||||
ParseState state = parse(
|
||||
"struct myStructOuter\n" +
|
||||
"struct myStructInner\n\n" +
|
||||
"end_struct\n" +
|
||||
"end_struct\n"
|
||||
);
|
||||
|
||||
// Now there are two structs!
|
||||
Assert.assertEquals(2, state.getStructs().size());
|
||||
|
||||
Assert.assertEquals("myStructInner", state.getStructs().get(0).name);
|
||||
Assert.assertEquals("myStructOuter", state.getStructs().get(1).name);
|
||||
|
||||
// Check that get last struct returns the outer one
|
||||
Assert.assertEquals(state.getStructs().get(1), state.getLastStruct());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void structContainsStruct() throws IOException {
|
||||
ParseState state = parse(
|
||||
"struct myStruct\n\n" +
|
||||
"end_struct\n" +
|
||||
"struct myStruct2\n" +
|
||||
"myStruct foo\n" +
|
||||
"end_struct"
|
||||
);
|
||||
|
||||
Assert.assertEquals(2, state.getStructs().size());
|
||||
|
||||
Struct inner = state.getStructs().get(0);
|
||||
Assert.assertEquals(0, inner.fields.size());
|
||||
|
||||
// Check that the outer contains a struct
|
||||
Struct outer = state.getStructs().get(1);
|
||||
Assert.assertEquals(1, outer.fields.size());
|
||||
Assert.assertTrue(outer.fields.get(0) instanceof StructField);
|
||||
}
|
||||
|
||||
@Test(expected = RuntimeException.class)
|
||||
public void structMissingStruct() throws IOException {
|
||||
parse(
|
||||
"struct myStruct2\n" +
|
||||
"myStruct foo\n" +
|
||||
"end_struct"
|
||||
);
|
||||
}
|
||||
|
||||
private static Field parseSingleField(String fieldLine) throws IOException {
|
||||
ParseState state = parse(
|
||||
"struct myStruct\n" +
|
||||
fieldLine + "\n" +
|
||||
"end_struct\n"
|
||||
);
|
||||
|
||||
List<Field> fields = state.getLastStruct().fields;
|
||||
|
||||
Assert.assertEquals(1, fields.size());
|
||||
|
||||
return fields.get(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void scalarOptions() throws IOException {
|
||||
Field f = parseSingleField("int foo;comment;\"units\", 1, 2, 3, 4, 5");
|
||||
ScalarField sf = (ScalarField) f;
|
||||
|
||||
FieldOptions opt = sf.options;
|
||||
|
||||
Assert.assertEquals("comment", opt.comment);
|
||||
Assert.assertEquals("\"units\"", opt.units);
|
||||
Assert.assertEquals(1, opt.scale, 0.001f);
|
||||
Assert.assertEquals(2, opt.offset, 0.001f);
|
||||
Assert.assertEquals(3, opt.min, 0.001f);
|
||||
Assert.assertEquals(4, opt.max, 0.001f);
|
||||
Assert.assertEquals(5, opt.digits);
|
||||
}
|
||||
|
||||
private static void checkType(String inputType, int size, String cType, String tsType) throws IOException {
|
||||
ScalarField sf = (ScalarField) parseSingleField(inputType + " foo");
|
||||
|
||||
Assert.assertEquals("foo", sf.name);
|
||||
Assert.assertEquals(false, sf.autoscale);
|
||||
Assert.assertEquals(size, sf.type.size);
|
||||
|
||||
Assert.assertEquals(cType, sf.type.cType);
|
||||
Assert.assertEquals(tsType, sf.type.tsType);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typeMappings() throws IOException {
|
||||
checkType("int", 4, "int", "S32");
|
||||
|
||||
checkType("int8_t", 1, "int8_t", "S08");
|
||||
checkType("int16_t", 2, "int16_t", "S16");
|
||||
checkType("int32_t", 4, "int32_t", "S32");
|
||||
checkType("uint8_t", 1, "uint8_t", "U08");
|
||||
checkType("uint16_t", 2, "uint16_t", "U16");
|
||||
checkType("uint32_t", 4, "uint32_t", "U32");
|
||||
|
||||
checkType("float", 4, "float", "F32");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arraySingleDimension() throws IOException {
|
||||
Field f = parseSingleField("uint8_t[10] testBins");
|
||||
|
||||
Assert.assertTrue(f instanceof ArrayField);
|
||||
ArrayField af = (ArrayField)f;
|
||||
|
||||
Assert.assertEquals(1, af.length.length);
|
||||
Assert.assertEquals(10, af.length[0]);
|
||||
|
||||
PrototypeField prototype = af.prototype;
|
||||
|
||||
Assert.assertTrue(prototype instanceof ScalarField);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayMultiDimension() throws IOException {
|
||||
Field f = parseSingleField("uint8_t[5 x 8] testBins");
|
||||
|
||||
Assert.assertTrue(f instanceof ArrayField);
|
||||
ArrayField af = (ArrayField)f;
|
||||
|
||||
Assert.assertEquals(2, af.length.length);
|
||||
Assert.assertEquals(5, af.length[0]);
|
||||
Assert.assertEquals(8, af.length[1]);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayIterate() throws IOException {
|
||||
Field f = parseSingleField("uint8_t[10 iterate] testBins");
|
||||
|
||||
Assert.assertTrue(f instanceof ArrayField);
|
||||
ArrayField af = (ArrayField)f;
|
||||
|
||||
Assert.assertEquals(true, af.iterate);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void checkMultiDimensionArrayIterateThrows() throws IOException {
|
||||
parseSingleField("uint8_t[5 x 8 iterate] testBins");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void arrayOfStructs() throws IOException {
|
||||
ParseState state = parse(
|
||||
"struct myStruct\n\n" +
|
||||
"end_struct\n" +
|
||||
"struct myStruct2\n" +
|
||||
"myStruct[5 iterate] foo\n" +
|
||||
"end_struct"
|
||||
);
|
||||
|
||||
Assert.assertEquals(2, state.getStructs().size());
|
||||
|
||||
// Inner should be empty
|
||||
Struct inner = state.getStructs().get(0);
|
||||
Assert.assertEquals(0, inner.fields.size());
|
||||
|
||||
// Check that the outer contains an array of structs
|
||||
Struct outer = state.getStructs().get(1);
|
||||
Assert.assertEquals(1, outer.fields.size());
|
||||
|
||||
ArrayField af = (ArrayField)outer.fields.get(0);
|
||||
|
||||
// Check length and that it contains a struct
|
||||
Assert.assertEquals(1, af.length.length);
|
||||
Assert.assertEquals(5, af.length[0]);
|
||||
Assert.assertTrue(af.prototype instanceof StructField);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typedefScalar() throws IOException {
|
||||
ParseState ps = parse("custom myTypedef 4 scalar, F32, @OFFSET@, \"unit\", 1, 2, 3, 4, 5\n" +
|
||||
"struct myStruct\n" +
|
||||
"myTypedef foo;comment\n" +
|
||||
"end_struct");
|
||||
ScalarField sf = (ScalarField)ps.getLastStruct().fields.get(0);
|
||||
|
||||
Assert.assertEquals("foo", sf.name);
|
||||
|
||||
Assert.assertEquals(false, sf.autoscale);
|
||||
Assert.assertEquals(4, sf.type.size);
|
||||
Assert.assertEquals("float", sf.type.cType);
|
||||
Assert.assertEquals("F32", sf.type.tsType);
|
||||
|
||||
FieldOptions opt = sf.options;
|
||||
Assert.assertEquals("comment", opt.comment);
|
||||
Assert.assertEquals("\"unit\"", opt.units);
|
||||
Assert.assertEquals(1, opt.scale, 0.001f);
|
||||
Assert.assertEquals(2, opt.offset, 0.001f);
|
||||
Assert.assertEquals(3, opt.min, 0.001f);
|
||||
Assert.assertEquals(4, opt.max, 0.001f);
|
||||
Assert.assertEquals(5, opt.digits);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void typedefString() throws IOException {
|
||||
ParseState ps = parse("custom lua_script_t 1000 string, ASCII, @OFFSET@, 1000\n" +
|
||||
"struct myStruct\n" +
|
||||
"lua_script_t luaScript\n" +
|
||||
"end_struct");
|
||||
StringField sf = (StringField)ps.getLastStruct().fields.get(0);
|
||||
|
||||
Assert.assertEquals("luaScript", sf.name);
|
||||
Assert.assertEquals(1000, sf.size);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unused() throws IOException {
|
||||
ParseState state = parse(
|
||||
"struct_no_prefix myStruct\n" +
|
||||
"unused 27\n" +
|
||||
"end_struct\n"
|
||||
);
|
||||
|
||||
UnusedField uf = (UnusedField)state.getLastStruct().fields.get(0);
|
||||
|
||||
Assert.assertEquals(27, uf.size);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bitFieldsBasic() throws IOException {
|
||||
ParseState state = parse(
|
||||
"struct_no_prefix myStruct\n" +
|
||||
"bit myBit1\n" +
|
||||
"bit myBit2\n" +
|
||||
"end_struct\n"
|
||||
);
|
||||
|
||||
BitGroup bf = (BitGroup)state.getLastStruct().fields.get(0);
|
||||
|
||||
Assert.assertEquals(2, bf.bitFields.size());
|
||||
|
||||
Assert.assertEquals("myBit1", bf.bitFields.get(0).name);
|
||||
Assert.assertEquals("myBit2", bf.bitFields.get(1).name);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bitFieldsAdvanced() throws IOException {
|
||||
ParseState state = parse(
|
||||
"struct_no_prefix myStruct\n" +
|
||||
"bit myBit,\"a\",\"b\";comment\n" +
|
||||
"end_struct\n"
|
||||
);
|
||||
|
||||
BitGroup bg = (BitGroup)state.getLastStruct().fields.get(0);
|
||||
BitField bf = bg.bitFields.get(0);
|
||||
|
||||
Assert.assertEquals("myBit", bf.name);
|
||||
Assert.assertEquals("\"a\"", bf.trueValue);
|
||||
Assert.assertEquals("\"b\"", bf.falseValue);
|
||||
Assert.assertEquals("comment", bf.comment);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bitFieldsThirtyThreeBits() throws IOException {
|
||||
StringBuilder input = new StringBuilder("struct myStruct\n");
|
||||
for (int i = 0; i < 33; i++) {
|
||||
input.append("bit myBit").append(i).append("\n");
|
||||
}
|
||||
input.append("end_struct\n");
|
||||
|
||||
ParseState state = parse(input.toString());
|
||||
|
||||
Assert.assertEquals(2, state.getLastStruct().fields.size());
|
||||
|
||||
Assert.assertEquals(32, ((BitGroup)state.getLastStruct().fields.get(0)).bitFields.size());
|
||||
Assert.assertEquals(1, ((BitGroup)state.getLastStruct().fields.get(1)).bitFields.size());
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue