1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 package org.objectweb.fractal.cecilia.adl.idl;
26
27 import java.util.ArrayList;
28 import java.util.LinkedHashMap;
29 import java.util.List;
30 import java.util.Map;
31
32 import org.objectweb.fractal.adl.ADLException;
33 import org.objectweb.fractal.adl.Node;
34 import org.objectweb.fractal.api.Component;
35 import org.objectweb.fractal.cecilia.adl.SourceCodeProvider;
36 import org.objectweb.fractal.cecilia.adl.file.CodeWriter;
37 import org.objectweb.fractal.cecilia.adl.idl.ast.Field;
38 import org.objectweb.fractal.cecilia.adl.idl.ast.IDLDefinition;
39 import org.objectweb.fractal.cecilia.adl.idl.ast.Import;
40 import org.objectweb.fractal.cecilia.adl.idl.ast.ImportContainer;
41 import org.objectweb.fractal.cecilia.adl.idl.ast.InterfaceDefinition;
42 import org.objectweb.fractal.cecilia.adl.idl.ast.Method;
43 import org.objectweb.fractal.cecilia.adl.idl.ast.PrimitiveType;
44 import org.objectweb.fractal.cecilia.adl.idl.ast.TypeContainer;
45 import org.objectweb.fractal.cecilia.adl.idl.util.CUtil;
46 import org.objectweb.fractal.cecilia.adl.idl.util.Util;
47 import org.objectweb.fractal.task.core.AbstractTaskFactoryUser;
48 import org.objectweb.fractal.task.core.Executable;
49 import org.objectweb.fractal.task.core.TaskException;
50 import org.objectweb.fractal.task.core.primitive.annotations.ClientInterfaceForEach;
51 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterface;
52 import org.objectweb.fractal.task.core.primitive.annotations.ServerInterfaces;
53 import org.objectweb.fractal.task.core.primitive.annotations.TaskParameters;
54
55
56
57
58 public class CInterfaceDefinitionVisitor extends AbstractTaskFactoryUser
59 implements
60 IDLDefinitionVisitor {
61
62
63
64
65
66
67
68
69
70 public Component visit(final List<Node> path,
71 final IDLDefinition idlDefinition, final Map<Object, Object> context)
72 throws ADLException, TaskException {
73
74 if (idlDefinition instanceof InterfaceDefinition) {
75
76 final List<IDLDefinition> importedDefinitions = new ArrayList<IDLDefinition>();
77 if (idlDefinition instanceof ImportContainer) {
78 for (final Import imp : ((ImportContainer) idlDefinition).getImports()) {
79 importedDefinitions.add((IDLDefinition) Util.getImportedAST(imp));
80 }
81 }
82
83 return taskFactoryItf.newPrimitiveTask(new CInterfaceHeaderTask(
84 (InterfaceDefinition) idlDefinition), idlDefinition,
85 importedDefinitions);
86 } else
87 return null;
88 }
89
90
91
92
93
94
95
96
97
98 @TaskParameters({"interfaceDefinitionNode", "importedDefinitions"})
99 @ServerInterfaces(@ServerInterface(name = "c-interface-definition-provider", signature = SourceCodeProvider.class, record = "role:cInterfaceDefinition, id:%", parameters = {"interfaceDefinitionNode"}))
100 public static class CInterfaceHeaderTask extends AbstractInterfaceVisitor
101 implements
102 Executable,
103 SourceCodeProvider {
104
105 protected final InterfaceDefinition itfDefinition;
106
107
108
109
110
111
112 @ClientInterfaceForEach(iterable = "importedDefinitions", prefix = "imported-definition", signature = SourceCodeProvider.class, record = "role:importedDefinition, id:%", parameters = "importedDefinitions.element")
113 public final Map<IDLDefinition, SourceCodeProvider> importedDefinitionItfs = new LinkedHashMap<IDLDefinition, SourceCodeProvider>();
114
115
116
117
118
119
120
121
122
123 public CInterfaceHeaderTask(final InterfaceDefinition itfDefinition) {
124 this.itfDefinition = itfDefinition;
125 }
126
127
128 protected String sourceCode;
129
130 protected CodeWriter cw;
131
132 protected String itfName;
133
134 protected String cItfName;
135
136
137
138
139
140 public void execute() throws Exception {
141 cw = new CodeWriter("C Interface builder");
142 itfName = itfDefinition.getName();
143 cItfName = itfName.replace('.', '_');
144
145 visit(itfDefinition);
146 cw.endl();
147 sourceCode = cw.toString();
148 }
149
150
151
152
153
154 public String getSourceCode() {
155 return sourceCode;
156 }
157
158
159
160
161
162 public void enterInterface(final InterfaceDefinition itf) throws Exception {
163 cw.append("/* Interface ").append(itfName).endl();
164 cw.appendln("Generated automatically, do not edit ! */");
165 cw.endl();
166
167 cw.append("#ifndef H").append(cItfName).endl();
168 cw.append("#define H").append(cItfName).endl();
169 cw.endl();
170
171 cw.append("// Interface descriptor");
172 cw.append("struct M").append(cItfName).append(";").endl();
173 cw.appendln("typedef struct {");
174 cw.append(" struct M").append(cItfName).append(" *meth;").endl();
175 cw.appendln(" void *selfdata;");
176 cw.appendln("#if defined(TYPEDINTERFACE)");
177 cw.appendln(" const char *type;");
178 cw.appendln("#endif");
179 cw.append("} ");
180 cw.append(" *").append(cItfName).append(",");
181
182 cw.append(" R").append(cItfName).append(";").endl();
183
184 for (final SourceCodeProvider importedDefinitionProvider : importedDefinitionItfs
185 .values()) {
186 cw.append(importedDefinitionProvider.getSourceCode());
187 }
188
189
190 cw.endl();
191 cw.append("/* some cecilia typedefs for predefinite C types */").endl();
192 cw.append("#include \"cecilia_types.h\"").endl();
193 cw.endl();
194
195 cw.endl();
196
197 cw.appendln(" /* Virtual table */");
198 cw.append("struct M").append(cItfName).append(" {").endl();
199 }
200
201 public void leaveInterface(final InterfaceDefinition itf) throws Exception {
202 cw.append("};").endl().endl();
203 cw.appendln("#endif");
204 }
205
206 public void visitMethod(final Method method) throws Exception {
207 cw.append(CUtil.buildMethodDefinition(method, true)).append(";").endl();
208 }
209
210 public void visitField(final Field field) throws Exception {
211 final PrimitiveType type = ((TypeContainer) field).getPrimitiveType();
212 cw.append("#define ").append(cItfName).append("_")
213 .append(field.getName()).append(" ((").append(
214 CUtil.buildPrimitiveType(type)).append(") ").append(
215 field.getValue()).append(')').endl();
216 cw.endl();
217 }
218 }
219 }