This is an automated email from the ASF dual-hosted git repository. cdutz pushed a commit to branch develop in repository https://gitbox.apache.org/repos/asf/plc4x.git
The following commit(s) were added to refs/heads/develop by this push: new 5ca19e4 - Changed the way the type-names are being generated to utilize the stdint.h types - Changed the way structs with non-variable length arrays are being generated 5ca19e4 is described below commit 5ca19e481eac278d4c88291ff3c7a8609d1a2ccc Author: Christofer Dutz <christofer.d...@c-ware.de> AuthorDate: Tue May 26 12:12:49 2020 +0200 - Changed the way the type-names are being generated to utilize the stdint.h types - Changed the way structs with non-variable length arrays are being generated --- build-utils/language-c/pom.xml | 5 + .../plc4x/language/c/CLanguageTemplateHelper.java | 111 ++++++++++++++++++++- .../resources/templates/c/pojo-template-h.ftlh | 3 +- 3 files changed, 115 insertions(+), 4 deletions(-) diff --git a/build-utils/language-c/pom.xml b/build-utils/language-c/pom.xml index 1ba5709..f557c02 100644 --- a/build-utils/language-c/pom.xml +++ b/build-utils/language-c/pom.xml @@ -53,6 +53,11 @@ <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/CLanguageTemplateHelper.java b/build-utils/language-c/src/main/java/org/apache/plc4x/language/c/CLanguageTemplateHelper.java index bdcf18b..049f524 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,6 +18,8 @@ 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.plc4x.plugins.codegenerator.protocol.freemarker.FreemarkerLanguageTemplateHelper; import org.apache.plc4x.plugins.codegenerator.types.definitions.ComplexTypeDefinition; @@ -25,12 +27,15 @@ import org.apache.plc4x.plugins.codegenerator.types.definitions.DataIoTypeDefini import org.apache.plc4x.plugins.codegenerator.types.definitions.EnumTypeDefinition; import org.apache.plc4x.plugins.codegenerator.types.definitions.TypeDefinition; import org.apache.plc4x.plugins.codegenerator.types.enums.EnumValue; +import org.apache.plc4x.plugins.codegenerator.types.fields.ArrayField; import org.apache.plc4x.plugins.codegenerator.types.fields.PropertyField; import org.apache.plc4x.plugins.codegenerator.types.fields.TypedField; import org.apache.plc4x.plugins.codegenerator.types.references.ComplexTypeReference; import org.apache.plc4x.plugins.codegenerator.types.references.FloatTypeReference; 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 sun.tools.tree.ArrayExpression; import java.util.*; @@ -155,9 +160,28 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper case BIT: return "bool"; case UINT: - return "unsigned int"; - case INT: - return "int"; + case INT: { + StringBuilder sb = new StringBuilder(); + if(simpleTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT) { + sb.append("u"); + } + if(simpleTypeReference.getSizeInBits() % 64 == 0) { + sb.append("int64_t"); + } else if(simpleTypeReference.getSizeInBits() % 32 == 0) { + sb.append("int32_t"); + } else if(simpleTypeReference.getSizeInBits() % 16 == 0) { + sb.append("int16_t"); + } else if(simpleTypeReference.getSizeInBits() % 8 == 0) { + sb.append("int8_t"); + } else { + if(simpleTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.UINT) { + // We already have the "u" in there ... + sb.append("nsigned "); + } + sb.append("int"); + } + return sb.toString(); + } case FLOAT: FloatTypeReference floatTypeReference = (FloatTypeReference) simpleTypeReference; int sizeInBits = ((floatTypeReference.getBaseType() == SimpleTypeReference.SimpleBaseType.FLOAT) ? 1 : 0) + @@ -186,6 +210,20 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper } } + public String getLoopExpressionSuffix(TypedField field) { + if(field instanceof ArrayField) { + ArrayField arrayField = (ArrayField) field; + if(arrayField.getLoopType() == ArrayField.LoopType.COUNT) { + Term countTerm = arrayField.getLoopExpression(); + if (isFixedValueExpression(countTerm)) { + int evaluatedCount = evaluateFixedValueExpression(countTerm); + return "[" + evaluatedCount +"]"; + } + } + } + return ""; + } + /** * Ge the type-size suffix in case of simple types. * @@ -201,8 +239,18 @@ public class CLanguageTemplateHelper implements FreemarkerLanguageTemplateHelper return " : 1"; case UINT: case INT: + // If the bit-size is exactly one of the built-in tpye-sizes, omit the suffix. + if((simpleTypeReference.getSizeInBits() == 8) || (simpleTypeReference.getSizeInBits() == 16) || + (simpleTypeReference.getSizeInBits() == 32) || (simpleTypeReference.getSizeInBits() == 64)) { + return ""; + } + return " : " + simpleTypeReference.getSizeInBits(); case FLOAT: case UFLOAT: + // If the bit-size is exactly one of the built-in tpye-sizes, omit the suffix. + if((simpleTypeReference.getSizeInBits() == 32) || (simpleTypeReference.getSizeInBits() == 64)) { + return ""; + } return " : " + simpleTypeReference.getSizeInBits(); case STRING: case TIME: @@ -274,4 +322,61 @@ 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 ""; + } + } 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 a91263c..aec596a 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 @@ -42,6 +42,7 @@ extern "C" { #endif #include <stdbool.h> +#include <stdint.h> <#if helper.getComplexTypeReferencesInFields()?has_content> <#list helper.getComplexTypeReferencesInFields() as complexType> #include "${helper.camelCaseToSnakeCase(complexType.getName())}.h" @@ -50,7 +51,7 @@ extern "C" { struct plc4c_${helper.getCTypeName(type.name)} { <#list type.allPropertyFields as field> - ${helper.getLanguageTypeNameForField(field)}<#if field.loopType??>/*[] TODO Implement this differently */</#if> ${helper.camelCaseToSnakeCase(field.name)}${helper.getTypeSizeForField(field)}; + ${helper.getLanguageTypeNameForField(field)} ${helper.camelCaseToSnakeCase(field.name)}${helper.getTypeSizeForField(field)}<#if field.loopType??>${helper.getLoopExpressionSuffix(field)}</#if>; </#list> }; typedef struct plc4c_${helper.getCTypeName(type.name)} plc4c_${helper.getCTypeName(type.name)};