You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@plc4x.apache.org by cd...@apache.org on 2020/06/12 14:24:18 UTC
[plc4x] branch feature/c-code-generation-tagged-unions updated: -
Greatly refactored the C template helper and moved a lot of functionality
into a new BaseFreemarkerLanguageTemplateHelper - Finished support of array
fields - Finished supporting static function calls in expressions -
Finished supporting enum properties in expressions
This is an automated email from the ASF dual-hosted git repository.
cdutz pushed a commit to branch feature/c-code-generation-tagged-unions
in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/feature/c-code-generation-tagged-unions by this push:
new 8fa97ef - Greatly refactored the C template helper and moved a lot of functionality into a new BaseFreemarkerLanguageTemplateHelper - Finished support of array fields - Finished supporting static function calls in expressions - Finished supporting enum properties in expressions
8fa97ef is described below
commit 8fa97ef6e2e04c2407f17cdc544b0084d68df8eb
Author: Christofer Dutz <ch...@c-ware.de>
AuthorDate: Fri Jun 12 16:24:10 2020 +0200
- Greatly refactored the C template helper and moved a lot of functionality into a new BaseFreemarkerLanguageTemplateHelper
- Finished support of array fields
- Finished supporting static function calls in expressions
- Finished supporting enum properties in expressions
---
build-utils/language-base-freemarker/pom.xml | 5 +
.../BaseFreemarkerLanguageTemplateHelper.java | 525 ++++++++++++++++++++
.../freemarker/FreemarkerLanguageOutput.java | 6 +-
build-utils/language-c/pom.xml | 5 -
.../apache/plc4x/language/c/CLanguageOutput.java | 4 +-
.../plc4x/language/c/CLanguageTemplateHelper.java | 543 +++------------------
.../main/resources/templates/c/enum-template.ftlh | 15 +-
.../resources/templates/c/pojo-template-c.ftlh | 105 ++--
.../resources/templates/c/pojo-template-h.ftlh | 24 +-
.../plc4x/language/java/JavaLanguageOutput.java | 4 +-
.../language/java/JavaLanguageTemplateHelper.java | 8 +-
.../definitions/DefaultDataIoTypeDefinition.java | 2 +
.../model/definitions/DefaultTypeDefinition.java | 6 +
.../modbus/includes/modbus_constants.h | 1 -
.../generated-sources/modbus/includes/modbus_pdu.h | 40 +-
.../modbus_pdu_read_file_record_request_item.h | 1 -
.../modbus_pdu_read_file_record_response_item.h | 1 -
.../modbus_pdu_write_file_record_request_item.h | 1 -
.../modbus_pdu_write_file_record_response_item.h | 1 -
.../modbus/includes/modbus_serial_adu.h | 1 -
.../modbus/includes/modbus_tcp_adu.h | 1 -
.../modbus/src/modbus_constants.c | 2 +-
.../generated-sources/modbus/src/modbus_pdu.c | 2 +-
.../src/modbus_pdu_read_file_record_request_item.c | 2 +-
.../modbus_pdu_read_file_record_response_item.c | 13 +-
.../modbus_pdu_write_file_record_request_item.c | 13 +-
.../modbus_pdu_write_file_record_response_item.c | 13 +-
.../modbus/src/modbus_serial_adu.c | 2 +-
.../generated-sources/modbus/src/modbus_tcp_adu.c | 2 +-
.../generated-sources/s7/includes/cotp_packet.h | 8 +
.../generated-sources/s7/includes/cotp_parameter.h | 5 +
.../generated-sources/s7/includes/s7_address.h | 3 +-
.../generated-sources/s7/includes/s7_message.h | 6 +-
.../generated-sources/s7/includes/s7_parameter.h | 9 +-
.../s7/includes/s7_parameter_user_data_item.h | 1 +
.../generated-sources/s7/includes/s7_payload.h | 11 +-
.../s7/includes/s7_payload_user_data_item.h | 6 +-
.../s7/includes/s7_var_payload_data_item.h | 3 +-
.../s7/includes/s7_var_payload_status_item.h | 1 -
.../s7/includes/s7_var_request_parameter_item.h | 1 +
.../s7/includes/szl_data_tree_item.h | 1 -
.../plc4c/generated-sources/s7/includes/szl_id.h | 1 -
.../generated-sources/s7/includes/tpkt_packet.h | 1 -
.../generated-sources/s7/includes/transport_size.h | 2 +-
.../plc4c/generated-sources/s7/src/cotp_packet.c | 15 +-
.../generated-sources/s7/src/cotp_parameter.c | 2 +-
.../plc4c/generated-sources/s7/src/s7_address.c | 2 +-
.../plc4c/generated-sources/s7/src/s7_message.c | 2 +-
.../plc4c/generated-sources/s7/src/s7_parameter.c | 2 +-
.../s7/src/s7_parameter_user_data_item.c | 2 +-
.../plc4c/generated-sources/s7/src/s7_payload.c | 2 +-
.../s7/src/s7_payload_user_data_item.c | 2 +-
.../s7/src/s7_var_payload_data_item.c | 16 +-
.../s7/src/s7_var_payload_status_item.c | 2 +-
.../s7/src/s7_var_request_parameter_item.c | 2 +-
.../generated-sources/s7/src/szl_data_tree_item.c | 14 +-
sandbox/plc4c/generated-sources/s7/src/szl_id.c | 2 +-
.../plc4c/generated-sources/s7/src/tpkt_packet.c | 2 +-
.../spi/include/plc4c/spi/evaluation_helper.h | 6 +
sandbox/plc4c/spi/src/evaluation_helper.c | 9 +
60 files changed, 916 insertions(+), 573 deletions(-)
diff --git a/build-utils/language-base-freemarker/pom.xml b/build-utils/language-base-freemarker/pom.xml
index 0885d35..423f13b 100644
--- a/build-utils/language-base-freemarker/pom.xml
+++ b/build-utils/language-base-freemarker/pom.xml
@@ -51,6 +51,11 @@
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
+ <dependency>
+ <groupId>net.objecthunter</groupId>
+ <artifactId>exp4j</artifactId>
+ <version>0.4.8</version>
+ </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
new file mode 100644
index 0000000..5f31929
--- /dev/null
+++ b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/BaseFreemarkerLanguageTemplateHelper.java
@@ -0,0 +1,525 @@
+/*
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements. See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership. The ASF licenses this file
+to you under the Apache License, Version 2.0 (the
+"License"); you may not use this file except in compliance
+with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing,
+software distributed under the License is distributed on an
+"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+KIND, either express or implied. See the License for the
+specific language governing permissions and limitations
+under the License.
+*/
+package org.apache.plc4x.plugins.codegenerator.protocol.freemarker;
+
+import net.objecthunter.exp4j.Expression;
+import net.objecthunter.exp4j.ExpressionBuilder;
+import org.apache.plc4x.plugins.codegenerator.types.definitions.*;
+import org.apache.plc4x.plugins.codegenerator.types.fields.*;
+import org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference;
+import org.apache.plc4x.plugins.codegenerator.types.references.SimpleTypeReference;
+import org.apache.plc4x.plugins.codegenerator.types.references.TypeReference;
+import org.apache.plc4x.plugins.codegenerator.types.terms.*;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+public abstract class BaseFreemarkerLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper {
+
+ private final TypeDefinition thisType;
+ private final String protocolName;
+ private final String flavorName;
+ private final Map<String, TypeDefinition> types;
+
+ // In mspec we are using some virtual virtual fields that are useful for code generation.
+ // As they should be shared over all language template implementations,
+ // these are defined here manually.
+ private static Map<String, SimpleTypeReference> builtInFields;
+ {
+ builtInFields = new HashMap<>();
+ builtInFields.put("curPos", new SimpleTypeReference() {
+ @Override
+ public SimpleBaseType getBaseType() {
+ return SimpleBaseType.UINT;
+ }
+
+ @Override
+ public int getSizeInBits() {
+ return 16;
+ }
+ });
+ builtInFields.put("startPos", new SimpleTypeReference() {
+ @Override
+ public SimpleBaseType getBaseType() {
+ return SimpleBaseType.UINT;
+ }
+
+ @Override
+ public int getSizeInBits() {
+ return 16;
+ }
+ });
+ }
+
+ public BaseFreemarkerLanguageTemplateHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
+ this.thisType = thisType;
+ this.protocolName = protocolName;
+ this.flavorName = flavorName;
+ this.types = types;
+ }
+
+ protected TypeDefinition getThisTypeDefinition() {
+ return thisType;
+ }
+
+ protected String getProtocolName() {
+ return protocolName;
+ }
+
+ protected String getFlavorName() {
+ return flavorName;
+ }
+
+ protected Map<String, TypeDefinition> getTypeDefinitions() {
+ return types;
+ }
+
+ protected static Map<String, SimpleTypeReference> getBuiltInFieldTypes() {
+ return builtInFields;
+ }
+
+ /* *********************************************************************************
+ * Methods that are language-dependent.
+ **********************************************************************************/
+
+ public abstract String getLanguageTypeNameForField(Field field);
+
+ public abstract String getLanguageTypeNameForTypeReference(TypeReference typeReference);
+
+ public abstract String getReadBufferReadMethodCall(SimpleTypeReference simpleTypeReference);
+
+ public abstract String getWriteBufferReadMethodCall(SimpleTypeReference simpleTypeReference);
+
+ public abstract String getNullValueForTypeReference(TypeReference typeReference);
+
+ public abstract String getDiscriminatorName(Term discriminatorExpression);
+
+ /* *********************************************************************************
+ * Methods related to type-references.
+ **********************************************************************************/
+
+ /**
+ * @param typeReference type reference
+ * @return true if the given type reference is a simple type reference.
+ */
+ public boolean isSimpleTypeReference(TypeReference typeReference) {
+ return typeReference instanceof SimpleTypeReference;
+ }
+
+ /**
+ * @param typeReference type reference
+ * @return true if the given type reference is a complex type reference.
+ */
+ public boolean isComplexTypeReference(TypeReference typeReference) {
+ return typeReference instanceof ComplexTypeReference;
+ }
+
+ /**
+ * Helper for collecting referenced complex types as these usually ned to be
+ * imported in some way.
+ *
+ * @return Collection of all complex type references used in fields or enum constants.
+ */
+ public Collection<ComplexTypeReference> getComplexTypeReferences() {
+ return getComplexTypeReferences(thisType);
+ }
+
+ /**
+ * Helper for collecting referenced complex types as these usually need to be
+ * imported in some way.
+ *
+ * @param baseType the base type we want to get the type references from
+ * @return collection of complex type references used in the type.
+ */
+ public Collection<ComplexTypeReference> getComplexTypeReferences(TypeDefinition baseType) {
+ Set<ComplexTypeReference> complexTypeReferences = new HashSet<>();
+ // If this is a subtype of a discriminated type, we have to add a reference to the parent type.
+ if (baseType instanceof DiscriminatedComplexTypeDefinition) {
+ DiscriminatedComplexTypeDefinition discriminatedComplexTypeDefinition = (DiscriminatedComplexTypeDefinition) baseType;
+ if(!discriminatedComplexTypeDefinition.isAbstract()) {
+ complexTypeReferences.add((ComplexTypeReference)
+ discriminatedComplexTypeDefinition.getParentType().getTypeReference());
+ }
+ }
+ // If it's a complex type definition, add all the types referenced by any property fields
+ // (Includes any types referenced by sub-types in case this is a discriminated type parent)
+ if (baseType instanceof ComplexTypeDefinition) {
+ ComplexTypeDefinition complexTypeDefinition = (ComplexTypeDefinition) baseType;
+ for (Field field : complexTypeDefinition.getFields()) {
+ if(field instanceof PropertyField) {
+ PropertyField propertyField = (PropertyField) field;
+ if (propertyField.getType() instanceof ComplexTypeReference) {
+ ComplexTypeReference complexTypeReference = (ComplexTypeReference) propertyField.getType();
+ complexTypeReferences.add(complexTypeReference);
+ }
+ } else if(field instanceof SwitchField) {
+ SwitchField switchField = (SwitchField) field;
+ for (DiscriminatedComplexTypeDefinition switchCase : switchField.getCases()) {
+ complexTypeReferences.addAll(getComplexTypeReferences(switchCase));
+ }
+ }
+ }
+ }
+ // In case this is a enum type, we have to check all the constant types.
+ else if (baseType instanceof EnumTypeDefinition) {
+ for (String constantName : ((EnumTypeDefinition) baseType).getConstantNames()) {
+ final TypeReference constantType = ((EnumTypeDefinition) thisType).getConstantType(constantName);
+ if (constantType instanceof ComplexTypeReference) {
+ ComplexTypeReference complexTypeReference = (ComplexTypeReference) constantType;
+ complexTypeReferences.add(complexTypeReference);
+ }
+ }
+ }
+ // If the type has any parser arguments, these have to be checked too.
+ if(baseType.getParserArguments() != null) {
+ for (Argument parserArgument : baseType.getParserArguments()) {
+ if (parserArgument.getType() instanceof ComplexTypeReference) {
+ ComplexTypeReference complexTypeReference = (ComplexTypeReference) parserArgument.getType();
+ complexTypeReferences.add(complexTypeReference);
+ }
+ }
+ }
+ return complexTypeReferences;
+ }
+
+ /**
+ * Little helper to return the type of a given property.
+ *
+ * @param baseType base type definition that contains the given property.
+ * @param propertyName name of the property
+ * @return the type reference of the given property
+ */
+ public Optional<TypeReference> getTypeReferenceForProperty(ComplexTypeDefinition baseType, String propertyName) {
+ // If this is a built-in type, use that.
+ if(builtInFields.containsKey(propertyName)) {
+ return Optional.of(builtInFields.get(propertyName));
+ }
+ // Check if the expression root is referencing a field
+ final Optional<PropertyField> propertyFieldOptional = baseType.getFields().stream().filter(
+ field -> field instanceof PropertyField).map(field -> (PropertyField) field).filter(
+ propertyField -> propertyField.getName().equals(propertyName)).findFirst();
+ if(propertyFieldOptional.isPresent()) {
+ final PropertyField propertyField = propertyFieldOptional.get();
+ return Optional.of(propertyField.getType());
+ }
+ // Check if the expression is a ImplicitField
+ final Optional<ImplicitField> implicitFieldOptional = baseType.getFields().stream().filter(
+ field -> field instanceof ImplicitField).map(field -> (ImplicitField) field).filter(
+ implicitField -> implicitField.getName().equals(propertyName)).findFirst();
+ if(implicitFieldOptional.isPresent()) {
+ final ImplicitField implicitField = implicitFieldOptional.get();
+ return Optional.of(implicitField.getType());
+ }
+ // Check if the expression root is referencing an argument
+ if(baseType.getParserArguments() != null) {
+ final Optional<Argument> argumentOptional = Arrays.stream(baseType.getParserArguments()).filter(
+ argument -> argument.getName().equals(propertyName)).findFirst();
+ if (argumentOptional.isPresent()) {
+ final Argument argument = argumentOptional.get();
+ return Optional.of(argument.getType());
+ }
+ }
+ // Check if the expression is a DiscriminatorField
+ // This is a more theoretical case where the expression is referencing a discriminator value of the current type
+ final Optional<DiscriminatorField> discriminatorFieldOptional = baseType.getFields().stream().filter(
+ field -> field instanceof DiscriminatorField).map(field -> (DiscriminatorField) field).filter(
+ discriminatorField -> discriminatorField.getName().equals(propertyName)).findFirst();
+ if(discriminatorFieldOptional.isPresent()) {
+ final DiscriminatorField discriminatorField = discriminatorFieldOptional.get();
+ return Optional.of(discriminatorField.getType());
+ }
+ return Optional.empty();
+ }
+
+ /**
+ * Enums are always based on a main type. This helper accesses this information in a safe manner.
+ *
+ * @param typeReference type reference
+ * @return simple type reference for the enum type referenced by the given type reference
+ */
+ public SimpleTypeReference getEnumBaseTypeReference(TypeReference typeReference) {
+ if (!(typeReference instanceof ComplexTypeReference)) {
+ throw new RuntimeException("type reference for enum types must be of type complex type");
+ }
+ ComplexTypeReference complexTypeReference = (ComplexTypeReference) typeReference;
+ final TypeDefinition typeDefinition = types.get(complexTypeReference.getName());
+ if(typeDefinition == null) {
+ throw new RuntimeException("Couldn't find given enum type definition with name " + complexTypeReference.getName());
+ }
+ if(!(typeDefinition instanceof EnumTypeDefinition)) {
+ throw new RuntimeException("Referenced tpye with name " + complexTypeReference.getName() + " is not an enum type");
+ }
+ EnumTypeDefinition enumTypeDefinition = (EnumTypeDefinition) typeDefinition;
+ // Enum types always have simple type references.
+ return (SimpleTypeReference) enumTypeDefinition.getType();
+ }
+
+ /* *********************************************************************************
+ * Methods related to fields.
+ **********************************************************************************/
+
+ public boolean isSwitchField(Field field) {
+ return field instanceof SwitchField;
+ }
+
+ public boolean isEnumField(Field field) {
+ return field instanceof EnumField;
+ }
+
+ public boolean isCountArrayField(Field field) {
+ if(field instanceof ArrayField) {
+ ArrayField arrayField = (ArrayField) field;
+ return arrayField.getLoopType() == ArrayField.LoopType.COUNT;
+ }
+ return false;
+ }
+
+ public boolean isLengthArrayField(Field field) {
+ if(field instanceof ArrayField) {
+ ArrayField arrayField = (ArrayField) field;
+ return arrayField.getLoopType() == ArrayField.LoopType.LENGTH;
+ }
+ return false;
+ }
+
+ public boolean isTerminatedArrayField(Field field) {
+ if(field instanceof ArrayField) {
+ ArrayField arrayField = (ArrayField) field;
+ return arrayField.getLoopType() == ArrayField.LoopType.TERMINATED;
+ }
+ return false;
+ }
+
+ /**
+ * @return switch field of the current base type.
+ */
+ protected SwitchField getSwitchField() {
+ return getSwitchField(thisType);
+ }
+
+ /**
+ * @return switch field of the provided base type.
+ */
+ protected SwitchField getSwitchField(TypeDefinition typeDefinition) {
+ if (typeDefinition instanceof ComplexTypeDefinition) {
+ ComplexTypeDefinition complexTypeDefinition = (ComplexTypeDefinition) typeDefinition;
+ // Sebastian would be proud of me ;-)
+ return (SwitchField) complexTypeDefinition.getFields().stream().filter(
+ field -> field instanceof SwitchField).findFirst().orElse(null);
+ }
+ return null;
+ }
+
+ public Collection<Field> getPropertyAndSwitchFields() {
+ return getPropertyAndSwitchFields(thisType);
+ }
+
+ public Collection<Field> getPropertyAndSwitchFields(TypeDefinition typeDefinition) {
+ if(thisType instanceof ComplexTypeDefinition) {
+ return ((ComplexTypeDefinition) thisType).getFields().stream().filter(
+ field -> (field instanceof PropertyField) || (field instanceof SwitchField)).collect(Collectors.toList());
+ }
+ return Collections.emptyList();
+ }
+
+ /* *********************************************************************************
+ * Methods related to type-definitions.
+ **********************************************************************************/
+
+ public boolean isDiscriminatedParentTypeDefinition(TypeDefinition typeDefinition) {
+ return (typeDefinition instanceof ComplexTypeDefinition) && ((ComplexTypeDefinition) typeDefinition).isAbstract();
+ }
+
+ public boolean isDiscriminatedChildTypeDefinition(TypeDefinition typeDefinition) {
+ return (typeDefinition instanceof DiscriminatedComplexTypeDefinition) && !((ComplexTypeDefinition) typeDefinition).isAbstract();
+ }
+
+ public TypeDefinition getTypeDefinitionForTypeReference(TypeReference typeReference) {
+ if(!(typeReference instanceof ComplexTypeReference)) {
+ throw new RuntimeException("Type reference must be a complex type reference");
+ }
+ return getTypeDefinitions().get(((ComplexTypeReference) typeReference).getName());
+ }
+
+ /**
+ * @return list of sub-types for the current base type or an empty collection, if there are none
+ */
+ public List<DiscriminatedComplexTypeDefinition> getSubTypeDefinitions() {
+ return getSubTypeDefinitions(thisType);
+ }
+
+ /**
+ * @return list of sub-types for a given type definition or an empty collection, if there are none
+ */
+ public List<DiscriminatedComplexTypeDefinition> getSubTypeDefinitions(TypeDefinition type) {
+ SwitchField switchField = getSwitchField(type);
+ if (switchField != null) {
+ return switchField.getCases();
+ }
+ return Collections.emptyList();
+ }
+
+ /* *********************************************************************************
+ * Methods related to terms and expressions.
+ **********************************************************************************/
+
+ /**
+ * Check if the expression doesn't reference any variables.
+ * If this is the case, the expression can be evaluated at code-generation time.
+ *
+ * @param term term
+ * @return true if it doesn't reference any variable literals.
+ */
+ protected boolean isFixedValueExpression(Term term) {
+ if (term instanceof VariableLiteral) {
+ return false;
+ }
+ if (term instanceof UnaryTerm) {
+ UnaryTerm unaryTerm = (UnaryTerm) term;
+ return isFixedValueExpression(unaryTerm.getA());
+ }
+ if (term instanceof BinaryTerm) {
+ BinaryTerm binaryTerm = (BinaryTerm) term;
+ return isFixedValueExpression(binaryTerm.getA()) && isFixedValueExpression(binaryTerm.getB());
+ }
+ if (term instanceof TernaryTerm) {
+ TernaryTerm ternaryTerm = (TernaryTerm) term;
+ return isFixedValueExpression(ternaryTerm.getA()) && isFixedValueExpression(ternaryTerm.getB()) &&
+ isFixedValueExpression(ternaryTerm.getC());
+ }
+ return true;
+ }
+
+ protected int evaluateFixedValueExpression(Term term) {
+ final Expression expression = new ExpressionBuilder(toString(term)).build();
+ return (int) expression.evaluate();
+ }
+
+ protected String toString(Term term) {
+ if (term instanceof NullLiteral) {
+ return "null";
+ }
+ if (term instanceof BooleanLiteral) {
+ return Boolean.toString(((BooleanLiteral) term).getValue());
+ }
+ if (term instanceof NumericLiteral) {
+ return ((NumericLiteral) term).getNumber().toString();
+ }
+ if (term instanceof StringLiteral) {
+ return "\"" + ((StringLiteral) term).getValue() + "\"";
+ }
+ if (term instanceof UnaryTerm) {
+ return ((UnaryTerm) term).getOperation() + toString(((UnaryTerm) term).getA());
+ }
+ if (term instanceof BinaryTerm) {
+ return toString(((BinaryTerm) term).getA()) + ((BinaryTerm) term).getOperation() + toString(((BinaryTerm) term).getB());
+ }
+ if (term instanceof TernaryTerm) {
+ return "(" + toString(((TernaryTerm) term).getA()) + ") ? (" + toString(((TernaryTerm) term).getB()) +
+ ") : (" + toString(((TernaryTerm) term).getC()) + ")";
+ }
+ return "";
+ }
+
+ /* *********************************************************************************
+ * Methods related to discriminators.
+ **********************************************************************************/
+
+ private Optional<TypeReference> getDiscriminatorType(ComplexTypeDefinition parentType, Term disciminatorExpression) {
+ if (!(disciminatorExpression instanceof VariableLiteral)) {
+ throw new RuntimeException("Currently no arithmetic expressions are supported as discriminator expressions.");
+ }
+ VariableLiteral variableLiteral = (VariableLiteral) disciminatorExpression;
+ Optional<TypeReference> type = getTypeReferenceForProperty(parentType, variableLiteral.getName());
+ // If we found something but there's a "rest" left, we got to use the type we
+ // found in this level, get that type's definition and continue from there.
+ if (type.isPresent() && (variableLiteral.getChild() != null)) {
+ TypeReference typeReference = type.get();
+ if (typeReference instanceof ComplexTypeReference) {
+ ComplexTypeReference complexTypeReference = (ComplexTypeReference) typeReference;
+ final TypeDefinition typeDefinition = this.types.get(complexTypeReference.getName());
+ if (typeDefinition instanceof ComplexTypeDefinition) {
+ return getDiscriminatorType((ComplexTypeDefinition) typeDefinition, variableLiteral.getChild());
+ }
+ }
+ }
+ return type;
+ }
+
+ public Map<String, TypeReference> getDiscriminatorTypes() {
+ // Get the parent type (Which contains the typeSwitch field)
+ ComplexTypeDefinition parentType;
+ if (thisType instanceof DiscriminatedComplexTypeDefinition) {
+ parentType = (ComplexTypeDefinition) thisType.getParentType();
+ } else {
+ parentType = (ComplexTypeDefinition) thisType;
+ }
+ // Get the typeSwitch field from that.
+ final SwitchField switchField = getSwitchField(parentType);
+ if (switchField != null) {
+ Map<String, TypeReference> discriminatorTypes = new TreeMap<>();
+ for (Term discriminatorExpression : switchField.getDiscriminatorExpressions()) {
+ // Get some symbolic name we can use.
+ String discriminatorName = getDiscriminatorName(discriminatorExpression);
+ Optional<TypeReference> discriminatorType = getDiscriminatorType(parentType, discriminatorExpression);
+ discriminatorTypes.put(discriminatorName, discriminatorType.orElse(null));
+ }
+ return discriminatorTypes;
+ }
+ return Collections.emptyMap();
+ }
+
+ public Map<String, Map<String, String>> getDiscriminatorValues() {
+ // Get the parent type (Which contains the typeSwitch field)
+ ComplexTypeDefinition parentType;
+ if (thisType instanceof DiscriminatedComplexTypeDefinition) {
+ parentType = (ComplexTypeDefinition) thisType.getParentType();
+ } else {
+ parentType = (ComplexTypeDefinition) thisType;
+ }
+ // Get the typeSwitch field from that.
+ final SwitchField switchField = getSwitchField(parentType);
+ if (switchField != null) {
+ // Get the symbolic names of all discriminators
+ String[] discriminatorNames = new String[switchField.getDiscriminatorExpressions().length];
+ for (int i = 0; i < switchField.getDiscriminatorExpressions().length; i++) {
+ discriminatorNames[i] = getDiscriminatorName(switchField.getDiscriminatorExpressions()[i]);
+ }
+ // Build a map containing the named discriminator values for every case of the typeSwitch.
+ Map<String, Map<String, String>> discriminatorTypes = new TreeMap<>();
+ for (DiscriminatedComplexTypeDefinition switchCase : switchField.getCases()) {
+ discriminatorTypes.put(switchCase.getName(), new TreeMap<>());
+ for (int i = 0; i < switchField.getDiscriminatorExpressions().length; i++) {
+ String discriminatorValue;
+ if (i < switchCase.getDiscriminatorValues().length) {
+ discriminatorValue = switchCase.getDiscriminatorValues()[i];
+ } else {
+ discriminatorValue = null;
+ }
+ discriminatorTypes.get(switchCase.getName()).put(discriminatorNames[i], discriminatorValue);
+ }
+ }
+ return discriminatorTypes;
+ }
+ return Collections.emptyMap();
+ }
+
+
+
+}
diff --git a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/FreemarkerLanguageOutput.java b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/FreemarkerLanguageOutput.java
index 50ea54a..7685187 100644
--- a/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/FreemarkerLanguageOutput.java
+++ b/build-utils/language-base-freemarker/src/main/java/org/apache/plc4x/plugins/codegenerator/protocol/freemarker/FreemarkerLanguageOutput.java
@@ -64,7 +64,7 @@ public abstract class FreemarkerLanguageOutput implements LanguageOutput {
typeContext.put("languageName", languageName);
typeContext.put("protocolName", protocolName);
typeContext.put("outputFlavor", outputFlavor);
- typeContext.put("helper", getHelper(types));
+ typeContext.put("helper", getHelper(null, protocolName, outputFlavor, types));
for(Template template : specTemplates) {
try {
@@ -85,7 +85,7 @@ public abstract class FreemarkerLanguageOutput implements LanguageOutput {
typeContext.put("outputFlavor", outputFlavor);
typeContext.put("typeName", typeEntry.getKey());
typeContext.put("type", typeEntry.getValue());
- typeContext.put("helper", getHelper(types));
+ typeContext.put("helper", getHelper(typeEntry.getValue(), protocolName, outputFlavor, types));
// Depending on the type, get the corresponding list of templates.
List<Template> templateList;
@@ -175,6 +175,6 @@ public abstract class FreemarkerLanguageOutput implements LanguageOutput {
protected abstract List<Template> getDataIoTemplates(Configuration freemarkerConfiguration) throws IOException;
- protected abstract FreemarkerLanguageTemplateHelper getHelper(Map<String, TypeDefinition> types);
+ protected abstract FreemarkerLanguageTemplateHelper getHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types);
}
diff --git a/build-utils/language-c/pom.xml b/build-utils/language-c/pom.xml
index f557c02..1ba5709 100644
--- a/build-utils/language-c/pom.xml
+++ b/build-utils/language-c/pom.xml
@@ -53,11 +53,6 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-text</artifactId>
</dependency>
- <dependency>
- <groupId>net.objecthunter</groupId>
- <artifactId>exp4j</artifactId>
- <version>0.4.8</version>
- </dependency>
</dependencies>
</project>
\ No newline at end of file
diff --git a/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageOutput.java b/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageOutput.java
index 8b2d292..2846731 100644
--- a/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageOutput.java
+++ b/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageOutput.java
@@ -66,8 +66,8 @@ public class CLanguageOutput extends FreemarkerLanguageOutput {
}
@Override
- protected FreemarkerLanguageTemplateHelper getHelper(Map<String, TypeDefinition> types) {
- return new CLanguageTemplateHelper(types);
+ protected FreemarkerLanguageTemplateHelper getHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
+ return new CLanguageTemplateHelper(thisType, protocolName, flavorName, types);
}
}
diff --git a/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageTemplateHelper.java b/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageTemplateHelper.java
index 30173fc..76642a7 100644
--- a/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageTemplateHelper.java
+++ b/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageTemplateHelper.java
@@ -18,11 +18,9 @@ under the License.
*/
package org.apache.plc4x.language.c;
-import net.objecthunter.exp4j.Expression;
-import net.objecthunter.exp4j.ExpressionBuilder;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.text.WordUtils;
-import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLanguageTemplateHelper;
+import org.apache.plc4x.plugins.codegenerator.protocol.freemarker.BaseFreemarkerLanguageTemplateHelper;
import org.apache.plc4x.plugins.codegenerator.types.definitions.*;
import org.apache.plc4x.plugins.codegenerator.types.enums.EnumValue;
import org.apache.plc4x.plugins.codegenerator.types.fields.*;
@@ -31,152 +29,19 @@ import org.apache.plc4x.plugins.codegenerator.types.terms.*;
import java.util.*;
import java.util.function.Function;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper {
+public class CLanguageTemplateHelper extends BaseFreemarkerLanguageTemplateHelper {
- private final Map<String, TypeDefinition> types;
- private TypeDefinition thisType;
- private String protocolName;
- private String flavorName;
-
- private static Map<String, SimpleTypeReference> builtInFields;
- {
- builtInFields = new HashMap<>();
- builtInFields.put("curPos", new SimpleTypeReference() {
- @Override
- public SimpleBaseType getBaseType() {
- return SimpleBaseType.UINT;
- }
-
- @Override
- public int getSizeInBits() {
- return 16;
- }
- });
- builtInFields.put("startPos", new SimpleTypeReference() {
- @Override
- public SimpleBaseType getBaseType() {
- return SimpleBaseType.UINT;
- }
-
- @Override
- public int getSizeInBits() {
- return 16;
- }
- });
- }
-
- public CLanguageTemplateHelper(Map<String, TypeDefinition> types) {
- this.types = types;
- }
-
- public void setConstants(TypeDefinition thisType, String protocolName, String flavorName) {
- this.thisType = thisType;
- this.protocolName = protocolName;
- this.flavorName = flavorName;
+ public CLanguageTemplateHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
+ super(thisType, protocolName, flavorName, types);
}
public String getSourceDirectory() {
- return String.join("", protocolName.split("-")) + ".src";
+ return String.join("", getProtocolName().split("-")) + ".src";
}
public String getIncludesDirectory() {
- return String.join("", protocolName.split("-")) + ".includes";
- }
-
- /**
- * Check if this is an abstract type ...
- *
- * @param typeDefinition the type definition
- * @return true if this is an abstract type
- */
- public boolean isAbstractType(ComplexTypeDefinition typeDefinition) {
- return typeDefinition.isAbstract();
- }
-
- public boolean isSimpleType(TypeReference typeReference) {
- return typeReference instanceof SimpleTypeReference;
- }
-
- public boolean isDiscriminatedType(ComplexTypeDefinition typeDefinition) {
- return typeDefinition instanceof DiscriminatedComplexTypeDefinition;
- }
-
- public boolean isSwitchField(Field field) {
- return field instanceof SwitchField;
- }
-
- public boolean isEnumField(Field field) {
- return field instanceof EnumField;
- }
-
- /**
- * Modified version returning all the normal property fields, but also the typeSwitch fields
- * As we need to generate the union structs for these.
- *
- * @return list of property fields as well as typeSwitch fields.
- */
- public Collection<Field> getFields() {
- return ((ComplexTypeDefinition) thisType).getFields().stream().filter(
- field -> (field instanceof PropertyField) || (field instanceof SwitchField)).collect(Collectors.toList());
- }
-
- private SwitchField getSwitchField() {
- return getSwitchField(thisType);
- }
-
- private SwitchField getSwitchField(TypeDefinition type) {
- if (type instanceof ComplexTypeDefinition) {
- ComplexTypeDefinition complexTypeDefinition = (ComplexTypeDefinition) type;
- // Sebastian would be proud of me ;-)
- return (SwitchField) complexTypeDefinition.getFields().stream().filter(
- field -> field instanceof SwitchField).findFirst().orElse(null);
- }
- return null;
- }
-
- public List<DiscriminatedComplexTypeDefinition> getDiscriminatedSubTypes() {
- SwitchField switchField = getSwitchField();
- if (switchField != null) {
- return switchField.getCases();
- }
- return Collections.emptyList();
- }
-
- public Collection<ComplexTypeReference> getComplexTypeReferencesInFields() {
- return getComplexTypeReferencesInFields(thisType);
- }
-
- public Collection<ComplexTypeReference> getComplexTypeReferencesInFields(TypeDefinition baseType) {
- Set<ComplexTypeReference> complexTypeReferences = new HashSet<>();
- if (baseType instanceof ComplexTypeDefinition) {
- for (Field field : ((ComplexTypeDefinition) baseType).getFields()) {
- if(field instanceof PropertyField) {
- PropertyField propertyField = (PropertyField) field;
- if (propertyField.getType() instanceof ComplexTypeReference) {
- ComplexTypeReference complexTypeReference = (ComplexTypeReference) propertyField.getType();
- complexTypeReferences.add(complexTypeReference);
- }
- } else if(field instanceof SwitchField) {
- SwitchField switchField = (SwitchField) field;
- for (DiscriminatedComplexTypeDefinition switchCase : switchField.getCases()) {
- complexTypeReferences.addAll(getComplexTypeReferencesInFields(switchCase));
- }
- }
- }
- } else if (baseType instanceof EnumTypeDefinition) {
- for (String constantName : ((EnumTypeDefinition) baseType).getConstantNames()) {
- final TypeReference constantType = ((EnumTypeDefinition) thisType).getConstantType(constantName);
- if (constantType instanceof ComplexTypeReference) {
- ComplexTypeReference complexTypeReference = (ComplexTypeReference) constantType;
- complexTypeReferences.add(complexTypeReference);
- }
- }
- }
- return complexTypeReferences;
+ return String.join("", getProtocolName().split("-")) + ".includes";
}
/**
@@ -187,8 +52,9 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
* @return c-style type name
*/
public String getCTypeName(String typeName) {
- return camelCaseToSnakeCase(protocolName).toLowerCase() + "_" + camelCaseToSnakeCase(flavorName).toLowerCase() + "_" +
- camelCaseToSnakeCase(typeName).toLowerCase();
+ return camelCaseToSnakeCase(getProtocolName()).toLowerCase() +
+ "_" + camelCaseToSnakeCase(getFlavorName()).toLowerCase() +
+ "_" + camelCaseToSnakeCase(typeName).toLowerCase();
}
/**
@@ -232,24 +98,24 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
* @param field field we want to get the type name for
* @return type name we should use in C
*/
- public String getLanguageTypeNameForField(TypedField field) {
- // If the referenced type is a DataIo type, the value is of type plc4c_data.
- if (field instanceof PropertyField) {
- PropertyField propertyField = (PropertyField) field;
- if (propertyField.getType() instanceof ComplexTypeReference) {
- ComplexTypeReference complexTypeReference = (ComplexTypeReference) propertyField.getType();
- final TypeDefinition typeDefinition = types.get(complexTypeReference.getName());
- if (typeDefinition instanceof DataIoTypeDefinition) {
- return "plc4c_data*";
- }
- }
+ @Override
+ public String getLanguageTypeNameForField(Field field) {
+ if(!(field instanceof TypedField)) {
+ throw new RuntimeException("Field " + field + " is not a TypedField");
}
// If this is an array with variable length, then we have to use our "plc4c_list" to store the data.
if ((field instanceof ArrayField) && (!isFixedValueExpression(((ArrayField) field).getLoopExpression()))) {
return "plc4c_list";
}
- TypeReference typeReference = field.getType();
- return getLanguageTypeName(typeReference);
+ TypedField typedField = (TypedField) field;
+ TypeReference typeReference = typedField.getType();
+ if (typeReference instanceof ComplexTypeReference) {
+ final TypeDefinition typeDefinition = getTypeDefinitionForTypeReference(typeReference);
+ if (typeDefinition instanceof DataIoTypeDefinition) {
+ return "plc4c_data*";
+ }
+ }
+ return getLanguageTypeNameForTypeReference(typeReference);
}
/**
@@ -260,7 +126,8 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
* @param typeReference type reference
* @return c type
*/
- public String getLanguageTypeName(TypeReference typeReference) {
+ @Override
+ public String getLanguageTypeNameForTypeReference(TypeReference typeReference) {
if (typeReference instanceof SimpleTypeReference) {
SimpleTypeReference simpleTypeReference = (SimpleTypeReference) typeReference;
switch (simpleTypeReference.getBaseType()) {
@@ -376,7 +243,7 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
if ("null".equals(valueString)) {
// C doesn't like NULL values for enums, so we have to return something else (we'll treat -1 as NULL)
if (typeReference instanceof ComplexTypeReference) {
- if (types.get(((ComplexTypeReference) typeReference).getName()) instanceof EnumTypeDefinition) {
+ if (getTypeDefinitionForTypeReference(typeReference) instanceof EnumTypeDefinition) {
return "-1";
}
}
@@ -410,7 +277,6 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
if ("null".equals(valueString)) {
return "-1";
}
- ComplexTypeReference complexTypeReference = (ComplexTypeReference) typeReference;
String typeName = valueString.substring(0, valueString.indexOf('.'));
String constantName = valueString.substring(valueString.indexOf('.') + 1);
return "plc4c_" + getCTypeName(typeName) + "_" + constantName;
@@ -429,64 +295,7 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
return filteredEnumValues.values();
}
- /**
- * Check if the expression doesn't reference any variables.
- * If this is the case, the expression can be evaluated at code-generation time.
- *
- * @param term term
- * @return true if it doesn't reference any variable literals.
- */
- private boolean isFixedValueExpression(Term term) {
- if (term instanceof VariableLiteral) {
- return false;
- }
- if (term instanceof UnaryTerm) {
- UnaryTerm unaryTerm = (UnaryTerm) term;
- return isFixedValueExpression(unaryTerm.getA());
- }
- if (term instanceof BinaryTerm) {
- BinaryTerm binaryTerm = (BinaryTerm) term;
- return isFixedValueExpression(binaryTerm.getA()) && isFixedValueExpression(binaryTerm.getB());
- }
- if (term instanceof TernaryTerm) {
- TernaryTerm ternaryTerm = (TernaryTerm) term;
- return isFixedValueExpression(ternaryTerm.getA()) && isFixedValueExpression(ternaryTerm.getB()) &&
- isFixedValueExpression(ternaryTerm.getC());
- }
- return true;
- }
-
- private int evaluateFixedValueExpression(Term term) {
- final Expression expression = new ExpressionBuilder(toString(term)).build();
- return (int) expression.evaluate();
- }
-
- private String toString(Term term) {
- if (term instanceof NullLiteral) {
- return "null";
- }
- if (term instanceof BooleanLiteral) {
- return Boolean.toString(((BooleanLiteral) term).getValue());
- }
- if (term instanceof NumericLiteral) {
- return ((NumericLiteral) term).getNumber().toString();
- }
- if (term instanceof StringLiteral) {
- return "\"" + ((StringLiteral) term).getValue() + "\"";
- }
- if (term instanceof UnaryTerm) {
- return ((UnaryTerm) term).getOperation() + toString(((UnaryTerm) term).getA());
- }
- if (term instanceof BinaryTerm) {
- return toString(((BinaryTerm) term).getA()) + ((BinaryTerm) term).getOperation() + toString(((BinaryTerm) term).getB());
- }
- if (term instanceof TernaryTerm) {
- return "(" + toString(((TernaryTerm) term).getA()) + ") ? (" + toString(((TernaryTerm) term).getB()) +
- ") : (" + toString(((TernaryTerm) term).getC()) + ")";
- }
- return "";
- }
-
+ @Override
public String getReadBufferReadMethodCall(SimpleTypeReference simpleTypeReference) {
switch (simpleTypeReference.getBaseType()) {
case BIT: {
@@ -541,6 +350,21 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
return "Hurz";
}
+ @Override
+ public String getWriteBufferReadMethodCall(SimpleTypeReference simpleTypeReference) {
+ return null;
+ }
+
+ @Override
+ public String getNullValueForTypeReference(TypeReference typeReference) {
+ return null;
+ }
+
+
+
+
+
+
public String toParseExpression(Term term, Argument[] parserArguments) {
return toExpression(term, term1 -> toVariableParseExpression(term1, parserArguments));
}
@@ -565,7 +389,7 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
} else if (term instanceof VariableLiteral) {
VariableLiteral variableLiteral = (VariableLiteral) term;
// If this literal references an Enum type, then we have to output it differently.
- if (types.get(variableLiteral.getName()) instanceof EnumTypeDefinition) {
+ if (getTypeDefinitions().get(variableLiteral.getName()) instanceof EnumTypeDefinition) {
return variableLiteral.getName() + "." + variableLiteral.getChild().getName();
} else {
return variableExpressionGenerator.apply(term);
@@ -614,83 +438,11 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
public String toVariableParseExpression(Term term, Argument[] parserArguments) {
VariableLiteral vl = (VariableLiteral) term;
- // CAST expressions are special as we need to add a ".class" to the second parameter in Java.
- if ("CAST".equals(vl.getName())) {
- StringBuilder sb = new StringBuilder(vl.getName());
- if ((vl.getArgs() == null) || (vl.getArgs().size() != 2)) {
- throw new RuntimeException("A CAST expression expects exactly two arguments.");
- }
- sb.append("(").append(toVariableParseExpression(vl.getArgs().get(0), parserArguments))
- .append(", ").append(((VariableLiteral) vl.getArgs().get(1)).getName()).append(".class)");
- return sb.toString() + ((vl.getChild() != null) ? "." + toVariableExpressionRest(vl.getChild()) : "");
- } else if ("COUNT".equals(vl.getName())) {
- StringBuilder sb = new StringBuilder();
- if ((vl.getArgs() == null) || (vl.getArgs().size() != 1)) {
- throw new RuntimeException("A COUNT expression expects exactly one argument.");
- }
- sb.append("plc4c_utils_list_size(&").append(((VariableLiteral) vl.getArgs().get(0)).getName()).append(")");
- return sb.toString();
- } else if ("STATIC_CALL".equals(vl.getName())) {
- StringBuilder sb = new StringBuilder();
- if (!(vl.getArgs().get(0) instanceof StringLiteral)) {
- throw new RuntimeException("Expecting the first argument of a 'STATIC_CALL' to be a StringLiteral");
- }
- // Get the class and method name
- String methodName = ((StringLiteral) vl.getArgs().get(0)).getValue();
- // Cut off the double-quptes
- methodName = methodName.substring(1, methodName.length() - 1);
- sb.append(methodName).append("(");
- for (int i = 1; i < vl.getArgs().size(); i++) {
- Term arg = vl.getArgs().get(i);
- if (i > 1) {
- sb.append(", ");
- }
- if (arg instanceof VariableLiteral) {
- VariableLiteral va = (VariableLiteral) arg;
- // "io" is the default name of the reader argument which is always available.
- boolean isParserArg = "io".equals(va.getName());
- boolean isTypeArg = "_type".equals(va.getName());
- if (!isParserArg && !isTypeArg && parserArguments != null) {
- for (Argument parserArgument : parserArguments) {
- if (parserArgument.getName().equals(va.getName())) {
- isParserArg = true;
- break;
- }
- }
- }
- if (isParserArg) {
- sb.append(va.getName() + ((va.getChild() != null) ? "." + toVariableExpressionRest(va.getChild()) : ""));
- }
- // We have to manually evaluate the type information at code-generation time.
- /*else if (isTypeArg) {
- String part = va.getChild().getName();
- switch (part) {
- case "name":
- sb.append("\"").append(field.getTypeName()).append("\"");
- break;
- case "length":
- sb.append("\"").append(((SimpleTypeReference) field).getSizeInBits()).append("\"");
- break;
- case "encoding":
- String encoding = ((StringTypeReference) field.getType()).getEncoding();
- // Cut off the single quotes.
- encoding = encoding.substring(1, encoding.length() - 1);
- sb.append("\"").append(encoding).append("\"");
- break;
- }
- }*/ else {
- sb.append(toVariableParseExpression(va, null));
- }
- } else if (arg instanceof StringLiteral) {
- sb.append(((StringLiteral) arg).getValue());
- }
- }
- sb.append(")");
- return sb.toString();
- }
- // All uppercase names are not fields, but utility methods.
- else if (vl.getName().equals(vl.getName().toUpperCase())) {
- StringBuilder sb = new StringBuilder(vl.getName());
+ // Any name that is full upper-case is considered a function call.
+ // These are generally defined in the spi file evaluation_helper.c.
+ // All should have a name prefix "plc4c_spi_evaluation_helper_".
+ if (vl.getName().equals(vl.getName().toUpperCase())) {
+ StringBuilder sb = new StringBuilder("plc4c_spi_evaluation_helper_" + vl.getName().toLowerCase());
if (vl.getArgs() != null) {
sb.append("(");
boolean firstArg = true;
@@ -712,11 +464,12 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
final String name = vl.getName();
// Try to find the type of the addressed property.
- final Optional<TypeReference> propertyTypeOptional = getTypeReference((ComplexTypeDefinition) thisType, name);
+ final Optional<TypeReference> propertyTypeOptional =
+ getTypeReferenceForProperty((ComplexTypeDefinition) getThisTypeDefinition(), name);
// If we couldn't find the type, we didn't find the property.
if(!propertyTypeOptional.isPresent()) {
- throw new RuntimeException("Could not find property with name '" + name + "' in type " + thisType.getName());
+ throw new RuntimeException("Could not find property with name '" + name + "' in type " + getThisTypeDefinition().getName());
}
final TypeReference propertyType = propertyTypeOptional.get();
@@ -730,7 +483,7 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
}
// If it references a complex, type we need to get that type's definition first.
- final TypeDefinition propertyTypeDefinition = types.get(((ComplexTypeReference) propertyType).getName());
+ final TypeDefinition propertyTypeDefinition = getTypeDefinitions().get(((ComplexTypeReference) propertyType).getName());
// If we're not accessing any child property, no need to handle anything special.
if(vl.getChild() == null) {
return name;
@@ -738,59 +491,28 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
// If there is a child we need to check if this is a discriminator property.
// As discriminator properties are not real properties, but saved in the static metadata
// of a type, we need to generate a different access pattern.
- final Optional<DiscriminatorField> discriminatorFieldOptional = ((ComplexTypeDefinition) propertyTypeDefinition).getFields().stream().filter(
- curField -> curField instanceof DiscriminatorField).map(curField -> (DiscriminatorField) curField).filter(
- discriminatorField -> discriminatorField.getName().equals(vl.getChild().getName())).findFirst();
- // If child references a discriminator field of the type we found, we have to escape it.
- if(discriminatorFieldOptional.isPresent()) {
- return "plc4c_" + getCTypeName(propertyTypeDefinition.getName()) + "_get_discriminator(" + name +"->_type)." + vl.getChild().getName();
+ if(propertyTypeDefinition instanceof ComplexTypeDefinition) {
+ final Optional<DiscriminatorField> discriminatorFieldOptional = ((ComplexTypeDefinition) propertyTypeDefinition).getFields().stream().filter(
+ curField -> curField instanceof DiscriminatorField).map(curField -> (DiscriminatorField) curField).filter(
+ discriminatorField -> discriminatorField.getName().equals(vl.getChild().getName())).findFirst();
+ // If child references a discriminator field of the type we found, we have to escape it.
+ if (discriminatorFieldOptional.isPresent()) {
+ return "plc4c_" + getCTypeName(propertyTypeDefinition.getName()) + "_get_discriminator(" + name + "->_type)." + vl.getChild().getName();
+ }
+ }
+ // Handling enum properties in C is a little more tricky as we have to use the enum value
+ // and pass this to a function that then returns the desired property value.
+ else if(propertyTypeDefinition instanceof EnumTypeDefinition) {
+ EnumTypeDefinition enumTypeDefinition = (EnumTypeDefinition) propertyTypeDefinition;
+ StringBuilder sb = new StringBuilder("plc4c_")
+ .append(getCTypeName(propertyTypeDefinition.getName()))
+ .append("_get_").append(camelCaseToSnakeCase(vl.getChild().getName()));
+ return sb.toString();
}
// Else ... generate a simple access path.
return vl.getName() + ((vl.getChild() != null) ? "." + toVariableExpressionRest(vl.getChild()) : "");
}
- private Optional<TypeReference> getTypeReference(ComplexTypeDefinition baseType, String propertyName) {
- // If this is a built-in type, use that.
- if(builtInFields.containsKey(propertyName)) {
- return Optional.of(builtInFields.get(propertyName));
- }
- // Check if the expression root is referencing a field
- final Optional<PropertyField> propertyFieldOptional = baseType.getFields().stream().filter(
- field -> field instanceof PropertyField).map(field -> (PropertyField) field).filter(
- propertyField -> propertyField.getName().equals(propertyName)).findFirst();
- if(propertyFieldOptional.isPresent()) {
- final PropertyField propertyField = propertyFieldOptional.get();
- return Optional.of(propertyField.getType());
- }
- // Check if the expression is a ImplicitField
- final Optional<ImplicitField> implicitFieldOptional = baseType.getFields().stream().filter(
- field -> field instanceof ImplicitField).map(field -> (ImplicitField) field).filter(
- implicitField -> implicitField.getName().equals(propertyName)).findFirst();
- if(implicitFieldOptional.isPresent()) {
- final ImplicitField implicitField = implicitFieldOptional.get();
- return Optional.of(implicitField.getType());
- }
- // Check if the expression root is referencing an argument
- if(baseType.getParserArguments() != null) {
- final Optional<Argument> argumentOptional = Arrays.stream(baseType.getParserArguments()).filter(
- argument -> argument.getName().equals(propertyName)).findFirst();
- if (argumentOptional.isPresent()) {
- final Argument argument = argumentOptional.get();
- return Optional.of(argument.getType());
- }
- }
- // Check if the expression is a DiscriminatorField
- // This is a more theoretical case where the expression is referencing a discriminator value of the current type
- final Optional<DiscriminatorField> discriminatorFieldOptional = baseType.getFields().stream().filter(
- field -> field instanceof DiscriminatorField).map(field -> (DiscriminatorField) field).filter(
- discriminatorField -> discriminatorField.getName().equals(propertyName)).findFirst();
- if(discriminatorFieldOptional.isPresent()) {
- final DiscriminatorField discriminatorField = discriminatorFieldOptional.get();
- return Optional.of(discriminatorField.getType());
- }
- return Optional.empty();
- }
-
private String toVariableSerializationExpression(Term term, Argument[] serialzerArguments) {
VariableLiteral vl = (VariableLiteral) term;
if ("STATIC_CALL".equals(vl.getName())) {
@@ -983,7 +705,7 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
}
public String getReservedValue(ReservedField reservedField) {
- final String languageTypeName = getLanguageTypeName(reservedField.getType());
+ final String languageTypeName = getLanguageTypeNameForField(reservedField);
if ("BigInteger".equals(languageTypeName)) {
return "BigInteger.valueOf(" + reservedField.getReferenceValue() + ")";
} else {
@@ -991,51 +713,8 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
}
}
- public SimpleTypeReference getEnumBaseType(TypeReference enumType) {
- if (!(enumType instanceof ComplexTypeReference)) {
- throw new RuntimeException("type reference for enum types must be of type complex type");
- }
- ComplexTypeReference complexType = (ComplexTypeReference) enumType;
- EnumTypeDefinition enumTypeDefinition = (EnumTypeDefinition) types.get(complexType.getName());
- return (SimpleTypeReference) enumTypeDefinition.getType();
- }
-
- public Collection<String> getIncludeTypesForHFiles() {
- Set<String> imports = new TreeSet<>();
- // Add all the complex types references in parser arguments.
- if (thisType.getParserArguments() != null) {
- for (Argument parserArgument : thisType.getParserArguments()) {
- if (parserArgument.getType() instanceof ComplexTypeReference) {
- ComplexTypeReference complexTypeReference = (ComplexTypeReference) parserArgument.getType();
- imports.add(camelCaseToSnakeCase(complexTypeReference.getName()));
- }
- }
- }
- // Add all the complex types referenced in field declarations.
- for (ComplexTypeReference complexTypeReferencesInField : getComplexTypeReferencesInFields()) {
- imports.add(camelCaseToSnakeCase(complexTypeReferencesInField.getName()));
- }
- // If this is a discriminated type, add an import to the parent type.
- if (thisType instanceof DiscriminatedComplexTypeDefinition) {
- DiscriminatedComplexTypeDefinition discriminatedType = (DiscriminatedComplexTypeDefinition) thisType;
- imports.add(camelCaseToSnakeCase(discriminatedType.getParentType().getName()));
- }
- return imports;
- }
-
- public Collection<String> getIncludeTypesForCFiles() {
- List<String> imports = new LinkedList<>();
- // Add a reference to the current types header file itself.
- imports.add(camelCaseToSnakeCase(thisType.getName()));
- return imports;
- }
-
- private String getVariableLiteralName(VariableLiteral variableLiteral) {
- return variableLiteral.getName() + ((variableLiteral.getChild() != null) ?
- "_" + getVariableLiteralName(variableLiteral.getChild()) : "");
- }
-
- private String getDiscriminatorName(Term discriminatorExpression) {
+ @Override
+ public String getDiscriminatorName(Term discriminatorExpression) {
if(discriminatorExpression instanceof Literal) {
Literal literal = (Literal) discriminatorExpression;
if(literal instanceof NullLiteral) {
@@ -1064,83 +743,9 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper
return "";
}
- private Optional<TypeReference> getDiscriminatorType(ComplexTypeDefinition parentType, Term disciminatorExpression) {
- if (!(disciminatorExpression instanceof VariableLiteral)) {
- throw new RuntimeException("Currently no arithmetic expressions are supported as discriminator expressions.");
- }
- VariableLiteral variableLiteral = (VariableLiteral) disciminatorExpression;
- Optional<TypeReference> type = getTypeReference(parentType, variableLiteral.getName());
- // If we found something but there's a "rest" left, we got to use the type we
- // found in this level, get that type's definition and continue from there.
- if (type.isPresent() && (variableLiteral.getChild() != null)) {
- TypeReference typeReference = type.get();
- if (typeReference instanceof ComplexTypeReference) {
- ComplexTypeReference complexTypeReference = (ComplexTypeReference) typeReference;
- final TypeDefinition typeDefinition = this.types.get(complexTypeReference.getName());
- if (typeDefinition instanceof ComplexTypeDefinition) {
- return getDiscriminatorType((ComplexTypeDefinition) typeDefinition, variableLiteral.getChild());
- }
- }
- }
- return type;
- }
-
- public Map<String, TypeReference> getDiscriminatorTypes() {
- // Get the parent type (Which contains the typeSwitch field)
- ComplexTypeDefinition parentType;
- if (thisType instanceof DiscriminatedComplexTypeDefinition) {
- parentType = (ComplexTypeDefinition) thisType.getParentType();
- } else {
- parentType = (ComplexTypeDefinition) thisType;
- }
- // Get the typeSwitch field from that.
- final SwitchField switchField = getSwitchField(parentType);
- if (switchField != null) {
- Map<String, TypeReference> discriminatorTypes = new TreeMap<>();
- for (Term discriminatorExpression : switchField.getDiscriminatorExpressions()) {
- // Get some symbolic name we can use.
- String discriminatorName = getDiscriminatorName(discriminatorExpression);
- Optional<TypeReference> discriminatorType = getDiscriminatorType(parentType, discriminatorExpression);
- discriminatorTypes.put(discriminatorName, discriminatorType.orElse(null));
- }
- return discriminatorTypes;
- }
- return Collections.emptyMap();
- }
-
- public Map<String, Map<String, String>> getDiscriminatorValues() {
- // Get the parent type (Which contains the typeSwitch field)
- ComplexTypeDefinition parentType;
- if (thisType instanceof DiscriminatedComplexTypeDefinition) {
- parentType = (ComplexTypeDefinition) thisType.getParentType();
- } else {
- parentType = (ComplexTypeDefinition) thisType;
- }
- // Get the typeSwitch field from that.
- final SwitchField switchField = getSwitchField(parentType);
- if (switchField != null) {
- // Get the symbolic names of all discriminators
- String[] discriminatorNames = new String[switchField.getDiscriminatorExpressions().length];
- for (int i = 0; i < switchField.getDiscriminatorExpressions().length; i++) {
- discriminatorNames[i] = getDiscriminatorName(switchField.getDiscriminatorExpressions()[i]);
- }
- // Build a map containing the named discriminator values for every case of the typeSwitch.
- Map<String, Map<String, String>> discriminatorTypes = new TreeMap<>();
- for (DiscriminatedComplexTypeDefinition switchCase : switchField.getCases()) {
- discriminatorTypes.put(switchCase.getName(), new TreeMap<>());
- for (int i = 0; i < switchField.getDiscriminatorExpressions().length; i++) {
- String discriminatorValue;
- if (i < switchCase.getDiscriminatorValues().length) {
- discriminatorValue = switchCase.getDiscriminatorValues()[i];
- } else {
- discriminatorValue = null;
- }
- discriminatorTypes.get(switchCase.getName()).put(discriminatorNames[i], discriminatorValue);
- }
- }
- return discriminatorTypes;
- }
- return Collections.emptyMap();
+ private String getVariableLiteralName(VariableLiteral variableLiteral) {
+ return variableLiteral.getName() + ((variableLiteral.getChild() != null) ?
+ "_" + getVariableLiteralName(variableLiteral.getChild()) : "");
}
}
diff --git a/build-utils/language-c/src/main/resources/templates/c/enum-template.ftlh b/build-utils/language-c/src/main/resources/templates/c/enum-template.ftlh
index 4c84d58..35994fd 100644
--- a/build-utils/language-c/src/main/resources/templates/c/enum-template.ftlh
+++ b/build-utils/language-c/src/main/resources/templates/c/enum-template.ftlh
@@ -16,7 +16,7 @@
specific language governing permissions and limitations
under the License.
-->
-${helper.setConstants(type, protocolName, outputFlavor)}${helper.getIncludesDirectory()?replace(".", "/")}/${helper.camelCaseToSnakeCase(typeName)}.h
+${helper.getIncludesDirectory()?replace(".", "/")}/${helper.camelCaseToSnakeCase(typeName)}.h
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -43,10 +43,13 @@ extern "C" {
#endif
#include <stdbool.h>
-<#if helper.getComplexTypeReferencesInFields()?has_content>
- <#list helper.getComplexTypeReferencesInFields() as complexType>
-#include "${helper.camelCaseToSnakeCase(complexType.getName())}.h"
- </#list>
+<#--
+ Add any import statements for partent-types, complex types used in properties or parser arguments.
+-->
+<#if helper.getComplexTypeReferences()?has_content>
+ <#list helper.getComplexTypeReferences() as typeReference>
+#include "${helper.camelCaseToSnakeCase(typeReference.name)}.h"
+ </#list>
</#if>
<#--
@@ -68,7 +71,7 @@ typedef enum plc4c_${helper.getCTypeName(type.name)} plc4c_${helper.getCTypeName
<#if type.constantNames?has_content>
<#list type.constantNames as constantName>
-${helper.getLanguageTypeName(type.getConstantType(constantName))} plc4c_${helper.getCTypeName(type.name)}_get_${helper.camelCaseToSnakeCase(constantName)}(plc4c_${helper.getCTypeName(type.name)} value) {
+${helper.getLanguageTypeNameForTypeReference(type.getConstantType(constantName))} plc4c_${helper.getCTypeName(type.name)}_get_${helper.camelCaseToSnakeCase(constantName)}(plc4c_${helper.getCTypeName(type.name)} value) {
switch(value) {
<#list helper.getUniqueEnumValues(type.enumValues) as enumValue>
case ${helper.escapeValue(type.type, enumValue.value)}: { /* '${enumValue.value}' */
diff --git a/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh b/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh
index d3c7cee..e4952dc 100644
--- a/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh
+++ b/build-utils/language-c/src/main/resources/templates/c/pojo-template-c.ftlh
@@ -16,7 +16,7 @@
specific language governing permissions and limitations
under the License.
-->
-<#if !helper.isDiscriminatedType(type)>${helper.setConstants(type, protocolName, outputFlavor)}${helper.getSourceDirectory()?replace(".", "/")}/${helper.camelCaseToSnakeCase(typeName)}.c
+<#if !helper.isDiscriminatedChildTypeDefinition(type)>${helper.getSourceDirectory()?replace(".", "/")}/${helper.camelCaseToSnakeCase(typeName)}.c
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -40,15 +40,10 @@
#include <plc4c/spi/read_buffer.h>
#include <plc4c/spi/write_buffer.h>
#include <plc4c/spi/evaluation_helper.h>
-<#-- Add any needed import statements -->
-<#if helper.getIncludeTypesForCFiles()?has_content>
- <#list helper.getIncludeTypesForCFiles() as typeImport>
-#include "${typeImport}.h"
- </#list>
-</#if>
-<#-- Helper function to get the discriminator for a given enum type constant -->
-<#if helper.isAbstractType(type)>
+#include "${helper.camelCaseToSnakeCase(type.name)}.h"
+<#-- Helper function to get the discriminator for a given enum type constant -->
+<#if helper.isDiscriminatedParentTypeDefinition(type)>
// Array of discriminator values that match the enum type constants.
// (The order is identical to the enum constants so we can use the
// enum constant to directly access a given types discriminator values)
@@ -66,10 +61,10 @@ const plc4c_${helper.getCTypeName(type.name)}_discriminator plc4c_${helper.getCT
plc4c_${helper.getCTypeName(type.name)}_discriminator plc4c_${helper.getCTypeName(type.name)}_get_discriminator(plc4c_${helper.getCTypeName(type.name)}_type type) {
return plc4c_${helper.getCTypeName(type.name)}_discriminators[type];
}
-</#if>
+</#if>
// Parse function.
-plc4c_return_code plc4c_${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* buf, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeName(parserArgument.type)}<#if !helper.isSimpleType(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>plc4c_${helper.getCTypeName(type.name)}** message) {
+plc4c_return_code plc4c_${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* buf, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}<#if !helper.isSimpleTypeReference(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>plc4c_${helper.getCTypeName(type.name)}** message) {
uint16_t startPos = plc4c_spi_read_get_pos(buf);
uint16_t curPos;
@@ -80,8 +75,57 @@ plc4c_return_code plc4c_${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_b
</#if>
<#list type.fields as field>
<#switch field.typeName>
- <#case "checksum">
+ <#case "array">
+ // Array field (${field.name})
+ <#-- Only update curPos if the length expression uses it -->
+ <#if field.loopExpression.contains("curPos")>
+ curPos = plc4c_spi_read_get_pos(buf) - startPos;
+ </#if>
+ <#-- In all other cases do we have to work with a list, that is later converted to an array -->
+ plc4c_list ${field.name};
+ {
+ <#if helper.isCountArrayField(field)>
+ // Count array
+ uint8_t itemCount = ${helper.toParseExpression(field.loopExpression, type.parserArguments)?no_esc};
+ for(int curItem = 0; curItem < itemCount; curItem++) {
+ <#if !helper.isSimpleTypeReference(field.type)>boolean lastItem = curItem == (itemCount - 1);</#if>
+ <#-- Inizialize a local variable with the simple type (Intentionally keeping the java-style names so they can be used in expressions) -->
+ <#if helper.isSimpleTypeReference(field.type)>
+ ${helper.getLanguageTypeNameForTypeReference(field.type)} value = ${helper.getReadBufferReadMethodCall(field.type)?no_esc};
+ <#else>
+ <#-- Inizialize a local variable with the complex type (Intentionally keeping the java-style names so they can be used in expressions) -->
+ ${helper.getLanguageTypeNameForField(field)}* value = NULL;
+ plc4c_${helper.getCTypeName(field.type.name)}_parse(buf<#if field.params?has_content>, <#list field.params as parserTerm>${helper.toParseExpression(parserTerm, type.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &${field.name});
+ </#if>
+ plc4c_utils_list_insert_head_value(&${field.name}, &value);
+ }
+ <#-- For a length array, we read data till the read position of the buffer reaches a given position -->
+ <#elseif helper.isLengthArrayField(field)>
+ // Length array
+ uint8_t _${field.name}Length = ${helper.toParseExpression(field.loopExpression, type.parserArguments)?no_esc};
+ uint8_t ${field.name}EndPos = plc4c_spi_read_get_pos(buf) + _${field.name}Length;
+ while(plc4c_spi_read_get_pos(buf) < ${field.name}EndPos) {
+ plc4c_utils_list_insert_head_value(&${field.name}, <#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)?no_esc}<#else>plc4c_${helper.getCTypeName(field.type.name)}_parse(buf<#if field.params?has_content>, <#list field.params as parserTerm>${helper.toParseExpression(parserTerm, type.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &${field.name})</#if>);
+ <#-- After parsing, update the current position, but only if it's needed -->
+ <#if field.loopExpression.contains("curPos")>
+ curPos = plc4c_spi_read_get_pos(buf) - startPos;
+ </#if>
+ }
+ <#-- A terminated array keeps on reading data as long as the termination expression evaluates to false -->
+ <#elseif helper.isTerminatedArrayField(field)>
+ // Terminated array
+ while(!((boolean) (${helper.toParseExpression(field.loopExpression, type.parserArguments)?no_esc}))) {
+ plc4c_utils_list_insert_head_value(&${field.name}, <#if helper.isSimpleTypeReference(field.type)>${helper.getReadBufferReadMethodCall(field.type)?no_esc}<#else>${field.type.name}IO.staticParse(io<#if field.params?has_content>, <#list field.params as parserArgument>(${helper.getArgumentType(field.type, parserArgument?index)}) (${helper.toParseExpression(parserArgument, type.parserArguments)?no_esc})<#sep>, </#sep></#list></#if>)</#if>);
+ <#-- After parsing, update the current position, but only if it's needed -->
+ <#if field.loopExpression.contains("curPos")>
+ curPos = plc4c_spi_read_get_pos(buf) - startPos;
+ </#if>
+ }
+ </#if>
+ }
+ <#break>
+ <#case "checksum">
// Checksum Field (${field.name})
${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getNullValueForType(field.type)};
{
@@ -94,47 +138,51 @@ plc4c_return_code plc4c_${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_b
// throw new ParseException(String.format("Checksum verification failed. Expected %04X but got %04X",_${field.name}Ref & 0xFFFF, ${field.name} & 0xFFFF));
}
}
+
<#break>
<#case "const">
-
// Const Field (${field.name})
${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getReadBufferReadMethodCall(field.type)?no_esc};
if(${field.name} != ${helper.getCTypeName(type.name)?upper_case}_${helper.camelCaseToSnakeCase(field.name)?upper_case}) {
return PARSE_ERROR;
// throw new ParseException("Expected constant value " + ${typeName}.${field.name?upper_case} + " but got " + ${field.name});
}
+
<#break>
<#case "enum">
-
// Enum field (${field.name})
- ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getReadBufferReadMethodCall(helper.getEnumBaseType(field.type))?no_esc};
+ ${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getReadBufferReadMethodCall(helper.getEnumBaseTypeReference(field.type))?no_esc};
msg->${helper.camelCaseToSnakeCase(field.name)} = ${field.name};
+
<#break>
<#case "discriminator">
-
// Discriminator Field (${field.name}) (Used as input to a switch field)
${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getReadBufferReadMethodCall(field.type)?no_esc};
+
<#break>
<#case "implicit">
-
// Implicit Field (${field.name}) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getReadBufferReadMethodCall(field.type)?no_esc};
+
<#break>
- <#case "manual">
+ <#case "manualArray">
+ <#-- TODO: Implement -->
+ <#break>
+ <#case "manual">
// Manual Field (${field.name})
${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(field.parseExpression, type.parserArguments)});
msg->${helper.camelCaseToSnakeCase(field.name)} = ${field.name};
+
<#break>
<#case "optional">
-
// Optional Field (${field.name}) (Can be skipped, if a given expression evaluates to false)
<#if field.conditionExpression.contains("curPos")>
curPos = plc4c_spi_read_get_pos(buf) - startPos;
</#if>
- ${helper.getLanguageTypeNameForField(field)}<#if !helper.isSimpleType(field.type)>*</#if> ${field.name} = <#if !helper.isSimpleType(field.type)>NULL<#else>0</#if>;
+ ${helper.getLanguageTypeNameForField(field)}<#if !helper.isSimpleTypeReference(field.type)>*</#if> ${field.name} = <#if !helper.isSimpleTypeReference(field.type)>NULL<#else>0</#if>;
if(${helper.toParseExpression(field.conditionExpression, type.parserArguments)?no_esc}) {
- <#if helper.isSimpleType(field.type)>
+ <#if helper.isSimpleTypeReference(field.type)>
${field.name} = ${helper.getReadBufferReadMethodCall(field.type)?no_esc};
<#else>
plc4c_${helper.getCTypeName(field.type.name)}* ${field.name} = NULL;
@@ -142,18 +190,18 @@ plc4c_return_code plc4c_${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_b
</#if>
msg->${helper.camelCaseToSnakeCase(field.name)} = ${field.name};
}
+
<#break>
<#case "padding">
-
// Padding Field (${field.name})
bool _${field.name}NeedsPadding = (bool) ((plc4c_spi_read_has_more(buf, ${helper.getNumBits(field.type)})) && (${helper.toParseExpression(field.paddingCondition, type.parserArguments)?no_esc}));
if(_${field.name}NeedsPadding) {
// Just read the padding data and ignore it
${helper.getReadBufferReadMethodCall(field.type)?no_esc};
}
+
<#break>
<#case "reserved">
-
// Reserved Field (Compartmentalized so the "reserved" variable can't leak)
{
${helper.getLanguageTypeNameForField(field)} reserved = ${helper.getReadBufferReadMethodCall(field.type)?no_esc};
@@ -161,12 +209,12 @@ plc4c_return_code plc4c_${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_b
printf("Expected constant value '%d' but got '%d' for reserved field.", ${field.referenceValue}, reserved);
}
}
+
<#break>
<#case "simple">
-
// Simple Field (${field.name})
<#-- Inizialize a local variable with the simple type (Intentionally keeping the java-style names so they can be used in expressions) -->
- <#if helper.isSimpleType(field.type)>
+ <#if helper.isSimpleTypeReference(field.type)>
${helper.getLanguageTypeNameForField(field)} ${field.name} = ${helper.getReadBufferReadMethodCall(field.type)?no_esc};
<#else>
<#-- Inizialize a local variable with the complex type (Intentionally keeping the java-style names so they can be used in expressions) -->
@@ -174,25 +222,26 @@ plc4c_return_code plc4c_${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_b
plc4c_${helper.getCTypeName(field.type.name)}_parse(buf<#if field.params?has_content>, <#list field.params as parserTerm>${helper.toParseExpression(parserTerm, type.parserArguments)}<#sep>, </#sep></#list></#if>, (void*) &${field.name});
</#if>
msg->${helper.camelCaseToSnakeCase(field.name)} = ${field.name};
+
<#break>
<#case "switch">
-
// Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
<#list field.cases as case>
<#if case.discriminatorValues?has_content>if(<#list case.discriminatorValues as discriminatorValue><#if case.discriminatorValues?size > 1>(</#if>${helper.toVariableParseExpression(field.discriminatorExpressions[discriminatorValue?index], type.parserArguments)?no_esc}<#--${helper.toVariableParseExpressionHurz(field)}--> == ${discriminatorValue}<#if case.discriminatorValues?size > 1>)</#if><#sep> && </#sep></#list>) </#if>{ /* ${case.name} */
<#list case.propertyFields as caseField>
- ${helper.getLanguageTypeNameForField(caseField)}<#if !helper.isSimpleType(caseField.type)>*</#if> ${caseField.name}<#if field.loopType??>${helper.getLoopExpressionSuffix(caseField)}</#if><#if helper.getLanguageTypeNameForField(caseField) == "plc4c_list"><#elseif !helper.isSimpleType(caseField.type)> = NULL<#else> = -1</#if>;
+ ${helper.getLanguageTypeNameForField(caseField)}<#if !helper.isSimpleTypeReference(caseField.type)>*</#if> ${caseField.name}<#if field.loopType??>${helper.getLoopExpressionSuffix(caseField)}</#if><#if helper.getLanguageTypeNameForField(caseField) == "plc4c_list"><#elseif !helper.isSimpleTypeReference(caseField.type)> = NULL<#else> = -1</#if>;
msg->${helper.camelCaseToSnakeCase(case.name)}_${helper.camelCaseToSnakeCase(caseField.name)} = ${caseField.name};
<#sep >
</#list>
}<#sep> else </#sep>
</#list>
+
<#break>
<#case "virtual">
-
// Virtual field (Just declare a local variable so we can access it in the parser)
${helper.getLanguageTypeNameForField(field)} ${field.name} = (${helper.getLanguageTypeNameForField(field)}) (${helper.toParseExpression(field.valueExpression, type.parserArguments)});
+
<#break>
</#switch>
</#list>
diff --git a/build-utils/language-c/src/main/resources/templates/c/pojo-template-h.ftlh b/build-utils/language-c/src/main/resources/templates/c/pojo-template-h.ftlh
index 3737ea6..b3599ff 100644
--- a/build-utils/language-c/src/main/resources/templates/c/pojo-template-h.ftlh
+++ b/build-utils/language-c/src/main/resources/templates/c/pojo-template-h.ftlh
@@ -16,7 +16,7 @@
specific language governing permissions and limitations
under the License.
-->
-<#if !helper.isDiscriminatedType(type)>${helper.setConstants(type, protocolName, outputFlavor)}${helper.getIncludesDirectory()?replace(".", "/")}/${helper.camelCaseToSnakeCase(typeName)}.h
+<#if !helper.isDiscriminatedChildTypeDefinition(type)>${helper.getIncludesDirectory()?replace(".", "/")}/${helper.camelCaseToSnakeCase(typeName)}.h
/*
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
@@ -47,9 +47,9 @@ extern "C" {
<#--
Add any import statements for partent-types, complex types used in properties or parser arguments.
-->
-<#if helper.getIncludeTypesForHFiles()?has_content>
- <#list helper.getIncludeTypesForHFiles() as typeImport>
-#include "${typeImport}.h"
+<#if helper.getComplexTypeReferences()?has_content>
+ <#list helper.getComplexTypeReferences() as typeReference>
+#include "${helper.camelCaseToSnakeCase(typeReference.name)}.h"
</#list>
</#if>
<#--
@@ -58,13 +58,13 @@ extern "C" {
data-structure. So with this enum we're doing exactly this. It will be used in the serializers and
parsers and stored in discriminated types.
-->
-<#if helper.isAbstractType(type)>
+<#if helper.isDiscriminatedParentTypeDefinition(type)>
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_${helper.getCTypeName(type.name)}_discriminator {
<#if helper.getDiscriminatorTypes()?has_content>
<#list helper.getDiscriminatorTypes()?keys as discriminatorName>
- ${helper.getLanguageTypeName(helper.getDiscriminatorTypes()[discriminatorName])} ${discriminatorName};
+ ${helper.getLanguageTypeNameForTypeReference(helper.getDiscriminatorTypes()[discriminatorName])} ${discriminatorName};
</#list>
</#if>
};
@@ -72,7 +72,7 @@ typedef struct plc4c_${helper.getCTypeName(type.name)}_discriminator plc4c_${hel
// Enum assigning each sub-type an individual id.
enum plc4c_${helper.getCTypeName(type.name)}_type {
- <#list helper.getDiscriminatedSubTypes() as subtype>
+ <#list helper.getSubTypeDefinitions() as subtype>
plc4c_${helper.getCTypeName(type.name)}_type_${helper.getCTypeName(subtype.name)} = ${subtype?index}<#sep>,
</#list>
};
@@ -97,18 +97,18 @@ const ${helper.getLanguageTypeNameForField(field)} ${helper.getCTypeName(type.na
Create the general data-structure for this type
-->
struct plc4c_${helper.getCTypeName(type.name)} {
+<#if helper.isDiscriminatedParentTypeDefinition(type)>
/* This is an abstract type so this property saves the type of this typed union */
-<#if helper.isAbstractType(type)>
plc4c_${helper.getCTypeName(type.name)}_type _type;
</#if>
/* Properties */
-<#list helper.getFields() as field>
+<#list helper.getPropertyAndSwitchFields() as field>
<#if helper.isSwitchField(field)>
union {
<#list field.cases as case>
struct { /* ${case.name} */
<#list case.propertyFields as caseField>
- ${helper.getLanguageTypeNameForField(caseField)}<#if !helper.isSimpleType(caseField.type)>*</#if> ${helper.camelCaseToSnakeCase(case.name)}_${helper.camelCaseToSnakeCase(caseField.name)}${helper.getTypeSizeForField(caseField)}<#if field.loopType??>${helper.getLoopExpressionSuffix(caseField)}</#if>;
+ ${helper.getLanguageTypeNameForField(caseField)}<#if !helper.isSimpleTypeReference(caseField.type)>*</#if> ${helper.camelCaseToSnakeCase(case.name)}_${helper.camelCaseToSnakeCase(caseField.name)}${helper.getTypeSizeForField(caseField)}<#if field.loopType??>${helper.getLoopExpressionSuffix(caseField)}</#if>;
</#list>
};
</#list>
@@ -116,7 +116,7 @@ struct plc4c_${helper.getCTypeName(type.name)} {
<#elseif helper.isEnumField(field)>
${helper.getLanguageTypeNameForField(field)} ${helper.camelCaseToSnakeCase(field.name)};
<#else>
- ${helper.getLanguageTypeNameForField(field)}<#if !helper.isSimpleType(field.type)>*</#if> ${helper.camelCaseToSnakeCase(field.name)}${helper.getTypeSizeForField(field)}<#if field.loopType??>${helper.getLoopExpressionSuffix(field)}</#if>;
+ ${helper.getLanguageTypeNameForField(field)}<#if !helper.isSimpleTypeReference(field.type)>*</#if> ${helper.camelCaseToSnakeCase(field.name)}${helper.getTypeSizeForField(field)}<#if field.loopType??>${helper.getLoopExpressionSuffix(field)}</#if>;
</#if>
</#list>
};
@@ -125,7 +125,7 @@ typedef struct plc4c_${helper.getCTypeName(type.name)} plc4c_${helper.getCTypeNa
<#--
Define the parse-method for elements of this tpye
-->
-plc4c_return_code plc4c_${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* buf, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeName(parserArgument.type)}<#if !helper.isSimpleType(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>plc4c_${helper.getCTypeName(type.name)}** message);
+plc4c_return_code plc4c_${helper.getCTypeName(type.name)}_parse(plc4c_spi_read_buffer* buf, <#if type.parserArguments?has_content><#list type.parserArguments as parserArgument>${helper.getLanguageTypeNameForTypeReference(parserArgument.type)}<#if !helper.isSimpleTypeReference(parserArgument.type)>*</#if> ${parserArgument.name}<#sep>, </#list>, </#if>plc4c_${helper.getCTypeName(type.name)}** message);
<#--
Define the serialize-method for elements of this tpye
diff --git a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageOutput.java b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageOutput.java
index 534765a..f3120a4 100644
--- a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageOutput.java
+++ b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageOutput.java
@@ -65,8 +65,8 @@ public class JavaLanguageOutput extends FreemarkerLanguageOutput {
}
@Override
- protected FreemarkerLanguageTemplateHelper getHelper(Map<String, TypeDefinition> types) {
- return new JavaLanguageTemplateHelper(types);
+ protected FreemarkerLanguageTemplateHelper getHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
+ return new JavaLanguageTemplateHelper(thisType, protocolName, flavorName, types);
}
}
diff --git a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
index 659b4f3..fe235bc 100644
--- a/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
+++ b/build-utils/language-java/src/main/java/org/apache/plc4x/language/java/JavaLanguageTemplateHelper.java
@@ -35,9 +35,15 @@ import java.util.regex.Pattern;
@SuppressWarnings({"unused", "WeakerAccess"})
public class JavaLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper {
+ private final TypeDefinition thisType;
+ private final String protocolName;
+ private final String flavorName;
private final Map<String, TypeDefinition> types;
- public JavaLanguageTemplateHelper(Map<String, TypeDefinition> types) {
+ public JavaLanguageTemplateHelper(TypeDefinition thisType, String protocolName, String flavorName, Map<String, TypeDefinition> types) {
+ this.thisType = thisType;
+ this.protocolName = protocolName;
+ this.flavorName = flavorName;
this.types = types;
}
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDataIoTypeDefinition.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDataIoTypeDefinition.java
index 0e6e2fd..bbc1480 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDataIoTypeDefinition.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultDataIoTypeDefinition.java
@@ -18,9 +18,11 @@ under the License.
*/
package org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions;
+import org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultComplexTypeReference;
import org.apache.plc4x.plugins.codegenerator.types.definitions.Argument;
import org.apache.plc4x.plugins.codegenerator.types.definitions.DataIoTypeDefinition;
import org.apache.plc4x.plugins.codegenerator.types.fields.SwitchField;
+import org.apache.plc4x.plugins.codegenerator.types.references.TypeReference;
public class DefaultDataIoTypeDefinition extends DefaultTypeDefinition implements DataIoTypeDefinition {
diff --git a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultTypeDefinition.java b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultTypeDefinition.java
index c4ebb22..2e1d7b4 100644
--- a/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultTypeDefinition.java
+++ b/build-utils/protocol-base-mspec/src/main/java/org/apache/plc4x/plugins/codegenerator/language/mspec/model/definitions/DefaultTypeDefinition.java
@@ -20,8 +20,10 @@
package org.apache.plc4x.plugins.codegenerator.language.mspec.model.definitions;
+import org.apache.plc4x.plugins.codegenerator.language.mspec.model.references.DefaultComplexTypeReference;
import org.apache.plc4x.plugins.codegenerator.types.definitions.Argument;
import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition;
+import org.apache.plc4x.plugins.codegenerator.types.references.TypeReference;
public abstract class DefaultTypeDefinition {
@@ -57,4 +59,8 @@ public abstract class DefaultTypeDefinition {
this.parentType = parentType;
}
+ public TypeReference getTypeReference() {
+ return new DefaultComplexTypeReference(getName());
+ }
+
}
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_constants.h b/sandbox/plc4c/generated-sources/modbus/includes/modbus_constants.h
index 2365896..86c511e 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_constants.h
+++ b/sandbox/plc4c/generated-sources/modbus/includes/modbus_constants.h
@@ -30,7 +30,6 @@ extern "C" {
const uint16_t MODBUS_READ_WRITE_MODBUS_CONSTANTS_MODBUS_TCP_DEFAULT_PORT = 502;
struct plc4c_modbus_read_write_modbus_constants {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
uint16_t modbus_tcp_default_port;
};
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu.h b/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu.h
index 7ed9afc..eef9471 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu.h
+++ b/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu.h
@@ -25,10 +25,46 @@ extern "C" {
#include <stdbool.h>
#include <stdint.h>
#include <plc4c/utils/list.h>
-#include "modbus_pdu_read_file_record_request_item.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu_write_file_record_response_item.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
#include "modbus_pdu_read_file_record_response_item.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
#include "modbus_pdu_write_file_record_request_item.h"
-#include "modbus_pdu_write_file_record_response_item.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu_read_file_record_request_item.h"
+#include "modbus_pdu.h"
+#include "modbus_pdu.h"
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_modbus_read_write_modbus_pdu_discriminator {
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_request_item.h b/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_request_item.h
index 9386b3c..f5fb10e 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_request_item.h
+++ b/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_request_item.h
@@ -27,7 +27,6 @@ extern "C" {
#include <plc4c/utils/list.h>
struct plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
uint8_t reference_type;
uint16_t file_number;
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_response_item.h b/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_response_item.h
index 9aa9a91..142f84b 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_response_item.h
+++ b/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_read_file_record_response_item.h
@@ -27,7 +27,6 @@ extern "C" {
#include <plc4c/utils/list.h>
struct plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
uint8_t reference_type;
plc4c_list data;
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_request_item.h b/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_request_item.h
index 3c41ee4..b6d0f89 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_request_item.h
+++ b/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_request_item.h
@@ -27,7 +27,6 @@ extern "C" {
#include <plc4c/utils/list.h>
struct plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
uint8_t reference_type;
uint16_t file_number;
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_response_item.h b/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_response_item.h
index 2dfa1f5..5a9316a 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_response_item.h
+++ b/sandbox/plc4c/generated-sources/modbus/includes/modbus_pdu_write_file_record_response_item.h
@@ -27,7 +27,6 @@ extern "C" {
#include <plc4c/utils/list.h>
struct plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
uint8_t reference_type;
uint16_t file_number;
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_serial_adu.h b/sandbox/plc4c/generated-sources/modbus/includes/modbus_serial_adu.h
index ed3951f..308c722 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_serial_adu.h
+++ b/sandbox/plc4c/generated-sources/modbus/includes/modbus_serial_adu.h
@@ -28,7 +28,6 @@ extern "C" {
#include "modbus_pdu.h"
struct plc4c_modbus_read_write_modbus_serial_adu {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
uint16_t transaction_id;
uint16_t length;
diff --git a/sandbox/plc4c/generated-sources/modbus/includes/modbus_tcp_adu.h b/sandbox/plc4c/generated-sources/modbus/includes/modbus_tcp_adu.h
index 7f3222e..aa3ae1f 100644
--- a/sandbox/plc4c/generated-sources/modbus/includes/modbus_tcp_adu.h
+++ b/sandbox/plc4c/generated-sources/modbus/includes/modbus_tcp_adu.h
@@ -31,7 +31,6 @@ extern "C" {
const uint16_t MODBUS_READ_WRITE_MODBUS_TCP_ADU_PROTOCOL_IDENTIFIER = 0x0000;
struct plc4c_modbus_read_write_modbus_tcp_adu {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
uint16_t transaction_identifier;
uint16_t protocol_identifier;
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_constants.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_constants.c
index 7bf422b..92b231e 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_constants.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_constants.c
@@ -30,7 +30,6 @@ plc4c_return_code plc4c_modbus_read_write_modbus_constants_parse(plc4c_spi_read_
// Pointer to the parsed data structure.
plc4c_modbus_read_write_modbus_constants* msg = malloc(sizeof(plc4c_modbus_read_write_modbus_constants));
-
// Const Field (modbusTcpDefaultPort)
uint16_t modbusTcpDefaultPort = plc4c_spi_read_unsigned_int(buf, 16);
if(modbusTcpDefaultPort != MODBUS_READ_WRITE_MODBUS_CONSTANTS_MODBUS_TCP_DEFAULT_PORT) {
@@ -38,6 +37,7 @@ plc4c_return_code plc4c_modbus_read_write_modbus_constants_parse(plc4c_spi_read_
// throw new ParseException("Expected constant value " + ModbusConstants.MODBUSTCPDEFAULTPORT + " but got " + modbusTcpDefaultPort);
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu.c
index f1fa992..6c88c36 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu.c
@@ -113,7 +113,6 @@ plc4c_return_code plc4c_modbus_read_write_modbus_pdu_parse(plc4c_spi_read_buffer
// Pointer to the parsed data structure.
plc4c_modbus_read_write_modbus_pdu* msg = malloc(sizeof(plc4c_modbus_read_write_modbus_pdu));
-
// Implicit Field (error) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
bool error = plc4c_spi_read_bit(buf);
@@ -334,6 +333,7 @@ plc4c_return_code plc4c_modbus_read_write_modbus_pdu_parse(plc4c_spi_read_buffer
if((error == false) && (function == 0x2B) && (response == true)) { /* ModbusPDUReadDeviceIdentificationResponse */
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_request_item.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_request_item.c
index dde8ef1..f32c60f 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_request_item.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_request_item.c
@@ -31,7 +31,6 @@ plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_request_it
// Pointer to the parsed data structure.
plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item* msg = malloc(sizeof(plc4c_modbus_read_write_modbus_pdu_read_file_record_request_item));
-
// Simple Field (referenceType)
uint8_t referenceType = plc4c_spi_read_unsigned_short(buf, 8);
msg->reference_type = referenceType;
@@ -48,6 +47,7 @@ plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_request_it
uint16_t recordLength = plc4c_spi_read_unsigned_int(buf, 16);
msg->record_length = recordLength;
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_response_item.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_response_item.c
index bb9f031..8424aeb 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_response_item.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_read_file_record_response_item.c
@@ -31,7 +31,6 @@ plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_response_i
// Pointer to the parsed data structure.
plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item* msg = malloc(sizeof(plc4c_modbus_read_write_modbus_pdu_read_file_record_response_item));
-
// Implicit Field (dataLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
uint8_t dataLength = plc4c_spi_read_unsigned_short(buf, 8);
@@ -39,6 +38,18 @@ plc4c_return_code plc4c_modbus_read_write_modbus_pdu_read_file_record_response_i
uint8_t referenceType = plc4c_spi_read_unsigned_short(buf, 8);
msg->reference_type = referenceType;
+ // Array field (data)
+ plc4c_list data;
+ {
+ // Length array
+ uint8_t _dataLength = (dataLength) - (1);
+ uint8_t dataEndPos = plc4c_spi_read_get_pos(buf) + _dataLength;
+ while(plc4c_spi_read_get_pos(buf) < dataEndPos) {
+ plc4c_utils_list_insert_head_value(&data, plc4c_spi_read_unsigned_int(buf, 16));
+ }
+ }
+
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_request_item.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_request_item.c
index 119d133..5fe4ade 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_request_item.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_request_item.c
@@ -31,7 +31,6 @@ plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_request_i
// Pointer to the parsed data structure.
plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item* msg = malloc(sizeof(plc4c_modbus_read_write_modbus_pdu_write_file_record_request_item));
-
// Simple Field (referenceType)
uint8_t referenceType = plc4c_spi_read_unsigned_short(buf, 8);
msg->reference_type = referenceType;
@@ -47,6 +46,18 @@ plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_request_i
// Implicit Field (recordLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
uint16_t recordLength = plc4c_spi_read_unsigned_int(buf, 16);
+ // Array field (recordData)
+ plc4c_list recordData;
+ {
+ // Length array
+ uint8_t _recordDataLength = (recordLength) * (2);
+ uint8_t recordDataEndPos = plc4c_spi_read_get_pos(buf) + _recordDataLength;
+ while(plc4c_spi_read_get_pos(buf) < recordDataEndPos) {
+ plc4c_utils_list_insert_head_value(&recordData, plc4c_spi_read_unsigned_int(buf, 16));
+ }
+ }
+
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_response_item.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_response_item.c
index 2f7dd3a..e54baa6 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_response_item.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_pdu_write_file_record_response_item.c
@@ -31,7 +31,6 @@ plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_response_
// Pointer to the parsed data structure.
plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item* msg = malloc(sizeof(plc4c_modbus_read_write_modbus_pdu_write_file_record_response_item));
-
// Simple Field (referenceType)
uint8_t referenceType = plc4c_spi_read_unsigned_short(buf, 8);
msg->reference_type = referenceType;
@@ -47,6 +46,18 @@ plc4c_return_code plc4c_modbus_read_write_modbus_pdu_write_file_record_response_
// Implicit Field (recordLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
uint16_t recordLength = plc4c_spi_read_unsigned_int(buf, 16);
+ // Array field (recordData)
+ plc4c_list recordData;
+ {
+ // Length array
+ uint8_t _recordDataLength = (recordLength) * (2);
+ uint8_t recordDataEndPos = plc4c_spi_read_get_pos(buf) + _recordDataLength;
+ while(plc4c_spi_read_get_pos(buf) < recordDataEndPos) {
+ plc4c_utils_list_insert_head_value(&recordData, plc4c_spi_read_unsigned_int(buf, 16));
+ }
+ }
+
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_serial_adu.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_serial_adu.c
index 5445050..8083611 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_serial_adu.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_serial_adu.c
@@ -31,7 +31,6 @@ plc4c_return_code plc4c_modbus_read_write_modbus_serial_adu_parse(plc4c_spi_read
// Pointer to the parsed data structure.
plc4c_modbus_read_write_modbus_serial_adu* msg = malloc(sizeof(plc4c_modbus_read_write_modbus_serial_adu));
-
// Simple Field (transactionId)
uint16_t transactionId = plc4c_spi_read_unsigned_int(buf, 16);
msg->transaction_id = transactionId;
@@ -57,6 +56,7 @@ plc4c_return_code plc4c_modbus_read_write_modbus_serial_adu_parse(plc4c_spi_read
plc4c_modbus_read_write_modbus_pdu_parse(buf, response, (void*) &pdu);
msg->pdu = pdu;
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/modbus/src/modbus_tcp_adu.c b/sandbox/plc4c/generated-sources/modbus/src/modbus_tcp_adu.c
index 2f1f058..314a825 100644
--- a/sandbox/plc4c/generated-sources/modbus/src/modbus_tcp_adu.c
+++ b/sandbox/plc4c/generated-sources/modbus/src/modbus_tcp_adu.c
@@ -31,7 +31,6 @@ plc4c_return_code plc4c_modbus_read_write_modbus_tcp_adu_parse(plc4c_spi_read_bu
// Pointer to the parsed data structure.
plc4c_modbus_read_write_modbus_tcp_adu* msg = malloc(sizeof(plc4c_modbus_read_write_modbus_tcp_adu));
-
// Simple Field (transactionIdentifier)
uint16_t transactionIdentifier = plc4c_spi_read_unsigned_int(buf, 16);
msg->transaction_identifier = transactionIdentifier;
@@ -55,6 +54,7 @@ plc4c_return_code plc4c_modbus_read_write_modbus_tcp_adu_parse(plc4c_spi_read_bu
plc4c_modbus_read_write_modbus_pdu_parse(buf, response, (void*) &pdu);
msg->pdu = pdu;
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/includes/cotp_packet.h b/sandbox/plc4c/generated-sources/s7/includes/cotp_packet.h
index 7708c24..5669cec 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/cotp_packet.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/cotp_packet.h
@@ -25,9 +25,17 @@ extern "C" {
#include <stdbool.h>
#include <stdint.h>
#include <plc4c/utils/list.h>
+#include "cotp_packet.h"
+#include "cotp_packet.h"
+#include "cotp_packet.h"
#include "cotp_parameter.h"
#include "cotp_protocol_class.h"
+#include "cotp_protocol_class.h"
+#include "cotp_protocol_class.h"
#include "s7_message.h"
+#include "cotp_packet.h"
+#include "cotp_packet.h"
+#include "cotp_packet.h"
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_s7_read_write_cotp_packet_discriminator {
diff --git a/sandbox/plc4c/generated-sources/s7/includes/cotp_parameter.h b/sandbox/plc4c/generated-sources/s7/includes/cotp_parameter.h
index 86ed288..9e086aa 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/cotp_parameter.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/cotp_parameter.h
@@ -26,6 +26,11 @@ extern "C" {
#include <stdint.h>
#include <plc4c/utils/list.h>
#include "cotp_tpdu_size.h"
+#include "cotp_parameter.h"
+#include "cotp_parameter.h"
+#include "cotp_parameter.h"
+#include "cotp_parameter.h"
+#include "cotp_parameter.h"
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_s7_read_write_cotp_parameter_discriminator {
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_address.h b/sandbox/plc4c/generated-sources/s7/includes/s7_address.h
index 96b1e4b..bcd2f29 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_address.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/s7_address.h
@@ -25,8 +25,9 @@ extern "C" {
#include <stdbool.h>
#include <stdint.h>
#include <plc4c/utils/list.h>
-#include "memory_area.h"
+#include "s7_address.h"
#include "transport_size.h"
+#include "memory_area.h"
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_s7_read_write_s7_address_discriminator {
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_message.h b/sandbox/plc4c/generated-sources/s7/includes/s7_message.h
index 0ba9ee6..a22beaf 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_message.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/s7_message.h
@@ -25,8 +25,12 @@ extern "C" {
#include <stdbool.h>
#include <stdint.h>
#include <plc4c/utils/list.h>
-#include "s7_parameter.h"
#include "s7_payload.h"
+#include "s7_message.h"
+#include "s7_message.h"
+#include "s7_message.h"
+#include "s7_message.h"
+#include "s7_parameter.h"
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_s7_read_write_s7_message_discriminator {
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_parameter.h b/sandbox/plc4c/generated-sources/s7/includes/s7_parameter.h
index b6c87eb..c51996e 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_parameter.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/s7_parameter.h
@@ -25,8 +25,15 @@ extern "C" {
#include <stdbool.h>
#include <stdint.h>
#include <plc4c/utils/list.h>
-#include "s7_parameter_user_data_item.h"
#include "s7_var_request_parameter_item.h"
+#include "s7_parameter.h"
+#include "s7_parameter.h"
+#include "s7_parameter.h"
+#include "s7_var_request_parameter_item.h"
+#include "s7_parameter.h"
+#include "s7_parameter.h"
+#include "s7_parameter_user_data_item.h"
+#include "s7_parameter.h"
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_s7_read_write_s7_parameter_discriminator {
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_parameter_user_data_item.h b/sandbox/plc4c/generated-sources/s7/includes/s7_parameter_user_data_item.h
index 5f3679d..9fbbf91 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_parameter_user_data_item.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/s7_parameter_user_data_item.h
@@ -25,6 +25,7 @@ extern "C" {
#include <stdbool.h>
#include <stdint.h>
#include <plc4c/utils/list.h>
+#include "s7_parameter_user_data_item.h"
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_s7_read_write_s7_parameter_user_data_item_discriminator {
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_payload.h b/sandbox/plc4c/generated-sources/s7/includes/s7_payload.h
index b364c99..c059e75 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_payload.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/s7_payload.h
@@ -26,9 +26,18 @@ extern "C" {
#include <stdint.h>
#include <plc4c/utils/list.h>
#include "s7_parameter.h"
-#include "s7_payload_user_data_item.h"
+#include "s7_parameter.h"
+#include "s7_parameter.h"
#include "s7_var_payload_data_item.h"
+#include "s7_payload.h"
+#include "s7_parameter.h"
+#include "s7_payload.h"
+#include "s7_parameter.h"
+#include "s7_var_payload_data_item.h"
+#include "s7_payload_user_data_item.h"
#include "s7_var_payload_status_item.h"
+#include "s7_payload.h"
+#include "s7_payload.h"
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_s7_read_write_s7_payload_discriminator {
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_payload_user_data_item.h b/sandbox/plc4c/generated-sources/s7/includes/s7_payload_user_data_item.h
index 67a035e..fe22481 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_payload_user_data_item.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/s7_payload_user_data_item.h
@@ -25,10 +25,12 @@ extern "C" {
#include <stdbool.h>
#include <stdint.h>
#include <plc4c/utils/list.h>
+#include "szl_id.h"
#include "data_transport_error_code.h"
-#include "data_transport_size.h"
+#include "s7_payload_user_data_item.h"
#include "szl_data_tree_item.h"
-#include "szl_id.h"
+#include "s7_payload_user_data_item.h"
+#include "data_transport_size.h"
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_s7_read_write_s7_payload_user_data_item_discriminator {
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_data_item.h b/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_data_item.h
index fa37aee..1e8d765 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_data_item.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_data_item.h
@@ -25,11 +25,10 @@ extern "C" {
#include <stdbool.h>
#include <stdint.h>
#include <plc4c/utils/list.h>
-#include "data_transport_error_code.h"
#include "data_transport_size.h"
+#include "data_transport_error_code.h"
struct plc4c_s7_read_write_s7_var_payload_data_item {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
plc4c_s7_read_write_data_transport_error_code return_code;
plc4c_s7_read_write_data_transport_size transport_size;
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_status_item.h b/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_status_item.h
index 196e2b5..500f464 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_status_item.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/s7_var_payload_status_item.h
@@ -28,7 +28,6 @@ extern "C" {
#include "data_transport_error_code.h"
struct plc4c_s7_read_write_s7_var_payload_status_item {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
plc4c_s7_read_write_data_transport_error_code return_code;
};
diff --git a/sandbox/plc4c/generated-sources/s7/includes/s7_var_request_parameter_item.h b/sandbox/plc4c/generated-sources/s7/includes/s7_var_request_parameter_item.h
index 85ef4a2..eb442d3 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/s7_var_request_parameter_item.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/s7_var_request_parameter_item.h
@@ -26,6 +26,7 @@ extern "C" {
#include <stdint.h>
#include <plc4c/utils/list.h>
#include "s7_address.h"
+#include "s7_var_request_parameter_item.h"
// Structure used to contain the discriminator values for discriminated types using this as a parent
struct plc4c_s7_read_write_s7_var_request_parameter_item_discriminator {
diff --git a/sandbox/plc4c/generated-sources/s7/includes/szl_data_tree_item.h b/sandbox/plc4c/generated-sources/s7/includes/szl_data_tree_item.h
index 1b9480a..65a0922 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/szl_data_tree_item.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/szl_data_tree_item.h
@@ -27,7 +27,6 @@ extern "C" {
#include <plc4c/utils/list.h>
struct plc4c_s7_read_write_szl_data_tree_item {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
uint16_t item_index;
int8_t mlfb[20];
diff --git a/sandbox/plc4c/generated-sources/s7/includes/szl_id.h b/sandbox/plc4c/generated-sources/s7/includes/szl_id.h
index 544460f..8ca6e44 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/szl_id.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/szl_id.h
@@ -29,7 +29,6 @@ extern "C" {
#include "szl_sublist.h"
struct plc4c_s7_read_write_szl_id {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
plc4c_s7_read_write_szl_module_type_class type_class;
unsigned int sublist_extract : 4;
diff --git a/sandbox/plc4c/generated-sources/s7/includes/tpkt_packet.h b/sandbox/plc4c/generated-sources/s7/includes/tpkt_packet.h
index 43501e3..1774b50 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/tpkt_packet.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/tpkt_packet.h
@@ -31,7 +31,6 @@ extern "C" {
const uint8_t S7_READ_WRITE_TPKT_PACKET_PROTOCOL_ID = 0x03;
struct plc4c_s7_read_write_tpkt_packet {
- /* This is an abstract type so this property saves the type of this typed union */
/* Properties */
uint8_t protocol_id;
plc4c_s7_read_write_cotp_packet* payload;
diff --git a/sandbox/plc4c/generated-sources/s7/includes/transport_size.h b/sandbox/plc4c/generated-sources/s7/includes/transport_size.h
index 9850c8b..044b4ef 100644
--- a/sandbox/plc4c/generated-sources/s7/includes/transport_size.h
+++ b/sandbox/plc4c/generated-sources/s7/includes/transport_size.h
@@ -24,8 +24,8 @@ extern "C" {
#endif
#include <stdbool.h>
-#include "data_transport_size.h"
#include "transport_size.h"
+#include "data_transport_size.h"
enum plc4c_s7_read_write_transport_size {
plc4c_s7_read_write_transport_size_BOOL = 0x01,
diff --git a/sandbox/plc4c/generated-sources/s7/src/cotp_packet.c b/sandbox/plc4c/generated-sources/s7/src/cotp_packet.c
index d5b88c8..9e9630d 100644
--- a/sandbox/plc4c/generated-sources/s7/src/cotp_packet.c
+++ b/sandbox/plc4c/generated-sources/s7/src/cotp_packet.c
@@ -54,7 +54,6 @@ plc4c_return_code plc4c_s7_read_write_cotp_packet_parse(plc4c_spi_read_buffer* b
// Pointer to the parsed data structure.
plc4c_s7_read_write_cotp_packet* msg = malloc(sizeof(plc4c_s7_read_write_cotp_packet));
-
// Implicit Field (headerLength) (Used for parsing, but it's value is not stored as it's implicitly given by the objects content)
uint8_t headerLength = plc4c_spi_read_unsigned_short(buf, 8);
@@ -114,6 +113,19 @@ plc4c_return_code plc4c_s7_read_write_cotp_packet_parse(plc4c_spi_read_buffer* b
msg->cotp_packet_tpdu_error_reject_cause = rejectCause;
}
+ // Array field (parameters)
+ curPos = plc4c_spi_read_get_pos(buf) - startPos;
+ plc4c_list parameters;
+ {
+ // Length array
+ uint8_t _parametersLength = (((headerLength) + (1))) - (curPos);
+ uint8_t parametersEndPos = plc4c_spi_read_get_pos(buf) + _parametersLength;
+ while(plc4c_spi_read_get_pos(buf) < parametersEndPos) {
+ plc4c_utils_list_insert_head_value(¶meters, plc4c_s7_read_write_cotp_parameter_parse(buf, (((headerLength) + (1))) - (curPos), (void*) ¶meters));
+ curPos = plc4c_spi_read_get_pos(buf) - startPos;
+ }
+ }
+
// Optional Field (payload) (Can be skipped, if a given expression evaluates to false)
curPos = plc4c_spi_read_get_pos(buf) - startPos;
plc4c_s7_read_write_s7_message* payload = NULL;
@@ -123,6 +135,7 @@ plc4c_return_code plc4c_s7_read_write_cotp_packet_parse(plc4c_spi_read_buffer* b
msg->payload = payload;
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/cotp_parameter.c b/sandbox/plc4c/generated-sources/s7/src/cotp_parameter.c
index 50bc779..7a3f295 100644
--- a/sandbox/plc4c/generated-sources/s7/src/cotp_parameter.c
+++ b/sandbox/plc4c/generated-sources/s7/src/cotp_parameter.c
@@ -51,7 +51,6 @@ plc4c_return_code plc4c_s7_read_write_cotp_parameter_parse(plc4c_spi_read_buffer
// Pointer to the parsed data structure.
plc4c_s7_read_write_cotp_parameter* msg = malloc(sizeof(plc4c_s7_read_write_cotp_parameter));
-
// Discriminator Field (parameterType) (Used as input to a switch field)
uint8_t parameterType = plc4c_spi_read_unsigned_short(buf, 8);
@@ -80,6 +79,7 @@ plc4c_return_code plc4c_s7_read_write_cotp_parameter_parse(plc4c_spi_read_buffer
msg->cotp_parameter_disconnect_additional_information_data = data;
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_address.c b/sandbox/plc4c/generated-sources/s7/src/s7_address.c
index 9b2967e..26b02c4 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_address.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_address.c
@@ -43,7 +43,6 @@ plc4c_return_code plc4c_s7_read_write_s7_address_parse(plc4c_spi_read_buffer* bu
// Pointer to the parsed data structure.
plc4c_s7_read_write_s7_address* msg = malloc(sizeof(plc4c_s7_read_write_s7_address));
-
// Discriminator Field (addressType) (Used as input to a switch field)
uint8_t addressType = plc4c_spi_read_unsigned_short(buf, 8);
@@ -68,6 +67,7 @@ plc4c_return_code plc4c_s7_read_write_s7_address_parse(plc4c_spi_read_buffer* bu
msg->s7_address_any_bit_address = bitAddress;
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_message.c b/sandbox/plc4c/generated-sources/s7/src/s7_message.c
index 31e9454..40a6095 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_message.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_message.c
@@ -50,7 +50,6 @@ plc4c_return_code plc4c_s7_read_write_s7_message_parse(plc4c_spi_read_buffer* bu
// Pointer to the parsed data structure.
plc4c_s7_read_write_s7_message* msg = malloc(sizeof(plc4c_s7_read_write_s7_message));
-
// Const Field (protocolId)
uint8_t protocolId = plc4c_spi_read_unsigned_short(buf, 8);
if(protocolId != S7_READ_WRITE_S7_MESSAGE_PROTOCOL_ID) {
@@ -115,6 +114,7 @@ plc4c_return_code plc4c_s7_read_write_s7_message_parse(plc4c_spi_read_buffer* bu
msg->payload = payload;
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_parameter.c b/sandbox/plc4c/generated-sources/s7/src/s7_parameter.c
index 1a092a3..88bfae7 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_parameter.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_parameter.c
@@ -53,7 +53,6 @@ plc4c_return_code plc4c_s7_read_write_s7_parameter_parse(plc4c_spi_read_buffer*
// Pointer to the parsed data structure.
plc4c_s7_read_write_s7_parameter* msg = malloc(sizeof(plc4c_s7_read_write_s7_parameter));
-
// Discriminator Field (parameterType) (Used as input to a switch field)
uint8_t parameterType = plc4c_spi_read_unsigned_short(buf, 8);
@@ -89,6 +88,7 @@ plc4c_return_code plc4c_s7_read_write_s7_parameter_parse(plc4c_spi_read_buffer*
msg->s7_parameter_user_data_items = items;
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_parameter_user_data_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_parameter_user_data_item.c
index b6fad93..34b5f53 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_parameter_user_data_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_parameter_user_data_item.c
@@ -43,7 +43,6 @@ plc4c_return_code plc4c_s7_read_write_s7_parameter_user_data_item_parse(plc4c_sp
// Pointer to the parsed data structure.
plc4c_s7_read_write_s7_parameter_user_data_item* msg = malloc(sizeof(plc4c_s7_read_write_s7_parameter_user_data_item));
-
// Discriminator Field (itemType) (Used as input to a switch field)
uint8_t itemType = plc4c_spi_read_unsigned_short(buf, 8);
@@ -74,6 +73,7 @@ plc4c_return_code plc4c_s7_read_write_s7_parameter_user_data_item_parse(plc4c_sp
msg->s7_parameter_user_data_item_cpu_functions_error_code = errorCode;
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_payload.c b/sandbox/plc4c/generated-sources/s7/src/s7_payload.c
index 6bc5df8..1faf88d 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_payload.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_payload.c
@@ -49,7 +49,6 @@ plc4c_return_code plc4c_s7_read_write_s7_payload_parse(plc4c_spi_read_buffer* bu
// Pointer to the parsed data structure.
plc4c_s7_read_write_s7_payload* msg = malloc(sizeof(plc4c_s7_read_write_s7_payload));
-
// Switch Field (Depending on the discriminator values, passes the instantiation to a sub-type)
if((plc4c_s7_read_write_s7_parameter_get_discriminator(parameter->_type).parameterType == 0x04) && (messageType == 0x03)) { /* S7PayloadReadVarResponse */
plc4c_list* items;
@@ -68,6 +67,7 @@ plc4c_return_code plc4c_s7_read_write_s7_payload_parse(plc4c_spi_read_buffer* bu
msg->s7_payload_user_data_items = items;
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c
index 06e2cc5..885a661 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_payload_user_data_item.c
@@ -46,7 +46,6 @@ plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_parse(plc4c_spi_
// Pointer to the parsed data structure.
plc4c_s7_read_write_s7_payload_user_data_item* msg = malloc(sizeof(plc4c_s7_read_write_s7_payload_user_data_item));
-
// Enum field (returnCode)
plc4c_s7_read_write_data_transport_error_code returnCode = plc4c_spi_read_byte(buf, 8);
msg->return_code = returnCode;
@@ -75,6 +74,7 @@ plc4c_return_code plc4c_s7_read_write_s7_payload_user_data_item_parse(plc4c_spi_
msg->s7_payload_user_data_item_cpu_function_read_szl_response_items = items;
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_data_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_data_item.c
index 63d594d..105a0e5 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_data_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_data_item.c
@@ -31,7 +31,6 @@ plc4c_return_code plc4c_s7_read_write_s7_var_payload_data_item_parse(plc4c_spi_r
// Pointer to the parsed data structure.
plc4c_s7_read_write_s7_var_payload_data_item* msg = malloc(sizeof(plc4c_s7_read_write_s7_var_payload_data_item));
-
// Enum field (returnCode)
plc4c_s7_read_write_data_transport_error_code returnCode = plc4c_spi_read_byte(buf, 8);
msg->return_code = returnCode;
@@ -44,13 +43,26 @@ plc4c_return_code plc4c_s7_read_write_s7_var_payload_data_item_parse(plc4c_spi_r
uint16_t dataLength = plc4c_spi_read_unsigned_int(buf, 16);
msg->data_length = dataLength;
+ // Array field (data)
+ plc4c_list data;
+ {
+ // Count array
+ uint8_t itemCount = ((plc4c_s7_read_write_data_transport_size_get_size_in_bits) ? plc4c_spi_evaluation_helper_ceil((dataLength) / (8.0)) : dataLength);
+ for(int curItem = 0; curItem < itemCount; curItem++) {
+
+ int8_t value = plc4c_spi_read_byte(buf, 8);
+ plc4c_utils_list_insert_head_value(&data, &value);
+ }
+ }
+
// Padding Field (pad)
- bool _padNeedsPadding = (bool) ((plc4c_spi_read_has_more(buf, 8)) && ((!(lastItem)) && (((((plc4c_utils_list_size(&data)) % (2))) == (1)))));
+ bool _padNeedsPadding = (bool) ((plc4c_spi_read_has_more(buf, 8)) && ((!(lastItem)) && (((((plc4c_spi_evaluation_helper_count(data)) % (2))) == (1)))));
if(_padNeedsPadding) {
// Just read the padding data and ignore it
plc4c_spi_read_unsigned_short(buf, 8);
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_status_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_status_item.c
index ae8ca78..11f34d3 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_status_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_var_payload_status_item.c
@@ -31,11 +31,11 @@ plc4c_return_code plc4c_s7_read_write_s7_var_payload_status_item_parse(plc4c_spi
// Pointer to the parsed data structure.
plc4c_s7_read_write_s7_var_payload_status_item* msg = malloc(sizeof(plc4c_s7_read_write_s7_var_payload_status_item));
-
// Enum field (returnCode)
plc4c_s7_read_write_data_transport_error_code returnCode = plc4c_spi_read_byte(buf, 8);
msg->return_code = returnCode;
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/s7_var_request_parameter_item.c b/sandbox/plc4c/generated-sources/s7/src/s7_var_request_parameter_item.c
index c50fbd6..6a2cc50 100644
--- a/sandbox/plc4c/generated-sources/s7/src/s7_var_request_parameter_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/s7_var_request_parameter_item.c
@@ -43,7 +43,6 @@ plc4c_return_code plc4c_s7_read_write_s7_var_request_parameter_item_parse(plc4c_
// Pointer to the parsed data structure.
plc4c_s7_read_write_s7_var_request_parameter_item* msg = malloc(sizeof(plc4c_s7_read_write_s7_var_request_parameter_item));
-
// Discriminator Field (itemType) (Used as input to a switch field)
uint8_t itemType = plc4c_spi_read_unsigned_short(buf, 8);
@@ -53,6 +52,7 @@ plc4c_return_code plc4c_s7_read_write_s7_var_request_parameter_item_parse(plc4c_
msg->s7_var_request_parameter_item_address_address = address;
}
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/szl_data_tree_item.c b/sandbox/plc4c/generated-sources/s7/src/szl_data_tree_item.c
index b6b86b3..d5b9c23 100644
--- a/sandbox/plc4c/generated-sources/s7/src/szl_data_tree_item.c
+++ b/sandbox/plc4c/generated-sources/s7/src/szl_data_tree_item.c
@@ -31,11 +31,22 @@ plc4c_return_code plc4c_s7_read_write_szl_data_tree_item_parse(plc4c_spi_read_bu
// Pointer to the parsed data structure.
plc4c_s7_read_write_szl_data_tree_item* msg = malloc(sizeof(plc4c_s7_read_write_szl_data_tree_item));
-
// Simple Field (itemIndex)
uint16_t itemIndex = plc4c_spi_read_unsigned_int(buf, 16);
msg->item_index = itemIndex;
+ // Array field (mlfb)
+ plc4c_list mlfb;
+ {
+ // Count array
+ uint8_t itemCount = 20;
+ for(int curItem = 0; curItem < itemCount; curItem++) {
+
+ int8_t value = plc4c_spi_read_byte(buf, 8);
+ plc4c_utils_list_insert_head_value(&mlfb, &value);
+ }
+ }
+
// Simple Field (moduleTypeId)
uint16_t moduleTypeId = plc4c_spi_read_unsigned_int(buf, 16);
msg->module_type_id = moduleTypeId;
@@ -48,6 +59,7 @@ plc4c_return_code plc4c_s7_read_write_szl_data_tree_item_parse(plc4c_spi_read_bu
uint16_t ausbe = plc4c_spi_read_unsigned_int(buf, 16);
msg->ausbe = ausbe;
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/szl_id.c b/sandbox/plc4c/generated-sources/s7/src/szl_id.c
index 87edb3e..7ab2f80 100644
--- a/sandbox/plc4c/generated-sources/s7/src/szl_id.c
+++ b/sandbox/plc4c/generated-sources/s7/src/szl_id.c
@@ -31,7 +31,6 @@ plc4c_return_code plc4c_s7_read_write_szl_id_parse(plc4c_spi_read_buffer* buf, p
// Pointer to the parsed data structure.
plc4c_s7_read_write_szl_id* msg = malloc(sizeof(plc4c_s7_read_write_szl_id));
-
// Enum field (typeClass)
plc4c_s7_read_write_szl_module_type_class typeClass = plc4c_spi_read_byte(buf, 4);
msg->type_class = typeClass;
@@ -44,6 +43,7 @@ plc4c_return_code plc4c_s7_read_write_szl_id_parse(plc4c_spi_read_buffer* buf, p
plc4c_s7_read_write_szl_sublist sublistList = plc4c_spi_read_byte(buf, 8);
msg->sublist_list = sublistList;
+
return OK;
}
diff --git a/sandbox/plc4c/generated-sources/s7/src/tpkt_packet.c b/sandbox/plc4c/generated-sources/s7/src/tpkt_packet.c
index d939c0f..656b44b 100644
--- a/sandbox/plc4c/generated-sources/s7/src/tpkt_packet.c
+++ b/sandbox/plc4c/generated-sources/s7/src/tpkt_packet.c
@@ -31,7 +31,6 @@ plc4c_return_code plc4c_s7_read_write_tpkt_packet_parse(plc4c_spi_read_buffer* b
// Pointer to the parsed data structure.
plc4c_s7_read_write_tpkt_packet* msg = malloc(sizeof(plc4c_s7_read_write_tpkt_packet));
-
// Const Field (protocolId)
uint8_t protocolId = plc4c_spi_read_unsigned_short(buf, 8);
if(protocolId != S7_READ_WRITE_TPKT_PACKET_PROTOCOL_ID) {
@@ -55,6 +54,7 @@ plc4c_return_code plc4c_s7_read_write_tpkt_packet_parse(plc4c_spi_read_buffer* b
plc4c_s7_read_write_cotp_packet_parse(buf, (len) - (4), (void*) &payload);
msg->payload = payload;
+
return OK;
}
diff --git a/sandbox/plc4c/spi/include/plc4c/spi/evaluation_helper.h b/sandbox/plc4c/spi/include/plc4c/spi/evaluation_helper.h
index 41fc1a1..32a6d2c 100644
--- a/sandbox/plc4c/spi/include/plc4c/spi/evaluation_helper.h
+++ b/sandbox/plc4c/spi/include/plc4c/spi/evaluation_helper.h
@@ -19,8 +19,14 @@
#ifndef PLC4C_SPI_EVALUATION_HELPER_H_
#define PLC4C_SPI_EVALUATION_HELPER_H_
+#include <stdint.h>
#include <stdbool.h>
+#include <plc4c/utils/list.h>
bool plc4c_spi_evaluation_helper_equals(int a, int b);
+double plc4c_spi_evaluation_helper_ceil(double a);
+
+uint8_t plc4c_spi_evaluation_helper_count(plc4c_list a);
+
#endif // PLC4C_SPI_EVALUATION_HELPER_H_
diff --git a/sandbox/plc4c/spi/src/evaluation_helper.c b/sandbox/plc4c/spi/src/evaluation_helper.c
index 36d320c..9be479f 100644
--- a/sandbox/plc4c/spi/src/evaluation_helper.c
+++ b/sandbox/plc4c/spi/src/evaluation_helper.c
@@ -20,8 +20,17 @@
#include <plc4c/spi/evaluation_helper.h>
#include <stdbool.h>
+#include <math.h>
bool plc4c_spi_evaluation_helper_equals(int a, int b) {
return a == b;
}
+double plc4c_spi_evaluation_helper_ceil(double a) {
+ return ceil(a);
+}
+
+uint8_t plc4c_spi_evaluation_helper_count(plc4c_list a) {
+ return plc4c_utils_list_size(&a);
+}
+