View Javadoc

1   /***
2    * Cecilia ADL Compiler
3    * Copyright (C) 2006-2007 STMicroelectronics
4    *
5    * This library is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU Lesser General Public
7    * License as published by the Free Software Foundation; either
8    * version 2 of the License, or (at your option) any later version.
9    *
10   * This library is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13   * Lesser General Public License for more details.
14   *
15   * You should have received a copy of the GNU Lesser General Public
16   * License along with this library; if not, write to the Free Software
17   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   *
19   * Contact: fractal@objectweb.org
20   *
21   * Author:Ali Erdem Ozcan
22   */
23  
24  package org.objectweb.fractal.cecilia.adl.idl;
25  
26  import java.util.ArrayList;
27  import java.util.LinkedHashMap;
28  import java.util.List;
29  import java.util.Map;
30  
31  import org.objectweb.fractal.adl.ADLException;
32  import org.objectweb.fractal.adl.Node;
33  import org.objectweb.fractal.api.Component;
34  import org.objectweb.fractal.cecilia.adl.SourceCodeProvider;
35  import org.objectweb.fractal.cecilia.adl.file.CodeWriter;
36  import org.objectweb.fractal.cecilia.adl.idl.ast.Field;
37  import org.objectweb.fractal.cecilia.adl.idl.ast.IDLDefinition;
38  import org.objectweb.fractal.cecilia.adl.idl.ast.Import;
39  import org.objectweb.fractal.cecilia.adl.idl.ast.ImportContainer;
40  import org.objectweb.fractal.cecilia.adl.idl.ast.UnionDefinition;
41  import org.objectweb.fractal.cecilia.adl.idl.util.CUtil;
42  import org.objectweb.fractal.cecilia.adl.idl.util.Util;
43  import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
44  import org.objectweb.fractal.task.core.Executable;
45  import org.objectweb.fractal.task.core.TaskException;
46  import org.objectweb.fractal.task.core.primitive.annotations.ClientInterfaceForEach;
47  import org.objectweb.fractal.task.core.primitive.annotations.ServerInterface;
48  import org.objectweb.fractal.task.core.primitive.annotations.ServerInterfaces;
49  import org.objectweb.fractal.task.core.primitive.annotations.TaskParameters;
50  
51  /**
52   * Visitor component for {@link UnionDefinition} nodes.
53   */
54  public class CUnionDefinitionVisitor extends AbstractTaskFactoryUser
55      implements
56        IDLDefinitionVisitor {
57  
58    // ---------------------------------------------------------------------------
59    // Implementation of the IDLVisitor interface
60    // ---------------------------------------------------------------------------
61  
62    /**
63     * Visits {@link UnionDefiniton} nodes, and creates a task that writes the
64     * corresponding C source code.
65     */
66    public Component visit(final List<Node> path,
67        final IDLDefinition idlDefinition, final Map<Object, Object> context)
68        throws ADLException, TaskException {
69      if (idlDefinition instanceof UnionDefinition) {
70  
71        final List<IDLDefinition> importedDefinitions = new ArrayList<IDLDefinition>();
72        if (idlDefinition instanceof ImportContainer) {
73          for (final Import imp : ((ImportContainer) idlDefinition).getImports()) {
74            importedDefinitions.add((IDLDefinition) Util.getImportedAST(imp));
75          }
76        }
77  
78        return taskFactoryItf
79            .newPrimitiveTask(new CUnionSourceTask(
80                (UnionDefinition) idlDefinition), idlDefinition,
81                importedDefinitions);
82      } else
83        return null;
84    }
85  
86    // ---------------------------------------------------------------------------
87    // Task classes
88    // ---------------------------------------------------------------------------
89  
90    /**
91     * Builds union definitions for C. It extends the Abstract Interface visitor
92     * and implements the required visit methods.
93     */
94    @TaskParameters({"unionDefinitionNode", "importedDefinitions"})
95    @ServerInterfaces(@ServerInterface(name = "c-union-definition-provider", signature = SourceCodeProvider.class, record = "role:cUnionDefinition, id:%", parameters = {"unionDefinitionNode"}))
96    public static class CUnionSourceTask extends AbstractUnionVisitor
97        implements
98          Executable,
99          SourceCodeProvider {
100 
101     protected final UnionDefinition                    unionDefinition;
102 
103     // -------------------------------------------------------------------------
104     // Client interfaces
105     // -------------------------------------------------------------------------
106 
107     /** Source code to be included to access to definition of imported IDLs. */
108     @ClientInterfaceForEach(iterable = "importedDefinitions", prefix = "imported-definition", signature = SourceCodeProvider.class, record = "role:importedDefinition, id:%", parameters = "importedDefinitions.element")
109     public final Map<IDLDefinition, SourceCodeProvider> importedDefinitionItfs = new LinkedHashMap<IDLDefinition, SourceCodeProvider>();
110 
111     // -------------------------------------------------------------------------
112     // Task constructor
113     // -------------------------------------------------------------------------
114 
115     /**
116      * Simple constructor.
117      * 
118      * @param unionDefinition The union definition node for which this task
119      *            must generate C source code.
120      */
121     public CUnionSourceTask(final UnionDefinition unionDefinition) {
122       this.unionDefinition = unionDefinition;
123     }
124 
125     // The generated source code.
126     protected String     sourceCode;
127     // The code writer that is used for code generation
128     protected CodeWriter cw;
129     // union names translated in C.
130     String               unionName;
131 
132     // -------------------------------------------------------------------------
133     // Implementation of the Executable interface
134     // -------------------------------------------------------------------------
135 
136     public void execute() throws Exception {
137       cw = new CodeWriter("C Union builder");
138       this.unionName = unionDefinition.getName();
139       if (unionName != null) {
140         // Visit
141         visit(unionDefinition);
142       }
143       sourceCode = cw.toString();
144     }
145 
146     // -------------------------------------------------------------------------
147     // Implementation of the SourceCodeProvider interface
148     // -------------------------------------------------------------------------
149 
150     public String getSourceCode() {
151       return sourceCode;
152     }
153 
154     // -------------------------------------------------------------------------
155     // Implementation of the visitor methods
156     // -------------------------------------------------------------------------
157 
158     public void enterUnion(final UnionDefinition union) throws Exception {
159       cw.append("/* Generated union :" + unionName + " */").endl();
160 
161       final String unionCName = unionName.replace('.', '_');
162       cw.append("#ifndef _").append(unionCName.toUpperCase()).append("_IDL_H_")
163           .endl();
164       cw.append("#define _").append(unionCName.toUpperCase()).append("_IDL_H_")
165           .endl();
166       cw.endl();
167 
168       for (final SourceCodeProvider importedDefinitionProvider : importedDefinitionItfs
169           .values()) {
170         cw.append(importedDefinitionProvider.getSourceCode());
171       }
172 
173       cw.endl();
174       cw.endl();
175       cw.append("/* some cecilia typedefs for predefinite C types */").endl();
176       cw.append("#include \"cecilia_types.h\"").endl();
177       cw.endl();
178       cw.endl();
179 
180       cw.append("union ").append(unionCName).append(";").endl();
181       cw.append("typedef union ").append(unionCName).append(' ').append(unionCName)
182           .append(";").endl();
183       cw.append("typedef union ").append(unionCName).append(" R").append(unionCName)
184           .append(";").endl();
185       cw.append("union ").append(unionCName).append("{").endl();
186     }
187 
188     public void leaveUnion(final UnionDefinition union) throws Exception {
189       cw.append("};").endl();
190       cw.endl();
191       final String unionCName = unionName.replace('.', '_');
192       cw.append("#define ").append(unionCName.toUpperCase()).append("_POINTER \\")
193           .endl();
194       cw.append("  union ").append(unionCName).append("* ").endl();
195       cw.append("#define ").append(unionCName.toUpperCase())
196           .append("_UNION \\").endl();
197       cw.append("  union ").append(unionCName).endl();
198 
199       cw.append("#endif").endl();
200     }
201 
202     public void visitField(final Field field) throws Exception {
203       cw.append(CUtil.buildUnionField(field));
204       cw.append(";").endl();
205     }
206 
207   }
208 }