1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 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 #include "CodeGenHelper.hh"
17 CodeGenHelper
* CodeGenHelper::instance
= 0;
19 CodeGenHelper::generated_output_t::generated_output_t() :
22 has_circular_import(false)
24 Code::init_output(&os
);
27 CodeGenHelper::generated_output_t::~generated_output_t() {
28 Code::free_output(&os
);
32 const char* const CodeGenHelper::typetypemap
[] = {
34 "", /**< erroneous (e.g. nonexistent reference) */
35 "", /**< null (ASN.1) */
38 "", /**< integer / ASN */
39 "", /**< real/float */
40 "", /**< enumerated / ASN */
41 "", /**< enumerated / TTCN */
44 "", /**< hexstring (TTCN-3) */
45 "", /**< octetstring */
46 "", /**< charstring (TTCN-3) */
47 "", /**< universal charstring (TTCN-3) */
48 "", /**< UTF8String (ASN.1) */
49 "", /**< NumericString (ASN.1) */
50 "", /**< PrintableString (ASN.1) */
51 "", /**< TeletexString (ASN.1) */
52 "", /**< VideotexString (ASN.1) */
53 "", /**< IA5String (ASN.1) */
54 "", /**< GraphicString (ASN.1) */
55 "", /**< VisibleString (ASN.1) */
56 "", /**< GeneralString (ASN.1) */
57 "", /**< UniversalString (ASN.1) */
58 "", /**< BMPString (ASN.1) */
59 "", /**< UnrestrictedCharacterString (ASN.1) */
60 "", /**< UTCTime (ASN.1) */
61 "", /**< GeneralizedTime (ASN.1) */
62 "", /** Object descriptor, a kind of string (ASN.1) */
63 "", /**< object identifier */
64 "", /**< relative OID (ASN.1) */
65 "_union", /**< choice /ASN, uses u.secho */
66 "_union", /**< union /TTCN, uses u.secho */
67 "_seqof", /**< sequence (record) of */
68 "_setof", /**< set of */
69 "_seq", /**< sequence /ASN, uses u.secho */
70 "_seq", /**< record /TTCN, uses u.secho */
71 "_set", /**< set /ASN, uses u.secho */
72 "_set", /**< set /TTCN, uses u.secho */
73 "", /**< ObjectClassFieldType (ASN.1) */
74 "", /**< open type (ASN.1) */
75 "", /**< ANY (deprecated ASN.1) */
76 "", /**< %EXTERNAL (ASN.1) */
77 "", /**< EMBEDDED PDV (ASN.1) */
78 "", /**< referenced */
79 "", /**< special referenced (by pointer, not by name) */
80 "", /**< selection type (ASN.1) */
81 "", /**< verdict type (TTCN-3) */
82 "", /**< port type (TTCN-3) */
83 "", /**< component type (TTCN-3) */
84 "", /**< address type (TTCN-3) */
85 "", /**< default type (TTCN-3) */
86 "", /**< array (TTCN-3), uses u.array */
87 "", /**< signature (TTCN-3) */
88 "", /**< function reference (TTCN-3) */
89 "", /**< altstep reference (TTCN-3) */
90 "", /**< testcase reference (TTCN-3) */
91 "", /**< anytype (TTCN-3) */
95 CodeGenHelper::CodeGenHelper() :
96 split_mode(SPLIT_NONE
)
99 FATAL_ERROR("Attempted to create a second code generator.");
103 CodeGenHelper
& CodeGenHelper::GetInstance() {
105 FATAL_ERROR("Trying to access to the already destroyed code generator.");
109 void CodeGenHelper::set_split_mode(split_type st
) {
113 bool CodeGenHelper::set_split_mode(const char* type
) {
114 if (strcmp(type
, "none") == 0)
115 split_mode
= SPLIT_NONE
;
116 else if (strcmp(type
, "type") == 0)
117 split_mode
= SPLIT_BY_KIND
;
123 CodeGenHelper::split_type
CodeGenHelper::get_split_mode() const {
127 void CodeGenHelper::add_module(const string
& name
, const string
& dispname
,
128 bool is_ttcn
, bool has_circular_import
) {
129 generated_output_t
* go
= new generated_output_t
;
130 go
->filename
.clear();
131 go
->modulename
= name
;
132 go
->module_dispname
= dispname
;
133 go
->is_module
= true;
134 go
->is_ttcn
= is_ttcn
;
135 go
->has_circular_import
= has_circular_import
;
136 generated_code
.add(dispname
, go
);
137 module_names_t
* mod_names
= new module_names_t
;
138 mod_names
->name
= name
;
139 mod_names
->dispname
= dispname
;
140 modules
.add(mod_names
);
143 output_struct
* CodeGenHelper::get_outputstruct(const string
& name
) {
144 return &generated_code
[name
]->os
;
147 void CodeGenHelper::set_current_module(const string
& name
) {
148 current_module
= name
;
151 output_struct
* CodeGenHelper::get_outputstruct(Ttcn::Definition
* def
) {
152 string key
= get_key(*def
);
153 const string
& new_name
= current_module
+ key
;
154 if (!generated_code
.has_key(new_name
)) {
155 generated_output_t
* go
= new generated_output_t
;
157 go
->modulename
= generated_code
[current_module
]->modulename
;
158 go
->module_dispname
= generated_code
[current_module
]->module_dispname
;
159 generated_code
.add(new_name
, go
);
160 go
->os
.source
.includes
= mprintf("\n#include \"%s.hh\"\n"
161 , current_module
.c_str());
163 return &generated_code
[new_name
]->os
;
166 output_struct
* CodeGenHelper::get_outputstruct(Type
* type
) {
167 string key
= get_key(*type
);
168 const string
& new_name
= current_module
+ key
;
169 if (!generated_code
.has_key(new_name
)) {
170 generated_output_t
* go
= new generated_output_t
;
172 go
->modulename
= generated_code
[current_module
]->modulename
;
173 go
->module_dispname
= generated_code
[current_module
]->module_dispname
;
174 generated_code
.add(new_name
, go
);
175 go
->os
.source
.includes
= mprintf("\n#include \"%s.hh\"\n"
176 , current_module
.c_str());
178 return &generated_code
[new_name
]->os
;
181 output_struct
* CodeGenHelper::get_current_outputstruct() {
182 return &generated_code
[current_module
]->os
;
185 void CodeGenHelper::transfer_value(char* &dst
, char* &src
) {
186 dst
= mputstr(dst
, src
);
191 void CodeGenHelper::finalize_generation(Type
* type
) {
192 string key
= get_key(*type
);
193 if (key
.empty()) return;
195 output_struct
& dst
= *get_current_outputstruct();
196 output_struct
& src
= *get_outputstruct(current_module
+ key
);
197 // key is not empty so these can never be the same
199 transfer_value(dst
.header
.includes
, src
.header
.includes
);
200 transfer_value(dst
.header
.class_decls
, src
.header
.class_decls
);
201 transfer_value(dst
.header
.typedefs
, src
.header
.typedefs
);
202 transfer_value(dst
.header
.class_defs
, src
.header
.class_defs
);
203 transfer_value(dst
.header
.function_prototypes
, src
.header
.function_prototypes
);
204 transfer_value(dst
.header
.global_vars
, src
.header
.global_vars
);
205 transfer_value(dst
.header
.testport_includes
, src
.header
.testport_includes
);
207 transfer_value(dst
.source
.global_vars
, src
.source
.global_vars
);
209 transfer_value(dst
.functions
.pre_init
, src
.functions
.pre_init
);
210 transfer_value(dst
.functions
.post_init
, src
.functions
.post_init
);
212 transfer_value(dst
.functions
.set_param
, src
.functions
.set_param
);
213 transfer_value(dst
.functions
.log_param
, src
.functions
.log_param
);
214 transfer_value(dst
.functions
.init_comp
, src
.functions
.init_comp
);
215 transfer_value(dst
.functions
.start
, src
.functions
.start
);
216 transfer_value(dst
.functions
.control
, src
.functions
.control
);
219 string
CodeGenHelper::get_key(Ttcn::Definition
& def
) const {
221 switch (split_mode
) {
223 // returns the current module
228 retval
+= "_" + def
.get_id().get_name();
230 case SPLIT_BY_HEURISTICS
:
236 string
CodeGenHelper::get_key(Type
& type
) const {
238 switch (split_mode
) {
241 case SPLIT_BY_KIND
: {
242 Type::typetype_t tt
= type
.get_typetype();
244 case Type::T_CHOICE_A
:
245 case Type::T_CHOICE_T
:
252 retval
+= typetypemap
[(int)tt
];
255 // put it into the module (no suffix)
261 case SPLIT_BY_HEURISTICS
:
267 void CodeGenHelper::write_output() {
269 if (split_mode
== SPLIT_BY_KIND
) {
270 // Create empty files to have a fix set of files to compile
272 for (j
= 0; j
< modules
.size(); j
++) {
273 for (i
= 0; typetypemap
[i
]; i
++) {
274 fname
= modules
[j
]->dispname
+ typetypemap
[i
];
275 if (!generated_code
.has_key(fname
)) {
276 generated_output_t
* go
= new generated_output_t
;
277 go
->filename
= typetypemap
[i
];
278 go
->modulename
= modules
[j
]->name
;
279 go
->module_dispname
= modules
[j
]->dispname
;
280 go
->os
.source
.includes
= mcopystr(
281 "\n//This file intentionally empty."
282 "\n#include <version.h>\n");
283 generated_code
.add(fname
, go
);
288 generated_output_t
* go
;
289 for (i
= 0; i
< generated_code
.size(); i
++) {
290 go
= generated_code
.get_nth_elem(i
);
291 ::write_output(&go
->os
, go
->modulename
.c_str(), go
->module_dispname
.c_str(),
292 go
->filename
.c_str(), go
->is_ttcn
, go
->has_circular_import
, go
->is_module
);
296 CodeGenHelper::~CodeGenHelper() {
298 for (i
= 0; i
< generated_code
.size(); i
++)
299 delete generated_code
.get_nth_elem(i
);
300 generated_code
.clear();
301 for (i
= 0; i
< modules
.size(); i
++)
This page took 0.037727 seconds and 5 git commands to generate.