blob: c013757809a8f24aaf821257a5db83f66a95a7f3 [file] [log] [blame]
Lev Walkinb46156d2017-09-05 02:53:05 -07001#include "asn1c_internal.h"
2#include "asn1c_naming.h"
3#include "asn1c_misc.h"
4#include "asn1c_misc.h"
5#include <asn1_buffer.h>
6
Lev Walkin5efafc52017-09-05 03:43:00 -07007struct intl_name {
8 asn1p_expr_t *expr;
9 asn1p_expr_t *clashes_with;
10 const char *name;
11 TQ_ENTRY(struct intl_name) next;
12};
13static TQ_HEAD(struct intl_name) used_names;
14
15void
16c_name_clash_finder_init() {
17 TQ_INIT(&used_names);
18}
19
Lev Walkin47fc74c2017-09-26 18:02:27 -070020void
21c_name_clash_finder_destroy() {
22 struct intl_name *n;
23
24 while((n = TQ_REMOVE(&used_names, next))) {
25 union {
26 const char *c_buf;
27 char *nc_buf;
28 } const_cast;
29
30 asn1p_expr_free(n->expr);
31 asn1p_expr_free(n->clashes_with);
32 const_cast.c_buf = n->name;
33 free(const_cast.nc_buf);
34 free(n);
35 }
36}
37
Lev Walkin5efafc52017-09-05 03:43:00 -070038static void
Lev Walkin6d692042017-09-29 23:15:30 -070039register_global_name(asn1p_expr_t *expr, const char *name) {
Lev Walkin5efafc52017-09-05 03:43:00 -070040 struct intl_name *n;
41
42 TQ_FOR(n, &used_names, next) {
43 if(strcmp(n->name, name) == 0) {
Lev Walkin6d692042017-09-29 23:15:30 -070044 if(!(expr->_mark & TM_NAMEGIVEN) && expr != n->expr) {
45 n->clashes_with = expr;
46 expr->ref_cnt++;
Lev Walkin5efafc52017-09-05 03:43:00 -070047 return;
48 }
49 }
50 }
51
Lev Walkin6d692042017-09-29 23:15:30 -070052 if(expr->_mark & TM_NAMEGIVEN)
Lev Walkin47fc74c2017-09-26 18:02:27 -070053 return;
54
Lev Walkin5efafc52017-09-05 03:43:00 -070055 n = calloc(1, sizeof(*n));
56 assert(n);
Lev Walkin6d692042017-09-29 23:15:30 -070057 n->expr = expr;
58 expr->ref_cnt++;
Lev Walkin5efafc52017-09-05 03:43:00 -070059 n->name = strdup(name);
60 TQ_ADD(&used_names, n, next);
61}
62
63int
64c_name_clash(arg_t *arg) {
65 struct intl_name *n;
66 size_t n_clashes = 0;
67 const size_t max_clashes = 5;
68
69 TQ_FOR(n, &used_names, next) {
70 if(n->clashes_with) {
71 if(n_clashes++ > max_clashes) continue;
72 FATAL(
73 "Name \"%s\" is generated by %s.%s at line %s:%d and "
74 "%s.%s at line %s:%d",
75 n->name, n->expr->module->ModuleName, n->expr->Identifier,
76 n->expr->module->source_file_name, n->expr->_lineno,
77 n->clashes_with->module->ModuleName,
78 n->clashes_with->Identifier,
79 n->clashes_with->module->source_file_name,
80 n->clashes_with->_lineno);
81 }
82 }
83
84 if(n_clashes > max_clashes) {
85 FATAL("... %zu more name clashes not shown", n_clashes - max_clashes);
86 }
87
88 return n_clashes > 0;
89}
90
91
Lev Walkinb46156d2017-09-05 02:53:05 -070092static abuf *
Lev Walkin6d692042017-09-29 23:15:30 -070093construct_base_name(abuf *buf, asn1p_expr_t *expr, int compound_names,
Lev Walkinb46156d2017-09-05 02:53:05 -070094 int avoid_keywords) {
95 const char *id;
96
Lev Walkin6d692042017-09-29 23:15:30 -070097 assert(buf);
Lev Walkinb46156d2017-09-05 02:53:05 -070098
Lev Walkin6d692042017-09-29 23:15:30 -070099 if(compound_names && expr->parent_expr) {
100 construct_base_name(buf, expr->parent_expr, compound_names, 0);
Lev Walkinb46156d2017-09-05 02:53:05 -0700101 if(buf->length) {
102 abuf_str(buf, "__"); /* component separator */
103 }
104 }
105
106 id = asn1c_make_identifier(
Lev Walkin6d692042017-09-29 23:15:30 -0700107 ((avoid_keywords && !buf->length) ? AMI_CHECK_RESERVED : 0), expr, 0);
Lev Walkinb46156d2017-09-05 02:53:05 -0700108
109 abuf_str(buf, id);
110
111 return buf;
112}
113
114static struct c_names
Lev Walkin6d692042017-09-29 23:15:30 -0700115c_name_impl(arg_t *arg, asn1p_expr_t *expr, int avoid_keywords) {
116 asn1p_expr_type_e expr_type = expr->expr_type;
Lev Walkinb46156d2017-09-05 02:53:05 -0700117 struct c_names names;
118 int compound_names = 0;
119
Lev Walkin6d692042017-09-29 23:15:30 -0700120 static abuf b_type_asn_name;
121 static abuf b_type_part_name;
122 static abuf b_type_base_name;
123 static abuf b_type_c_name;
Lev Walkinb5450702017-10-04 02:52:57 -0700124 static abuf b_type_constrained_c_name;
Lev Walkin6d692042017-09-29 23:15:30 -0700125 static abuf b_asn_name;
126 static abuf b_part_name;
Lev Walkinb46156d2017-09-05 02:53:05 -0700127 static abuf b_base_name;
128 static abuf b_short_name;
129 static abuf b_full_name;
130 static abuf b_as_member;
131 static abuf b_presence_enum;
132 static abuf b_presence_name;
133 static abuf b_members_enum;
134 static abuf b_members_name;
135
Lev Walkin6d692042017-09-29 23:15:30 -0700136 abuf_clear(&b_type_asn_name);
137 abuf_clear(&b_type_part_name);
138 abuf_clear(&b_type_base_name);
139 abuf_clear(&b_type_c_name);
Lev Walkinb5450702017-10-04 02:52:57 -0700140 abuf_clear(&b_type_constrained_c_name);
Lev Walkin6d692042017-09-29 23:15:30 -0700141 abuf_clear(&b_asn_name);
Lev Walkinb46156d2017-09-05 02:53:05 -0700142 abuf_clear(&b_base_name);
Lev Walkin6d692042017-09-29 23:15:30 -0700143 abuf_clear(&b_part_name);
Lev Walkinb46156d2017-09-05 02:53:05 -0700144 abuf_clear(&b_short_name);
145 abuf_clear(&b_full_name);
146 abuf_clear(&b_as_member);
147 abuf_clear(&b_presence_enum);
148 abuf_clear(&b_presence_name);
149 abuf_clear(&b_members_enum);
150 abuf_clear(&b_members_name);
151
Lev Walkin6d692042017-09-29 23:15:30 -0700152
153 abuf_str(&b_type_asn_name, asn1c_type_name(arg, expr, TNF_UNMODIFIED));
154 abuf_str(&b_type_part_name, asn1c_type_name(arg, expr, TNF_SAFE));
155 abuf_str(&b_type_base_name, asn1c_type_name(arg, expr, TNF_SAFE));
156 abuf_str(&b_type_c_name, asn1c_type_name(arg, expr, TNF_CTYPE));
Lev Walkinb5450702017-10-04 02:52:57 -0700157 abuf_str(&b_type_constrained_c_name,
158 asn1c_type_name(arg, expr, TNF_CONSTYPE));
Lev Walkin6d692042017-09-29 23:15:30 -0700159
160
Lev Walkinb46156d2017-09-05 02:53:05 -0700161 if((arg->flags & A1C_COMPOUND_NAMES)) {
162 if((expr_type & ASN_CONSTR_MASK)
163 || expr_type == ASN_BASIC_ENUMERATED
164 || ((expr_type == ASN_BASIC_INTEGER
165 || expr_type == ASN_BASIC_BIT_STRING))) {
166 compound_names = 1;
167 }
168 }
169
Lev Walkin6d692042017-09-29 23:15:30 -0700170 construct_base_name(&b_asn_name, expr, 0, 0);
171 construct_base_name(&b_part_name, expr, 0, 0);
172 construct_base_name(&b_base_name, expr, compound_names, avoid_keywords);
173 construct_base_name(&b_as_member, expr, 0, 1);
Lev Walkinb46156d2017-09-05 02:53:05 -0700174
Lev Walkin6d692042017-09-29 23:15:30 -0700175 static abuf tmp_compoundable_part_name;
Bi-Ruei, Chiudcc822a2017-10-19 01:06:57 +0800176 static abuf compound_part_name;
Lev Walkin6d692042017-09-29 23:15:30 -0700177 abuf_clear(&tmp_compoundable_part_name);
Bi-Ruei, Chiudcc822a2017-10-19 01:06:57 +0800178 abuf_clear(&compound_part_name);
Lev Walkin6d692042017-09-29 23:15:30 -0700179 construct_base_name(&tmp_compoundable_part_name, expr, compound_names, 0);
Bi-Ruei, Chiudcc822a2017-10-19 01:06:57 +0800180 construct_base_name(&compound_part_name, expr, 1, 0);
Lev Walkin6d692042017-09-29 23:15:30 -0700181
182 if(!expr->_anonymous_type) {
Lev Walkinb46156d2017-09-05 02:53:05 -0700183 if(arg->embed) {
Lev Walkin6d692042017-09-29 23:15:30 -0700184 abuf_printf(&b_short_name, "%s", b_as_member.buffer);
Lev Walkinb46156d2017-09-05 02:53:05 -0700185 } else {
Lev Walkin6d692042017-09-29 23:15:30 -0700186 abuf_printf(&b_short_name, "%s_t", b_as_member.buffer);
Lev Walkinb46156d2017-09-05 02:53:05 -0700187 }
188 }
Lev Walkin6d692042017-09-29 23:15:30 -0700189 abuf_printf(&b_full_name, "struct %s", b_base_name.buffer);
190 abuf_printf(&b_presence_enum, "enum %s_PR", tmp_compoundable_part_name.buffer);
191 abuf_printf(&b_presence_name, "%s_PR", tmp_compoundable_part_name.buffer);
192 abuf_printf(&b_members_enum, "enum %s", b_base_name.buffer);
193 abuf_printf(&b_members_name, "e_%s", tmp_compoundable_part_name.buffer);
Lev Walkinb46156d2017-09-05 02:53:05 -0700194
Lev Walkin6d692042017-09-29 23:15:30 -0700195 names.type.asn_name = b_type_asn_name.buffer;
196 names.type.base_name = b_type_base_name.buffer;
197 names.type.part_name = b_type_part_name.buffer;
198 names.type.c_name = b_type_c_name.buffer;
Lev Walkinb5450702017-10-04 02:52:57 -0700199 names.type.constrained_c_name = b_type_constrained_c_name.buffer;
Lev Walkin6d692042017-09-29 23:15:30 -0700200 names.asn_name = b_asn_name.buffer;
201 names.part_name = b_part_name.buffer;
Lev Walkinb46156d2017-09-05 02:53:05 -0700202 names.base_name = b_base_name.buffer;
203 names.short_name = b_short_name.buffer;
204 names.full_name = b_full_name.buffer;
205 names.as_member = b_as_member.buffer;
206 names.presence_enum = b_presence_enum.buffer;
207 names.presence_name = b_presence_name.buffer;
208 names.members_enum = b_members_enum.buffer;
209 names.members_name = b_members_name.buffer;
Bi-Ruei, Chiudcc822a2017-10-19 01:06:57 +0800210 names.compound_name = compound_part_name.buffer;
Lev Walkinb46156d2017-09-05 02:53:05 -0700211
Lev Walkin5efafc52017-09-05 03:43:00 -0700212 /* A _subset_ of names is checked against being globally unique */
Lev Walkin6d692042017-09-29 23:15:30 -0700213 register_global_name(expr, names.base_name);
214 register_global_name(expr, names.full_name);
215 register_global_name(expr, names.presence_enum);
216 register_global_name(expr, names.presence_name);
217 register_global_name(expr, names.members_enum);
218 register_global_name(expr, names.members_name);
Lev Walkin5efafc52017-09-05 03:43:00 -0700219
Lev Walkin6d692042017-09-29 23:15:30 -0700220 expr->_mark |= TM_NAMEGIVEN;
Lev Walkin5efafc52017-09-05 03:43:00 -0700221
Lev Walkinb46156d2017-09-05 02:53:05 -0700222 return names;
223}
224
225struct c_names
226c_name(arg_t *arg) {
Lev Walkin6d692042017-09-29 23:15:30 -0700227 return c_name_impl(arg, arg->expr, 1);
228}
229
230struct c_names
231c_expr_name(arg_t *arg, asn1p_expr_t *expr) {
232 return c_name_impl(arg, expr, 1);
Lev Walkinb46156d2017-09-05 02:53:05 -0700233}
234
235const char *
236c_member_name(arg_t *arg, asn1p_expr_t *expr) {
237 static abuf ab;
238
239 abuf_clear(&ab);
240
Lev Walkin6d692042017-09-29 23:15:30 -0700241 /* NB: do not use part_name, doesn't work for -fcompound-names */
242 abuf_str(&ab, c_name_impl(arg, arg->expr, 0).base_name);
Lev Walkin9023dea2017-09-11 08:40:15 -0700243 abuf_str(&ab, "_");
244 abuf_str(&ab, asn1c_make_identifier(0, expr, 0));
Lev Walkinb46156d2017-09-05 02:53:05 -0700245
246 return ab.buffer;
247}
248
249
250const char *
251c_presence_name(arg_t *arg, asn1p_expr_t *expr) {
252 static abuf ab;
253
254 abuf_clear(&ab);
255
256 if(expr) {
Lev Walkin6d692042017-09-29 23:15:30 -0700257 /* NB: do not use part_name, doesn't work for -fcompound-names */
258 abuf_str(&ab, c_name_impl(arg, arg->expr, 0).base_name);
Lev Walkin9023dea2017-09-11 08:40:15 -0700259 abuf_str(&ab, "_PR_");
260 abuf_str(&ab, asn1c_make_identifier(0, expr, 0));
Lev Walkinb46156d2017-09-05 02:53:05 -0700261 } else {
Lev Walkin6d692042017-09-29 23:15:30 -0700262 abuf_printf(&ab, "%s_PR_NOTHING",
263 c_name_impl(arg, arg->expr, 0).base_name);
Lev Walkinb46156d2017-09-05 02:53:05 -0700264 }
265
266 return ab.buffer;
267}
Lev Walkin6d692042017-09-29 23:15:30 -0700268
269const char *
270c_names_format(struct c_names ns) {
271 static abuf nbuf;
272 abuf_clear(&nbuf);
273
274#define FMT_COMPONENT(x) abuf_printf(&nbuf, " ." #x "=\"%s\",", ns.x);
275
276 abuf_str(&nbuf, "{");
277 FMT_COMPONENT(type.asn_name);
278 FMT_COMPONENT(type.part_name);
279 FMT_COMPONENT(type.base_name);
280 FMT_COMPONENT(type.c_name);
Lev Walkinb5450702017-10-04 02:52:57 -0700281 FMT_COMPONENT(type.constrained_c_name);
Lev Walkin6d692042017-09-29 23:15:30 -0700282 FMT_COMPONENT(asn_name);
283 FMT_COMPONENT(part_name);
284 FMT_COMPONENT(base_name);
285 FMT_COMPONENT(full_name);
286 FMT_COMPONENT(short_name);
287 FMT_COMPONENT(full_name);
288 FMT_COMPONENT(as_member);
289 FMT_COMPONENT(presence_enum);
290 FMT_COMPONENT(presence_name);
291 FMT_COMPONENT(members_enum);
292 FMT_COMPONENT(members_name);
293 abuf_printf(&nbuf, " .members_name=\"%s\" }", ns.members_name);
294 return nbuf.buffer;
295}
296