blob: b110ab59e544bfb35ad05989c70989485db9d66d [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>
Lev Walkina67d1102017-11-05 22:46:12 -08006#include <genhash.h>
Lev Walkinb46156d2017-09-05 02:53:05 -07007
Lev Walkin5efafc52017-09-05 03:43:00 -07008struct intl_name {
9 asn1p_expr_t *expr;
10 asn1p_expr_t *clashes_with;
11 const char *name;
12 TQ_ENTRY(struct intl_name) next;
13};
Lev Walkina67d1102017-11-05 22:46:12 -080014
15genhash_t *used_names_hash;
16
17static void
18name_entry_destroy(void *np) {
19 struct intl_name *n = np;
20
21 union {
22 const char *c_buf;
23 char *nc_buf;
24 } const_cast;
25
26 asn1p_expr_free(n->expr);
27 asn1p_expr_free(n->clashes_with);
28 const_cast.c_buf = n->name;
29 free(const_cast.nc_buf);
30 free(n);
31}
Lev Walkin5efafc52017-09-05 03:43:00 -070032
33void
34c_name_clash_finder_init() {
Lev Walkina67d1102017-11-05 22:46:12 -080035 assert(used_names_hash == NULL);
36 used_names_hash =
37 genhash_new(cmpf_string, hashf_string, NULL, name_entry_destroy);
38 assert(used_names_hash);
Lev Walkin5efafc52017-09-05 03:43:00 -070039}
40
Lev Walkin47fc74c2017-09-26 18:02:27 -070041void
42c_name_clash_finder_destroy() {
Lev Walkina67d1102017-11-05 22:46:12 -080043 genhash_destroy(used_names_hash);
44 used_names_hash = NULL;
Lev Walkin47fc74c2017-09-26 18:02:27 -070045}
46
Lev Walkin5efafc52017-09-05 03:43:00 -070047static void
Lev Walkin6d692042017-09-29 23:15:30 -070048register_global_name(asn1p_expr_t *expr, const char *name) {
Lev Walkin5efafc52017-09-05 03:43:00 -070049 struct intl_name *n;
50
Lev Walkina67d1102017-11-05 22:46:12 -080051 n = genhash_get(used_names_hash, (const void *)name);
52 if(n) {
53 if(!(expr->_mark & TM_NAMEGIVEN) && (expr != n->expr)) {
54 n->clashes_with = expr;
55 expr->ref_cnt++;
56 return;
Lev Walkin5efafc52017-09-05 03:43:00 -070057 }
58 }
59
Lev Walkin6d692042017-09-29 23:15:30 -070060 if(expr->_mark & TM_NAMEGIVEN)
Lev Walkin47fc74c2017-09-26 18:02:27 -070061 return;
62
Lev Walkina67d1102017-11-05 22:46:12 -080063 char *name_copy = strdup(name);
64
Lev Walkin5efafc52017-09-05 03:43:00 -070065 n = calloc(1, sizeof(*n));
66 assert(n);
Lev Walkin6d692042017-09-29 23:15:30 -070067 n->expr = expr;
68 expr->ref_cnt++;
Lev Walkina67d1102017-11-05 22:46:12 -080069 n->name = name_copy;
70 int ret = genhash_add(used_names_hash, name_copy, n);
71 assert(ret == 0);
Lev Walkin5efafc52017-09-05 03:43:00 -070072}
73
74int
75c_name_clash(arg_t *arg) {
76 struct intl_name *n;
77 size_t n_clashes = 0;
78 const size_t max_clashes = 5;
79
Lev Walkina67d1102017-11-05 22:46:12 -080080 genhash_iter_t iter;
81
82 genhash_iter_init(&iter, used_names_hash, 0);
83 while(genhash_iter(&iter, NULL, (void *)&n)) {
Lev Walkin5efafc52017-09-05 03:43:00 -070084 if(n->clashes_with) {
85 if(n_clashes++ > max_clashes) continue;
86 FATAL(
87 "Name \"%s\" is generated by %s.%s at line %s:%d and "
88 "%s.%s at line %s:%d",
89 n->name, n->expr->module->ModuleName, n->expr->Identifier,
90 n->expr->module->source_file_name, n->expr->_lineno,
91 n->clashes_with->module->ModuleName,
92 n->clashes_with->Identifier,
93 n->clashes_with->module->source_file_name,
94 n->clashes_with->_lineno);
95 }
96 }
97
Lev Walkina67d1102017-11-05 22:46:12 -080098 genhash_iter_done(&iter);
99
Lev Walkin5efafc52017-09-05 03:43:00 -0700100 if(n_clashes > max_clashes) {
101 FATAL("... %zu more name clashes not shown", n_clashes - max_clashes);
102 }
103
104 return n_clashes > 0;
105}
106
107
Lev Walkinb46156d2017-09-05 02:53:05 -0700108static abuf *
Lev Walkin6d692042017-09-29 23:15:30 -0700109construct_base_name(abuf *buf, asn1p_expr_t *expr, int compound_names,
Lev Walkinb46156d2017-09-05 02:53:05 -0700110 int avoid_keywords) {
111 const char *id;
112
Lev Walkin6d692042017-09-29 23:15:30 -0700113 assert(buf);
Lev Walkinb46156d2017-09-05 02:53:05 -0700114
Lev Walkin6d692042017-09-29 23:15:30 -0700115 if(compound_names && expr->parent_expr) {
116 construct_base_name(buf, expr->parent_expr, compound_names, 0);
Lev Walkinb46156d2017-09-05 02:53:05 -0700117 if(buf->length) {
118 abuf_str(buf, "__"); /* component separator */
119 }
120 }
121
122 id = asn1c_make_identifier(
Lev Walkin6d692042017-09-29 23:15:30 -0700123 ((avoid_keywords && !buf->length) ? AMI_CHECK_RESERVED : 0), expr, 0);
Lev Walkinb46156d2017-09-05 02:53:05 -0700124
125 abuf_str(buf, id);
126
127 return buf;
128}
129
130static struct c_names
Lev Walkin6d692042017-09-29 23:15:30 -0700131c_name_impl(arg_t *arg, asn1p_expr_t *expr, int avoid_keywords) {
132 asn1p_expr_type_e expr_type = expr->expr_type;
Lev Walkinb46156d2017-09-05 02:53:05 -0700133 struct c_names names;
134 int compound_names = 0;
135
Lev Walkin6d692042017-09-29 23:15:30 -0700136 static abuf b_type_asn_name;
137 static abuf b_type_part_name;
138 static abuf b_type_base_name;
139 static abuf b_type_c_name;
Lev Walkinb5450702017-10-04 02:52:57 -0700140 static abuf b_type_constrained_c_name;
Lev Walkin6d692042017-09-29 23:15:30 -0700141 static abuf b_asn_name;
142 static abuf b_part_name;
Lev Walkinb46156d2017-09-05 02:53:05 -0700143 static abuf b_base_name;
144 static abuf b_short_name;
145 static abuf b_full_name;
146 static abuf b_as_member;
147 static abuf b_presence_enum;
148 static abuf b_presence_name;
149 static abuf b_members_enum;
150 static abuf b_members_name;
151
Lev Walkin6d692042017-09-29 23:15:30 -0700152 abuf_clear(&b_type_asn_name);
153 abuf_clear(&b_type_part_name);
154 abuf_clear(&b_type_base_name);
155 abuf_clear(&b_type_c_name);
Lev Walkinb5450702017-10-04 02:52:57 -0700156 abuf_clear(&b_type_constrained_c_name);
Lev Walkin6d692042017-09-29 23:15:30 -0700157 abuf_clear(&b_asn_name);
Lev Walkinb46156d2017-09-05 02:53:05 -0700158 abuf_clear(&b_base_name);
Lev Walkin6d692042017-09-29 23:15:30 -0700159 abuf_clear(&b_part_name);
Lev Walkinb46156d2017-09-05 02:53:05 -0700160 abuf_clear(&b_short_name);
161 abuf_clear(&b_full_name);
162 abuf_clear(&b_as_member);
163 abuf_clear(&b_presence_enum);
164 abuf_clear(&b_presence_name);
165 abuf_clear(&b_members_enum);
166 abuf_clear(&b_members_name);
167
Lev Walkin6d692042017-09-29 23:15:30 -0700168
169 abuf_str(&b_type_asn_name, asn1c_type_name(arg, expr, TNF_UNMODIFIED));
170 abuf_str(&b_type_part_name, asn1c_type_name(arg, expr, TNF_SAFE));
171 abuf_str(&b_type_base_name, asn1c_type_name(arg, expr, TNF_SAFE));
172 abuf_str(&b_type_c_name, asn1c_type_name(arg, expr, TNF_CTYPE));
Lev Walkinb5450702017-10-04 02:52:57 -0700173 abuf_str(&b_type_constrained_c_name,
174 asn1c_type_name(arg, expr, TNF_CONSTYPE));
Lev Walkin6d692042017-09-29 23:15:30 -0700175
176
Lev Walkinb46156d2017-09-05 02:53:05 -0700177 if((arg->flags & A1C_COMPOUND_NAMES)) {
178 if((expr_type & ASN_CONSTR_MASK)
179 || expr_type == ASN_BASIC_ENUMERATED
180 || ((expr_type == ASN_BASIC_INTEGER
181 || expr_type == ASN_BASIC_BIT_STRING))) {
182 compound_names = 1;
183 }
184 }
185
Lev Walkin6d692042017-09-29 23:15:30 -0700186 construct_base_name(&b_asn_name, expr, 0, 0);
187 construct_base_name(&b_part_name, expr, 0, 0);
188 construct_base_name(&b_base_name, expr, compound_names, avoid_keywords);
189 construct_base_name(&b_as_member, expr, 0, 1);
Lev Walkinb46156d2017-09-05 02:53:05 -0700190
Lev Walkin6d692042017-09-29 23:15:30 -0700191 static abuf tmp_compoundable_part_name;
Bi-Ruei, Chiudcc822a2017-10-19 01:06:57 +0800192 static abuf compound_part_name;
Lev Walkin6d692042017-09-29 23:15:30 -0700193 abuf_clear(&tmp_compoundable_part_name);
Bi-Ruei, Chiudcc822a2017-10-19 01:06:57 +0800194 abuf_clear(&compound_part_name);
Lev Walkin6d692042017-09-29 23:15:30 -0700195 construct_base_name(&tmp_compoundable_part_name, expr, compound_names, 0);
Bi-Ruei, Chiudcc822a2017-10-19 01:06:57 +0800196 construct_base_name(&compound_part_name, expr, 1, 0);
Lev Walkin6d692042017-09-29 23:15:30 -0700197
198 if(!expr->_anonymous_type) {
Lev Walkinb46156d2017-09-05 02:53:05 -0700199 if(arg->embed) {
Lev Walkin6d692042017-09-29 23:15:30 -0700200 abuf_printf(&b_short_name, "%s", b_as_member.buffer);
Lev Walkinb46156d2017-09-05 02:53:05 -0700201 } else {
Lev Walkin6d692042017-09-29 23:15:30 -0700202 abuf_printf(&b_short_name, "%s_t", b_as_member.buffer);
Lev Walkinb46156d2017-09-05 02:53:05 -0700203 }
204 }
Lev Walkin6d692042017-09-29 23:15:30 -0700205 abuf_printf(&b_full_name, "struct %s", b_base_name.buffer);
206 abuf_printf(&b_presence_enum, "enum %s_PR", tmp_compoundable_part_name.buffer);
207 abuf_printf(&b_presence_name, "%s_PR", tmp_compoundable_part_name.buffer);
208 abuf_printf(&b_members_enum, "enum %s", b_base_name.buffer);
209 abuf_printf(&b_members_name, "e_%s", tmp_compoundable_part_name.buffer);
Lev Walkinb46156d2017-09-05 02:53:05 -0700210
Lev Walkin6d692042017-09-29 23:15:30 -0700211 names.type.asn_name = b_type_asn_name.buffer;
212 names.type.base_name = b_type_base_name.buffer;
213 names.type.part_name = b_type_part_name.buffer;
214 names.type.c_name = b_type_c_name.buffer;
Lev Walkinb5450702017-10-04 02:52:57 -0700215 names.type.constrained_c_name = b_type_constrained_c_name.buffer;
Lev Walkin6d692042017-09-29 23:15:30 -0700216 names.asn_name = b_asn_name.buffer;
217 names.part_name = b_part_name.buffer;
Lev Walkinb46156d2017-09-05 02:53:05 -0700218 names.base_name = b_base_name.buffer;
219 names.short_name = b_short_name.buffer;
220 names.full_name = b_full_name.buffer;
221 names.as_member = b_as_member.buffer;
222 names.presence_enum = b_presence_enum.buffer;
223 names.presence_name = b_presence_name.buffer;
224 names.members_enum = b_members_enum.buffer;
225 names.members_name = b_members_name.buffer;
Bi-Ruei, Chiudcc822a2017-10-19 01:06:57 +0800226 names.compound_name = compound_part_name.buffer;
Lev Walkinb46156d2017-09-05 02:53:05 -0700227
Lev Walkin5efafc52017-09-05 03:43:00 -0700228 /* A _subset_ of names is checked against being globally unique */
Lev Walkin6d692042017-09-29 23:15:30 -0700229 register_global_name(expr, names.base_name);
230 register_global_name(expr, names.full_name);
231 register_global_name(expr, names.presence_enum);
232 register_global_name(expr, names.presence_name);
233 register_global_name(expr, names.members_enum);
234 register_global_name(expr, names.members_name);
Lev Walkin5efafc52017-09-05 03:43:00 -0700235
Lev Walkin6d692042017-09-29 23:15:30 -0700236 expr->_mark |= TM_NAMEGIVEN;
Lev Walkin5efafc52017-09-05 03:43:00 -0700237
Lev Walkinb46156d2017-09-05 02:53:05 -0700238 return names;
239}
240
241struct c_names
242c_name(arg_t *arg) {
Lev Walkin6d692042017-09-29 23:15:30 -0700243 return c_name_impl(arg, arg->expr, 1);
244}
245
246struct c_names
247c_expr_name(arg_t *arg, asn1p_expr_t *expr) {
248 return c_name_impl(arg, expr, 1);
Lev Walkinb46156d2017-09-05 02:53:05 -0700249}
250
251const char *
252c_member_name(arg_t *arg, asn1p_expr_t *expr) {
253 static abuf ab;
254
255 abuf_clear(&ab);
256
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, "_");
260 abuf_str(&ab, asn1c_make_identifier(0, expr, 0));
Lev Walkinb46156d2017-09-05 02:53:05 -0700261
262 return ab.buffer;
263}
264
265
266const char *
267c_presence_name(arg_t *arg, asn1p_expr_t *expr) {
268 static abuf ab;
269
270 abuf_clear(&ab);
271
272 if(expr) {
Lev Walkin6d692042017-09-29 23:15:30 -0700273 /* NB: do not use part_name, doesn't work for -fcompound-names */
274 abuf_str(&ab, c_name_impl(arg, arg->expr, 0).base_name);
Lev Walkin9023dea2017-09-11 08:40:15 -0700275 abuf_str(&ab, "_PR_");
276 abuf_str(&ab, asn1c_make_identifier(0, expr, 0));
Lev Walkinb46156d2017-09-05 02:53:05 -0700277 } else {
Lev Walkin6d692042017-09-29 23:15:30 -0700278 abuf_printf(&ab, "%s_PR_NOTHING",
279 c_name_impl(arg, arg->expr, 0).base_name);
Lev Walkinb46156d2017-09-05 02:53:05 -0700280 }
281
282 return ab.buffer;
283}
Lev Walkin6d692042017-09-29 23:15:30 -0700284
285const char *
286c_names_format(struct c_names ns) {
287 static abuf nbuf;
288 abuf_clear(&nbuf);
289
290#define FMT_COMPONENT(x) abuf_printf(&nbuf, " ." #x "=\"%s\",", ns.x);
291
292 abuf_str(&nbuf, "{");
293 FMT_COMPONENT(type.asn_name);
294 FMT_COMPONENT(type.part_name);
295 FMT_COMPONENT(type.base_name);
296 FMT_COMPONENT(type.c_name);
Lev Walkinb5450702017-10-04 02:52:57 -0700297 FMT_COMPONENT(type.constrained_c_name);
Lev Walkin6d692042017-09-29 23:15:30 -0700298 FMT_COMPONENT(asn_name);
299 FMT_COMPONENT(part_name);
300 FMT_COMPONENT(base_name);
301 FMT_COMPONENT(full_name);
302 FMT_COMPONENT(short_name);
303 FMT_COMPONENT(full_name);
304 FMT_COMPONENT(as_member);
305 FMT_COMPONENT(presence_enum);
306 FMT_COMPONENT(presence_name);
307 FMT_COMPONENT(members_enum);
308 FMT_COMPONENT(members_name);
309 abuf_printf(&nbuf, " .members_name=\"%s\" }", ns.members_name);
310 return nbuf.buffer;
311}
312