diff options
Diffstat (limited to 'plugins/org.eclipse.etrice.generator.c/src/org/eclipse/etrice')
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; + } + +} |