fixed compilation errors when DEBUG is switched on
[deliverable/titan.core.git] / compiler2 / CodeGenHelper.cc
1 /******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Balasko, Jeno
10 * Baranyi, Botond
11 * Raduly, Csaba
12 * Zalanyi, Balazs Andor
13 *
14 ******************************************************************************/
15 #include "CodeGenHelper.hh"
16 #include "Code.hh"
17 #include "error.h"
18 #include "main.hh"
19 #include <cstdio>
20 #include <cstring>
21
22 namespace Common {
23
24 CodeGenHelper* CodeGenHelper::instance = 0;
25
26 CodeGenHelper::generated_output_t::generated_output_t() :
27 is_module(false),
28 is_ttcn(true),
29 has_circular_import(false)
30 {
31 Code::init_output(&os);
32 }
33
34 CodeGenHelper::generated_output_t::~generated_output_t() {
35 Code::free_output(&os);
36 }
37
38 // from Type.cc
39 const char* const CodeGenHelper::typetypemap[] = {
40 "", /**< undefined */
41 "", /**< erroneous (e.g. nonexistent reference) */
42 "", /**< null (ASN.1) */
43 "", /**< boolean */
44 "", /**< integer */
45 "", /**< integer / ASN */
46 "", /**< real/float */
47 "", /**< enumerated / ASN */
48 "", /**< enumerated / TTCN */
49 "", /**< bitstring */
50 "", /**< bitstring */
51 "", /**< hexstring (TTCN-3) */
52 "", /**< octetstring */
53 "", /**< charstring (TTCN-3) */
54 "", /**< universal charstring (TTCN-3) */
55 "", /**< UTF8String (ASN.1) */
56 "", /**< NumericString (ASN.1) */
57 "", /**< PrintableString (ASN.1) */
58 "", /**< TeletexString (ASN.1) */
59 "", /**< VideotexString (ASN.1) */
60 "", /**< IA5String (ASN.1) */
61 "", /**< GraphicString (ASN.1) */
62 "", /**< VisibleString (ASN.1) */
63 "", /**< GeneralString (ASN.1) */
64 "", /**< UniversalString (ASN.1) */
65 "", /**< BMPString (ASN.1) */
66 "", /**< UnrestrictedCharacterString (ASN.1) */
67 "", /**< UTCTime (ASN.1) */
68 "", /**< GeneralizedTime (ASN.1) */
69 "", /** Object descriptor, a kind of string (ASN.1) */
70 "", /**< object identifier */
71 "", /**< relative OID (ASN.1) */
72 "_union", /**< choice /ASN, uses u.secho */
73 "_union", /**< union /TTCN, uses u.secho */
74 "_seqof", /**< sequence (record) of */
75 "_setof", /**< set of */
76 "_seq", /**< sequence /ASN, uses u.secho */
77 "_seq", /**< record /TTCN, uses u.secho */
78 "_set", /**< set /ASN, uses u.secho */
79 "_set", /**< set /TTCN, uses u.secho */
80 "", /**< ObjectClassFieldType (ASN.1) */
81 "", /**< open type (ASN.1) */
82 "", /**< ANY (deprecated ASN.1) */
83 "", /**< %EXTERNAL (ASN.1) */
84 "", /**< EMBEDDED PDV (ASN.1) */
85 "", /**< referenced */
86 "", /**< special referenced (by pointer, not by name) */
87 "", /**< selection type (ASN.1) */
88 "", /**< verdict type (TTCN-3) */
89 "", /**< port type (TTCN-3) */
90 "", /**< component type (TTCN-3) */
91 "", /**< address type (TTCN-3) */
92 "", /**< default type (TTCN-3) */
93 "", /**< array (TTCN-3), uses u.array */
94 "", /**< signature (TTCN-3) */
95 "", /**< function reference (TTCN-3) */
96 "", /**< altstep reference (TTCN-3) */
97 "", /**< testcase reference (TTCN-3) */
98 "", /**< anytype (TTCN-3) */
99 0
100 };
101
102 CodeGenHelper::CodeGenHelper() :
103 split_mode(SPLIT_NONE)
104 {
105 if (instance != 0)
106 FATAL_ERROR("Attempted to create a second code generator.");
107 instance = this;
108 }
109
110 CodeGenHelper& CodeGenHelper::GetInstance() {
111 if (instance == 0)
112 FATAL_ERROR("Trying to access to the already destroyed code generator.");
113 return *instance;
114 }
115
116 void CodeGenHelper::set_split_mode(split_type st) {
117 split_mode = st;
118 }
119
120 bool CodeGenHelper::set_split_mode(const char* type) {
121 if (strcmp(type, "none") == 0)
122 split_mode = SPLIT_NONE;
123 else if (strcmp(type, "type") == 0)
124 split_mode = SPLIT_BY_KIND;
125 else
126 return false;
127 return true;
128 }
129
130 CodeGenHelper::split_type CodeGenHelper::get_split_mode() const {
131 return split_mode;
132 }
133
134 void CodeGenHelper::add_module(const string& name, const string& dispname,
135 bool is_ttcn, bool has_circular_import) {
136 generated_output_t* go = new generated_output_t;
137 go->filename.clear();
138 go->modulename = name;
139 go->module_dispname = dispname;
140 go->is_module = true;
141 go->is_ttcn = is_ttcn;
142 go->has_circular_import = has_circular_import;
143 generated_code.add(dispname, go);
144 module_names_t* mod_names = new module_names_t;
145 mod_names->name = name;
146 mod_names->dispname = dispname;
147 modules.add(mod_names);
148 }
149
150 output_struct* CodeGenHelper::get_outputstruct(const string& name) {
151 return &generated_code[name]->os;
152 }
153
154 void CodeGenHelper::set_current_module(const string& name) {
155 current_module = name;
156 }
157
158 output_struct* CodeGenHelper::get_outputstruct(Ttcn::Definition* def) {
159 string key = get_key(*def);
160 const string& new_name = current_module + key;
161 if (!generated_code.has_key(new_name)) {
162 generated_output_t* go = new generated_output_t;
163 go->filename = key;
164 go->modulename = generated_code[current_module]->modulename;
165 go->module_dispname = generated_code[current_module]->module_dispname;
166 generated_code.add(new_name, go);
167 go->os.source.includes = mprintf("\n#include \"%s.hh\"\n"
168 , current_module.c_str());
169 }
170 return &generated_code[new_name]->os;
171 }
172
173 output_struct* CodeGenHelper::get_outputstruct(Type* type) {
174 string key = get_key(*type);
175 const string& new_name = current_module + key;
176 if (!generated_code.has_key(new_name)) {
177 generated_output_t* go = new generated_output_t;
178 go->filename = key;
179 go->modulename = generated_code[current_module]->modulename;
180 go->module_dispname = generated_code[current_module]->module_dispname;
181 generated_code.add(new_name, go);
182 go->os.source.includes = mprintf("\n#include \"%s.hh\"\n"
183 , current_module.c_str());
184 }
185 return &generated_code[new_name]->os;
186 }
187
188 output_struct* CodeGenHelper::get_current_outputstruct() {
189 return &generated_code[current_module]->os;
190 }
191
192 void CodeGenHelper::transfer_value(char* &dst, char* &src) {
193 dst = mputstr(dst, src);
194 Free(src);
195 src = 0;
196 }
197
198 void CodeGenHelper::finalize_generation(Type* type) {
199 string key = get_key(*type);
200 if (key.empty()) return;
201
202 output_struct& dst = *get_current_outputstruct();
203 output_struct& src = *get_outputstruct(current_module + key);
204 // key is not empty so these can never be the same
205
206 transfer_value(dst.header.includes, src.header.includes);
207 transfer_value(dst.header.class_decls, src.header.class_decls);
208 transfer_value(dst.header.typedefs, src.header.typedefs);
209 transfer_value(dst.header.class_defs, src.header.class_defs);
210 transfer_value(dst.header.function_prototypes, src.header.function_prototypes);
211 transfer_value(dst.header.global_vars, src.header.global_vars);
212 transfer_value(dst.header.testport_includes, src.header.testport_includes);
213
214 transfer_value(dst.source.global_vars, src.source.global_vars);
215
216 transfer_value(dst.functions.pre_init, src.functions.pre_init);
217 transfer_value(dst.functions.post_init, src.functions.post_init);
218
219 transfer_value(dst.functions.set_param, src.functions.set_param);
220 transfer_value(dst.functions.get_param, src.functions.get_param);
221 transfer_value(dst.functions.log_param, src.functions.log_param);
222 transfer_value(dst.functions.init_comp, src.functions.init_comp);
223 transfer_value(dst.functions.start, src.functions.start);
224 transfer_value(dst.functions.control, src.functions.control);
225 }
226
227 string CodeGenHelper::get_key(Ttcn::Definition& def) const {
228 string retval;
229 switch (split_mode) {
230 case SPLIT_NONE:
231 // returns the current module
232 break;
233 case SPLIT_BY_KIND:
234 break;
235 case SPLIT_BY_NAME:
236 retval += "_" + def.get_id().get_name();
237 break;
238 case SPLIT_BY_HEURISTICS:
239 break;
240 }
241 return retval;
242 }
243
244 string CodeGenHelper::get_key(Type& type) const {
245 string retval;
246 switch (split_mode) {
247 case SPLIT_NONE:
248 break;
249 case SPLIT_BY_KIND: {
250 Type::typetype_t tt = type.get_typetype();
251 switch(tt) {
252 case Type::T_CHOICE_A:
253 case Type::T_CHOICE_T:
254 case Type::T_SEQOF:
255 case Type::T_SETOF:
256 case Type::T_SEQ_A:
257 case Type::T_SEQ_T:
258 case Type::T_SET_A:
259 case Type::T_SET_T:
260 retval += typetypemap[(int)tt];
261 break;
262 default:
263 // put it into the module (no suffix)
264 break;
265 }
266 break; }
267 case SPLIT_BY_NAME:
268 break;
269 case SPLIT_BY_HEURISTICS:
270 break;
271 }
272 return retval;
273 }
274
275 void CodeGenHelper::write_output() {
276 size_t i, j;
277 if (split_mode == SPLIT_BY_KIND) {
278 // Create empty files to have a fix set of files to compile
279 string fname;
280 for (j = 0; j < modules.size(); j++) {
281 for (i = 0; typetypemap[i]; i++) {
282 fname = modules[j]->dispname + typetypemap[i];
283 if (!generated_code.has_key(fname)) {
284 generated_output_t* go = new generated_output_t;
285 go->filename = typetypemap[i];
286 go->modulename = modules[j]->name;
287 go->module_dispname = modules[j]->dispname;
288 go->os.source.includes = mcopystr(
289 "\n//This file intentionally empty."
290 "\n#include <version.h>\n");
291 generated_code.add(fname, go);
292 }
293 }
294 }
295 }
296 generated_output_t* go;
297 for (i = 0; i < generated_code.size(); i++) {
298 go = generated_code.get_nth_elem(i);
299 ::write_output(&go->os, go->modulename.c_str(), go->module_dispname.c_str(),
300 go->filename.c_str(), go->is_ttcn, go->has_circular_import, go->is_module);
301 }
302 }
303
304 CodeGenHelper::~CodeGenHelper() {
305 size_t i;
306 for (i = 0; i < generated_code.size(); i++)
307 delete generated_code.get_nth_elem(i);
308 generated_code.clear();
309 for (i = 0; i < modules.size(); i++)
310 delete modules[i];
311 modules.clear();
312 instance = 0;
313 }
314
315 }
This page took 0.037453 seconds and 5 git commands to generate.