Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice')
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/Main.java584
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend532
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend630
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CTranslationProvider.java320
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/DataClassGen.xtend240
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/Initialization.xtend196
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/MainGen.xtend106
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeGen.xtend1444
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeRunnerGen.xtend210
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ProtocolClassGen.xtend774
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend182
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/Validator.java52
-rw-r--r--plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/setup/GeneratorModule.java106
13 files changed, 2688 insertions, 2688 deletions
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/Main.java b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/Main.java
index 4c2ee673b..9b86b706c 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/Main.java
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/Main.java
@@ -1,292 +1,292 @@
-/*******************************************************************************
- * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c;
-
-import java.util.ArrayList;
-import java.util.List;
-
-import org.eclipse.emf.common.EMFPlugin;
-import org.eclipse.etrice.core.etmap.util.ETMapUtil;
-import org.eclipse.etrice.core.genmodel.etricegen.Root;
-import org.eclipse.etrice.generator.base.AbstractGenerator;
-import org.eclipse.etrice.generator.base.GlobalGeneratorSettings;
-import org.eclipse.etrice.generator.base.IDataConfiguration;
-import org.eclipse.etrice.generator.base.IncrementalGenerationFileIo;
-import org.eclipse.etrice.generator.c.gen.Validator;
-import org.eclipse.etrice.generator.c.setup.GeneratorModule;
-import org.eclipse.etrice.generator.generic.RoomExtensions;
-import org.eclipse.xtext.generator.IGenerator;
-import org.eclipse.etrice.core.etmap.ETMapStandaloneSetup;
-import org.eclipse.etrice.core.etphys.ETPhysStandaloneSetup;
-
-import com.google.inject.Inject;
-
-/**
- * This class is implementing the eTrice C generator.
- *
- * <p>
- * It is based on the {@link org.eclipse.etrice.generator.base.AbstractGenerator AbstractGenerator}
- * and is a plain Java program with a main method and command line options.
- * </p>
- * <p>
- * It can be called using the launcher (see plug-in org.eclipse.etrice.generator.launch.c, i.e. using a
- * launch configuration (Run or Debug) which allows to configure command line options).
- * </p>
- * <p>
- * Alternatively it can be called from the command line as Java application. In this case the following jars
- * have to be on the class path:
- * <ul>
- * <li>org.eclipse.etrice.core.room</li>
- * <li>org.eclipse.etrice.core.genmodel</li>
- * <li>org.eclipse.etrice.generator</li>
- * <li>org.eclipse.emf.ecore</li>
- * <li>org.eclipse.emf.common</li>
- * <li>org.eclipse.emf.ecore.xmi</li>
- * <li>org.eclipse.xtext</li>
- * <li>org.eclipse.equinox.common</li>
- * <li>org.eclipse.xtext.util</li>
- * <li>org.eclipse.xtend.lib</li>
- * <li>org.eclipse.xtext.xbase.lib</li>
- * <li>org.apache.log4j</li>
- * <li>org.antlr.runtime</li>
- * <li>com.google.inject</li>
- * <li>com.google.guava</li>
- * <li>javax.inject</li>
- * </ul>
- * </p>
- *
- * @author Henrik Rentz-Reichert
- *
- */
-public class Main extends AbstractGenerator {
-
- public static final String OPTION_LIB = "-lib";
- public static final String OPTION_NOEXIT = "-noexit";
- public static final String OPTION_GEN_INST_DIAG = "-genInstDiag";
- public static final String OPTION_SAVE_GEN_MODEL = "-saveGenModel";
- public static final String OPTION_GEN_INCREMENTAL = "-inc";
- public static final String OPTION_GEN_DIR = "-genDir";
- public static final String OPTION_GEN_INFO_DIR = "-genInfoDir";
- public static final String OPTION_GEN_DOC_DIR = "-genDocDir";
- public static final String OPTION_DEBUG = "-debug";
- public static final String OPTION_MSC = "-msc_instr";
- public static final String OPTION_VERBOSE_RT = "-gen_as_verbose";
-
- /**
- * print usage message to stderr
- */
- private static void printUsage() {
- output.println(Main.class.getName()+" [-saveGenModel <genmodel path>] [-genInstDiag] [-lib] [-inc] [-debug] [-genDir <generation directory>] [-genInfoDir <generation info directory>] [-genInfoDir <gen documentation directory>] <list of model file paths>");
- output.println(" <list of model file paths> # model file paths may be specified as");
- output.println(" # e.g. C:\\path\\to\\model\\mymodel.room");
- output.println(" -saveGenModel <genmodel path> # if specified the generator model will be saved to this location");
- output.println(" -genInstDiag # if specified an instance diagram is created for each subsystem");
- output.println(" -lib # if specified all classes are generated and no instances");
- output.println(" -noexit # if specified the JVM is not exited");
- output.println(" -inc # if specified the generation is incremental");
- output.println(" -genDir <generation directory> # the directory for generated files");
- output.println(" -genInfoDir <generation info dir> # the directory for generated info files");
- output.println(" -genDocDir <gen documentation dir> # the directory for generated documentation files");
- }
-
- public static void main(String[] args) {
- int ret = createAndRunGenerator(new GeneratorModule(), args);
- if (isTerminateOnError() && ret!=GENERATOR_OK)
- System.exit(ret);
- }
-
- @Inject
- private IGenerator mainGenerator;
-
- @Inject
- protected org.eclipse.etrice.generator.doc.gen.MainGen mainDocGenerator;
-
- @Inject
- private Validator validator;
-
- @Inject
- protected IDataConfiguration dataConfig;
-
-
- public int runGenerator(String[] args) {
- if (args.length == 0) {
- return usageError("no arguments!");
- }
-
- // setting defaults
- String genModelPath = null;
- List<String> uriList = new ArrayList<String>();
- boolean genInstDiag = false;
- boolean asLibrary = false;
- boolean debug = false;
- IncrementalGenerationFileIo.setGenerateIncremental(false);
- RoomExtensions.setDefaultGenDir();
- RoomExtensions.setDefaultGenInfoDir();
- RoomExtensions.setDefaultGenDocDir();
-
- // parsing arguments
- for (int i=0; i<args.length; ++i) {
- if (args[i].equals(OPTION_SAVE_GEN_MODEL)) {
- if (++i<args.length) {
- genModelPath = args[i]+"/genmodel.egm";
- }
- else {
- return usageError(OPTION_SAVE_GEN_MODEL+" needs path");
- }
- }
- else if (args[i].equals(OPTION_GEN_DIR)) {
- if (++i<args.length) {
- RoomExtensions.setGenDir(args[i]);
- }
- else {
- return usageError(OPTION_GEN_DIR+" needs directory");
- }
- }
- else if (args[i].equals(OPTION_GEN_INFO_DIR)) {
- if (++i<args.length) {
- RoomExtensions.setGenInfoDir(args[i]);
- }
- else {
- return usageError(OPTION_GEN_INFO_DIR+" needs directory");
- }
- }
- else if (args[i].equals(OPTION_GEN_DOC_DIR)) {
- if (++i<args.length) {
- RoomExtensions.setGenDocDir(args[i]);
- }
- else {
- return usageError(OPTION_GEN_DOC_DIR+" needs directory");
- }
- }
- else if (args[i].equals(OPTION_GEN_INCREMENTAL)) {
- IncrementalGenerationFileIo.setGenerateIncremental(true);
- }
- else if (args[i].equals(OPTION_GEN_INST_DIAG)) {
- genInstDiag = true;
- }
- else if (args[i].equals(OPTION_LIB)) {
- asLibrary = true;
- }
- else if (args[i].equals(OPTION_NOEXIT)) {
- setTerminateOnError(false);
- }
- else if (args[i].equals(OPTION_MSC)) {
- GlobalGeneratorSettings.setGenerateMSCInstrumentation(true);
- }
- else if (args[i].equals(OPTION_VERBOSE_RT)) {
- GlobalGeneratorSettings.setGenerateWithVerboseOutput(true);
- }
- else if (args[i].equals(OPTION_DEBUG)) {
- debug = true;
- }
- else {
- uriList.add(args[i]);
- }
- }
-
- setupRoomModel();
- dataConfig.doSetup();
- setupMappingModel();
- setupPhysicalModel();
-
- if (!runGenerator(uriList, genModelPath, genInstDiag, asLibrary, debug))
- return GENERATOR_ERROR;
-
- return GENERATOR_OK;
- }
-
- /**
- * setup the eTrice mapping model plug-in
- */
- protected void setupMappingModel() {
- if (!EMFPlugin.IS_ECLIPSE_RUNNING) {
- ETMapStandaloneSetup.doSetup();
- }
- }
-
- /**
- * setup the eTrice mapping model plug-in
- */
- protected void setupPhysicalModel() {
- if (!EMFPlugin.IS_ECLIPSE_RUNNING)
- ETPhysStandaloneSetup.doSetup();
- }
-
- protected int usageError(String text) {
- logger.logError(Main.class.getName() + " - aborting: " + text, null);
- printUsage();
- return GENERATOR_ERROR;
- }
-
- protected boolean runGenerator(List<String> uriList, String genModelPath, boolean genInstDiag, boolean asLibrary, boolean debug) {
- if (!loadModels(uriList)) {
- logger.logInfo("loading of models failed");
- logger.logError("-- terminating", null);
- return false;
- }
-
- if (!validateModels()) {
- logger.logInfo("validation failed");
- logger.logError("-- terminating", null);
- return false;
- }
-
- if (!dataConfig.setResources(getResourceSet(), logger)) {
- logger.logInfo("configuration errors");
- logger.logError("-- terminating", null);
- return false;
- }
-
- Root genModel = createGeneratorModel(asLibrary, genModelPath);
- if (diagnostician.isFailed() || genModel==null) {
- logger.logInfo("errors during build of generator model");
- logger.logError("-- terminating", null);
- return false;
- }
-
- if (!validator.validate(genModel)) {
- logger.logInfo("validation failed during build of generator model");
- logger.logError("-- terminating", null);
- return false;
- }
-
- ETMapUtil.processModels(genModel, getResourceSet(), diagnostician);
- if (debug) {
- logger.logInfo("-- begin dump of mappings");
- logger.logInfo(ETMapUtil.dumpMappings());
- logger.logInfo("-- end dump of mappings");
- }
- if (diagnostician.isFailed() || genModel==null) {
- logger.logInfo("errors in mapping");
- logger.logError("-- terminating", null);
- return false;
- }
-
- logger.logInfo("-- starting code generation");
- fileAccess.setOutputPath("src-gen/");
- mainGenerator.doGenerate(genModel.eResource(), fileAccess);
-
- if (genInstDiag) {
- mainDocGenerator.doGenerate(genModel);
- }
-
- if (diagnostician.isFailed()) {
- logger.logInfo("errors during code generation");
- logger.logError("-- terminating", null);
- return false;
- }
- logger.logInfo("-- finished code generation");
-
- return true;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.common.EMFPlugin;
+import org.eclipse.etrice.core.etmap.util.ETMapUtil;
+import org.eclipse.etrice.core.genmodel.etricegen.Root;
+import org.eclipse.etrice.generator.base.AbstractGenerator;
+import org.eclipse.etrice.generator.base.GlobalGeneratorSettings;
+import org.eclipse.etrice.generator.base.IDataConfiguration;
+import org.eclipse.etrice.generator.base.IncrementalGenerationFileIo;
+import org.eclipse.etrice.generator.c.gen.Validator;
+import org.eclipse.etrice.generator.c.setup.GeneratorModule;
+import org.eclipse.etrice.generator.generic.RoomExtensions;
+import org.eclipse.xtext.generator.IGenerator;
+import org.eclipse.etrice.core.etmap.ETMapStandaloneSetup;
+import org.eclipse.etrice.core.etphys.ETPhysStandaloneSetup;
+
+import com.google.inject.Inject;
+
+/**
+ * This class is implementing the eTrice C generator.
+ *
+ * <p>
+ * It is based on the {@link org.eclipse.etrice.generator.base.AbstractGenerator AbstractGenerator}
+ * and is a plain Java program with a main method and command line options.
+ * </p>
+ * <p>
+ * It can be called using the launcher (see plug-in org.eclipse.etrice.generator.launch.c, i.e. using a
+ * launch configuration (Run or Debug) which allows to configure command line options).
+ * </p>
+ * <p>
+ * Alternatively it can be called from the command line as Java application. In this case the following jars
+ * have to be on the class path:
+ * <ul>
+ * <li>org.eclipse.etrice.core.room</li>
+ * <li>org.eclipse.etrice.core.genmodel</li>
+ * <li>org.eclipse.etrice.generator</li>
+ * <li>org.eclipse.emf.ecore</li>
+ * <li>org.eclipse.emf.common</li>
+ * <li>org.eclipse.emf.ecore.xmi</li>
+ * <li>org.eclipse.xtext</li>
+ * <li>org.eclipse.equinox.common</li>
+ * <li>org.eclipse.xtext.util</li>
+ * <li>org.eclipse.xtend.lib</li>
+ * <li>org.eclipse.xtext.xbase.lib</li>
+ * <li>org.apache.log4j</li>
+ * <li>org.antlr.runtime</li>
+ * <li>com.google.inject</li>
+ * <li>com.google.guava</li>
+ * <li>javax.inject</li>
+ * </ul>
+ * </p>
+ *
+ * @author Henrik Rentz-Reichert
+ *
+ */
+public class Main extends AbstractGenerator {
+
+ public static final String OPTION_LIB = "-lib";
+ public static final String OPTION_NOEXIT = "-noexit";
+ public static final String OPTION_GEN_INST_DIAG = "-genInstDiag";
+ public static final String OPTION_SAVE_GEN_MODEL = "-saveGenModel";
+ public static final String OPTION_GEN_INCREMENTAL = "-inc";
+ public static final String OPTION_GEN_DIR = "-genDir";
+ public static final String OPTION_GEN_INFO_DIR = "-genInfoDir";
+ public static final String OPTION_GEN_DOC_DIR = "-genDocDir";
+ public static final String OPTION_DEBUG = "-debug";
+ public static final String OPTION_MSC = "-msc_instr";
+ public static final String OPTION_VERBOSE_RT = "-gen_as_verbose";
+
+ /**
+ * print usage message to stderr
+ */
+ private static void printUsage() {
+ output.println(Main.class.getName()+" [-saveGenModel <genmodel path>] [-genInstDiag] [-lib] [-inc] [-debug] [-genDir <generation directory>] [-genInfoDir <generation info directory>] [-genInfoDir <gen documentation directory>] <list of model file paths>");
+ output.println(" <list of model file paths> # model file paths may be specified as");
+ output.println(" # e.g. C:\\path\\to\\model\\mymodel.room");
+ output.println(" -saveGenModel <genmodel path> # if specified the generator model will be saved to this location");
+ output.println(" -genInstDiag # if specified an instance diagram is created for each subsystem");
+ output.println(" -lib # if specified all classes are generated and no instances");
+ output.println(" -noexit # if specified the JVM is not exited");
+ output.println(" -inc # if specified the generation is incremental");
+ output.println(" -genDir <generation directory> # the directory for generated files");
+ output.println(" -genInfoDir <generation info dir> # the directory for generated info files");
+ output.println(" -genDocDir <gen documentation dir> # the directory for generated documentation files");
+ }
+
+ public static void main(String[] args) {
+ int ret = createAndRunGenerator(new GeneratorModule(), args);
+ if (isTerminateOnError() && ret!=GENERATOR_OK)
+ System.exit(ret);
+ }
+
+ @Inject
+ private IGenerator mainGenerator;
+
+ @Inject
+ protected org.eclipse.etrice.generator.doc.gen.MainGen mainDocGenerator;
+
+ @Inject
+ private Validator validator;
+
+ @Inject
+ protected IDataConfiguration dataConfig;
+
+
+ public int runGenerator(String[] args) {
+ if (args.length == 0) {
+ return usageError("no arguments!");
+ }
+
+ // setting defaults
+ String genModelPath = null;
+ List<String> uriList = new ArrayList<String>();
+ boolean genInstDiag = false;
+ boolean asLibrary = false;
+ boolean debug = false;
+ IncrementalGenerationFileIo.setGenerateIncremental(false);
+ RoomExtensions.setDefaultGenDir();
+ RoomExtensions.setDefaultGenInfoDir();
+ RoomExtensions.setDefaultGenDocDir();
+
+ // parsing arguments
+ for (int i=0; i<args.length; ++i) {
+ if (args[i].equals(OPTION_SAVE_GEN_MODEL)) {
+ if (++i<args.length) {
+ genModelPath = args[i]+"/genmodel.egm";
+ }
+ else {
+ return usageError(OPTION_SAVE_GEN_MODEL+" needs path");
+ }
+ }
+ else if (args[i].equals(OPTION_GEN_DIR)) {
+ if (++i<args.length) {
+ RoomExtensions.setGenDir(args[i]);
+ }
+ else {
+ return usageError(OPTION_GEN_DIR+" needs directory");
+ }
+ }
+ else if (args[i].equals(OPTION_GEN_INFO_DIR)) {
+ if (++i<args.length) {
+ RoomExtensions.setGenInfoDir(args[i]);
+ }
+ else {
+ return usageError(OPTION_GEN_INFO_DIR+" needs directory");
+ }
+ }
+ else if (args[i].equals(OPTION_GEN_DOC_DIR)) {
+ if (++i<args.length) {
+ RoomExtensions.setGenDocDir(args[i]);
+ }
+ else {
+ return usageError(OPTION_GEN_DOC_DIR+" needs directory");
+ }
+ }
+ else if (args[i].equals(OPTION_GEN_INCREMENTAL)) {
+ IncrementalGenerationFileIo.setGenerateIncremental(true);
+ }
+ else if (args[i].equals(OPTION_GEN_INST_DIAG)) {
+ genInstDiag = true;
+ }
+ else if (args[i].equals(OPTION_LIB)) {
+ asLibrary = true;
+ }
+ else if (args[i].equals(OPTION_NOEXIT)) {
+ setTerminateOnError(false);
+ }
+ else if (args[i].equals(OPTION_MSC)) {
+ GlobalGeneratorSettings.setGenerateMSCInstrumentation(true);
+ }
+ else if (args[i].equals(OPTION_VERBOSE_RT)) {
+ GlobalGeneratorSettings.setGenerateWithVerboseOutput(true);
+ }
+ else if (args[i].equals(OPTION_DEBUG)) {
+ debug = true;
+ }
+ else {
+ uriList.add(args[i]);
+ }
+ }
+
+ setupRoomModel();
+ dataConfig.doSetup();
+ setupMappingModel();
+ setupPhysicalModel();
+
+ if (!runGenerator(uriList, genModelPath, genInstDiag, asLibrary, debug))
+ return GENERATOR_ERROR;
+
+ return GENERATOR_OK;
+ }
+
+ /**
+ * setup the eTrice mapping model plug-in
+ */
+ protected void setupMappingModel() {
+ if (!EMFPlugin.IS_ECLIPSE_RUNNING) {
+ ETMapStandaloneSetup.doSetup();
+ }
+ }
+
+ /**
+ * setup the eTrice mapping model plug-in
+ */
+ protected void setupPhysicalModel() {
+ if (!EMFPlugin.IS_ECLIPSE_RUNNING)
+ ETPhysStandaloneSetup.doSetup();
+ }
+
+ protected int usageError(String text) {
+ logger.logError(Main.class.getName() + " - aborting: " + text, null);
+ printUsage();
+ return GENERATOR_ERROR;
+ }
+
+ protected boolean runGenerator(List<String> uriList, String genModelPath, boolean genInstDiag, boolean asLibrary, boolean debug) {
+ if (!loadModels(uriList)) {
+ logger.logInfo("loading of models failed");
+ logger.logError("-- terminating", null);
+ return false;
+ }
+
+ if (!validateModels()) {
+ logger.logInfo("validation failed");
+ logger.logError("-- terminating", null);
+ return false;
+ }
+
+ if (!dataConfig.setResources(getResourceSet(), logger)) {
+ logger.logInfo("configuration errors");
+ logger.logError("-- terminating", null);
+ return false;
+ }
+
+ Root genModel = createGeneratorModel(asLibrary, genModelPath);
+ if (diagnostician.isFailed() || genModel==null) {
+ logger.logInfo("errors during build of generator model");
+ logger.logError("-- terminating", null);
+ return false;
+ }
+
+ if (!validator.validate(genModel)) {
+ logger.logInfo("validation failed during build of generator model");
+ logger.logError("-- terminating", null);
+ return false;
+ }
+
+ ETMapUtil.processModels(genModel, getResourceSet(), diagnostician);
+ if (debug) {
+ logger.logInfo("-- begin dump of mappings");
+ logger.logInfo(ETMapUtil.dumpMappings());
+ logger.logInfo("-- end dump of mappings");
+ }
+ if (diagnostician.isFailed() || genModel==null) {
+ logger.logInfo("errors in mapping");
+ logger.logError("-- terminating", null);
+ return false;
+ }
+
+ logger.logInfo("-- starting code generation");
+ fileAccess.setOutputPath("src-gen/");
+ mainGenerator.doGenerate(genModel.eResource(), fileAccess);
+
+ if (genInstDiag) {
+ mainDocGenerator.doGenerate(genModel);
+ }
+
+ if (diagnostician.isFailed()) {
+ logger.logInfo("errors during code generation");
+ logger.logError("-- terminating", null);
+ return false;
+ }
+ logger.logInfo("-- finished code generation");
+
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
index bec589e94..1ad59dcc9 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ActorClassGen.xtend
@@ -1,266 +1,266 @@
-/*******************************************************************************
- * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- * Thomas Schuetz (changed for C code generator)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import org.eclipse.etrice.core.genmodel.base.ILogger
-import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass
-import org.eclipse.etrice.core.genmodel.etricegen.Root
-import org.eclipse.etrice.core.room.ActorCommunicationType
-import org.eclipse.etrice.core.room.CommunicationType
-import org.eclipse.etrice.core.room.ProtocolClass
-import org.eclipse.etrice.generator.base.IGeneratorFileIo
-import org.eclipse.etrice.generator.generic.GenericActorClassGenerator
-import org.eclipse.etrice.generator.generic.ILanguageExtension
-import org.eclipse.etrice.generator.generic.ProcedureHelpers
-import org.eclipse.etrice.generator.generic.RoomExtensions
-
-import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
-import org.eclipse.etrice.generator.base.GlobalGeneratorSettings
-
-@Singleton
-class ActorClassGen extends GenericActorClassGenerator {
-
- @Inject protected extension RoomExtensions
- @Inject extension CExtensions
- @Inject extension ProcedureHelpers
- @Inject extension StateMachineGen
-
- @Inject protected ILanguageExtension langExt
- @Inject IGeneratorFileIo fileIO
- @Inject ILogger logger
-
- def doGenerate(Root root) {
- for (xpac: root.xpActorClasses) {
- val path = xpac.actorClass.generationTargetPath+xpac.actorClass.getPath
- val infopath = xpac.actorClass.generationInfoPath+xpac.actorClass.getPath
- var file = xpac.actorClass.getCHeaderFileName
-
- // header file
- fileIO.generateFile("generating ActorClass header", path, infopath, file, root.generateHeaderFile(xpac))
-
- // source file
- if (xpac.actorClass.isBehaviorAnnotationPresent("BehaviorManual")) {
- logger.logInfo("omitting ActorClass source for '"+xpac.actorClass.name+"' since @BehaviorManual is specified")
- }
- else {
- file = xpac.actorClass.getCSourceFileName
- fileIO.generateFile("generating ActorClass source", path, infopath, file, root.generateSourceFile(xpac))
- }
- }
- }
-
- def private generateHeaderFile(Root root, ExpandedActorClass xpac) {
- val ac = xpac.actorClass
- val eventPorts = ac.allEndPorts.filter(p|(p.protocol as ProtocolClass).commType==CommunicationType::EVENT_DRIVEN)
- val sendPorts = ac.allEndPorts.filter(p|(p.protocol as ProtocolClass).commType==CommunicationType::DATA_DRIVEN && p.conjugated)
- val recvPorts = ac.allEndPorts.filter(p|(p.protocol as ProtocolClass).commType==CommunicationType::DATA_DRIVEN && !p.conjugated)
- val dataDriven = ac.commType==ActorCommunicationType::DATA_DRIVEN
- val async = ac.commType==ActorCommunicationType::ASYNCHRONOUS
- val hasConstData = !(eventPorts.empty && recvPorts.empty && ac.allSAPs.empty && ac.allServiceImplementations.empty)
- || GlobalGeneratorSettings::generateMSCInstrumentation
- val hasVarData = !(sendPorts.empty && ac.allAttributes.empty && xpac.stateMachine.empty && !hasConstData)
-
- '''
- /**
- * @author generated by eTrice
- *
- * Header File of ActorClass «ac.name»
- *
- */
-
- «generateIncludeGuardBegin(ac)»
-
- #include "etDatatypes.h"
- #include "messaging/etMessage.h"
-
- «FOR dataClass : root.getReferencedDataClasses(ac)»
- #include «dataClass.includePath»
- «ENDFOR»
- «FOR pc : root.getReferencedProtocolClasses(ac)»
- #include «pc.includePath»
- «ENDFOR»
-
- «ac.userCode(1)»
-
- typedef struct «ac.name» «ac.name»;
-
- /* const part of ActorClass (ROM) */
- «IF hasConstData»
- typedef struct «ac.name»_const {
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- const char* instName;
-
- «ENDIF»
- /* simple ports */
- «FOR ep : eventPorts»
- «IF ep.multiplicity==1»
- const «ep.getPortClassName()» «ep.name»;
- «ENDIF»
- «ENDFOR»
-
- /* data receive ports */
- «FOR ep : recvPorts»
- «IF ep.multiplicity==1»
- const «ep.getPortClassName()» «ep.name»;
- «ENDIF»
- «ENDFOR»
-
- /* saps */
- «FOR sap: ac.allSAPs»
- const «sap.getPortClassName()» «sap.name»;
- «ENDFOR»
-
- /* replicated ports */
- «FOR ep : ac.allEndPorts»
- «IF ep.multiplicity!=1»
- const etReplPort «ep.name»;
- «ENDIF»
- «ENDFOR»
-
- /* services */
- «FOR svc : ac.allServiceImplementations»
- const etReplPort «svc.spp.name»;
- «ENDFOR»
- } «ac.name»_const;
- «ELSE»
- /* this actor class has no ports and thus no constant data */
- «ENDIF»
-
- «IF !xpac.stateMachine.empty»
-
- «xpac.genHeaderConstants»
- «ENDIF»
-
- /* variable part of ActorClass (RAM) */
- «IF hasVarData»
- struct «ac.name» {
- «IF hasConstData»
- const «ac.name»_const* const constData;
-
- «ENDIF»
- /* data send ports */
- «FOR ep : sendPorts»
- «IF ep.multiplicity==1»
- «ep.getPortClassName()» «ep.name»;
- «ENDIF»
- «ENDFOR»
-
- «ac.allAttributes.attributes»
-
- «IF !xpac.stateMachine.empty»
-
- «xpac.genDataMembers»
- «ENDIF»
- };
- «ELSE»
- struct «ac.name» {
- /* This actor class has no data at all.
- But the private actor instance data is passed to all life cycle functions.
- By introducing the dummy data we keep this case simple
- */
- int dummy;
- };
- «ENDIF»
-
- void «ac.name»_init(«ac.name»* self);
-
- void «ac.name»_receiveMessage(void* self, const void* ifitem, const etMessage* msg);
-
- «IF dataDriven || async»
- void «ac.name»_execute(«ac.name»* self);
- «ENDIF»
-
- «ac.operations.operationsDeclaration(ac.name)»
-
- «ac.userCode(2)»
-
- «generateIncludeGuardEnd(ac)»
-
- '''
- }
-
- def private generateSourceFile(Root root, ExpandedActorClass xpac) {
- val ac = xpac.actorClass
- val async = ac.commType==ActorCommunicationType::ASYNCHRONOUS
- val eventDriven = ac.commType==ActorCommunicationType::EVENT_DRIVEN
- val dataDriven = ac.commType==ActorCommunicationType::DATA_DRIVEN
- val handleEvents = async || eventDriven
-
- '''
- /**
- * @author generated by eTrice
- *
- * Source File of ActorClass «ac.name»
- *
- */
-
- #include "«ac.getCHeaderFileName»"
-
- #include "modelbase/etActor.h"
- #include "debugging/etLogger.h"
- #include "debugging/etMSCLogger.h"
- #include "etUnit/etUnit.h"
- #include "osal/etMemory.h"
-
- «FOR pc : root.getReferencedProtocolClasses(ac)»
- #include «pc.includePath»
- «ENDFOR»
-
- «ac.userCode(3)»
-
- /* interface item IDs */
- «xpac.genInterfaceItemConstants»
-
- «IF !xpac.stateMachine.empty»
- «xpac.genStateMachine()»
- «ENDIF»
-
- void «ac.name»_init(«ac.name»* self){
- ET_MSC_LOGGER_SYNC_ENTRY("«ac.name»", "init")
- «IF !xpac.stateMachine.empty»
- «xpac.genInitialization»
- «ENDIF»
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
-
- void «ac.name»_receiveMessage(void* self, const void* ifitem, const etMessage* msg){
- ET_MSC_LOGGER_SYNC_ENTRY("«ac.name»", "_receiveMessage")
- «IF !xpac.stateMachine.empty»
-
- «langExt.operationScope(ac.name, false)»receiveEvent(self«IF handleEvents», (etPort*)ifitem, msg->evtID, (void*)(((char*)msg)+MEM_CEIL(sizeof(etMessage)))«ENDIF»);
- «ENDIF»
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- «IF dataDriven || async»
- void «ac.name»_execute(«ac.name»* self) {
- ET_MSC_LOGGER_SYNC_ENTRY("«ac.name»", "_execute")
- «IF !xpac.stateMachine.empty»
-
- «langExt.operationScope(ac.name, false)»receiveEvent(self«IF handleEvents», NULL, 0, NULL«ENDIF»);
- «ENDIF»
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
- «ENDIF»
-
- «ac.operationsImplementation»
-
- '''
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ * Thomas Schuetz (changed for C code generator)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import org.eclipse.etrice.core.genmodel.base.ILogger
+import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass
+import org.eclipse.etrice.core.genmodel.etricegen.Root
+import org.eclipse.etrice.core.room.ActorCommunicationType
+import org.eclipse.etrice.core.room.CommunicationType
+import org.eclipse.etrice.core.room.ProtocolClass
+import org.eclipse.etrice.generator.base.IGeneratorFileIo
+import org.eclipse.etrice.generator.generic.GenericActorClassGenerator
+import org.eclipse.etrice.generator.generic.ILanguageExtension
+import org.eclipse.etrice.generator.generic.ProcedureHelpers
+import org.eclipse.etrice.generator.generic.RoomExtensions
+
+import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
+import org.eclipse.etrice.generator.base.GlobalGeneratorSettings
+
+@Singleton
+class ActorClassGen extends GenericActorClassGenerator {
+
+ @Inject protected extension RoomExtensions
+ @Inject extension CExtensions
+ @Inject extension ProcedureHelpers
+ @Inject extension StateMachineGen
+
+ @Inject protected ILanguageExtension langExt
+ @Inject IGeneratorFileIo fileIO
+ @Inject ILogger logger
+
+ def doGenerate(Root root) {
+ for (xpac: root.xpActorClasses) {
+ val path = xpac.actorClass.generationTargetPath+xpac.actorClass.getPath
+ val infopath = xpac.actorClass.generationInfoPath+xpac.actorClass.getPath
+ var file = xpac.actorClass.getCHeaderFileName
+
+ // header file
+ fileIO.generateFile("generating ActorClass header", path, infopath, file, root.generateHeaderFile(xpac))
+
+ // source file
+ if (xpac.actorClass.isBehaviorAnnotationPresent("BehaviorManual")) {
+ logger.logInfo("omitting ActorClass source for '"+xpac.actorClass.name+"' since @BehaviorManual is specified")
+ }
+ else {
+ file = xpac.actorClass.getCSourceFileName
+ fileIO.generateFile("generating ActorClass source", path, infopath, file, root.generateSourceFile(xpac))
+ }
+ }
+ }
+
+ def private generateHeaderFile(Root root, ExpandedActorClass xpac) {
+ val ac = xpac.actorClass
+ val eventPorts = ac.allEndPorts.filter(p|(p.protocol as ProtocolClass).commType==CommunicationType::EVENT_DRIVEN)
+ val sendPorts = ac.allEndPorts.filter(p|(p.protocol as ProtocolClass).commType==CommunicationType::DATA_DRIVEN && p.conjugated)
+ val recvPorts = ac.allEndPorts.filter(p|(p.protocol as ProtocolClass).commType==CommunicationType::DATA_DRIVEN && !p.conjugated)
+ val dataDriven = ac.commType==ActorCommunicationType::DATA_DRIVEN
+ val async = ac.commType==ActorCommunicationType::ASYNCHRONOUS
+ val hasConstData = !(eventPorts.empty && recvPorts.empty && ac.allSAPs.empty && ac.allServiceImplementations.empty)
+ || GlobalGeneratorSettings::generateMSCInstrumentation
+ val hasVarData = !(sendPorts.empty && ac.allAttributes.empty && xpac.stateMachine.empty && !hasConstData)
+
+ '''
+ /**
+ * @author generated by eTrice
+ *
+ * Header File of ActorClass «ac.name»
+ *
+ */
+
+ «generateIncludeGuardBegin(ac)»
+
+ #include "etDatatypes.h"
+ #include "messaging/etMessage.h"
+
+ «FOR dataClass : root.getReferencedDataClasses(ac)»
+ #include «dataClass.includePath»
+ «ENDFOR»
+ «FOR pc : root.getReferencedProtocolClasses(ac)»
+ #include «pc.includePath»
+ «ENDFOR»
+
+ «ac.userCode(1)»
+
+ typedef struct «ac.name» «ac.name»;
+
+ /* const part of ActorClass (ROM) */
+ «IF hasConstData»
+ typedef struct «ac.name»_const {
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ const char* instName;
+
+ «ENDIF»
+ /* simple ports */
+ «FOR ep : eventPorts»
+ «IF ep.multiplicity==1»
+ const «ep.getPortClassName()» «ep.name»;
+ «ENDIF»
+ «ENDFOR»
+
+ /* data receive ports */
+ «FOR ep : recvPorts»
+ «IF ep.multiplicity==1»
+ const «ep.getPortClassName()» «ep.name»;
+ «ENDIF»
+ «ENDFOR»
+
+ /* saps */
+ «FOR sap: ac.allSAPs»
+ const «sap.getPortClassName()» «sap.name»;
+ «ENDFOR»
+
+ /* replicated ports */
+ «FOR ep : ac.allEndPorts»
+ «IF ep.multiplicity!=1»
+ const etReplPort «ep.name»;
+ «ENDIF»
+ «ENDFOR»
+
+ /* services */
+ «FOR svc : ac.allServiceImplementations»
+ const etReplPort «svc.spp.name»;
+ «ENDFOR»
+ } «ac.name»_const;
+ «ELSE»
+ /* this actor class has no ports and thus no constant data */
+ «ENDIF»
+
+ «IF !xpac.stateMachine.empty»
+
+ «xpac.genHeaderConstants»
+ «ENDIF»
+
+ /* variable part of ActorClass (RAM) */
+ «IF hasVarData»
+ struct «ac.name» {
+ «IF hasConstData»
+ const «ac.name»_const* const constData;
+
+ «ENDIF»
+ /* data send ports */
+ «FOR ep : sendPorts»
+ «IF ep.multiplicity==1»
+ «ep.getPortClassName()» «ep.name»;
+ «ENDIF»
+ «ENDFOR»
+
+ «ac.allAttributes.attributes»
+
+ «IF !xpac.stateMachine.empty»
+
+ «xpac.genDataMembers»
+ «ENDIF»
+ };
+ «ELSE»
+ struct «ac.name» {
+ /* This actor class has no data at all.
+ But the private actor instance data is passed to all life cycle functions.
+ By introducing the dummy data we keep this case simple
+ */
+ int dummy;
+ };
+ «ENDIF»
+
+ void «ac.name»_init(«ac.name»* self);
+
+ void «ac.name»_receiveMessage(void* self, const void* ifitem, const etMessage* msg);
+
+ «IF dataDriven || async»
+ void «ac.name»_execute(«ac.name»* self);
+ «ENDIF»
+
+ «ac.operations.operationsDeclaration(ac.name)»
+
+ «ac.userCode(2)»
+
+ «generateIncludeGuardEnd(ac)»
+
+ '''
+ }
+
+ def private generateSourceFile(Root root, ExpandedActorClass xpac) {
+ val ac = xpac.actorClass
+ val async = ac.commType==ActorCommunicationType::ASYNCHRONOUS
+ val eventDriven = ac.commType==ActorCommunicationType::EVENT_DRIVEN
+ val dataDriven = ac.commType==ActorCommunicationType::DATA_DRIVEN
+ val handleEvents = async || eventDriven
+
+ '''
+ /**
+ * @author generated by eTrice
+ *
+ * Source File of ActorClass «ac.name»
+ *
+ */
+
+ #include "«ac.getCHeaderFileName»"
+
+ #include "modelbase/etActor.h"
+ #include "debugging/etLogger.h"
+ #include "debugging/etMSCLogger.h"
+ #include "etUnit/etUnit.h"
+ #include "osal/etMemory.h"
+
+ «FOR pc : root.getReferencedProtocolClasses(ac)»
+ #include «pc.includePath»
+ «ENDFOR»
+
+ «ac.userCode(3)»
+
+ /* interface item IDs */
+ «xpac.genInterfaceItemConstants»
+
+ «IF !xpac.stateMachine.empty»
+ «xpac.genStateMachine()»
+ «ENDIF»
+
+ void «ac.name»_init(«ac.name»* self){
+ ET_MSC_LOGGER_SYNC_ENTRY("«ac.name»", "init")
+ «IF !xpac.stateMachine.empty»
+ «xpac.genInitialization»
+ «ENDIF»
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+
+ void «ac.name»_receiveMessage(void* self, const void* ifitem, const etMessage* msg){
+ ET_MSC_LOGGER_SYNC_ENTRY("«ac.name»", "_receiveMessage")
+ «IF !xpac.stateMachine.empty»
+
+ «langExt.operationScope(ac.name, false)»receiveEvent(self«IF handleEvents», (etPort*)ifitem, msg->evtID, (void*)(((char*)msg)+MEM_CEIL(sizeof(etMessage)))«ENDIF»);
+ «ENDIF»
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ «IF dataDriven || async»
+ void «ac.name»_execute(«ac.name»* self) {
+ ET_MSC_LOGGER_SYNC_ENTRY("«ac.name»", "_execute")
+ «IF !xpac.stateMachine.empty»
+
+ «langExt.operationScope(ac.name, false)»receiveEvent(self«IF handleEvents», NULL, 0, NULL«ENDIF»);
+ «ENDIF»
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+ «ENDIF»
+
+ «ac.operationsImplementation»
+
+ '''
+ }
+}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend
index 672d00e7d..7fc64191f 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CExtensions.xtend
@@ -1,315 +1,315 @@
-/*******************************************************************************
- * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
- * Thomas Schuetz (changed for C code generator)
- *
- *******************************************************************************/
-
-/*
- collection of convenience functions for code generation
-*/
-
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import java.util.List
-import org.eclipse.etrice.core.etphys.eTPhys.NodeRef
-import org.eclipse.etrice.core.genmodel.etricegen.IDiagnostician
-import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance
-import org.eclipse.etrice.core.room.Attribute
-import org.eclipse.etrice.core.room.DataClass
-import org.eclipse.etrice.core.room.DataType
-import org.eclipse.etrice.core.room.ExternalType
-import org.eclipse.etrice.core.room.LiteralType
-import org.eclipse.etrice.core.room.Message
-import org.eclipse.etrice.core.room.PrimitiveType
-import org.eclipse.etrice.core.room.RoomClass
-import org.eclipse.etrice.core.room.RoomModel
-import org.eclipse.etrice.core.room.VarDecl
-import org.eclipse.etrice.generator.generic.ILanguageExtension
-import org.eclipse.xtext.util.Pair
-
-import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
-
-@Singleton
-class CExtensions implements ILanguageExtension {
-
- @Inject IDiagnostician diagnostician
-
- override String getTypedDataDefinition(Message m) {
- generateArglistAndTypedData(m.data).get(1)
- }
-
- // in C no access levels can be defined
- override String accessLevelPrivate(){"static "}
- override String accessLevelProtected(){"static "}
- override String accessLevelPublic(){""}
-
- override String memberAccess(){"self->"}
- override String selfPointer(String classname, boolean hasArgs){
- classname+
- if (hasArgs)
- "* self, "
- else
- "* self"
- }
-
- override String selfPointer(boolean hasArgs) { if (hasArgs) "self, " else "self" }
-
- override String operationScope(String classname, boolean isDeclaration){classname+"_"}
-
- override String memberInDeclaration(String namespace, String member) {
- return namespace+"_"+member
- }
-
- override String memberInUse(String namespace, String member) {
- return namespace+"_"+member
- }
-
-
- //**** C-Specific
- /* TODO: move specific code elsewhere */
- // used
- def String getCHeaderFileName(RoomClass rc) {
- return rc.name+".h";
- }
-
- // used
- def String getCSourceFileName(RoomClass rc) {
- return rc.name+".c";
- }
-
- def String getInstSourceFileName(RoomClass rc) {
- return rc.name+"_Inst.h";
- }
-
- def String getDispSourceFileName(RoomClass rc) {
- return rc.name+"_Disp.h";
- }
-
- // used
- def String getCHeaderFileName(NodeRef nr, SubSystemInstance ssi) {
- return nr.name+"_"+ssi.name+".h";
- }
-
- def String getCSourceFileName(NodeRef nr, SubSystemInstance ssi) {
- return nr.name+"_"+ssi.name+".c";
- }
-
- def String getInstSourceFileName(NodeRef nr, SubSystemInstance ssi) {
- return nr.name+"_"+ssi.name+"_Inst.h";
- }
-
- def String getDispSourceFileName(NodeRef nr, SubSystemInstance ssi) {
- return nr.name+"_"+ssi.name+"_Disp.h";
- }
-
- def getIncludeGuardString(String filename){
- '''_«filename.toUpperCase»_H_'''
- }
-
- def generateIncludeGuardBegin(RoomClass rc) {
- val filename = (rc.eContainer as RoomModel).name.replaceAll("\\.","_")+"_"+rc.name
- filename.generateIncludeGuardBegin
- }
-
- def generateIncludeGuardEnd(RoomClass rc) {
- val filename = (rc.eContainer as RoomModel).name.replaceAll("\\.","_")+"_"+rc.name
- filename.generateIncludeGuardEnd
- }
-
- def generateIncludeGuardBegin(String filename) {
- '''
- #ifndef «filename.getIncludeGuardString»
- #define «filename.getIncludeGuardString»
- '''
- }
-
- def generateIncludeGuardEnd(String filename) {
- '''
- #endif /* «filename.getIncludeGuardString» */
- '''
- }
-
- override boolean usesInheritance() {
- return false
- }
-
- override boolean usesPointers() {
- return true
- }
-
- override String genEnumeration(String name, List<Pair<String, String>> entries) {
- if (entries.empty)
- return "/* empty enum not generated */"
-
- '''
- enum «name» {
- «FOR entry: entries SEPARATOR ","»
- «entry.first» = «entry.second»
- «ENDFOR»
- };
- '''.toString
- }
-
- override String booleanConstant(boolean b) {
- if (b) "TRUE" else "FALSE"
- }
-
- override String pointerLiteral() { "*" }
- override String nullPointer() { "NULL" }
- override String voidPointer() { "void*" }
-
- override String arrayDeclaration(String type, int size, String name, boolean isRef) {
- if (isRef){
- type+"* "+name+"["+size+"]";
- }else {
- type+" "+name+"["+size+"]";
- }
- }
-
- override String constructorName(String cls) {
- "ctor"
- }
- override String destructorName(String cls) {
- "dtor"
- }
- override String constructorReturnType() {
- "void"
- }
- override String destructorReturnType() {
- "void"
- }
-
- override String superCall(String baseClassName, String method, String args) {
- ""
- }
- override String toValueLiteral(PrimitiveType type, String value){
- switch(type.targetName){
- // TODO JH: char* with length 1
- case type.targetName.equals("char") && value.length == 1:
- "'"+value+"'"
- case type.type == LiteralType::CHAR:
- "\""+value+"\""
- case value.contains(','): {
- var singleValues = value.replace('{', '').replace('}', '').trim.split(',')
- '''{ «FOR v: singleValues SEPARATOR ', '»«toValueLiteral(type, v.trim)»«ENDFOR» }'''.toString
- }
- case "boolean":
- value.toUpperCase
- default:
- value
- }
- }
-
- override String defaultValue(DataType dt) {
- switch dt{
- PrimitiveType:
- toValueLiteral(dt, dt.defaultValueLiteral)
- ExternalType:{
- if (dt.defaultValueLiteral != null )
- return dt.getDefaultValueLiteral
- diagnostician.error("cannot initialize external type "+dt.name, dt.eContainer, dt.eContainingFeature)
- "cannot instantiate external data type "+dt.name
- }
- DataClass:
- '''
- {
- «FOR att : dt.allAttributes SEPARATOR ","»
- «att.initializationWithDefaultValues»
- «ENDFOR»
- }
- '''
- }
- }
-
- override initializationWithDefaultValues(DataType dt, int size) {
- val dv = dt.defaultValue
- dv.initializer(size)
- }
-
- def private initializer(String dv, int size) {
- if (size>1) {
- var res = "{"
- var i = 0
- while (i<size) {
- res = res + dv
- i = i+1
- if (i<size)
- res = res + ","
- }
- res+"}"
- }
- else
- dv
- }
-
- def initializationWithDefaultValues(Attribute att) {
- val dv = att.defaultValueLiteral
- if (dv!=null) {
- if (dv.startsWith("{"))
- dv
- else
- dv.initializer(att.size)
- }
- else if (att.refType.ref) {
- "NULL".initializer(att.size)
- }
- else
- att.refType.type.initializationWithDefaultValues(att.size)
- }
-
- override generateArglistAndTypedData(VarDecl data) {
- if (data==null)
- return newArrayList("", "", "")
-
- var typeName = if (data.getRefType().getType() instanceof PrimitiveType)
- (data.getRefType().getType() as PrimitiveType).getTargetName()
- else
- data.getRefType().getType().getName()
-
- var castTypeName = if (data.getRefType().getType() instanceof PrimitiveType) {
- val ct = (data.getRefType().getType() as PrimitiveType).getCastName()
- if (ct!=null && !ct.isEmpty())
- ct
- else
- typeName
- }
- else
- typeName
- castTypeName = castTypeName+"*"
- var deRef = "*"
-
- val isRef = data.getRefType().isRef()
- val isPrim = (data.getRefType().getType() instanceof PrimitiveType)
- if (isRef) {
- typeName = typeName+"*"
- castTypeName = castTypeName+"*"
- }
- else {
- if (!isPrim) {
- typeName = typeName+"*"
- deRef = ""
- }
- }
-
- val typedData = typeName+" "+data.getName() + " = "+deRef+"(("+castTypeName+") generic_data);\n"
-
- val dataArg = ", "+data.getName()
- val typedArgList = ", "+typeName+" "+data.getName()
-
- return newArrayList(dataArg, typedData, typedArgList);
- }
-
- def getIncludePath(RoomClass rc) {
- "\""+(rc.eContainer as RoomModel).name.replaceAll("\\.","/")+"/"+rc.getCHeaderFileName+"\""
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2010 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Thomas Schuetz and Henrik Rentz-Reichert (initial contribution)
+ * Thomas Schuetz (changed for C code generator)
+ *
+ *******************************************************************************/
+
+/*
+ collection of convenience functions for code generation
+*/
+
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import java.util.List
+import org.eclipse.etrice.core.etphys.eTPhys.NodeRef
+import org.eclipse.etrice.core.genmodel.etricegen.IDiagnostician
+import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance
+import org.eclipse.etrice.core.room.Attribute
+import org.eclipse.etrice.core.room.DataClass
+import org.eclipse.etrice.core.room.DataType
+import org.eclipse.etrice.core.room.ExternalType
+import org.eclipse.etrice.core.room.LiteralType
+import org.eclipse.etrice.core.room.Message
+import org.eclipse.etrice.core.room.PrimitiveType
+import org.eclipse.etrice.core.room.RoomClass
+import org.eclipse.etrice.core.room.RoomModel
+import org.eclipse.etrice.core.room.VarDecl
+import org.eclipse.etrice.generator.generic.ILanguageExtension
+import org.eclipse.xtext.util.Pair
+
+import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
+
+@Singleton
+class CExtensions implements ILanguageExtension {
+
+ @Inject IDiagnostician diagnostician
+
+ override String getTypedDataDefinition(Message m) {
+ generateArglistAndTypedData(m.data).get(1)
+ }
+
+ // in C no access levels can be defined
+ override String accessLevelPrivate(){"static "}
+ override String accessLevelProtected(){"static "}
+ override String accessLevelPublic(){""}
+
+ override String memberAccess(){"self->"}
+ override String selfPointer(String classname, boolean hasArgs){
+ classname+
+ if (hasArgs)
+ "* self, "
+ else
+ "* self"
+ }
+
+ override String selfPointer(boolean hasArgs) { if (hasArgs) "self, " else "self" }
+
+ override String operationScope(String classname, boolean isDeclaration){classname+"_"}
+
+ override String memberInDeclaration(String namespace, String member) {
+ return namespace+"_"+member
+ }
+
+ override String memberInUse(String namespace, String member) {
+ return namespace+"_"+member
+ }
+
+
+ //**** C-Specific
+ /* TODO: move specific code elsewhere */
+ // used
+ def String getCHeaderFileName(RoomClass rc) {
+ return rc.name+".h";
+ }
+
+ // used
+ def String getCSourceFileName(RoomClass rc) {
+ return rc.name+".c";
+ }
+
+ def String getInstSourceFileName(RoomClass rc) {
+ return rc.name+"_Inst.h";
+ }
+
+ def String getDispSourceFileName(RoomClass rc) {
+ return rc.name+"_Disp.h";
+ }
+
+ // used
+ def String getCHeaderFileName(NodeRef nr, SubSystemInstance ssi) {
+ return nr.name+"_"+ssi.name+".h";
+ }
+
+ def String getCSourceFileName(NodeRef nr, SubSystemInstance ssi) {
+ return nr.name+"_"+ssi.name+".c";
+ }
+
+ def String getInstSourceFileName(NodeRef nr, SubSystemInstance ssi) {
+ return nr.name+"_"+ssi.name+"_Inst.h";
+ }
+
+ def String getDispSourceFileName(NodeRef nr, SubSystemInstance ssi) {
+ return nr.name+"_"+ssi.name+"_Disp.h";
+ }
+
+ def getIncludeGuardString(String filename){
+ '''_«filename.toUpperCase»_H_'''
+ }
+
+ def generateIncludeGuardBegin(RoomClass rc) {
+ val filename = (rc.eContainer as RoomModel).name.replaceAll("\\.","_")+"_"+rc.name
+ filename.generateIncludeGuardBegin
+ }
+
+ def generateIncludeGuardEnd(RoomClass rc) {
+ val filename = (rc.eContainer as RoomModel).name.replaceAll("\\.","_")+"_"+rc.name
+ filename.generateIncludeGuardEnd
+ }
+
+ def generateIncludeGuardBegin(String filename) {
+ '''
+ #ifndef «filename.getIncludeGuardString»
+ #define «filename.getIncludeGuardString»
+ '''
+ }
+
+ def generateIncludeGuardEnd(String filename) {
+ '''
+ #endif /* «filename.getIncludeGuardString» */
+ '''
+ }
+
+ override boolean usesInheritance() {
+ return false
+ }
+
+ override boolean usesPointers() {
+ return true
+ }
+
+ override String genEnumeration(String name, List<Pair<String, String>> entries) {
+ if (entries.empty)
+ return "/* empty enum not generated */"
+
+ '''
+ enum «name» {
+ «FOR entry: entries SEPARATOR ","»
+ «entry.first» = «entry.second»
+ «ENDFOR»
+ };
+ '''.toString
+ }
+
+ override String booleanConstant(boolean b) {
+ if (b) "TRUE" else "FALSE"
+ }
+
+ override String pointerLiteral() { "*" }
+ override String nullPointer() { "NULL" }
+ override String voidPointer() { "void*" }
+
+ override String arrayDeclaration(String type, int size, String name, boolean isRef) {
+ if (isRef){
+ type+"* "+name+"["+size+"]";
+ }else {
+ type+" "+name+"["+size+"]";
+ }
+ }
+
+ override String constructorName(String cls) {
+ "ctor"
+ }
+ override String destructorName(String cls) {
+ "dtor"
+ }
+ override String constructorReturnType() {
+ "void"
+ }
+ override String destructorReturnType() {
+ "void"
+ }
+
+ override String superCall(String baseClassName, String method, String args) {
+ ""
+ }
+ override String toValueLiteral(PrimitiveType type, String value){
+ switch(type.targetName){
+ // TODO JH: char* with length 1
+ case type.targetName.equals("char") && value.length == 1:
+ "'"+value+"'"
+ case type.type == LiteralType::CHAR:
+ "\""+value+"\""
+ case value.contains(','): {
+ var singleValues = value.replace('{', '').replace('}', '').trim.split(',')
+ '''{ «FOR v: singleValues SEPARATOR ', '»«toValueLiteral(type, v.trim)»«ENDFOR» }'''.toString
+ }
+ case "boolean":
+ value.toUpperCase
+ default:
+ value
+ }
+ }
+
+ override String defaultValue(DataType dt) {
+ switch dt{
+ PrimitiveType:
+ toValueLiteral(dt, dt.defaultValueLiteral)
+ ExternalType:{
+ if (dt.defaultValueLiteral != null )
+ return dt.getDefaultValueLiteral
+ diagnostician.error("cannot initialize external type "+dt.name, dt.eContainer, dt.eContainingFeature)
+ "cannot instantiate external data type "+dt.name
+ }
+ DataClass:
+ '''
+ {
+ «FOR att : dt.allAttributes SEPARATOR ","»
+ «att.initializationWithDefaultValues»
+ «ENDFOR»
+ }
+ '''
+ }
+ }
+
+ override initializationWithDefaultValues(DataType dt, int size) {
+ val dv = dt.defaultValue
+ dv.initializer(size)
+ }
+
+ def private initializer(String dv, int size) {
+ if (size>1) {
+ var res = "{"
+ var i = 0
+ while (i<size) {
+ res = res + dv
+ i = i+1
+ if (i<size)
+ res = res + ","
+ }
+ res+"}"
+ }
+ else
+ dv
+ }
+
+ def initializationWithDefaultValues(Attribute att) {
+ val dv = att.defaultValueLiteral
+ if (dv!=null) {
+ if (dv.startsWith("{"))
+ dv
+ else
+ dv.initializer(att.size)
+ }
+ else if (att.refType.ref) {
+ "NULL".initializer(att.size)
+ }
+ else
+ att.refType.type.initializationWithDefaultValues(att.size)
+ }
+
+ override generateArglistAndTypedData(VarDecl data) {
+ if (data==null)
+ return newArrayList("", "", "")
+
+ var typeName = if (data.getRefType().getType() instanceof PrimitiveType)
+ (data.getRefType().getType() as PrimitiveType).getTargetName()
+ else
+ data.getRefType().getType().getName()
+
+ var castTypeName = if (data.getRefType().getType() instanceof PrimitiveType) {
+ val ct = (data.getRefType().getType() as PrimitiveType).getCastName()
+ if (ct!=null && !ct.isEmpty())
+ ct
+ else
+ typeName
+ }
+ else
+ typeName
+ castTypeName = castTypeName+"*"
+ var deRef = "*"
+
+ val isRef = data.getRefType().isRef()
+ val isPrim = (data.getRefType().getType() instanceof PrimitiveType)
+ if (isRef) {
+ typeName = typeName+"*"
+ castTypeName = castTypeName+"*"
+ }
+ else {
+ if (!isPrim) {
+ typeName = typeName+"*"
+ deRef = ""
+ }
+ }
+
+ val typedData = typeName+" "+data.getName() + " = "+deRef+"(("+castTypeName+") generic_data);\n"
+
+ val dataArg = ", "+data.getName()
+ val typedArgList = ", "+typeName+" "+data.getName()
+
+ return newArrayList(dataArg, typedData, typedArgList);
+ }
+
+ def getIncludePath(RoomClass rc) {
+ "\""+(rc.eContainer as RoomModel).name.replaceAll("\\.","/")+"/"+rc.getCHeaderFileName+"\""
+ }
+}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CTranslationProvider.java b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CTranslationProvider.java
index 658be0216..c3ab360a4 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CTranslationProvider.java
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/CTranslationProvider.java
@@ -1,160 +1,160 @@
-/*******************************************************************************
- * Copyright (c) 2012 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen;
-
-import java.util.ArrayList;
-
-import org.eclipse.emf.ecore.EObject;
-import org.eclipse.etrice.core.room.Attribute;
-import org.eclipse.etrice.core.room.CommunicationType;
-import org.eclipse.etrice.core.room.DetailCode;
-import org.eclipse.etrice.core.room.InterfaceItem;
-import org.eclipse.etrice.core.room.Message;
-import org.eclipse.etrice.core.room.Operation;
-import org.eclipse.etrice.core.room.Port;
-import org.eclipse.etrice.core.room.PortClass;
-import org.eclipse.etrice.core.room.ProtocolClass;
-import org.eclipse.etrice.core.room.RoomClass;
-import org.eclipse.etrice.core.room.SAPRef;
-import org.eclipse.etrice.core.room.SPPRef;
-import org.eclipse.etrice.generator.base.DefaultTranslationProvider;
-import org.eclipse.etrice.generator.generic.ILanguageExtension;
-import org.eclipse.etrice.generator.generic.RoomExtensions;
-
-import com.google.inject.Inject;
-
-public class CTranslationProvider extends DefaultTranslationProvider {
-
- @Inject private RoomExtensions roomExt;
- @Inject ILanguageExtension langExt;
- private String self = "self->";
-
- @Override
- public void setContainerClass(EObject container) {
- if (container instanceof PortClass) {
- PortClass pc = (PortClass) container;
- ProtocolClass prot = (ProtocolClass) container.eContainer();
- String portClassName = roomExt.getPortClassName(prot, prot.getConjugate()==pc);
- self = "(("+portClassName+"_var*)(self->varData))->";
- }
- }
-
- @Override
- public boolean translateMembers() {
- return true;
- }
-
- @Override
- public String getAttributeGetter(Attribute att, String index, String orig) {
- if (index==null)
- return self+att.getName() + getOrigComment(orig);
- else
- return self+att.getName()+"["+index+"]"+getOrigComment(orig);
- }
-
- @Override
- public String getAttributeSetter(Attribute att, String index, String value, String orig) {
- if (index==null)
- return self+att.getName()+" = "+value + getOrigComment(orig);
- else
- return self+att.getName()+"["+index+"] = "+value + getOrigComment(orig);
- }
-
- @Override
- public String getOperationText(Operation op, ArrayList<String> args, String orig) {
- StringBuilder result = new StringBuilder();
- result.append(langExt.memberInUse(((RoomClass)op.eContainer()).getName(), op.getName())+"(self");
- for (String arg : args) {
- result.append(", "+arg);
- }
- result.append(")"+getOrigComment(orig));
- return result.toString();
- }
-
- @Override
- public String getInterfaceItemMessageText(InterfaceItem item, Message msg, ArrayList<String> args, String index, String orig) {
- StringBuilder argtext = new StringBuilder();
- for (String arg : args) {
- argtext.append(", "+arg);
- }
-
- String result = orig;
- if (item instanceof Port) {
- Port p = (Port) item;
- if (p.getProtocol() instanceof ProtocolClass) {
-
- ProtocolClass pc = (ProtocolClass) p.getProtocol();
- if (pc.getCommType()==CommunicationType.EVENT_DRIVEN) {
- if (p.getMultiplicity()==1)
- result = roomExt.getPortClassName(p)+"_"+msg.getName()+"(&self->constData->"+item.getName()+argtext+")";
- else {
- if (index==null)
- result = roomExt.getPortClassName(p)+"_"+msg.getName()+"_broadcast(&self->constData->"+item.getName()+argtext+")";
- else
- result = roomExt.getPortClassName(p)+"_"+msg.getName()+"(&self->constData->"+item.getName()+", "+index+argtext+")";
- }
- result += getOrigComment(orig);
- }
- else if (pc.getCommType()==CommunicationType.DATA_DRIVEN) {
- if (p.isConjugated())
- result = roomExt.getPortClassName(p)+"_"+msg.getName()+"_set(&(self->"+item.getName()+")"+argtext+")";
- else
- result = roomExt.getPortClassName(p)+"_"+msg.getName()+"_get(&(self->constData->"+item.getName()+"))";
- result += getOrigComment(orig);
- }
- }
- }
- else if (item instanceof SAPRef) {
- result = roomExt.getPortClassName(((SAPRef)item))+"_"+msg.getName()+"(&self->constData->"+item.getName()+argtext+")";
- result += getOrigComment(orig);
- }
- else if (item instanceof SPPRef) {
- if (index==null)
- result = roomExt.getPortClassName(((SPPRef)item))+"_"+msg.getName()+"_broadcast(&self->constData->"+item.getName()+argtext+")";
- else
- result = roomExt.getPortClassName(((SPPRef)item))+"_"+msg.getName()+"(&self->constData->"+item.getName()+", "+index+argtext+")";
- result += getOrigComment(orig);
- }
-
- return result;
- }
-
- @Override
- public String getInterfaceItemMessageValue(InterfaceItem item, Message msg, String orig) {
- String result = orig;
- if (item instanceof Port) {
- Port p = (Port) item;
- result = roomExt.getPortClassName(p)+"_"+msg.getName()+"_get(&(self->constData->"+item.getName()+"))";
- result += getOrigComment(orig);
- }
- return result;
- }
-
- @Override
- public boolean translateTags() {
- return true;
- }
-
- @Override
- public String translateTag(String tag, DetailCode code) {
- if (tag.equals("ifitem.index"))
- return "((etReplSubPort*)ifitem)->index";
-
- return super.translateTag(tag, code);
- }
-
- private String getOrigComment(String orig) {
- return " /* ORIG: "+orig +" */";
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2012 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen;
+
+import java.util.ArrayList;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.etrice.core.room.Attribute;
+import org.eclipse.etrice.core.room.CommunicationType;
+import org.eclipse.etrice.core.room.DetailCode;
+import org.eclipse.etrice.core.room.InterfaceItem;
+import org.eclipse.etrice.core.room.Message;
+import org.eclipse.etrice.core.room.Operation;
+import org.eclipse.etrice.core.room.Port;
+import org.eclipse.etrice.core.room.PortClass;
+import org.eclipse.etrice.core.room.ProtocolClass;
+import org.eclipse.etrice.core.room.RoomClass;
+import org.eclipse.etrice.core.room.SAPRef;
+import org.eclipse.etrice.core.room.SPPRef;
+import org.eclipse.etrice.generator.base.DefaultTranslationProvider;
+import org.eclipse.etrice.generator.generic.ILanguageExtension;
+import org.eclipse.etrice.generator.generic.RoomExtensions;
+
+import com.google.inject.Inject;
+
+public class CTranslationProvider extends DefaultTranslationProvider {
+
+ @Inject private RoomExtensions roomExt;
+ @Inject ILanguageExtension langExt;
+ private String self = "self->";
+
+ @Override
+ public void setContainerClass(EObject container) {
+ if (container instanceof PortClass) {
+ PortClass pc = (PortClass) container;
+ ProtocolClass prot = (ProtocolClass) container.eContainer();
+ String portClassName = roomExt.getPortClassName(prot, prot.getConjugate()==pc);
+ self = "(("+portClassName+"_var*)(self->varData))->";
+ }
+ }
+
+ @Override
+ public boolean translateMembers() {
+ return true;
+ }
+
+ @Override
+ public String getAttributeGetter(Attribute att, String index, String orig) {
+ if (index==null)
+ return self+att.getName() + getOrigComment(orig);
+ else
+ return self+att.getName()+"["+index+"]"+getOrigComment(orig);
+ }
+
+ @Override
+ public String getAttributeSetter(Attribute att, String index, String value, String orig) {
+ if (index==null)
+ return self+att.getName()+" = "+value + getOrigComment(orig);
+ else
+ return self+att.getName()+"["+index+"] = "+value + getOrigComment(orig);
+ }
+
+ @Override
+ public String getOperationText(Operation op, ArrayList<String> args, String orig) {
+ StringBuilder result = new StringBuilder();
+ result.append(langExt.memberInUse(((RoomClass)op.eContainer()).getName(), op.getName())+"(self");
+ for (String arg : args) {
+ result.append(", "+arg);
+ }
+ result.append(")"+getOrigComment(orig));
+ return result.toString();
+ }
+
+ @Override
+ public String getInterfaceItemMessageText(InterfaceItem item, Message msg, ArrayList<String> args, String index, String orig) {
+ StringBuilder argtext = new StringBuilder();
+ for (String arg : args) {
+ argtext.append(", "+arg);
+ }
+
+ String result = orig;
+ if (item instanceof Port) {
+ Port p = (Port) item;
+ if (p.getProtocol() instanceof ProtocolClass) {
+
+ ProtocolClass pc = (ProtocolClass) p.getProtocol();
+ if (pc.getCommType()==CommunicationType.EVENT_DRIVEN) {
+ if (p.getMultiplicity()==1)
+ result = roomExt.getPortClassName(p)+"_"+msg.getName()+"(&self->constData->"+item.getName()+argtext+")";
+ else {
+ if (index==null)
+ result = roomExt.getPortClassName(p)+"_"+msg.getName()+"_broadcast(&self->constData->"+item.getName()+argtext+")";
+ else
+ result = roomExt.getPortClassName(p)+"_"+msg.getName()+"(&self->constData->"+item.getName()+", "+index+argtext+")";
+ }
+ result += getOrigComment(orig);
+ }
+ else if (pc.getCommType()==CommunicationType.DATA_DRIVEN) {
+ if (p.isConjugated())
+ result = roomExt.getPortClassName(p)+"_"+msg.getName()+"_set(&(self->"+item.getName()+")"+argtext+")";
+ else
+ result = roomExt.getPortClassName(p)+"_"+msg.getName()+"_get(&(self->constData->"+item.getName()+"))";
+ result += getOrigComment(orig);
+ }
+ }
+ }
+ else if (item instanceof SAPRef) {
+ result = roomExt.getPortClassName(((SAPRef)item))+"_"+msg.getName()+"(&self->constData->"+item.getName()+argtext+")";
+ result += getOrigComment(orig);
+ }
+ else if (item instanceof SPPRef) {
+ if (index==null)
+ result = roomExt.getPortClassName(((SPPRef)item))+"_"+msg.getName()+"_broadcast(&self->constData->"+item.getName()+argtext+")";
+ else
+ result = roomExt.getPortClassName(((SPPRef)item))+"_"+msg.getName()+"(&self->constData->"+item.getName()+", "+index+argtext+")";
+ result += getOrigComment(orig);
+ }
+
+ return result;
+ }
+
+ @Override
+ public String getInterfaceItemMessageValue(InterfaceItem item, Message msg, String orig) {
+ String result = orig;
+ if (item instanceof Port) {
+ Port p = (Port) item;
+ result = roomExt.getPortClassName(p)+"_"+msg.getName()+"_get(&(self->constData->"+item.getName()+"))";
+ result += getOrigComment(orig);
+ }
+ return result;
+ }
+
+ @Override
+ public boolean translateTags() {
+ return true;
+ }
+
+ @Override
+ public String translateTag(String tag, DetailCode code) {
+ if (tag.equals("ifitem.index"))
+ return "((etReplSubPort*)ifitem)->index";
+
+ return super.translateTag(tag, code);
+ }
+
+ private String getOrigComment(String orig) {
+ return " /* ORIG: "+orig +" */";
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/DataClassGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/DataClassGen.xtend
index 259659997..70d3ca2f9 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/DataClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/DataClassGen.xtend
@@ -1,121 +1,121 @@
-/*******************************************************************************
- * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- * Thomas Schuetz (changed for C code generator)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import org.eclipse.etrice.core.genmodel.base.ILogger
-import org.eclipse.etrice.core.genmodel.etricegen.Root
-import org.eclipse.etrice.core.room.DataClass
-import org.eclipse.etrice.generator.base.IGeneratorFileIo
-import org.eclipse.etrice.generator.generic.ProcedureHelpers
-import org.eclipse.etrice.generator.generic.RoomExtensions
-
-import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
-
-@Singleton
-class DataClassGen {
-
- @Inject IGeneratorFileIo fileIO
- @Inject extension CExtensions
- @Inject extension RoomExtensions
- @Inject extension ProcedureHelpers
- @Inject ILogger logger
-
- def doGenerate(Root root) {
- for (dc: root.usedDataClasses) {
- val path = dc.generationTargetPath+dc.getPath
- val infopath = dc.generationInfoPath+dc.getPath
- var file = dc.getCHeaderFileName
-
- // header file
- fileIO.generateFile("generating DataClass header", path, infopath, file, root.generateHeaderFile(dc))
-
- // source file
- file = dc.getCSourceFileName
- fileIO.generateFile("generating DataClass header", path, infopath, file, root.generateSourceFile(dc))
-
- }
- }
-
- def generateHeaderFile(Root root, DataClass dc) {'''
- /**
- * @author generated by eTrice
- *
- * Header File of DataClass «dc.name»
- *
- */
-
- «generateIncludeGuardBegin(dc)»
-
- #include "etDatatypes.h"
-
-««« TODO: includes only for used DataClasses, also for other models
- «FOR dataClass : root.getReferencedDataClasses(dc)»
- #include «dataClass.includePath»
- «ENDFOR»
-
- «dc.userCode(1)»
-
- typedef struct {
- «dc.allAttributes.attributes»
- } «dc.name»;
-
- «FOR a:dc.allAttributes»
- «IF a.defaultValueLiteral!=null»
- «logger.logInfo(dc.name+" "+a.name+": Attribute initialization not supported in C")»
- «ENDIF»
- «ENDFOR»
-
-««« TODO: do we need setters and getters for C and C++ ?
-
- «dc.operations.operationsDeclaration(dc.name)»
-
- /* deep copy */
- void «dc.name»_deepCopy(«dc.name»* source, «dc.name»* target);
-
- «dc.userCode(2)»
-
- «generateIncludeGuardEnd(dc)»
-
- '''
- }
-
- def generateSourceFile(Root root, DataClass dc) {'''
- /**
- * @author generated by eTrice
- *
- * Source File of DataClass «dc.name»
- *
- */
-
- #include "«dc.getCHeaderFileName»"
-
- #include <string.h>
-
- «dc.userCode(3)»
-
-««« TODO: do we need setters and getters for C and C++ ?
-
- «dc.operations.operationsImplementation(dc.name)»
-
- void «dc.name»_deepCopy(«dc.name»* source, «dc.name»* target) {
- memcpy(target, source, sizeof(«dc.name»));
- }
-
-
- '''}
-
-
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ * Thomas Schuetz (changed for C code generator)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import org.eclipse.etrice.core.genmodel.base.ILogger
+import org.eclipse.etrice.core.genmodel.etricegen.Root
+import org.eclipse.etrice.core.room.DataClass
+import org.eclipse.etrice.generator.base.IGeneratorFileIo
+import org.eclipse.etrice.generator.generic.ProcedureHelpers
+import org.eclipse.etrice.generator.generic.RoomExtensions
+
+import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
+
+@Singleton
+class DataClassGen {
+
+ @Inject IGeneratorFileIo fileIO
+ @Inject extension CExtensions
+ @Inject extension RoomExtensions
+ @Inject extension ProcedureHelpers
+ @Inject ILogger logger
+
+ def doGenerate(Root root) {
+ for (dc: root.usedDataClasses) {
+ val path = dc.generationTargetPath+dc.getPath
+ val infopath = dc.generationInfoPath+dc.getPath
+ var file = dc.getCHeaderFileName
+
+ // header file
+ fileIO.generateFile("generating DataClass header", path, infopath, file, root.generateHeaderFile(dc))
+
+ // source file
+ file = dc.getCSourceFileName
+ fileIO.generateFile("generating DataClass header", path, infopath, file, root.generateSourceFile(dc))
+
+ }
+ }
+
+ def generateHeaderFile(Root root, DataClass dc) {'''
+ /**
+ * @author generated by eTrice
+ *
+ * Header File of DataClass «dc.name»
+ *
+ */
+
+ «generateIncludeGuardBegin(dc)»
+
+ #include "etDatatypes.h"
+
+««« TODO: includes only for used DataClasses, also for other models
+ «FOR dataClass : root.getReferencedDataClasses(dc)»
+ #include «dataClass.includePath»
+ «ENDFOR»
+
+ «dc.userCode(1)»
+
+ typedef struct {
+ «dc.allAttributes.attributes»
+ } «dc.name»;
+
+ «FOR a:dc.allAttributes»
+ «IF a.defaultValueLiteral!=null»
+ «logger.logInfo(dc.name+" "+a.name+": Attribute initialization not supported in C")»
+ «ENDIF»
+ «ENDFOR»
+
+««« TODO: do we need setters and getters for C and C++ ?
+
+ «dc.operations.operationsDeclaration(dc.name)»
+
+ /* deep copy */
+ void «dc.name»_deepCopy(«dc.name»* source, «dc.name»* target);
+
+ «dc.userCode(2)»
+
+ «generateIncludeGuardEnd(dc)»
+
+ '''
+ }
+
+ def generateSourceFile(Root root, DataClass dc) {'''
+ /**
+ * @author generated by eTrice
+ *
+ * Source File of DataClass «dc.name»
+ *
+ */
+
+ #include "«dc.getCHeaderFileName»"
+
+ #include <string.h>
+
+ «dc.userCode(3)»
+
+««« TODO: do we need setters and getters for C and C++ ?
+
+ «dc.operations.operationsImplementation(dc.name)»
+
+ void «dc.name»_deepCopy(«dc.name»* source, «dc.name»* target) {
+ memcpy(target, source, sizeof(«dc.name»));
+ }
+
+
+ '''}
+
+
} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/Initialization.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/Initialization.xtend
index f475050f4..28ed03234 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/Initialization.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/Initialization.xtend
@@ -1,99 +1,99 @@
-/*******************************************************************************
- * Copyright (c) 2012 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Juergen Haug (initial contribution)
- *
- *******************************************************************************/
-
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import java.util.ArrayList
-import java.util.List
-import org.eclipse.etrice.core.genmodel.etricegen.ActorInstance
-import org.eclipse.etrice.core.genmodel.etricegen.InstanceBase
-import org.eclipse.etrice.core.genmodel.etricegen.InterfaceItemInstance
-import org.eclipse.etrice.core.room.Attribute
-import org.eclipse.etrice.core.room.DataClass
-import org.eclipse.etrice.core.room.ExternalType
-import org.eclipse.etrice.core.room.PrimitiveType
-import org.eclipse.etrice.core.room.util.RoomHelpers
-import org.eclipse.etrice.generator.generic.RoomExtensions
-import org.eclipse.etrice.generator.generic.TypeHelpers
-import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
-
-class Initialization {
-
- @Inject CExtensions languageExt
- @Inject extension RoomExtensions
- @Inject extension TypeHelpers
-
- def generateAttributeInit(InstanceBase instance, List<Attribute> attributes){'''
- «FOR a : attributes SEPARATOR ','»
- «initAttributeArray(instance, new ArrayList<Attribute>.union(a))»
- «ENDFOR»
- '''
- }
-
- def private String initAttributeArray(InstanceBase instance, List<Attribute> path){
- var a = path.last
- var COMMENT = ''' /* «a.name»«IF a.size>1»[«a.size»]«ENDIF» */'''.toString
- if(a.size == 0 || (!a.refType.ref && a.refType.type.primitive))
- initAttribute(instance, path)+COMMENT
- else
- '''
- { «FOR Integer i:1..a.size SEPARATOR ', '»«initAttribute(instance, path)»«ENDFOR» } «COMMENT»
- '''
- }
-
- def private initAttribute(InstanceBase instance, List<Attribute> path) {
- var a = path.last
- var aType = a.refType.type
- if(a.refType.ref){
- return if(a.defaultValueLiteral != null)
- a.defaultValueLiteral
- else
- languageExt.nullPointer
- }
- switch aType{
- DataClass:
- '''
- {
- «FOR subA : (aType as DataClass).allAttributes SEPARATOR ','»
- «initAttributeArray(instance, path.union(subA))»
- «ENDFOR»
- }'''
- ExternalType:
- if(a.defaultValueLiteral != null)
- a.defaultValueLiteral
- else
- languageExt.defaultValue(aType)
- PrimitiveType: {
- var value = getPrimitiveValue(instance, path)
- if(a.size > 0 && !aType.characterType && !value.trim.startsWith('{'))
- '''{ «FOR Integer i:1..a.size SEPARATOR ', '»«value»«ENDFOR» }'''
- else
- value
- }
- }
- }
-
- def private getPrimitiveValue(InstanceBase instance, List<Attribute> path){
- var value = path.getAttrInstanceConfigValue(instance)
- if(value == null)
- value = switch instance {
- ActorInstance: path.getAttrClassConfigValue(instance.actorClass, true)
- InterfaceItemInstance: path.getAttrClassConfigValue(RoomHelpers::getPortClass(instance.interfaceItem))
- }
- if(value == null)
- value = path.last.defaultValueLiteral
- return if(value != null) languageExt.toValueLiteral(path.last.refType.type as PrimitiveType, value)
- else languageExt.defaultValue(path.last.refType.type)
- }
+/*******************************************************************************
+ * Copyright (c) 2012 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Juergen Haug (initial contribution)
+ *
+ *******************************************************************************/
+
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import java.util.ArrayList
+import java.util.List
+import org.eclipse.etrice.core.genmodel.etricegen.ActorInstance
+import org.eclipse.etrice.core.genmodel.etricegen.InstanceBase
+import org.eclipse.etrice.core.genmodel.etricegen.InterfaceItemInstance
+import org.eclipse.etrice.core.room.Attribute
+import org.eclipse.etrice.core.room.DataClass
+import org.eclipse.etrice.core.room.ExternalType
+import org.eclipse.etrice.core.room.PrimitiveType
+import org.eclipse.etrice.core.room.util.RoomHelpers
+import org.eclipse.etrice.generator.generic.RoomExtensions
+import org.eclipse.etrice.generator.generic.TypeHelpers
+import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
+
+class Initialization {
+
+ @Inject CExtensions languageExt
+ @Inject extension RoomExtensions
+ @Inject extension TypeHelpers
+
+ def generateAttributeInit(InstanceBase instance, List<Attribute> attributes){'''
+ «FOR a : attributes SEPARATOR ','»
+ «initAttributeArray(instance, new ArrayList<Attribute>.union(a))»
+ «ENDFOR»
+ '''
+ }
+
+ def private String initAttributeArray(InstanceBase instance, List<Attribute> path){
+ var a = path.last
+ var COMMENT = ''' /* «a.name»«IF a.size>1»[«a.size»]«ENDIF» */'''.toString
+ if(a.size == 0 || (!a.refType.ref && a.refType.type.primitive))
+ initAttribute(instance, path)+COMMENT
+ else
+ '''
+ { «FOR Integer i:1..a.size SEPARATOR ', '»«initAttribute(instance, path)»«ENDFOR» } «COMMENT»
+ '''
+ }
+
+ def private initAttribute(InstanceBase instance, List<Attribute> path) {
+ var a = path.last
+ var aType = a.refType.type
+ if(a.refType.ref){
+ return if(a.defaultValueLiteral != null)
+ a.defaultValueLiteral
+ else
+ languageExt.nullPointer
+ }
+ switch aType{
+ DataClass:
+ '''
+ {
+ «FOR subA : (aType as DataClass).allAttributes SEPARATOR ','»
+ «initAttributeArray(instance, path.union(subA))»
+ «ENDFOR»
+ }'''
+ ExternalType:
+ if(a.defaultValueLiteral != null)
+ a.defaultValueLiteral
+ else
+ languageExt.defaultValue(aType)
+ PrimitiveType: {
+ var value = getPrimitiveValue(instance, path)
+ if(a.size > 0 && !aType.characterType && !value.trim.startsWith('{'))
+ '''{ «FOR Integer i:1..a.size SEPARATOR ', '»«value»«ENDFOR» }'''
+ else
+ value
+ }
+ }
+ }
+
+ def private getPrimitiveValue(InstanceBase instance, List<Attribute> path){
+ var value = path.getAttrInstanceConfigValue(instance)
+ if(value == null)
+ value = switch instance {
+ ActorInstance: path.getAttrClassConfigValue(instance.actorClass, true)
+ InterfaceItemInstance: path.getAttrClassConfigValue(RoomHelpers::getPortClass(instance.interfaceItem))
+ }
+ if(value == null)
+ value = path.last.defaultValueLiteral
+ return if(value != null) languageExt.toValueLiteral(path.last.refType.type as PrimitiveType, value)
+ else languageExt.defaultValue(path.last.refType.type)
+ }
}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/MainGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/MainGen.xtend
index 4156a3fa4..dc18e8dfe 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/MainGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/MainGen.xtend
@@ -1,54 +1,54 @@
-/*******************************************************************************
- * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- * Thomas Schuetz (changed for C code generator)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import org.eclipse.emf.ecore.resource.Resource
-import org.eclipse.etrice.core.genmodel.etricegen.Root
-import org.eclipse.xtext.generator.IFileSystemAccess
-import org.eclipse.xtext.generator.IGenerator
-import org.eclipse.etrice.generator.generic.PrepareFileSystem
-import org.eclipse.etrice.generator.c.gen.NodeGen
-
-@Singleton
-class MainGen implements IGenerator {
-
- @Inject DataClassGen dataClassGen
- @Inject ProtocolClassGen protocolClassGen
- @Inject ActorClassGen actorClassGen
- @Inject NodeGen nodeGen
- @Inject NodeRunnerGen nodeRunnerGen
- @Inject PrepareFileSystem prepFS
-
- override void doGenerate(Resource resource, IFileSystemAccess fsa) {
- prepFS.prepare(resource)
- for (e: resource.contents){
- if (e instanceof Root) {
- doGenerate(e as Root)
- }
- }
- }
-
- def void doGenerate(Root e) {
- dataClassGen.doGenerate(e);
- protocolClassGen.doGenerate(e);
- actorClassGen.doGenerate(e);
- nodeGen.doGenerate(e);
-
- if (!e.library) {
- nodeRunnerGen.doGenerate(e);
- }
- }
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ * Thomas Schuetz (changed for C code generator)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.etrice.core.genmodel.etricegen.Root
+import org.eclipse.xtext.generator.IFileSystemAccess
+import org.eclipse.xtext.generator.IGenerator
+import org.eclipse.etrice.generator.generic.PrepareFileSystem
+import org.eclipse.etrice.generator.c.gen.NodeGen
+
+@Singleton
+class MainGen implements IGenerator {
+
+ @Inject DataClassGen dataClassGen
+ @Inject ProtocolClassGen protocolClassGen
+ @Inject ActorClassGen actorClassGen
+ @Inject NodeGen nodeGen
+ @Inject NodeRunnerGen nodeRunnerGen
+ @Inject PrepareFileSystem prepFS
+
+ override void doGenerate(Resource resource, IFileSystemAccess fsa) {
+ prepFS.prepare(resource)
+ for (e: resource.contents){
+ if (e instanceof Root) {
+ doGenerate(e as Root)
+ }
+ }
+ }
+
+ def void doGenerate(Root e) {
+ dataClassGen.doGenerate(e);
+ protocolClassGen.doGenerate(e);
+ actorClassGen.doGenerate(e);
+ nodeGen.doGenerate(e);
+
+ if (!e.library) {
+ nodeRunnerGen.doGenerate(e);
+ }
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeGen.xtend
index 92dff5f3c..ed722fa13 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeGen.xtend
@@ -1,722 +1,722 @@
-/*******************************************************************************
- * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- * Thomas Schuetz (changed for C code generator)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import java.util.ArrayList
-import java.util.HashMap
-import java.util.HashSet
-import org.eclipse.etrice.core.etmap.util.ETMapUtil
-import org.eclipse.etrice.core.etphys.eTPhys.ExecMode
-import org.eclipse.etrice.core.etphys.eTPhys.PhysicalThread
-import org.eclipse.etrice.core.genmodel.etricegen.ActorInstance
-import org.eclipse.etrice.core.genmodel.etricegen.IDiagnostician
-import org.eclipse.etrice.core.genmodel.etricegen.InterfaceItemInstance
-import org.eclipse.etrice.core.genmodel.etricegen.PortInstance
-import org.eclipse.etrice.core.genmodel.etricegen.Root
-import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance
-import org.eclipse.etrice.core.room.ActorCommunicationType
-import org.eclipse.etrice.core.room.CommunicationType
-import org.eclipse.etrice.core.room.Port
-import org.eclipse.etrice.core.room.ProtocolClass
-import org.eclipse.etrice.core.room.SAPRef
-import org.eclipse.etrice.core.room.SPPRef
-import org.eclipse.etrice.generator.base.IGeneratorFileIo
-import org.eclipse.etrice.generator.base.IntelligentSeparator
-import org.eclipse.etrice.generator.generic.ILanguageExtension
-import org.eclipse.etrice.generator.generic.ProcedureHelpers
-import org.eclipse.etrice.generator.generic.RoomExtensions
-
-import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
-import org.eclipse.etrice.generator.base.GlobalGeneratorSettings
-
-@Singleton
-class NodeGen {
-
- @Inject extension CExtensions
- @Inject extension RoomExtensions
- @Inject extension ProcedureHelpers helpers
-
- @Inject IGeneratorFileIo fileIO
- @Inject Initialization attrInitGenAddon
- @Inject ILanguageExtension languageExt
- @Inject IDiagnostician diagnostician
-
- def doGenerate(Root root) {
- for (nr : ETMapUtil::getNodeRefs()) {
- for (instpath : ETMapUtil::getSubSystemInstancePaths(nr)) {
- val ssi = root.getInstance(instpath) as SubSystemInstance
- val filepath = ssi.subSystemClass.generationTargetPath+ssi.subSystemClass.getPath
- val infopath = ssi.subSystemClass.generationInfoPath+ssi.subSystemClass.getPath
- var file = nr.getCHeaderFileName(ssi)
-
- checkDataPorts(ssi)
-
- val usedThreads = new HashSet<PhysicalThread>();
- for (thread: nr.type.threads) {
- val instancesOnThread = ssi.allContainedInstances.filter(ai|ETMapUtil::getPhysicalThread(ai)==thread)
- if (!instancesOnThread.empty)
- usedThreads.add(thread)
- }
-
- fileIO.generateFile("generating Node declaration", filepath, infopath, file, root.generateHeaderFile(ssi))
-
- file = nr.getCSourceFileName(ssi)
- fileIO.generateFile("generating Node implementation", filepath, infopath, file, root.generateSourceFile(ssi, usedThreads))
-
- file = nr.getInstSourceFileName(ssi)
- fileIO.generateFile("generating Node instance file", filepath, infopath, file, root.generateInstanceFile(ssi, usedThreads))
-
- file = nr.getDispSourceFileName(ssi)
- fileIO.generateFile("generating Node dispatcher file", filepath, infopath, file, root.generateDispatcherFile(ssi, usedThreads))
- }
- }
- }
-
- def private generateHeaderFile(Root root, SubSystemInstance ssi) {
- val nr = ETMapUtil::getNodeRef(ssi)
- val ssc = ssi.subSystemClass
- val clsname = nr.name+"_"+ssi.name
- '''
- /**
- * @author generated by eTrice
- *
- * Header File of Node «nr.name» with SubSystem «ssi.name»
- *
- */
-
- «generateIncludeGuardBegin(clsname)»
-
- #include "etDatatypes.h"
-
-««« TODOCGENPHYS: user code?
- «helpers.userCode(ssc.userCode1)»
-
-
- /* lifecycle functions
- * init -> start -> run (loop) -> stop -> destroy
- */
-
- void «clsname»_init(void); /* lifecycle init */
- void «clsname»_start(void); /* lifecycle start */
-
- void «clsname»_run(etBool runAsTest); /* lifecycle run */
-
- void «clsname»_stop(void); /* lifecycle stop */
- void «clsname»_destroy(void); /* lifecycle destroy */
-
- void «clsname»_shutdown(void); /* shutdown the dispatcher loop */
-
-««« TODOCGENPHYS: user code?
- «helpers.userCode(ssc.userCode2)»
-
- «generateIncludeGuardEnd(clsname)»
-
-
- '''
- }
-
- def private generateSourceFile(Root root, SubSystemInstance ssi, HashSet<PhysicalThread> usedThreads) {
- val nr = ETMapUtil::getNodeRef(ssi)
- val ssc = ssi.subSystemClass
- val clsname = nr.name+"_"+ssi.name
- val threads = nr.type.threads.filter(t|usedThreads.contains(t))
- '''
- /**
- * @author generated by eTrice
- *
- * Source File of Node «nr.name» with SubSystem «ssi.name»
- *
- */
-
- #include <stdio.h>
-
- #include "«nr.getCHeaderFileName(ssi)»"
-
- #include "debugging/etLogger.h"
- #include "debugging/etMSCLogger.h"
- #include "messaging/etSystemProtocol.h"
- #include "osal/etTimer.h"
- #include "osal/etSema.h"
- #include "runtime/etRuntime.h"
- #include "etRuntimeConfig.h"
-
-««« TODOCGENPHYS: user code?
- «helpers.userCode(ssc.userCode3)»
-
- /* data for Node «nr.name» with SubSystem «ssi.name» */
- typedef struct «clsname» {
- char *name;
- volatile int shutdownRequest;
- } «clsname»;
-
- static «clsname» «clsname»Inst = {"«clsname»", 0};
-
- static void «clsname»_initActorInstances(void);
- static void «clsname»_constructActorInstances(void);
-
- /* include instances for all classes */
- #include "«nr.getInstSourceFileName(ssi)»"
- #include "«nr.getDispSourceFileName(ssi)»"
-
- static void «clsname»_initMessageServices(void) {
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "initMessageServices")
- {
- etTime interval;
-
- /* initialization of all message services */
- «FOR thread: threads»
- «IF thread.execmode==ExecMode::POLLED || thread.execmode==ExecMode::MIXED»
-««« interval.sec = «thread.sec» <-- use convenience functions to split time in sec and nsec
- interval.sec = 0;
- interval.nSec = «thread.time»;
- «ENDIF»
- etMessageService_init(
- &msgService_«thread.name»,
- msgBuffer_«thread.name»,
- «thread.name.toUpperCase»_POOL_SIZE,
- «thread.name.toUpperCase»_BLOCK_SIZE,
- «thread.stacksize»,
- «thread.prio»,
- interval,
- MsgDispatcher_«thread.name»_receiveMessage,
- EXECMODE_«thread.execmode.toString.toUpperCase»);
-
- «ENDFOR»
- }
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- static void «clsname»_startMessageServices(void) {
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "startMessageServices")
-
- «FOR thread: threads»
- etMessageService_start(&msgService_«thread.name»);
- «ENDFOR»
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- static void «clsname»_stopMessageServices(void) {
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "stopMessageServices")
-
- «FOR thread: threads»
- etMessageService_stop(&msgService_«thread.name»);
- «ENDFOR»
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- static void «clsname»_destroyMessageServices(void) {
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "destroyMessageServices")
-
- «FOR thread: threads»
- etMessageService_destroy(&msgService_«thread.name»);
- «ENDFOR»
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- void «clsname»_init(void) {
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "init")
- etLogger_logInfoF("%s_init", «clsname»Inst.name);
-
- /* construct all actors */
- «clsname»_constructActorInstances();
-
- /* initialization of all message services */
- «clsname»_initMessageServices();
-
- /* init all actors */
- «clsname»_initActorInstances();
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- void «clsname»_start(void) {
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "start")
- etLogger_logInfoF("%s_start", «clsname»Inst.name);
- «clsname»_startMessageServices();
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- void «clsname»_run(etBool runAsTest) {
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "run")
-
- if (runAsTest) {
- etSema_waitForWakeup(etRuntime_getTerminateSemaphore());
- }
- else {
- printf("type quit to exit\n");
- fflush(stdout);
- while (TRUE) {
- char line[64];
-
- if (fgets(line, 64, stdin) == NULL) {
- printf("got NULL\n");
- break;
- }
- else if (strncmp(line, "quit", 4)==0){
- break;
- }
- }
- }
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- void «clsname»_stop(void){
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "stop")
- etLogger_logInfoF("%s_stop", «clsname»Inst.name);
-
- «clsname»_stopMessageServices();
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- void «clsname»_destroy(void){
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "destroy")
- etLogger_logInfoF("%s_destroy", «clsname»Inst.name);
- «FOR ai : ssi.allContainedInstances.reverseView»
- «IF !ai.actorClass.operations.filter(op|op.destructor).empty»
- «languageExt.memberInUse(ai.actorClass.name, languageExt.destructorName(ai.actorClass.name))»(&«ai.path.getPathName()»);
- «ENDIF»
- «ENDFOR»
-
- «clsname»_destroyMessageServices();
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- void «clsname»_shutdown(void){
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "shutdown")
- etLogger_logInfoF("%s_shutdown", «clsname»Inst.name);
-
- «clsname»Inst.shutdownRequest = 1;
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
-
- static void «clsname»_constructActorInstances(void){
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "constructActorInstances")
-
- «FOR ai : ssi.allContainedInstances»
- «IF !ai.actorClass.operations.filter(op|op.constructor).empty»
- «languageExt.memberInUse(ai.actorClass.name, languageExt.constructorName(ai.actorClass.name))»(&«ai.path.getPathName()»);
- «ENDIF»
- «ENDFOR»
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
-
- static void «clsname»_initActorInstances(void){
- ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "initActorInstances")
-
- «FOR ai : ssi.allContainedInstances»
- «ai.actorClass.name»_init(&«ai.path.getPathName()»);
- «ENDFOR»
-
- ET_MSC_LOGGER_SYNC_EXIT
- }
- '''
- }
-
- def private generateInstanceFile(Root root, SubSystemInstance ssi, HashSet<PhysicalThread> usedThreads) {
- val nr = ETMapUtil::getNodeRef(ssi)
- '''
- /**
- * @author generated by eTrice
- *
- * Instance File of Node «nr.name» with SubSystem «ssi.name»
- * - instantiation of all actor instances and port instances
- * - configuration of data and connection of ports
- */
-
- #include "messaging/etMessageService.h"
-
- /* include all referenced ActorClasses */
- «FOR actorClass : root.getReferencedActorClasses(ssi.subSystemClass)»
- #include «actorClass.includePath»
- «ENDFOR»
-
- /* include all referenced ProtcolClasses */
- «FOR protocolClass : root.getReferencedProtocolClasses(ssi.subSystemClass)»
- #include «protocolClass.includePath»
- «ENDFOR»
-
- /* instantiation of message services and message buffers */
- «FOR thread: nr.type.threads.filter(t|usedThreads.contains(t))»
- /* «thread.name» */
- #define «thread.name.toUpperCase»_POOL_SIZE «thread.msgpoolsize»
- #define «thread.name.toUpperCase»_BLOCK_SIZE «thread.msgblocksize»
- static uint8 msgBuffer_«thread.name»[«thread.name.toUpperCase»_POOL_SIZE * «thread.name.toUpperCase»_BLOCK_SIZE];
- static etMessageService msgService_«thread.name»;
- «ENDFOR»
-
- /* declarations of all ActorClass instances (const and variable structs) */
-
- /* forward declaration of variable actor structs */
- «FOR ai : ssi.allContainedInstances»
- static «ai.actorClass.name» «ai.path.getPathName()»;
- «ENDFOR»
-
- /* forward declaration of variable port structs */
- «FOR ai: ssi.allContainedInstances»
- «IF ai.orderedIfItemInstances.empty»
- /* nothing to do */
- «ELSE»
- «FOR pi:ai.orderedIfItemInstances»
- «IF pi.protocol.getPortClass(pi.conjugated)?.attributes?.size > 0»
- static «pi.protocol.getPortClassName(pi.conjugated)»_var «pi.path.pathName»_var«IF pi.replicated»[«pi.peers.size»]«ENDIF»={
- «FOR Integer i:1.. if(pi.peers.size==0)1 else pi.peers.size SEPARATOR ', '»
- «attrInitGenAddon.generateAttributeInit(pi, pi.interfaceItem.portClass.attributes)»
- «ENDFOR»};
- «ENDIF»
- «ENDFOR»
- «ENDIF»
- «ENDFOR»
-
- «FOR ai : ssi.allContainedInstances»
-
- /* instance «ai.path.getPathName()» */
- «IF !GlobalGeneratorSettings::generateMSCInstrumentation && ai.orderedIfItemInstances.empty»
- /* no ports/saps/services - nothing to initialize statically */
- «ELSE»
- «genActorInstanceInitializer(root, ai)»
- «ENDIF»
- «ENDFOR»
-
- '''
- }
-
- def private genActorInstanceInitializer(Root root, ActorInstance ai) {
- val instName = ai.path.pathName
-
- // list of replicated interface items (all are event driven ports)
- val replEventItems = new ArrayList<InterfaceItemInstance>()
- replEventItems.addAll(ai.orderedIfItemInstances.filter(e|e.replicated))
- val haveReplSubItems = replEventItems.findFirst(e|!e.peers.empty)!=null
- val replEventPorts = replEventItems.filter(i|i.interfaceItem instanceof Port)
- val replEventSPPs = replEventItems.filter(i|i.interfaceItem instanceof SPPRef)
-
- val simplePorts = ai.orderedIfItemInstances.filter(e|e.simple)
-
- // list of simple event interface items
- val simpleEventItems = new ArrayList<InterfaceItemInstance>()
- simpleEventItems.addAll(simplePorts.filter(p|p.protocol.commType==CommunicationType::EVENT_DRIVEN))
-
- // lists of event driven ports and saps
- val simpleEventPorts = simpleEventItems.filter(i|i.interfaceItem instanceof Port)
- val simpleEventSAPs = simpleEventItems.filter(i|i.interfaceItem instanceof SAPRef)
-
- val dataPorts = simplePorts.filter(p|p.protocol.commType==CommunicationType::DATA_DRIVEN)
- val recvPorts = dataPorts.filter(p|p instanceof PortInstance && !(p as PortInstance).port.conjugated)
- val sendPorts = dataPorts.filter(p|p instanceof PortInstance && (p as PortInstance).port.conjugated)
-
- // compute replicated port offsets
- val offsets = new HashMap<InterfaceItemInstance, Integer>()
- var offset = 0
- for (p: replEventItems) {
- offsets.put(p, offset)
- offset = offset + p.peers.size
- }
-
- var replSubPortsArray = if (haveReplSubItems) instName+"_repl_sub_ports" else "NULL"
- val haveConstData = !simpleEventItems.empty || !recvPorts.empty || !replEventItems.empty
- || GlobalGeneratorSettings::generateMSCInstrumentation
- val sep = new IntelligentSeparator(",");
- '''
- «IF haveReplSubItems»
- static const etReplSubPort «replSubPortsArray»[«offset»] = {
- /* Replicated Sub Ports: {varData, msgService, peerAddress, localId, index} */
- «FOR pi : replEventItems.filter(e|!e.peers.empty) SEPARATOR ","»
- «genReplSubPortInitializers(root, ai, pi)»
- «ENDFOR»
- };
- «ENDIF»
- «IF haveConstData»
- static const «ai.actorClass.name»_const «instName»_const = {
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- «sep»"«ai.path»"
-
- «ENDIF»
- /* Ports: {varData, msgService, peerAddress, localId} */
- /* simple ports */
- «FOR pi : simpleEventPorts»
- «sep»«genPortInitializer(root, ai, pi)»
- «ENDFOR»
-
- /* data receive ports */
- «FOR pi : recvPorts»
- «sep»«genRecvPortInitializer(root, ai, pi)»
- «ENDFOR»
-
- /* saps */
- «FOR pi : simpleEventSAPs»
- «sep»«genPortInitializer(root, ai, pi)»
- «ENDFOR»
-
- /* replicated ports */
- «FOR pi : replEventPorts»
- «sep»{«pi.peers.size», «replSubPortsArray»+«offsets.get(pi)»}
- «ENDFOR»
-
- /* services */
- «FOR pi : replEventSPPs»
- «sep»{«pi.peers.size», «replSubPortsArray»+«offsets.get(pi)»}
- «ENDFOR»
- };
- «ENDIF»
- static «ai.actorClass.name» «instName» = {
- «IF haveConstData»
- &«instName»_const,
-
- «ENDIF»
- /* data send ports */
- «FOR pi : sendPorts»
- «pi.genSendPortInitializer»,
- «ENDFOR»
-
- /* attributes */
- «attrInitGenAddon.generateAttributeInit(ai, ai.actorClass.allAttributes)»
-
- /* state and history are initialized in init fuction */
- };
- '''}
-
- def private String genPortInitializer(Root root, ActorInstance ai, InterfaceItemInstance pi) {
- val objId = if (pi.peers.empty) 0 else pi.peers.get(0).objId
- val idx = if (pi.peers.empty) 0 else pi.peers.get(0).peers.indexOf(pi)
- val msgSvc = if (pi.peers.empty) "NULL" else "&msgService_"+ETMapUtil::getPhysicalThread(pi.peers.get(0).eContainer as ActorInstance).name
- val myInst = if (GlobalGeneratorSettings::generateMSCInstrumentation) ",\""+(pi.eContainer as ActorInstance).path+"\","
- else ""
- val peerInst = if (GlobalGeneratorSettings::generateMSCInstrumentation) "\""+(pi.peers.get(0).eContainer as ActorInstance).path+"\""
- else ""
-
- "{"+getInterfaceItemInstanceData(pi)+", "
- +msgSvc+", "
- +(objId+idx)+"+BASE_ADDRESS, "
- +(root.getExpandedActorClass(ai).getInterfaceItemLocalId(pi.interfaceItem)+1)
- +myInst
- +peerInst
- +"} /* Port "+pi.name+" */"
- }
-
- def private genSendPortInitializer(InterfaceItemInstance pi) {
- val pc = (pi as PortInstance).port.protocol as ProtocolClass
-
- '''
- {
- «FOR m : pc.incomingMessages SEPARATOR ","»
- «m.data.refType.type.defaultValue»
- «ENDFOR»
- } /* send port «pi.name» */
- '''
- }
-
- def private getInterfaceItemInstanceData(InterfaceItemInstance pi){
- if (pi.protocol.getPortClass(pi.conjugated)== null) return "NULL"
- if (pi.protocol.getPortClass(pi.conjugated).attributes.empty){
- return "NULL"
- }else{
- return "&"+pi.path.pathName+"_var"
- }
- }
-
-
- def private String genRecvPortInitializer(Root root, ActorInstance ai, InterfaceItemInstance pi) {
- if (pi.peers.empty)
- return "{NULL}"
-
- var peer = pi.peers.get(0)
- var peerInst = pi.peers.get(0).eContainer() as ActorInstance
- var instName = peerInst.path.pathName
-
- "{&"+instName+"."+peer.name+"}"
- }
-
- def private String genReplSubPortInitializers(Root root, ActorInstance ai, InterfaceItemInstance pi) {
- var result = ""
- val myInst = if (GlobalGeneratorSettings::generateMSCInstrumentation) ",\""+(pi.eContainer as ActorInstance).path+"\","
- else ""
-
- for (p: pi.peers) {
- val idx = pi.peers.indexOf(p)
- val comma = if (idx<pi.peers.size-1) "," else ""
- val thread = ETMapUtil::getPhysicalThread(p.eContainer as ActorInstance).name
- var iiiD = getInterfaceItemInstanceData(pi)
- val peerInst = if (GlobalGeneratorSettings::generateMSCInstrumentation) "\""+(p.eContainer as ActorInstance).path+"\""
- else ""
- iiiD = if (iiiD.equals("NULL")) iiiD+"," else iiiD+"["+idx+"],"
- result = result +
- "{{"+iiiD
- +"&msgService_"+thread+", "
- +p.objId+"+BASE_ADDRESS, "
- +(root.getExpandedActorClass(ai).getInterfaceItemLocalId(pi.interfaceItem)+1)
- +myInst
- +peerInst
- +"},"
- +idx
- +"}"+comma+" /* Repl Sub Port "+pi.name+" idx +"+idx+"*/\n"
- }
-
- return result
- }
-
- def private generateDispatcherFile(Root root, SubSystemInstance ssi, HashSet<PhysicalThread> usedThreads) {
- val nr = ETMapUtil::getNodeRef(ssi)
-
- '''
- /**
- * @author generated by eTrice
- *
- * Dispatcher File of Node «nr.name» with SubSystem «ssi.name»
- * - one generated message dispatcher (receiveMessage) for each MessageService (Thread)
- * - one generated execute dispatcher (execute) for each MessageService (Thread)
- */
-
- #include "messaging/etMessageReceiver.h"
- #include "debugging/etLogger.h"
- #include "debugging/etMSCLogger.h"
-
- «FOR thread: nr.type.threads.filter(t|usedThreads.contains(t)) SEPARATOR "\n"»
- «val instancesOnThread = ssi.allContainedInstances.filter(ai|ETMapUtil::getPhysicalThread(ai)==thread)»
- «val dispatchedInstances = instancesOnThread.filter(ai|ai.actorClass.commType == ActorCommunicationType::EVENT_DRIVEN || ai.actorClass.commType == ActorCommunicationType::ASYNCHRONOUS)»
- «val executedInstances = instancesOnThread.filter(ai|ai.actorClass.commType == ActorCommunicationType::DATA_DRIVEN || ai.actorClass.commType == ActorCommunicationType::ASYNCHRONOUS)»
-
- «IF executedInstances.size > 0»
- /**
- * generated execute function for all cyclic execute calls for the async or datadriven actor instances of thread "«thread.name»"
- */
- static void MsgDispatcher_«thread.name»_poll(void){
- ET_MSC_LOGGER_SYNC_ENTRY("MsgDispatcher_«thread.name»", "execute")
- «FOR ai : executedInstances»
- «ai.actorClass.name»_execute((void*)&«ai.path.pathName»);
- «ENDFOR»
- ET_MSC_LOGGER_SYNC_EXIT
- }
- «ENDIF»
-
- /**
- * generated dispatch function for all messages for the thread "«thread.name»"
- */
- static etBool MsgDispatcher_«thread.name»_receiveMessage(const etMessage* msg){
- ET_MSC_LOGGER_SYNC_ENTRY("MsgDispatcher_«thread.name»", "receiveMessage")
- switch(msg->address){
-
- case MESSAGESERVICE_ADDRESS:
- «IF !executedInstances.empty»
- if (msg->evtID == etSystemProtocol_IN_poll)
- MsgDispatcher_«thread.name»_poll();
- else
- «ENDIF»
- if (msg->evtID == etSystemProtocol_IN_terminate)
- return FALSE;
- break;
- «FOR ai : dispatchedInstances»
-
- /* interface items of «ai.path» */
- «FOR pi : ai. orderedIfItemInstances.filter(p|p.protocol.commType==CommunicationType::EVENT_DRIVEN)»
- «IF pi.replicated»
- «FOR peer: pi.peers»
- case «pi.objId+pi.peers.indexOf(peer)»+BASE_ADDRESS:
- «IF (pi.protocol.handlesReceive(pi.isConjugated()))»
- switch (msg->evtID){
- «FOR h:getReceiveHandlers(pi.protocol,pi.isConjugated())»
- case «pi.protocol.name»_«h.msg.codeName»:
- «pi.protocol.getPortClassName(pi.isConjugated)»_«h.msg.name»_receiveHandler((etPort *)&«ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»],msg,(void*)&«ai.path.pathName»,«ai.actorClass.name»_receiveMessage);
- break;
- «ENDFOR»
- default: «ai.actorClass.name»_receiveMessage((void*)&«ai.path.pathName»,(etPort*)&«ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»], msg);
- break;
- }
- «ELSE»
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- ET_MSC_LOGGER_ASYNC_IN(
- «ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»].port.peerInstName,
- «pi.protocol.name»_getMessageString(msg->evtID),
- «ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»].port.myInstName
- )
- «ENDIF»
- «ai.actorClass.name»_receiveMessage((void*)&«ai.path.pathName»,&«ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»].port, msg);
- «ENDIF»
- break;
- «ENDFOR»
- «ELSE»
- case «pi.objId»+BASE_ADDRESS:
- «IF (pi.protocol.handlesReceive(pi.isConjugated()))»
- switch (msg->evtID){
- «FOR h:getReceiveHandlers(pi.protocol,pi.isConjugated())»
- case «pi.protocol.name»_«h.msg.codeName»:
- «pi.protocol.getPortClassName(pi.isConjugated)»_«h.msg.name»_receiveHandler((etPort *)&«ai.path.pathName»_const.«pi.name»,msg,(void*)&«ai.path.pathName»,«ai.actorClass.name»_receiveMessage);
- break;
- «ENDFOR»
- default: «ai.actorClass.name»_receiveMessage((void*)&«ai.path.pathName»,(etPort*)&«ai.path.pathName»_const.«pi.name», msg);
- break;
- }
- «ELSE»
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- ET_MSC_LOGGER_ASYNC_IN(
- ((etPort*)&«ai.path.pathName»_const.«pi.name»)->peerInstName,
- «pi.protocol.name»_getMessageString(msg->evtID),
- ((etPort*)&«ai.path.pathName»_const.«pi.name»)->myInstName
- )
- «ENDIF»
- «ai.actorClass.name»_receiveMessage((void*)&«ai.path.pathName»,(etPort*)&«ai.path.pathName»_const.«pi.name», msg);
- «ENDIF»
- break;
- «ENDIF»
- «ENDFOR»
- «ENDFOR»
-
- default:
- etLogger_logErrorF("MessageService_«thread.name»_receiveMessage: address %d does not exist ", msg->address);
- break;
- }
- ET_MSC_LOGGER_SYNC_EXIT
- return TRUE;
- }
- «ENDFOR»
- '''
- }
-
- def private checkDataPorts(SubSystemInstance comp) {
- val found = new HashSet<String>()
- for (ai: comp.allContainedInstances) {
- val thread = ai.threadId
- for (pi: ai.orderedIfItemInstances) {
- if (pi.protocol.commType==CommunicationType::DATA_DRIVEN) {
- for (peer: pi.peers) {
- val peer_ai = peer.eContainer as ActorInstance
- val peer_thread = peer_ai.threadId
- if (thread!=peer_thread) {
- val path = pi.path
- val ppath = peer.path
- val pair = if (path.compareTo(ppath)<0) path+" and "+ppath
- else ppath+" and "+path
- if (!found.contains(pair)) {
- found.add(pair)
- diagnostician.error(pair+": data ports placed on different threads (not supported yet)",
- pi.interfaceItem, pi.interfaceItem.eContainingFeature)
- }
- }
- }
- }
- }
- }
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ * Thomas Schuetz (changed for C code generator)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import java.util.ArrayList
+import java.util.HashMap
+import java.util.HashSet
+import org.eclipse.etrice.core.etmap.util.ETMapUtil
+import org.eclipse.etrice.core.etphys.eTPhys.ExecMode
+import org.eclipse.etrice.core.etphys.eTPhys.PhysicalThread
+import org.eclipse.etrice.core.genmodel.etricegen.ActorInstance
+import org.eclipse.etrice.core.genmodel.etricegen.IDiagnostician
+import org.eclipse.etrice.core.genmodel.etricegen.InterfaceItemInstance
+import org.eclipse.etrice.core.genmodel.etricegen.PortInstance
+import org.eclipse.etrice.core.genmodel.etricegen.Root
+import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance
+import org.eclipse.etrice.core.room.ActorCommunicationType
+import org.eclipse.etrice.core.room.CommunicationType
+import org.eclipse.etrice.core.room.Port
+import org.eclipse.etrice.core.room.ProtocolClass
+import org.eclipse.etrice.core.room.SAPRef
+import org.eclipse.etrice.core.room.SPPRef
+import org.eclipse.etrice.generator.base.IGeneratorFileIo
+import org.eclipse.etrice.generator.base.IntelligentSeparator
+import org.eclipse.etrice.generator.generic.ILanguageExtension
+import org.eclipse.etrice.generator.generic.ProcedureHelpers
+import org.eclipse.etrice.generator.generic.RoomExtensions
+
+import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
+import org.eclipse.etrice.generator.base.GlobalGeneratorSettings
+
+@Singleton
+class NodeGen {
+
+ @Inject extension CExtensions
+ @Inject extension RoomExtensions
+ @Inject extension ProcedureHelpers helpers
+
+ @Inject IGeneratorFileIo fileIO
+ @Inject Initialization attrInitGenAddon
+ @Inject ILanguageExtension languageExt
+ @Inject IDiagnostician diagnostician
+
+ def doGenerate(Root root) {
+ for (nr : ETMapUtil::getNodeRefs()) {
+ for (instpath : ETMapUtil::getSubSystemInstancePaths(nr)) {
+ val ssi = root.getInstance(instpath) as SubSystemInstance
+ val filepath = ssi.subSystemClass.generationTargetPath+ssi.subSystemClass.getPath
+ val infopath = ssi.subSystemClass.generationInfoPath+ssi.subSystemClass.getPath
+ var file = nr.getCHeaderFileName(ssi)
+
+ checkDataPorts(ssi)
+
+ val usedThreads = new HashSet<PhysicalThread>();
+ for (thread: nr.type.threads) {
+ val instancesOnThread = ssi.allContainedInstances.filter(ai|ETMapUtil::getPhysicalThread(ai)==thread)
+ if (!instancesOnThread.empty)
+ usedThreads.add(thread)
+ }
+
+ fileIO.generateFile("generating Node declaration", filepath, infopath, file, root.generateHeaderFile(ssi))
+
+ file = nr.getCSourceFileName(ssi)
+ fileIO.generateFile("generating Node implementation", filepath, infopath, file, root.generateSourceFile(ssi, usedThreads))
+
+ file = nr.getInstSourceFileName(ssi)
+ fileIO.generateFile("generating Node instance file", filepath, infopath, file, root.generateInstanceFile(ssi, usedThreads))
+
+ file = nr.getDispSourceFileName(ssi)
+ fileIO.generateFile("generating Node dispatcher file", filepath, infopath, file, root.generateDispatcherFile(ssi, usedThreads))
+ }
+ }
+ }
+
+ def private generateHeaderFile(Root root, SubSystemInstance ssi) {
+ val nr = ETMapUtil::getNodeRef(ssi)
+ val ssc = ssi.subSystemClass
+ val clsname = nr.name+"_"+ssi.name
+ '''
+ /**
+ * @author generated by eTrice
+ *
+ * Header File of Node «nr.name» with SubSystem «ssi.name»
+ *
+ */
+
+ «generateIncludeGuardBegin(clsname)»
+
+ #include "etDatatypes.h"
+
+««« TODOCGENPHYS: user code?
+ «helpers.userCode(ssc.userCode1)»
+
+
+ /* lifecycle functions
+ * init -> start -> run (loop) -> stop -> destroy
+ */
+
+ void «clsname»_init(void); /* lifecycle init */
+ void «clsname»_start(void); /* lifecycle start */
+
+ void «clsname»_run(etBool runAsTest); /* lifecycle run */
+
+ void «clsname»_stop(void); /* lifecycle stop */
+ void «clsname»_destroy(void); /* lifecycle destroy */
+
+ void «clsname»_shutdown(void); /* shutdown the dispatcher loop */
+
+««« TODOCGENPHYS: user code?
+ «helpers.userCode(ssc.userCode2)»
+
+ «generateIncludeGuardEnd(clsname)»
+
+
+ '''
+ }
+
+ def private generateSourceFile(Root root, SubSystemInstance ssi, HashSet<PhysicalThread> usedThreads) {
+ val nr = ETMapUtil::getNodeRef(ssi)
+ val ssc = ssi.subSystemClass
+ val clsname = nr.name+"_"+ssi.name
+ val threads = nr.type.threads.filter(t|usedThreads.contains(t))
+ '''
+ /**
+ * @author generated by eTrice
+ *
+ * Source File of Node «nr.name» with SubSystem «ssi.name»
+ *
+ */
+
+ #include <stdio.h>
+
+ #include "«nr.getCHeaderFileName(ssi)»"
+
+ #include "debugging/etLogger.h"
+ #include "debugging/etMSCLogger.h"
+ #include "messaging/etSystemProtocol.h"
+ #include "osal/etTimer.h"
+ #include "osal/etSema.h"
+ #include "runtime/etRuntime.h"
+ #include "etRuntimeConfig.h"
+
+««« TODOCGENPHYS: user code?
+ «helpers.userCode(ssc.userCode3)»
+
+ /* data for Node «nr.name» with SubSystem «ssi.name» */
+ typedef struct «clsname» {
+ char *name;
+ volatile int shutdownRequest;
+ } «clsname»;
+
+ static «clsname» «clsname»Inst = {"«clsname»", 0};
+
+ static void «clsname»_initActorInstances(void);
+ static void «clsname»_constructActorInstances(void);
+
+ /* include instances for all classes */
+ #include "«nr.getInstSourceFileName(ssi)»"
+ #include "«nr.getDispSourceFileName(ssi)»"
+
+ static void «clsname»_initMessageServices(void) {
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "initMessageServices")
+ {
+ etTime interval;
+
+ /* initialization of all message services */
+ «FOR thread: threads»
+ «IF thread.execmode==ExecMode::POLLED || thread.execmode==ExecMode::MIXED»
+««« interval.sec = «thread.sec» <-- use convenience functions to split time in sec and nsec
+ interval.sec = 0;
+ interval.nSec = «thread.time»;
+ «ENDIF»
+ etMessageService_init(
+ &msgService_«thread.name»,
+ msgBuffer_«thread.name»,
+ «thread.name.toUpperCase»_POOL_SIZE,
+ «thread.name.toUpperCase»_BLOCK_SIZE,
+ «thread.stacksize»,
+ «thread.prio»,
+ interval,
+ MsgDispatcher_«thread.name»_receiveMessage,
+ EXECMODE_«thread.execmode.toString.toUpperCase»);
+
+ «ENDFOR»
+ }
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ static void «clsname»_startMessageServices(void) {
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "startMessageServices")
+
+ «FOR thread: threads»
+ etMessageService_start(&msgService_«thread.name»);
+ «ENDFOR»
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ static void «clsname»_stopMessageServices(void) {
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "stopMessageServices")
+
+ «FOR thread: threads»
+ etMessageService_stop(&msgService_«thread.name»);
+ «ENDFOR»
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ static void «clsname»_destroyMessageServices(void) {
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "destroyMessageServices")
+
+ «FOR thread: threads»
+ etMessageService_destroy(&msgService_«thread.name»);
+ «ENDFOR»
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ void «clsname»_init(void) {
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "init")
+ etLogger_logInfoF("%s_init", «clsname»Inst.name);
+
+ /* construct all actors */
+ «clsname»_constructActorInstances();
+
+ /* initialization of all message services */
+ «clsname»_initMessageServices();
+
+ /* init all actors */
+ «clsname»_initActorInstances();
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ void «clsname»_start(void) {
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "start")
+ etLogger_logInfoF("%s_start", «clsname»Inst.name);
+ «clsname»_startMessageServices();
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ void «clsname»_run(etBool runAsTest) {
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "run")
+
+ if (runAsTest) {
+ etSema_waitForWakeup(etRuntime_getTerminateSemaphore());
+ }
+ else {
+ printf("type quit to exit\n");
+ fflush(stdout);
+ while (TRUE) {
+ char line[64];
+
+ if (fgets(line, 64, stdin) == NULL) {
+ printf("got NULL\n");
+ break;
+ }
+ else if (strncmp(line, "quit", 4)==0){
+ break;
+ }
+ }
+ }
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ void «clsname»_stop(void){
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "stop")
+ etLogger_logInfoF("%s_stop", «clsname»Inst.name);
+
+ «clsname»_stopMessageServices();
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ void «clsname»_destroy(void){
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "destroy")
+ etLogger_logInfoF("%s_destroy", «clsname»Inst.name);
+ «FOR ai : ssi.allContainedInstances.reverseView»
+ «IF !ai.actorClass.operations.filter(op|op.destructor).empty»
+ «languageExt.memberInUse(ai.actorClass.name, languageExt.destructorName(ai.actorClass.name))»(&«ai.path.getPathName()»);
+ «ENDIF»
+ «ENDFOR»
+
+ «clsname»_destroyMessageServices();
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ void «clsname»_shutdown(void){
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "shutdown")
+ etLogger_logInfoF("%s_shutdown", «clsname»Inst.name);
+
+ «clsname»Inst.shutdownRequest = 1;
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+
+ static void «clsname»_constructActorInstances(void){
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "constructActorInstances")
+
+ «FOR ai : ssi.allContainedInstances»
+ «IF !ai.actorClass.operations.filter(op|op.constructor).empty»
+ «languageExt.memberInUse(ai.actorClass.name, languageExt.constructorName(ai.actorClass.name))»(&«ai.path.getPathName()»);
+ «ENDIF»
+ «ENDFOR»
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+
+ static void «clsname»_initActorInstances(void){
+ ET_MSC_LOGGER_SYNC_ENTRY("«clsname»", "initActorInstances")
+
+ «FOR ai : ssi.allContainedInstances»
+ «ai.actorClass.name»_init(&«ai.path.getPathName()»);
+ «ENDFOR»
+
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+ '''
+ }
+
+ def private generateInstanceFile(Root root, SubSystemInstance ssi, HashSet<PhysicalThread> usedThreads) {
+ val nr = ETMapUtil::getNodeRef(ssi)
+ '''
+ /**
+ * @author generated by eTrice
+ *
+ * Instance File of Node «nr.name» with SubSystem «ssi.name»
+ * - instantiation of all actor instances and port instances
+ * - configuration of data and connection of ports
+ */
+
+ #include "messaging/etMessageService.h"
+
+ /* include all referenced ActorClasses */
+ «FOR actorClass : root.getReferencedActorClasses(ssi.subSystemClass)»
+ #include «actorClass.includePath»
+ «ENDFOR»
+
+ /* include all referenced ProtcolClasses */
+ «FOR protocolClass : root.getReferencedProtocolClasses(ssi.subSystemClass)»
+ #include «protocolClass.includePath»
+ «ENDFOR»
+
+ /* instantiation of message services and message buffers */
+ «FOR thread: nr.type.threads.filter(t|usedThreads.contains(t))»
+ /* «thread.name» */
+ #define «thread.name.toUpperCase»_POOL_SIZE «thread.msgpoolsize»
+ #define «thread.name.toUpperCase»_BLOCK_SIZE «thread.msgblocksize»
+ static uint8 msgBuffer_«thread.name»[«thread.name.toUpperCase»_POOL_SIZE * «thread.name.toUpperCase»_BLOCK_SIZE];
+ static etMessageService msgService_«thread.name»;
+ «ENDFOR»
+
+ /* declarations of all ActorClass instances (const and variable structs) */
+
+ /* forward declaration of variable actor structs */
+ «FOR ai : ssi.allContainedInstances»
+ static «ai.actorClass.name» «ai.path.getPathName()»;
+ «ENDFOR»
+
+ /* forward declaration of variable port structs */
+ «FOR ai: ssi.allContainedInstances»
+ «IF ai.orderedIfItemInstances.empty»
+ /* nothing to do */
+ «ELSE»
+ «FOR pi:ai.orderedIfItemInstances»
+ «IF pi.protocol.getPortClass(pi.conjugated)?.attributes?.size > 0»
+ static «pi.protocol.getPortClassName(pi.conjugated)»_var «pi.path.pathName»_var«IF pi.replicated»[«pi.peers.size»]«ENDIF»={
+ «FOR Integer i:1.. if(pi.peers.size==0)1 else pi.peers.size SEPARATOR ', '»
+ «attrInitGenAddon.generateAttributeInit(pi, pi.interfaceItem.portClass.attributes)»
+ «ENDFOR»};
+ «ENDIF»
+ «ENDFOR»
+ «ENDIF»
+ «ENDFOR»
+
+ «FOR ai : ssi.allContainedInstances»
+
+ /* instance «ai.path.getPathName()» */
+ «IF !GlobalGeneratorSettings::generateMSCInstrumentation && ai.orderedIfItemInstances.empty»
+ /* no ports/saps/services - nothing to initialize statically */
+ «ELSE»
+ «genActorInstanceInitializer(root, ai)»
+ «ENDIF»
+ «ENDFOR»
+
+ '''
+ }
+
+ def private genActorInstanceInitializer(Root root, ActorInstance ai) {
+ val instName = ai.path.pathName
+
+ // list of replicated interface items (all are event driven ports)
+ val replEventItems = new ArrayList<InterfaceItemInstance>()
+ replEventItems.addAll(ai.orderedIfItemInstances.filter(e|e.replicated))
+ val haveReplSubItems = replEventItems.findFirst(e|!e.peers.empty)!=null
+ val replEventPorts = replEventItems.filter(i|i.interfaceItem instanceof Port)
+ val replEventSPPs = replEventItems.filter(i|i.interfaceItem instanceof SPPRef)
+
+ val simplePorts = ai.orderedIfItemInstances.filter(e|e.simple)
+
+ // list of simple event interface items
+ val simpleEventItems = new ArrayList<InterfaceItemInstance>()
+ simpleEventItems.addAll(simplePorts.filter(p|p.protocol.commType==CommunicationType::EVENT_DRIVEN))
+
+ // lists of event driven ports and saps
+ val simpleEventPorts = simpleEventItems.filter(i|i.interfaceItem instanceof Port)
+ val simpleEventSAPs = simpleEventItems.filter(i|i.interfaceItem instanceof SAPRef)
+
+ val dataPorts = simplePorts.filter(p|p.protocol.commType==CommunicationType::DATA_DRIVEN)
+ val recvPorts = dataPorts.filter(p|p instanceof PortInstance && !(p as PortInstance).port.conjugated)
+ val sendPorts = dataPorts.filter(p|p instanceof PortInstance && (p as PortInstance).port.conjugated)
+
+ // compute replicated port offsets
+ val offsets = new HashMap<InterfaceItemInstance, Integer>()
+ var offset = 0
+ for (p: replEventItems) {
+ offsets.put(p, offset)
+ offset = offset + p.peers.size
+ }
+
+ var replSubPortsArray = if (haveReplSubItems) instName+"_repl_sub_ports" else "NULL"
+ val haveConstData = !simpleEventItems.empty || !recvPorts.empty || !replEventItems.empty
+ || GlobalGeneratorSettings::generateMSCInstrumentation
+ val sep = new IntelligentSeparator(",");
+ '''
+ «IF haveReplSubItems»
+ static const etReplSubPort «replSubPortsArray»[«offset»] = {
+ /* Replicated Sub Ports: {varData, msgService, peerAddress, localId, index} */
+ «FOR pi : replEventItems.filter(e|!e.peers.empty) SEPARATOR ","»
+ «genReplSubPortInitializers(root, ai, pi)»
+ «ENDFOR»
+ };
+ «ENDIF»
+ «IF haveConstData»
+ static const «ai.actorClass.name»_const «instName»_const = {
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ «sep»"«ai.path»"
+
+ «ENDIF»
+ /* Ports: {varData, msgService, peerAddress, localId} */
+ /* simple ports */
+ «FOR pi : simpleEventPorts»
+ «sep»«genPortInitializer(root, ai, pi)»
+ «ENDFOR»
+
+ /* data receive ports */
+ «FOR pi : recvPorts»
+ «sep»«genRecvPortInitializer(root, ai, pi)»
+ «ENDFOR»
+
+ /* saps */
+ «FOR pi : simpleEventSAPs»
+ «sep»«genPortInitializer(root, ai, pi)»
+ «ENDFOR»
+
+ /* replicated ports */
+ «FOR pi : replEventPorts»
+ «sep»{«pi.peers.size», «replSubPortsArray»+«offsets.get(pi)»}
+ «ENDFOR»
+
+ /* services */
+ «FOR pi : replEventSPPs»
+ «sep»{«pi.peers.size», «replSubPortsArray»+«offsets.get(pi)»}
+ «ENDFOR»
+ };
+ «ENDIF»
+ static «ai.actorClass.name» «instName» = {
+ «IF haveConstData»
+ &«instName»_const,
+
+ «ENDIF»
+ /* data send ports */
+ «FOR pi : sendPorts»
+ «pi.genSendPortInitializer»,
+ «ENDFOR»
+
+ /* attributes */
+ «attrInitGenAddon.generateAttributeInit(ai, ai.actorClass.allAttributes)»
+
+ /* state and history are initialized in init fuction */
+ };
+ '''}
+
+ def private String genPortInitializer(Root root, ActorInstance ai, InterfaceItemInstance pi) {
+ val objId = if (pi.peers.empty) 0 else pi.peers.get(0).objId
+ val idx = if (pi.peers.empty) 0 else pi.peers.get(0).peers.indexOf(pi)
+ val msgSvc = if (pi.peers.empty) "NULL" else "&msgService_"+ETMapUtil::getPhysicalThread(pi.peers.get(0).eContainer as ActorInstance).name
+ val myInst = if (GlobalGeneratorSettings::generateMSCInstrumentation) ",\""+(pi.eContainer as ActorInstance).path+"\","
+ else ""
+ val peerInst = if (GlobalGeneratorSettings::generateMSCInstrumentation) "\""+(pi.peers.get(0).eContainer as ActorInstance).path+"\""
+ else ""
+
+ "{"+getInterfaceItemInstanceData(pi)+", "
+ +msgSvc+", "
+ +(objId+idx)+"+BASE_ADDRESS, "
+ +(root.getExpandedActorClass(ai).getInterfaceItemLocalId(pi.interfaceItem)+1)
+ +myInst
+ +peerInst
+ +"} /* Port "+pi.name+" */"
+ }
+
+ def private genSendPortInitializer(InterfaceItemInstance pi) {
+ val pc = (pi as PortInstance).port.protocol as ProtocolClass
+
+ '''
+ {
+ «FOR m : pc.incomingMessages SEPARATOR ","»
+ «m.data.refType.type.defaultValue»
+ «ENDFOR»
+ } /* send port «pi.name» */
+ '''
+ }
+
+ def private getInterfaceItemInstanceData(InterfaceItemInstance pi){
+ if (pi.protocol.getPortClass(pi.conjugated)== null) return "NULL"
+ if (pi.protocol.getPortClass(pi.conjugated).attributes.empty){
+ return "NULL"
+ }else{
+ return "&"+pi.path.pathName+"_var"
+ }
+ }
+
+
+ def private String genRecvPortInitializer(Root root, ActorInstance ai, InterfaceItemInstance pi) {
+ if (pi.peers.empty)
+ return "{NULL}"
+
+ var peer = pi.peers.get(0)
+ var peerInst = pi.peers.get(0).eContainer() as ActorInstance
+ var instName = peerInst.path.pathName
+
+ "{&"+instName+"."+peer.name+"}"
+ }
+
+ def private String genReplSubPortInitializers(Root root, ActorInstance ai, InterfaceItemInstance pi) {
+ var result = ""
+ val myInst = if (GlobalGeneratorSettings::generateMSCInstrumentation) ",\""+(pi.eContainer as ActorInstance).path+"\","
+ else ""
+
+ for (p: pi.peers) {
+ val idx = pi.peers.indexOf(p)
+ val comma = if (idx<pi.peers.size-1) "," else ""
+ val thread = ETMapUtil::getPhysicalThread(p.eContainer as ActorInstance).name
+ var iiiD = getInterfaceItemInstanceData(pi)
+ val peerInst = if (GlobalGeneratorSettings::generateMSCInstrumentation) "\""+(p.eContainer as ActorInstance).path+"\""
+ else ""
+ iiiD = if (iiiD.equals("NULL")) iiiD+"," else iiiD+"["+idx+"],"
+ result = result +
+ "{{"+iiiD
+ +"&msgService_"+thread+", "
+ +p.objId+"+BASE_ADDRESS, "
+ +(root.getExpandedActorClass(ai).getInterfaceItemLocalId(pi.interfaceItem)+1)
+ +myInst
+ +peerInst
+ +"},"
+ +idx
+ +"}"+comma+" /* Repl Sub Port "+pi.name+" idx +"+idx+"*/\n"
+ }
+
+ return result
+ }
+
+ def private generateDispatcherFile(Root root, SubSystemInstance ssi, HashSet<PhysicalThread> usedThreads) {
+ val nr = ETMapUtil::getNodeRef(ssi)
+
+ '''
+ /**
+ * @author generated by eTrice
+ *
+ * Dispatcher File of Node «nr.name» with SubSystem «ssi.name»
+ * - one generated message dispatcher (receiveMessage) for each MessageService (Thread)
+ * - one generated execute dispatcher (execute) for each MessageService (Thread)
+ */
+
+ #include "messaging/etMessageReceiver.h"
+ #include "debugging/etLogger.h"
+ #include "debugging/etMSCLogger.h"
+
+ «FOR thread: nr.type.threads.filter(t|usedThreads.contains(t)) SEPARATOR "\n"»
+ «val instancesOnThread = ssi.allContainedInstances.filter(ai|ETMapUtil::getPhysicalThread(ai)==thread)»
+ «val dispatchedInstances = instancesOnThread.filter(ai|ai.actorClass.commType == ActorCommunicationType::EVENT_DRIVEN || ai.actorClass.commType == ActorCommunicationType::ASYNCHRONOUS)»
+ «val executedInstances = instancesOnThread.filter(ai|ai.actorClass.commType == ActorCommunicationType::DATA_DRIVEN || ai.actorClass.commType == ActorCommunicationType::ASYNCHRONOUS)»
+
+ «IF executedInstances.size > 0»
+ /**
+ * generated execute function for all cyclic execute calls for the async or datadriven actor instances of thread "«thread.name»"
+ */
+ static void MsgDispatcher_«thread.name»_poll(void){
+ ET_MSC_LOGGER_SYNC_ENTRY("MsgDispatcher_«thread.name»", "execute")
+ «FOR ai : executedInstances»
+ «ai.actorClass.name»_execute((void*)&«ai.path.pathName»);
+ «ENDFOR»
+ ET_MSC_LOGGER_SYNC_EXIT
+ }
+ «ENDIF»
+
+ /**
+ * generated dispatch function for all messages for the thread "«thread.name»"
+ */
+ static etBool MsgDispatcher_«thread.name»_receiveMessage(const etMessage* msg){
+ ET_MSC_LOGGER_SYNC_ENTRY("MsgDispatcher_«thread.name»", "receiveMessage")
+ switch(msg->address){
+
+ case MESSAGESERVICE_ADDRESS:
+ «IF !executedInstances.empty»
+ if (msg->evtID == etSystemProtocol_IN_poll)
+ MsgDispatcher_«thread.name»_poll();
+ else
+ «ENDIF»
+ if (msg->evtID == etSystemProtocol_IN_terminate)
+ return FALSE;
+ break;
+ «FOR ai : dispatchedInstances»
+
+ /* interface items of «ai.path» */
+ «FOR pi : ai. orderedIfItemInstances.filter(p|p.protocol.commType==CommunicationType::EVENT_DRIVEN)»
+ «IF pi.replicated»
+ «FOR peer: pi.peers»
+ case «pi.objId+pi.peers.indexOf(peer)»+BASE_ADDRESS:
+ «IF (pi.protocol.handlesReceive(pi.isConjugated()))»
+ switch (msg->evtID){
+ «FOR h:getReceiveHandlers(pi.protocol,pi.isConjugated())»
+ case «pi.protocol.name»_«h.msg.codeName»:
+ «pi.protocol.getPortClassName(pi.isConjugated)»_«h.msg.name»_receiveHandler((etPort *)&«ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»],msg,(void*)&«ai.path.pathName»,«ai.actorClass.name»_receiveMessage);
+ break;
+ «ENDFOR»
+ default: «ai.actorClass.name»_receiveMessage((void*)&«ai.path.pathName»,(etPort*)&«ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»], msg);
+ break;
+ }
+ «ELSE»
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ ET_MSC_LOGGER_ASYNC_IN(
+ «ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»].port.peerInstName,
+ «pi.protocol.name»_getMessageString(msg->evtID),
+ «ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»].port.myInstName
+ )
+ «ENDIF»
+ «ai.actorClass.name»_receiveMessage((void*)&«ai.path.pathName»,&«ai.path.pathName»_const.«pi.name».ports[«pi.peers.indexOf(peer)»].port, msg);
+ «ENDIF»
+ break;
+ «ENDFOR»
+ «ELSE»
+ case «pi.objId»+BASE_ADDRESS:
+ «IF (pi.protocol.handlesReceive(pi.isConjugated()))»
+ switch (msg->evtID){
+ «FOR h:getReceiveHandlers(pi.protocol,pi.isConjugated())»
+ case «pi.protocol.name»_«h.msg.codeName»:
+ «pi.protocol.getPortClassName(pi.isConjugated)»_«h.msg.name»_receiveHandler((etPort *)&«ai.path.pathName»_const.«pi.name»,msg,(void*)&«ai.path.pathName»,«ai.actorClass.name»_receiveMessage);
+ break;
+ «ENDFOR»
+ default: «ai.actorClass.name»_receiveMessage((void*)&«ai.path.pathName»,(etPort*)&«ai.path.pathName»_const.«pi.name», msg);
+ break;
+ }
+ «ELSE»
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ ET_MSC_LOGGER_ASYNC_IN(
+ ((etPort*)&«ai.path.pathName»_const.«pi.name»)->peerInstName,
+ «pi.protocol.name»_getMessageString(msg->evtID),
+ ((etPort*)&«ai.path.pathName»_const.«pi.name»)->myInstName
+ )
+ «ENDIF»
+ «ai.actorClass.name»_receiveMessage((void*)&«ai.path.pathName»,(etPort*)&«ai.path.pathName»_const.«pi.name», msg);
+ «ENDIF»
+ break;
+ «ENDIF»
+ «ENDFOR»
+ «ENDFOR»
+
+ default:
+ etLogger_logErrorF("MessageService_«thread.name»_receiveMessage: address %d does not exist ", msg->address);
+ break;
+ }
+ ET_MSC_LOGGER_SYNC_EXIT
+ return TRUE;
+ }
+ «ENDFOR»
+ '''
+ }
+
+ def private checkDataPorts(SubSystemInstance comp) {
+ val found = new HashSet<String>()
+ for (ai: comp.allContainedInstances) {
+ val thread = ai.threadId
+ for (pi: ai.orderedIfItemInstances) {
+ if (pi.protocol.commType==CommunicationType::DATA_DRIVEN) {
+ for (peer: pi.peers) {
+ val peer_ai = peer.eContainer as ActorInstance
+ val peer_thread = peer_ai.threadId
+ if (thread!=peer_thread) {
+ val path = pi.path
+ val ppath = peer.path
+ val pair = if (path.compareTo(ppath)<0) path+" and "+ppath
+ else ppath+" and "+path
+ if (!found.contains(pair)) {
+ found.add(pair)
+ diagnostician.error(pair+": data ports placed on different threads (not supported yet)",
+ pi.interfaceItem, pi.interfaceItem.eContainingFeature)
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeRunnerGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeRunnerGen.xtend
index 7acd1769a..86e0eec2f 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeRunnerGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/NodeRunnerGen.xtend
@@ -1,106 +1,106 @@
-/*******************************************************************************
- * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- * Thomas Schuetz (changed for C code generator)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import org.eclipse.etrice.core.genmodel.etricegen.Root
-import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance
-import org.eclipse.xtext.generator.JavaIoFileSystemAccess
-import org.eclipse.etrice.generator.generic.RoomExtensions
-import org.eclipse.etrice.core.etmap.util.ETMapUtil
-
-@Singleton
-class NodeRunnerGen {
-
- @Inject extension JavaIoFileSystemAccess fileAccess
- @Inject extension CExtensions
- @Inject extension RoomExtensions
-
- def doGenerate(Root root) {
- var first = true
- for (nr : ETMapUtil::getNodeRefs()) {
- for (instpath : ETMapUtil::getSubSystemInstancePaths(nr)) {
- val ssi = root.getInstance(instpath) as SubSystemInstance
- val clsname = nr.name+"_"+ssi.name
- fileAccess.setOutputPath(ssi.subSystemClass.generationTargetPath+ssi.subSystemClass.getPath)
- fileAccess.generateFile( clsname+"_Runner.c", root.generateSourceFile(ssi, first))
- first = false
- }
- }
- }
-
- def generateSourceFile(Root root, SubSystemInstance ssi, boolean first) {
- val nr = ETMapUtil::getNodeRef(ssi)
- val clsname = nr.name+"_"+ssi.name
- '''
- /**
- * @author generated by eTrice
- *
- * this class contains the main function running Node «nr.name» with SubSystem «ssi.name»
- * it instantiates Node «nr.name» with SubSystem «ssi.name» and starts and ends the lifecycle
- */
-
-
- #include "«nr.getCHeaderFileName(ssi)»"
-
- #include "debugging/etLogger.h"
- #include "debugging/etMSCLogger.h"
-
- #include "osal/etPlatformLifecycle.h"
-
- /**
- * main function
- * creates component and starts and stops the lifecycle
- */
-
- int main(int argc, char** argv) {
- etBool runAsTest = FALSE;
-
- if (argc>1 && strcmp(argv[1], "-headless")==0)
- runAsTest = TRUE;
- if (argc>1 && strcmp(argv[1], "-run_as_test")==0)
- runAsTest = TRUE;
-
- etUserEntry(); /* platform specific */
-
- etLogger_logInfo("*** T H E B E G I N ***");
- ET_MSC_LOGGER_OPEN("main");
-
- /* startup sequence of lifecycle */
- «clsname»_init(); /* lifecycle init */
- «clsname»_start(); /* lifecycle start */
-
- etUserPreRun(); /* platform specific */
-
- /* run Scheduler */
- «clsname»_run(runAsTest);
-
- etUserPostRun(); /* platform specific */
-
- /* shutdown sequence of lifecycle */
- «clsname»_stop(); /* lifecycle stop */
- «clsname»_destroy(); /* lifecycle destroy */
-
- ET_MSC_LOGGER_CLOSE
- etLogger_logInfo("*** T H E E N D ***");
-
- etUserExit(); /* platform specific */
-
- return 0;
- }
-
- '''
- }
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ * Thomas Schuetz (changed for C code generator)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import org.eclipse.etrice.core.genmodel.etricegen.Root
+import org.eclipse.etrice.core.genmodel.etricegen.SubSystemInstance
+import org.eclipse.xtext.generator.JavaIoFileSystemAccess
+import org.eclipse.etrice.generator.generic.RoomExtensions
+import org.eclipse.etrice.core.etmap.util.ETMapUtil
+
+@Singleton
+class NodeRunnerGen {
+
+ @Inject extension JavaIoFileSystemAccess fileAccess
+ @Inject extension CExtensions
+ @Inject extension RoomExtensions
+
+ def doGenerate(Root root) {
+ var first = true
+ for (nr : ETMapUtil::getNodeRefs()) {
+ for (instpath : ETMapUtil::getSubSystemInstancePaths(nr)) {
+ val ssi = root.getInstance(instpath) as SubSystemInstance
+ val clsname = nr.name+"_"+ssi.name
+ fileAccess.setOutputPath(ssi.subSystemClass.generationTargetPath+ssi.subSystemClass.getPath)
+ fileAccess.generateFile( clsname+"_Runner.c", root.generateSourceFile(ssi, first))
+ first = false
+ }
+ }
+ }
+
+ def generateSourceFile(Root root, SubSystemInstance ssi, boolean first) {
+ val nr = ETMapUtil::getNodeRef(ssi)
+ val clsname = nr.name+"_"+ssi.name
+ '''
+ /**
+ * @author generated by eTrice
+ *
+ * this class contains the main function running Node «nr.name» with SubSystem «ssi.name»
+ * it instantiates Node «nr.name» with SubSystem «ssi.name» and starts and ends the lifecycle
+ */
+
+
+ #include "«nr.getCHeaderFileName(ssi)»"
+
+ #include "debugging/etLogger.h"
+ #include "debugging/etMSCLogger.h"
+
+ #include "osal/etPlatformLifecycle.h"
+
+ /**
+ * main function
+ * creates component and starts and stops the lifecycle
+ */
+
+ int main(int argc, char** argv) {
+ etBool runAsTest = FALSE;
+
+ if (argc>1 && strcmp(argv[1], "-headless")==0)
+ runAsTest = TRUE;
+ if (argc>1 && strcmp(argv[1], "-run_as_test")==0)
+ runAsTest = TRUE;
+
+ etUserEntry(); /* platform specific */
+
+ etLogger_logInfo("*** T H E B E G I N ***");
+ ET_MSC_LOGGER_OPEN("main");
+
+ /* startup sequence of lifecycle */
+ «clsname»_init(); /* lifecycle init */
+ «clsname»_start(); /* lifecycle start */
+
+ etUserPreRun(); /* platform specific */
+
+ /* run Scheduler */
+ «clsname»_run(runAsTest);
+
+ etUserPostRun(); /* platform specific */
+
+ /* shutdown sequence of lifecycle */
+ «clsname»_stop(); /* lifecycle stop */
+ «clsname»_destroy(); /* lifecycle destroy */
+
+ ET_MSC_LOGGER_CLOSE
+ etLogger_logInfo("*** T H E E N D ***");
+
+ etUserExit(); /* platform specific */
+
+ return 0;
+ }
+
+ '''
+ }
} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ProtocolClassGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ProtocolClassGen.xtend
index 0b3fdfa1f..255677da5 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ProtocolClassGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/ProtocolClassGen.xtend
@@ -1,388 +1,388 @@
-/*******************************************************************************
- * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- * Thomas Schuetz (changed for C code generator)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import org.eclipse.etrice.core.genmodel.base.ILogger
-import org.eclipse.etrice.core.genmodel.etricegen.Root
-import org.eclipse.etrice.core.room.CommunicationType
-import org.eclipse.etrice.core.room.PrimitiveType
-import org.eclipse.etrice.core.room.ProtocolClass
-import org.eclipse.etrice.generator.base.AbstractGenerator
-import org.eclipse.etrice.generator.base.IGeneratorFileIo
-import org.eclipse.etrice.generator.generic.GenericProtocolClassGenerator
-import org.eclipse.etrice.generator.generic.ProcedureHelpers
-import org.eclipse.etrice.generator.generic.RoomExtensions
-import org.eclipse.etrice.generator.generic.TypeHelpers
-
-import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
-import org.eclipse.etrice.generator.base.GlobalGeneratorSettings
-
-@Singleton
-class ProtocolClassGen extends GenericProtocolClassGenerator {
-
- @Inject IGeneratorFileIo fileIO
- @Inject extension CExtensions
- @Inject extension RoomExtensions
- @Inject extension ProcedureHelpers
- @Inject extension TypeHelpers
- @Inject ILogger logger
-
- def doGenerate(Root root) {
- for (pc: root.usedProtocolClasses) {
- val path = pc.generationTargetPath+pc.getPath
- val infopath = pc.generationInfoPath+pc.getPath
- var file = pc.getCHeaderFileName
-
- // header file
- fileIO.generateFile("generating ProtocolClass header", path, infopath, file, root.generateHeaderFile(pc))
-
- // source file
- file = pc.getCSourceFileName
- fileIO.generateFile("generating ProtocolClass source", path, infopath, file, root.generateSourceFile(pc))
- }
- }
-
-
- def private generateHeaderFile(Root root, ProtocolClass pc) {'''
- /**
- * @author generated by eTrice
- *
- * Header File of ProtocolClass «pc.name»
- *
- */
-
- «generateIncludeGuardBegin(pc)»
-
- #include "etDatatypes.h"
- #include "modelbase/etPort.h"
-
- «pc.userCode(1)»
-
- «FOR dataClass : root.getReferencedDataClasses(pc)»
- #include «dataClass.includePath»
- «ENDFOR»
-
- «IF pc.commType==CommunicationType::EVENT_DRIVEN»
-
- /* message IDs */
- «genMessageIDs(pc)»
-
- /*--------------------- port structs and methods */
- «portClassHeader(pc, false)»
- «portClassHeader(pc, true)»
- «ELSEIF pc.commType==CommunicationType::DATA_DRIVEN»
- /*--------------------- port structs and methods */
- «pc.genDataDrivenPortHeaders»
- «ELSEIF pc.commType==CommunicationType::SYNCHRONOUS»
- #error "synchronoue protocols not implemented yet"
- «ENDIF»
-««« «portClass(pc, false)»
-««« «portClass(pc, true)»
-
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- /*--------------------- debug helpers */
-
- /* get message string for message id */
- const char* «pc.name»_getMessageString(int msg_id);
- «ENDIF»
-
- «pc.userCode(2)»
-
- «generateIncludeGuardEnd(pc)»
-
- '''
- }
-
- def private generateSourceFile(Root root, ProtocolClass pc) {'''
- /**
- * @author generated by eTrice
- *
- * Source File of ProtocolClass «pc.name»
- *
- */
-
- #include "«pc.getCHeaderFileName»"
- #include "debugging/etMSCLogger.h"
-
- «pc.userCode(3)»
-
- /*--------------------- port methods */
- «IF pc.commType==CommunicationType::EVENT_DRIVEN»
- «portClassSource(pc, false)»
- «portClassSource(pc, true)»
-
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- /*--------------------- debug helpers */
- «generateDebugHelpersImplementation(root, pc)»
- «ENDIF»
- «ELSEIF pc.commType==CommunicationType::DATA_DRIVEN»
- «pc.genDataDrivenPortSources»
- «ELSEIF pc.commType==CommunicationType::SYNCHRONOUS»
- #error "synchronous protocols not implemented yet"
- «ENDIF»
- '''
- }
-
- def private portClassHeader(ProtocolClass pc, Boolean conj){
- var portClassName = pc.getPortClassName(conj)
- var replPortClassName = pc.getPortClassName(conj, true)
- var messages = if (conj) pc.allIncomingMessages else pc.allOutgoingMessages
-
- '''
- typedef etPort «portClassName»;
- typedef etReplPort «replPortClassName»;
-
- «IF pc.getPortClass(conj)!=null»
- «IF !(pc.getPortClass(conj).attributes.empty)»
- /* variable part of PortClass (RAM) */
- typedef struct «portClassName»_var «portClassName»_var;
- struct «portClassName»_var {
- «pc.getPortClass(conj).attributes.attributes»
- };
- «FOR a:pc.getPortClass(conj).attributes»
- «IF a.defaultValueLiteral!=null»
- «logger.logInfo(portClassName+" "+a.name+": Attribute initialization not supported in C")»
- «ENDIF»
- «ENDFOR»
- «ENDIF»
- «ENDIF»
-
- «FOR message : messages»
- «var hasData = message.data!=null»
- «var typeName = if (hasData) message.data.refType.type.typeName else ""»
- «var refp = if (hasData && (!(message.data.refType.type instanceof PrimitiveType)||(message.data.refType.ref))) "*" else ""»
- «var data = if (hasData) ", "+typeName+refp+" data" else ""»
- «messageSignature(portClassName, message.name, "", data)»;
- «messageSignature(replPortClassName, message.name, "_broadcast", data)»;
- «messageSignature(replPortClassName, message.name, "", ", int idx"+data)»;
- «ENDFOR»
-
- «IF (pc.getPortClass(conj) != null)»
- «pc.getPortClass(conj).operations.operationsDeclaration(portClassName)»
- «ENDIF»
-
- «IF pc.handlesReceive(conj)»
- «FOR h:getReceiveHandlers(pc,conj)»
- void «portClassName»_«h.msg.name»_receiveHandler(«portClassName»* self, const etMessage* msg, void * actor, etActorReceiveMessage receiveMessageFunc);
- «ENDFOR»
- «ENDIF»
- etInt32 «replPortClassName»_getReplication(const «replPortClassName»* self);
- '''
- }
-
-
-
- def private genDataDrivenPortHeaders(ProtocolClass pc) {
- var sentMsgs = pc.allIncomingMessages.filter(m|m.data!=null)
-
- '''
- /* data driven send port (conjugated) */
- typedef struct {
- «FOR msg : sentMsgs»
- «var typeName = msg.data.refType.type.typeName»
- «var refp = if (msg.data.refType.ref) "*" else ""»
- «typeName»«refp» «msg.name»;
- «ENDFOR»
- }
- «pc.getPortClassName(true)»;
-
- /* data driven receive port (regular) */
- typedef struct {
- const «pc.getPortClassName(true)»* peer;
- }
- «pc.getPortClassName(false)»;
-
- «FOR message : sentMsgs»
- «var hasData = message.data!=null»
- «var typeName = if (hasData) message.data.refType.type.typeName else ""»
- «var refp = if (hasData && !(message.data.refType.type instanceof PrimitiveType)) "*" else ""»
- «var data = if (hasData) ", "+typeName+refp+" data" else ""»
- «messageSetterSignature(pc.getPortClassName(true), message.name, data)»;
- «messageGetterSignature(pc.getPortClassName(false), message.name, typeName)»;
-
- «ENDFOR»
- '''
- }
- def private genDataDrivenPortSources(ProtocolClass pc) {
- var messages = pc.allIncomingMessages.filter(m|m.data!=null)
- '''
- «FOR message : messages»
- «var typeName =message.data.refType.type.typeName»
- «var refp = if (!(message.data.refType.type instanceof PrimitiveType)) "*" else ""»
- «var data = ", "+typeName+refp+" data"»
- «messageSetterSignature(pc.getPortClassName(true), message.name, data)» {
- self->«message.name» = «refp»data;
- }
- «messageGetterSignature(pc.getPortClassName(false), message.name, typeName)» {
- return self->peer->«message.name»;
- }
-
- «ENDFOR»
- '''
- }
-
- def private portClassSource(ProtocolClass pc, Boolean conj) {
- val pclass = pc.getPortClass(conj)
- val portClassName = pc.getPortClassName(conj)
- val replPortClassName = pc.getPortClassName(conj, true)
- val messages = if (conj) pc.allIncomingMessages else pc.allOutgoingMessages
- val dir = if (conj) "IN_" else "OUT_"
-
- '''
- «FOR message : messages»
- «var hasData = message.data!=null»
- «var typeName = if (hasData) message.data.refType.type.typeName else ""»
- «var refp = if (hasData && ((message.data.refType.ref))) "*" else ""»
- «var refpd = if (hasData && (!(message.data.refType.type instanceof PrimitiveType)||(message.data.refType.ref))) "*" else ""»
- «var refa = if (hasData && (!(message.data.refType.type instanceof PrimitiveType))&&(!(message.data.refType.ref))) "" else "&"»
- «var data = if (hasData) ", "+typeName+refpd+" data" else ""»
- «var dataCall = if (hasData) ", data" else ""»
- «var hdlr = message.getSendHandler(conj)»
-
- «messageSignature(portClassName, message.name, "", data)» {
- «IF hdlr != null»
- «AbstractGenerator::getInstance().getTranslatedCode(hdlr.detailCode)»
- «ELSE»
- ET_MSC_LOGGER_SYNC_ENTRY("«portClassName»", "«message.name»")
- «sendMessageCall(hasData, "self", memberInUse(pc.name, dir+message.name), typeName+refp, refa+"data")»
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- ET_MSC_LOGGER_ASYNC_OUT(self->myInstName, "«message.name»", self->peerInstName)
- «ENDIF»
- ET_MSC_LOGGER_SYNC_EXIT
- «ENDIF»
- }
-
- «messageSignature(replPortClassName, message.name, "_broadcast", data)» {
- «IF hdlr != null»
- int i;
- for (i=0; i<((etReplPort*)self)->size; ++i) {
- «portClassName»_«message.name»(&((etReplPort*)self)->ports[i].port«dataCall»);
- }
- «ELSE»
- int i;
- ET_MSC_LOGGER_SYNC_ENTRY("«replPortClassName»", "«message.name»")
- for (i=0; i<((etReplPort*)self)->size; ++i) {
- «sendMessageCall(hasData, "(&((etReplPort*)self)->ports[i].port)", memberInUse(pc.name, dir+message.name), typeName+refp, refa+"data")»
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- ET_MSC_LOGGER_ASYNC_OUT(((etReplPort*)self)->ports[i].port.myInstName, "«message.name»", ((etReplPort*)self)->ports[i].port.peerInstName)
- «ENDIF»
- }
- ET_MSC_LOGGER_SYNC_EXIT
- «ENDIF»
- }
-
- «messageSignature(replPortClassName, message.name, "", ", int idx"+data)» {
- «IF hdlr != null»
- «portClassName»_«message.name»(&((etReplPort*)self)->ports[idx].port«dataCall»);
- «ELSE»
- ET_MSC_LOGGER_SYNC_ENTRY("«replPortClassName»", "«message.name»")
- if (0<=idx && idx<((etReplPort*)self)->size) {
- «sendMessageCall(hasData, "(&((etReplPort*)self)->ports[idx].port)", memberInUse(pc.name, dir+message.name), typeName+refp, refa+"data")»
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- ET_MSC_LOGGER_ASYNC_OUT(((etReplPort*)self)->ports[idx].port.myInstName, "«message.name»", ((etReplPort*)self)->ports[idx].port.peerInstName)
- «ENDIF»
- }
- ET_MSC_LOGGER_SYNC_EXIT
- «ENDIF»
- }
-
- «ENDFOR»
- «IF pclass!=null»
- /* begin «portClassName» specific */
- «pclass.userCode.userCode»
-
- «pc.getPortClass(conj).operations.operationsImplementation(portClassName)»
- /* end «portClassName» specific */
-
- «ENDIF»
- etInt32 «replPortClassName»_getReplication(const «replPortClassName»* self) {
- return ((etReplPort*)self)->size;
- }
-
- «IF pc.handlesReceive(conj)»
- «genReceiveHandlers(pc,conj)»
- «ENDIF»
-
- '''
- }
-
- def private sendMessageCall(boolean hasData, String self, String msg, String typeName, String data) {
- if (hasData)
- "etPort_sendMessage("+self+", "+msg+", sizeof("+typeName+"), "+data+");"
- else
- "etPort_sendMessage("+self+", "+msg+", 0, NULL);"
- }
-
- def private messageSignature(String className, String messageName, String methodSuffix, String data) {
- "void "+className+"_"+messageName+methodSuffix+"(const "+className+"* self"+data+")"
- }
-
- def private messageSetterSignature(String className, String messageName, String data) {
- "void "+className+"_"+messageName+"_set("+className+"* self"+data+")"
- }
-
- def private messageGetterSignature(String className, String messageName, String type) {
- type+" "+className+"_"+messageName+"_get(const "+className+"* const self)"
- }
-
-// TODO: can this be deleted?
-// def sendMessage(Message m, boolean conj) {'''
-// «var dir = if (conj) "IN" else "OUT"»
-// «var hdlr = m.getSendHandler(conj)»
-// «messageSignature(m)»{
-// if (getPeerAddress()!=null)
-// «IF m.data==null»getPeerMsgReceiver().receive(new EventMessage(getPeerAddress(), «dir»_«m.name»));
-// «ELSE»getPeerMsgReceiver().receive(new EventWithDataMessage(getPeerAddress(), «dir»_«m.name», «m.data.name»«IF (!m.data.ref)».deepCopy()«ENDIF»));
-// «ENDIF»
-// }
-// '''
-// }
-
- def private genReceiveHandlers(ProtocolClass pc, Boolean conj){
- var portClassName = pc.getPortClassName(conj)
-
- '''
- /* receiver handlers */
- «FOR h:getReceiveHandlers(pc,conj)»
- void «portClassName»_«h.msg.name»_receiveHandler(«portClassName»* self, const etMessage* msg, void * actor, etActorReceiveMessage receiveMessageFunc){
- «AbstractGenerator::getInstance().getTranslatedCode(h.detailCode)»
- /* hand over the message to the actor: */
- /* (*receiveMessageFunc)(actor, self, msg); */
- }
- «ENDFOR»
- '''}
-
-
-
- def private generateDebugHelpersImplementation(Root root, ProtocolClass pc){'''
-
-««« TODO: make this optional or different for smaller footprint
- /* message names as strings for debugging (generate MSC) */
- static const char* const «pc.name»_messageStrings[] = {"MIN", «FOR m : pc.getAllOutgoingMessages()»"«m.name»",«ENDFOR»«FOR m : pc.getAllIncomingMessages()»"«m.name»", «ENDFOR»"MAX"};
-
- const char* «pc.name»_getMessageString(int msg_id) {
- if (msg_id<«pc.name»_MSG_MIN || msg_id>«pc.name»_MSG_MAX+1){
- /* id out of range */
- return "Message ID out of range";
- }
- else{
- return «pc.name»_messageStrings[msg_id];
- }
- }
- '''
- }
-
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ * Thomas Schuetz (changed for C code generator)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import org.eclipse.etrice.core.genmodel.base.ILogger
+import org.eclipse.etrice.core.genmodel.etricegen.Root
+import org.eclipse.etrice.core.room.CommunicationType
+import org.eclipse.etrice.core.room.PrimitiveType
+import org.eclipse.etrice.core.room.ProtocolClass
+import org.eclipse.etrice.generator.base.AbstractGenerator
+import org.eclipse.etrice.generator.base.IGeneratorFileIo
+import org.eclipse.etrice.generator.generic.GenericProtocolClassGenerator
+import org.eclipse.etrice.generator.generic.ProcedureHelpers
+import org.eclipse.etrice.generator.generic.RoomExtensions
+import org.eclipse.etrice.generator.generic.TypeHelpers
+
+import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
+import org.eclipse.etrice.generator.base.GlobalGeneratorSettings
+
+@Singleton
+class ProtocolClassGen extends GenericProtocolClassGenerator {
+
+ @Inject IGeneratorFileIo fileIO
+ @Inject extension CExtensions
+ @Inject extension RoomExtensions
+ @Inject extension ProcedureHelpers
+ @Inject extension TypeHelpers
+ @Inject ILogger logger
+
+ def doGenerate(Root root) {
+ for (pc: root.usedProtocolClasses) {
+ val path = pc.generationTargetPath+pc.getPath
+ val infopath = pc.generationInfoPath+pc.getPath
+ var file = pc.getCHeaderFileName
+
+ // header file
+ fileIO.generateFile("generating ProtocolClass header", path, infopath, file, root.generateHeaderFile(pc))
+
+ // source file
+ file = pc.getCSourceFileName
+ fileIO.generateFile("generating ProtocolClass source", path, infopath, file, root.generateSourceFile(pc))
+ }
+ }
+
+
+ def private generateHeaderFile(Root root, ProtocolClass pc) {'''
+ /**
+ * @author generated by eTrice
+ *
+ * Header File of ProtocolClass «pc.name»
+ *
+ */
+
+ «generateIncludeGuardBegin(pc)»
+
+ #include "etDatatypes.h"
+ #include "modelbase/etPort.h"
+
+ «pc.userCode(1)»
+
+ «FOR dataClass : root.getReferencedDataClasses(pc)»
+ #include «dataClass.includePath»
+ «ENDFOR»
+
+ «IF pc.commType==CommunicationType::EVENT_DRIVEN»
+
+ /* message IDs */
+ «genMessageIDs(pc)»
+
+ /*--------------------- port structs and methods */
+ «portClassHeader(pc, false)»
+ «portClassHeader(pc, true)»
+ «ELSEIF pc.commType==CommunicationType::DATA_DRIVEN»
+ /*--------------------- port structs and methods */
+ «pc.genDataDrivenPortHeaders»
+ «ELSEIF pc.commType==CommunicationType::SYNCHRONOUS»
+ #error "synchronoue protocols not implemented yet"
+ «ENDIF»
+««« «portClass(pc, false)»
+««« «portClass(pc, true)»
+
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ /*--------------------- debug helpers */
+
+ /* get message string for message id */
+ const char* «pc.name»_getMessageString(int msg_id);
+ «ENDIF»
+
+ «pc.userCode(2)»
+
+ «generateIncludeGuardEnd(pc)»
+
+ '''
+ }
+
+ def private generateSourceFile(Root root, ProtocolClass pc) {'''
+ /**
+ * @author generated by eTrice
+ *
+ * Source File of ProtocolClass «pc.name»
+ *
+ */
+
+ #include "«pc.getCHeaderFileName»"
+ #include "debugging/etMSCLogger.h"
+
+ «pc.userCode(3)»
+
+ /*--------------------- port methods */
+ «IF pc.commType==CommunicationType::EVENT_DRIVEN»
+ «portClassSource(pc, false)»
+ «portClassSource(pc, true)»
+
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ /*--------------------- debug helpers */
+ «generateDebugHelpersImplementation(root, pc)»
+ «ENDIF»
+ «ELSEIF pc.commType==CommunicationType::DATA_DRIVEN»
+ «pc.genDataDrivenPortSources»
+ «ELSEIF pc.commType==CommunicationType::SYNCHRONOUS»
+ #error "synchronous protocols not implemented yet"
+ «ENDIF»
+ '''
+ }
+
+ def private portClassHeader(ProtocolClass pc, Boolean conj){
+ var portClassName = pc.getPortClassName(conj)
+ var replPortClassName = pc.getPortClassName(conj, true)
+ var messages = if (conj) pc.allIncomingMessages else pc.allOutgoingMessages
+
+ '''
+ typedef etPort «portClassName»;
+ typedef etReplPort «replPortClassName»;
+
+ «IF pc.getPortClass(conj)!=null»
+ «IF !(pc.getPortClass(conj).attributes.empty)»
+ /* variable part of PortClass (RAM) */
+ typedef struct «portClassName»_var «portClassName»_var;
+ struct «portClassName»_var {
+ «pc.getPortClass(conj).attributes.attributes»
+ };
+ «FOR a:pc.getPortClass(conj).attributes»
+ «IF a.defaultValueLiteral!=null»
+ «logger.logInfo(portClassName+" "+a.name+": Attribute initialization not supported in C")»
+ «ENDIF»
+ «ENDFOR»
+ «ENDIF»
+ «ENDIF»
+
+ «FOR message : messages»
+ «var hasData = message.data!=null»
+ «var typeName = if (hasData) message.data.refType.type.typeName else ""»
+ «var refp = if (hasData && (!(message.data.refType.type instanceof PrimitiveType)||(message.data.refType.ref))) "*" else ""»
+ «var data = if (hasData) ", "+typeName+refp+" data" else ""»
+ «messageSignature(portClassName, message.name, "", data)»;
+ «messageSignature(replPortClassName, message.name, "_broadcast", data)»;
+ «messageSignature(replPortClassName, message.name, "", ", int idx"+data)»;
+ «ENDFOR»
+
+ «IF (pc.getPortClass(conj) != null)»
+ «pc.getPortClass(conj).operations.operationsDeclaration(portClassName)»
+ «ENDIF»
+
+ «IF pc.handlesReceive(conj)»
+ «FOR h:getReceiveHandlers(pc,conj)»
+ void «portClassName»_«h.msg.name»_receiveHandler(«portClassName»* self, const etMessage* msg, void * actor, etActorReceiveMessage receiveMessageFunc);
+ «ENDFOR»
+ «ENDIF»
+ etInt32 «replPortClassName»_getReplication(const «replPortClassName»* self);
+ '''
+ }
+
+
+
+ def private genDataDrivenPortHeaders(ProtocolClass pc) {
+ var sentMsgs = pc.allIncomingMessages.filter(m|m.data!=null)
+
+ '''
+ /* data driven send port (conjugated) */
+ typedef struct {
+ «FOR msg : sentMsgs»
+ «var typeName = msg.data.refType.type.typeName»
+ «var refp = if (msg.data.refType.ref) "*" else ""»
+ «typeName»«refp» «msg.name»;
+ «ENDFOR»
+ }
+ «pc.getPortClassName(true)»;
+
+ /* data driven receive port (regular) */
+ typedef struct {
+ const «pc.getPortClassName(true)»* peer;
+ }
+ «pc.getPortClassName(false)»;
+
+ «FOR message : sentMsgs»
+ «var hasData = message.data!=null»
+ «var typeName = if (hasData) message.data.refType.type.typeName else ""»
+ «var refp = if (hasData && !(message.data.refType.type instanceof PrimitiveType)) "*" else ""»
+ «var data = if (hasData) ", "+typeName+refp+" data" else ""»
+ «messageSetterSignature(pc.getPortClassName(true), message.name, data)»;
+ «messageGetterSignature(pc.getPortClassName(false), message.name, typeName)»;
+
+ «ENDFOR»
+ '''
+ }
+ def private genDataDrivenPortSources(ProtocolClass pc) {
+ var messages = pc.allIncomingMessages.filter(m|m.data!=null)
+ '''
+ «FOR message : messages»
+ «var typeName =message.data.refType.type.typeName»
+ «var refp = if (!(message.data.refType.type instanceof PrimitiveType)) "*" else ""»
+ «var data = ", "+typeName+refp+" data"»
+ «messageSetterSignature(pc.getPortClassName(true), message.name, data)» {
+ self->«message.name» = «refp»data;
+ }
+ «messageGetterSignature(pc.getPortClassName(false), message.name, typeName)» {
+ return self->peer->«message.name»;
+ }
+
+ «ENDFOR»
+ '''
+ }
+
+ def private portClassSource(ProtocolClass pc, Boolean conj) {
+ val pclass = pc.getPortClass(conj)
+ val portClassName = pc.getPortClassName(conj)
+ val replPortClassName = pc.getPortClassName(conj, true)
+ val messages = if (conj) pc.allIncomingMessages else pc.allOutgoingMessages
+ val dir = if (conj) "IN_" else "OUT_"
+
+ '''
+ «FOR message : messages»
+ «var hasData = message.data!=null»
+ «var typeName = if (hasData) message.data.refType.type.typeName else ""»
+ «var refp = if (hasData && ((message.data.refType.ref))) "*" else ""»
+ «var refpd = if (hasData && (!(message.data.refType.type instanceof PrimitiveType)||(message.data.refType.ref))) "*" else ""»
+ «var refa = if (hasData && (!(message.data.refType.type instanceof PrimitiveType))&&(!(message.data.refType.ref))) "" else "&"»
+ «var data = if (hasData) ", "+typeName+refpd+" data" else ""»
+ «var dataCall = if (hasData) ", data" else ""»
+ «var hdlr = message.getSendHandler(conj)»
+
+ «messageSignature(portClassName, message.name, "", data)» {
+ «IF hdlr != null»
+ «AbstractGenerator::getInstance().getTranslatedCode(hdlr.detailCode)»
+ «ELSE»
+ ET_MSC_LOGGER_SYNC_ENTRY("«portClassName»", "«message.name»")
+ «sendMessageCall(hasData, "self", memberInUse(pc.name, dir+message.name), typeName+refp, refa+"data")»
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ ET_MSC_LOGGER_ASYNC_OUT(self->myInstName, "«message.name»", self->peerInstName)
+ «ENDIF»
+ ET_MSC_LOGGER_SYNC_EXIT
+ «ENDIF»
+ }
+
+ «messageSignature(replPortClassName, message.name, "_broadcast", data)» {
+ «IF hdlr != null»
+ int i;
+ for (i=0; i<((etReplPort*)self)->size; ++i) {
+ «portClassName»_«message.name»(&((etReplPort*)self)->ports[i].port«dataCall»);
+ }
+ «ELSE»
+ int i;
+ ET_MSC_LOGGER_SYNC_ENTRY("«replPortClassName»", "«message.name»")
+ for (i=0; i<((etReplPort*)self)->size; ++i) {
+ «sendMessageCall(hasData, "(&((etReplPort*)self)->ports[i].port)", memberInUse(pc.name, dir+message.name), typeName+refp, refa+"data")»
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ ET_MSC_LOGGER_ASYNC_OUT(((etReplPort*)self)->ports[i].port.myInstName, "«message.name»", ((etReplPort*)self)->ports[i].port.peerInstName)
+ «ENDIF»
+ }
+ ET_MSC_LOGGER_SYNC_EXIT
+ «ENDIF»
+ }
+
+ «messageSignature(replPortClassName, message.name, "", ", int idx"+data)» {
+ «IF hdlr != null»
+ «portClassName»_«message.name»(&((etReplPort*)self)->ports[idx].port«dataCall»);
+ «ELSE»
+ ET_MSC_LOGGER_SYNC_ENTRY("«replPortClassName»", "«message.name»")
+ if (0<=idx && idx<((etReplPort*)self)->size) {
+ «sendMessageCall(hasData, "(&((etReplPort*)self)->ports[idx].port)", memberInUse(pc.name, dir+message.name), typeName+refp, refa+"data")»
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ ET_MSC_LOGGER_ASYNC_OUT(((etReplPort*)self)->ports[idx].port.myInstName, "«message.name»", ((etReplPort*)self)->ports[idx].port.peerInstName)
+ «ENDIF»
+ }
+ ET_MSC_LOGGER_SYNC_EXIT
+ «ENDIF»
+ }
+
+ «ENDFOR»
+ «IF pclass!=null»
+ /* begin «portClassName» specific */
+ «pclass.userCode.userCode»
+
+ «pc.getPortClass(conj).operations.operationsImplementation(portClassName)»
+ /* end «portClassName» specific */
+
+ «ENDIF»
+ etInt32 «replPortClassName»_getReplication(const «replPortClassName»* self) {
+ return ((etReplPort*)self)->size;
+ }
+
+ «IF pc.handlesReceive(conj)»
+ «genReceiveHandlers(pc,conj)»
+ «ENDIF»
+
+ '''
+ }
+
+ def private sendMessageCall(boolean hasData, String self, String msg, String typeName, String data) {
+ if (hasData)
+ "etPort_sendMessage("+self+", "+msg+", sizeof("+typeName+"), "+data+");"
+ else
+ "etPort_sendMessage("+self+", "+msg+", 0, NULL);"
+ }
+
+ def private messageSignature(String className, String messageName, String methodSuffix, String data) {
+ "void "+className+"_"+messageName+methodSuffix+"(const "+className+"* self"+data+")"
+ }
+
+ def private messageSetterSignature(String className, String messageName, String data) {
+ "void "+className+"_"+messageName+"_set("+className+"* self"+data+")"
+ }
+
+ def private messageGetterSignature(String className, String messageName, String type) {
+ type+" "+className+"_"+messageName+"_get(const "+className+"* const self)"
+ }
+
+// TODO: can this be deleted?
+// def sendMessage(Message m, boolean conj) {'''
+// «var dir = if (conj) "IN" else "OUT"»
+// «var hdlr = m.getSendHandler(conj)»
+// «messageSignature(m)»{
+// if (getPeerAddress()!=null)
+// «IF m.data==null»getPeerMsgReceiver().receive(new EventMessage(getPeerAddress(), «dir»_«m.name»));
+// «ELSE»getPeerMsgReceiver().receive(new EventWithDataMessage(getPeerAddress(), «dir»_«m.name», «m.data.name»«IF (!m.data.ref)».deepCopy()«ENDIF»));
+// «ENDIF»
+// }
+// '''
+// }
+
+ def private genReceiveHandlers(ProtocolClass pc, Boolean conj){
+ var portClassName = pc.getPortClassName(conj)
+
+ '''
+ /* receiver handlers */
+ «FOR h:getReceiveHandlers(pc,conj)»
+ void «portClassName»_«h.msg.name»_receiveHandler(«portClassName»* self, const etMessage* msg, void * actor, etActorReceiveMessage receiveMessageFunc){
+ «AbstractGenerator::getInstance().getTranslatedCode(h.detailCode)»
+ /* hand over the message to the actor: */
+ /* (*receiveMessageFunc)(actor, self, msg); */
+ }
+ «ENDFOR»
+ '''}
+
+
+
+ def private generateDebugHelpersImplementation(Root root, ProtocolClass pc){'''
+
+««« TODO: make this optional or different for smaller footprint
+ /* message names as strings for debugging (generate MSC) */
+ static const char* const «pc.name»_messageStrings[] = {"MIN", «FOR m : pc.getAllOutgoingMessages()»"«m.name»",«ENDFOR»«FOR m : pc.getAllIncomingMessages()»"«m.name»", «ENDFOR»"MAX"};
+
+ const char* «pc.name»_getMessageString(int msg_id) {
+ if (msg_id<«pc.name»_MSG_MIN || msg_id>«pc.name»_MSG_MAX+1){
+ /* id out of range */
+ return "Message ID out of range";
+ }
+ else{
+ return «pc.name»_messageStrings[msg_id];
+ }
+ }
+ '''
+ }
+
} \ No newline at end of file
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend
index c5e1bf686..3523b1cf4 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/StateMachineGen.xtend
@@ -1,91 +1,91 @@
-/*******************************************************************************
- * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen
-
-import com.google.inject.Inject
-import com.google.inject.Singleton
-import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass
-import org.eclipse.etrice.generator.generic.RoomExtensions
-import org.eclipse.etrice.generator.generic.GenericStateMachineGenerator
-import static extension org.eclipse.etrice.generator.base.CodegenHelpers.*
-import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
-import org.eclipse.etrice.generator.base.GlobalGeneratorSettings
-
-@Singleton
-class StateMachineGen extends GenericStateMachineGenerator {
-
- @Inject extension RoomExtensions
-
- def genHeaderConstants(ExpandedActorClass xpac) {
- val ac = xpac.actorClass
- /* TODO: can save one entry if NO_STATE=-1 but influences Java */
- val historySize = ac.allBaseStates.size - ac.allLeafStates.size + 2
- '''
- /* constant for state machine data */
- #define «ac.name.toUpperCase»_HISTORY_SIZE «historySize»
- '''
- }
-
- def genDataMembers(ExpandedActorClass xpac) {
- val ac = xpac.actorClass
- '''
- /* state machine variables */
- etInt16 state;
- etInt16 history[«ac.name.toUpperCase»_HISTORY_SIZE];
- '''
- }
-
- def genInitialization(ExpandedActorClass xpac) {
- val ac = xpac.actorClass
- '''
- self->state = STATE_TOP;
- {
- int i;
- for (i=0; i<«ac.name.toUpperCase»_HISTORY_SIZE; ++i)
- self->history[i] = NO_STATE;
- }
- «langExt.operationScope(ac.name, false)»executeInitTransition(self);
- '''
- }
-
- override protected genExtra(ExpandedActorClass xpac) {
- val ac = xpac.actorClass
- '''
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- /* state names */
- static char* stateStrings[] = {"<no state>","<top>",«FOR state : ac.getAllBaseStatesLeavesLast() SEPARATOR ","»"«state.genStatePathName»"
- «ENDFOR»};
- «ENDIF»
-
- «langExt.accessLevelPrivate»void setState(«ac.name»* self, «stateType» new_state) {
- self->state = new_state;
- «IF GlobalGeneratorSettings::generateMSCInstrumentation»
- ET_MSC_LOGGER_CHANGE_STATE(self->constData->instName, stateStrings[new_state])
- «ENDIF»
- }
-
- «langExt.accessLevelPrivate»«stateType» getState(«ac.name»* self) {
- return self->state;
- }
- '''
- }
-
- override protected stateType() {
- "etInt16"
- }
-
- override protected unreachableReturn() {
- "/* return NO_STATE; // required by CDT but detected as unreachable by JDT because of while (true) */"
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen
+
+import com.google.inject.Inject
+import com.google.inject.Singleton
+import org.eclipse.etrice.core.genmodel.etricegen.ExpandedActorClass
+import org.eclipse.etrice.generator.generic.RoomExtensions
+import org.eclipse.etrice.generator.generic.GenericStateMachineGenerator
+import static extension org.eclipse.etrice.generator.base.CodegenHelpers.*
+import static extension org.eclipse.etrice.core.room.util.RoomHelpers.*
+import org.eclipse.etrice.generator.base.GlobalGeneratorSettings
+
+@Singleton
+class StateMachineGen extends GenericStateMachineGenerator {
+
+ @Inject extension RoomExtensions
+
+ def genHeaderConstants(ExpandedActorClass xpac) {
+ val ac = xpac.actorClass
+ /* TODO: can save one entry if NO_STATE=-1 but influences Java */
+ val historySize = ac.allBaseStates.size - ac.allLeafStates.size + 2
+ '''
+ /* constant for state machine data */
+ #define «ac.name.toUpperCase»_HISTORY_SIZE «historySize»
+ '''
+ }
+
+ def genDataMembers(ExpandedActorClass xpac) {
+ val ac = xpac.actorClass
+ '''
+ /* state machine variables */
+ etInt16 state;
+ etInt16 history[«ac.name.toUpperCase»_HISTORY_SIZE];
+ '''
+ }
+
+ def genInitialization(ExpandedActorClass xpac) {
+ val ac = xpac.actorClass
+ '''
+ self->state = STATE_TOP;
+ {
+ int i;
+ for (i=0; i<«ac.name.toUpperCase»_HISTORY_SIZE; ++i)
+ self->history[i] = NO_STATE;
+ }
+ «langExt.operationScope(ac.name, false)»executeInitTransition(self);
+ '''
+ }
+
+ override protected genExtra(ExpandedActorClass xpac) {
+ val ac = xpac.actorClass
+ '''
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ /* state names */
+ static char* stateStrings[] = {"<no state>","<top>",«FOR state : ac.getAllBaseStatesLeavesLast() SEPARATOR ","»"«state.genStatePathName»"
+ «ENDFOR»};
+ «ENDIF»
+
+ «langExt.accessLevelPrivate»void setState(«ac.name»* self, «stateType» new_state) {
+ self->state = new_state;
+ «IF GlobalGeneratorSettings::generateMSCInstrumentation»
+ ET_MSC_LOGGER_CHANGE_STATE(self->constData->instName, stateStrings[new_state])
+ «ENDIF»
+ }
+
+ «langExt.accessLevelPrivate»«stateType» getState(«ac.name»* self) {
+ return self->state;
+ }
+ '''
+ }
+
+ override protected stateType() {
+ "etInt16"
+ }
+
+ override protected unreachableReturn() {
+ "/* return NO_STATE; // required by CDT but detected as unreachable by JDT because of while (true) */"
+ }
+
+}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/Validator.java b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/Validator.java
index a478373fc..05c00fec1 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/Validator.java
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/gen/Validator.java
@@ -1,26 +1,26 @@
-/*******************************************************************************
- * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.gen;
-
-import org.eclipse.etrice.core.genmodel.etricegen.Root;
-
-/**
- * @author Henrik Rentz-Reichert
- *
- */
-public class Validator {
-
- public boolean validate(Root genModel) {
- return true;
- }
-}
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.gen;
+
+import org.eclipse.etrice.core.genmodel.etricegen.Root;
+
+/**
+ * @author Henrik Rentz-Reichert
+ *
+ */
+public class Validator {
+
+ public boolean validate(Root genModel) {
+ return true;
+ }
+}
diff --git a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/setup/GeneratorModule.java b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/setup/GeneratorModule.java
index 72dc7ac72..77421388a 100644
--- a/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/setup/GeneratorModule.java
+++ b/plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice/generator/c/setup/GeneratorModule.java
@@ -1,53 +1,53 @@
-/*******************************************************************************
- * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * CONTRIBUTORS:
- * Henrik Rentz-Reichert (initial contribution)
- *
- *******************************************************************************/
-
-package org.eclipse.etrice.generator.c.setup;
-
-import org.eclipse.etrice.generator.base.AbstractGenerator;
-import org.eclipse.etrice.generator.base.AbstractGeneratorBaseModule;
-import org.eclipse.etrice.generator.base.IDataConfiguration;
-import org.eclipse.etrice.generator.base.ITranslationProvider;
-import org.eclipse.etrice.generator.c.Main;
-import org.eclipse.etrice.generator.c.gen.CTranslationProvider;
-import org.eclipse.etrice.generator.c.gen.MainGen;
-import org.eclipse.etrice.generator.generic.ILanguageExtension;
-import org.eclipse.xtext.generator.IGenerator;
-import org.eclipse.etrice.generator.c.gen.CExtensions;
-import org.eclipse.etrice.generator.config.DataConfiguration;
-import com.google.inject.Binder;
-
-public class GeneratorModule extends AbstractGeneratorBaseModule {
-
-// @Override
- public void configure(Binder binder) {
- super.configure(binder);
-
- binder.bind(AbstractGenerator.class).to(Main.class);
- binder.bind(IGenerator.class).to(MainGen.class);
- }
-
- @Override
- public Class<? extends ILanguageExtension> bindILanguageExtension() {
- return CExtensions.class;
- }
-
- @Override
- public Class<? extends ITranslationProvider> bindITranslationProvider() {
- return CTranslationProvider.class;
- }
-
- @Override
- public Class<? extends IDataConfiguration> bindIDataConfiguration() {
- return DataConfiguration.class;
- }
-
-}
+/*******************************************************************************
+ * Copyright (c) 2011 protos software gmbh (http://www.protos.de).
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * CONTRIBUTORS:
+ * Henrik Rentz-Reichert (initial contribution)
+ *
+ *******************************************************************************/
+
+package org.eclipse.etrice.generator.c.setup;
+
+import org.eclipse.etrice.generator.base.AbstractGenerator;
+import org.eclipse.etrice.generator.base.AbstractGeneratorBaseModule;
+import org.eclipse.etrice.generator.base.IDataConfiguration;
+import org.eclipse.etrice.generator.base.ITranslationProvider;
+import org.eclipse.etrice.generator.c.Main;
+import org.eclipse.etrice.generator.c.gen.CTranslationProvider;
+import org.eclipse.etrice.generator.c.gen.MainGen;
+import org.eclipse.etrice.generator.generic.ILanguageExtension;
+import org.eclipse.xtext.generator.IGenerator;
+import org.eclipse.etrice.generator.c.gen.CExtensions;
+import org.eclipse.etrice.generator.config.DataConfiguration;
+import com.google.inject.Binder;
+
+public class GeneratorModule extends AbstractGeneratorBaseModule {
+
+// @Override
+ public void configure(Binder binder) {
+ super.configure(binder);
+
+ binder.bind(AbstractGenerator.class).to(Main.class);
+ binder.bind(IGenerator.class).to(MainGen.class);
+ }
+
+ @Override
+ public Class<? extends ILanguageExtension> bindILanguageExtension() {
+ return CExtensions.class;
+ }
+
+ @Override
+ public Class<? extends ITranslationProvider> bindITranslationProvider() {
+ return CTranslationProvider.class;
+ }
+
+ @Override
+ public Class<? extends IDataConfiguration> bindIDataConfiguration() {
+ return DataConfiguration.class;
+ }
+
+}

Back to the top