blob: 127ba8c348ba60a57ef58d7ffb961f7a240d9307 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include "asn1fix_internal.h"
Lev Walkin4efbfb72005-02-25 14:20:30 +00002#include "asn1fix.h"
Lev Walkinf15320b2004-06-03 03:38:44 +00003
4/* Print everything to stderr */
5static void _default_error_logger(int _severity, const char *fmt, ...);
6
7/*
8 * Internal check functions.
9 */
Lev Walkind24c62d2004-09-15 11:47:23 +000010static int asn1f_fix_module__phase_1(arg_t *arg);
11static int asn1f_fix_module__phase_2(arg_t *arg);
Lev Walkinf15320b2004-06-03 03:38:44 +000012static int asn1f_fix_simple(arg_t *arg); /* For INTEGER/ENUMERATED */
13static int asn1f_fix_constructed(arg_t *arg); /* For SEQUENCE/SET/CHOICE */
Lev Walkin1ef05162004-08-25 00:42:25 +000014static int asn1f_resolve_constraints(arg_t *arg); /* For subtype constraints */
15static int asn1f_check_constraints(arg_t *arg); /* For subtype constraints */
Lev Walkinf593f102005-02-22 07:59:59 +000016static int asn1f_check_duplicate(arg_t *arg);
Lev Walkin1dec5802005-03-04 09:02:27 +000017static int asn1f_apply_unique_index(arg_t *arg);
Lev Walkina00d6b32006-03-21 03:40:38 +000018static int phase_1_1(arg_t *arg, int prm2);
Lev Walkinf15320b2004-06-03 03:38:44 +000019
Lev Walkinb45e0672004-08-18 05:42:05 +000020arg_t a1f_replace_me_with_proper_interface_arg;
Lev Walkinf15320b2004-06-03 03:38:44 +000021
22/*
23 * Scan every module defined here in search for inconsistences.
24 */
25int
26asn1f_process(asn1p_t *asn, enum asn1f_flags flags,
27 error_logger_f error_logger) {
28 arg_t arg;
29 int fatals = 0;
30 int warnings = 0;
Lev Walkin4533a5f2005-03-18 04:22:41 +000031 int ret;
Lev Walkinf15320b2004-06-03 03:38:44 +000032
33 /*
34 * Check validity of arguments.
35 */
36 if(asn == NULL) {
37 errno = EINVAL;
38 return -1;
39 }
40
41 /*
42 * If errors handler is not specified, default to internal one.
43 */
44 if(error_logger == 0) {
45 error_logger = _default_error_logger;
46 }
47
48 memset(&arg, 0, sizeof(arg));
49 arg.asn = asn;
50 arg.eh = error_logger;
51
52 if(flags & A1F_DEBUG) {
53 arg.debug = arg.eh;
54 arg.debug(-1, "Called %s() with flags %d", __func__, flags);
55 flags &= ~A1F_DEBUG;
56 }
57
Lev Walkin5253da42004-08-20 13:25:56 +000058 /* Allow SIZE() constraint for INTEGER and other types */
59 if(flags & A1F_EXTENDED_SizeConstraint) {
60 arg.flags |= A1F_EXTENDED_SizeConstraint;
61 flags &= ~A1F_EXTENDED_SizeConstraint;
62 if(arg.debug) {
63 arg.debug(-1,
64 "Extended SizeConstraint support enabled");
65 }
66 }
67
Lev Walkinb45e0672004-08-18 05:42:05 +000068 a1f_replace_me_with_proper_interface_arg = arg;
69
Lev Walkinf15320b2004-06-03 03:38:44 +000070 /*
71 * Check that we haven't missed an unknown flag.
72 */
73 if(flags) {
74 errno = EINVAL;
75 return -1;
76 }
77
Lev Walkinc0e03b92017-08-22 01:48:23 -070078 /*
79 * Process each module in the list.
80 * PHASE I.
81 */
82 TQ_FOR(arg.mod, &(asn->modules), mod_next) {
83 arg.ns = asn1_namespace_new_from_module(arg.mod, 0);
84 ret = asn1f_fix_module__phase_1(&arg);
85 /*
86 * These lines are used for illustration purposes.
87 * RET2RVAL() is used everywhere else.
88 */
89 if(ret == -1) fatals++;
90 if(ret == 1) warnings++;
91 asn1_namespace_free(arg.ns);
92 arg.ns = 0;
93 }
94 /* PHASE II. */
95 TQ_FOR(arg.mod, &(asn->modules), mod_next) {
96 arg.ns = asn1_namespace_new_from_module(arg.mod, 0);
97 ret = asn1f_fix_module__phase_2(&arg);
98 if(ret == -1) fatals++;
99 if(ret == 1) warnings++;
100 asn1_namespace_free(arg.ns);
101 arg.ns = 0;
102 }
Lev Walkind24c62d2004-09-15 11:47:23 +0000103
Lev Walkinc0e03b92017-08-22 01:48:23 -0700104 memset(&a1f_replace_me_with_proper_interface_arg, 0, sizeof(arg_t));
Lev Walkinf15320b2004-06-03 03:38:44 +0000105
106 /*
107 * Compute a return value.
108 */
109 return fatals?-1:warnings?1:0;
110}
111
112/*
113 * Check the internals of a single module.
114 */
115static int
Lev Walkind24c62d2004-09-15 11:47:23 +0000116asn1f_fix_module__phase_1(arg_t *arg) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000117 asn1p_expr_t *expr;
118 int rvalue = 0;
Lev Walkin1ef05162004-08-25 00:42:25 +0000119 int ret;
Lev Walkin4533a5f2005-03-18 04:22:41 +0000120 asn1p_module_t *omod;
121
122 /*
123 * Check that we don't have a similarly named module.
124 */
125 TQ_FOR(omod, &arg->asn->modules, mod_next) {
126 int sameNames;
127 if(omod == arg->mod) break;
Lev Walkinb36317c2005-08-12 10:09:10 +0000128 sameNames = strcmp(omod->ModuleName, arg->mod->ModuleName)?0:1;
Lev Walkin4533a5f2005-03-18 04:22:41 +0000129 if(omod->module_oid && arg->mod->module_oid) {
130 /* Compare only the OID. */
131 if(asn1p_oid_compare(omod->module_oid,
132 arg->mod->module_oid) == 0) {
Lev Walkin1a447952005-03-18 04:26:12 +0000133 FATAL("ASN.1 module %s in %s "
Lev Walkin4533a5f2005-03-18 04:22:41 +0000134 "has the same OBJECT IDENTIFIER"
Lev Walkin1a447952005-03-18 04:26:12 +0000135 " as module %s",
Lev Walkinb36317c2005-08-12 10:09:10 +0000136 omod->ModuleName,
Lev Walkin1a447952005-03-18 04:26:12 +0000137 omod->source_file_name,
Lev Walkinb36317c2005-08-12 10:09:10 +0000138 arg->mod->ModuleName
Lev Walkin4533a5f2005-03-18 04:22:41 +0000139 );
140 RET2RVAL(-1, rvalue);
141 } else if(sameNames) {
Lev Walkinb36317c2005-08-12 10:09:10 +0000142 WARNING("ASN.1 module %s is defined more than once, with different OIDs", omod->ModuleName);
Lev Walkin4533a5f2005-03-18 04:22:41 +0000143 RET2RVAL(1, rvalue);
144 }
145 } else if(sameNames) {
146 FATAL("ASN.1 module %s is defined more than once",
Lev Walkinb36317c2005-08-12 10:09:10 +0000147 omod->ModuleName);
Lev Walkin4533a5f2005-03-18 04:22:41 +0000148 RET2RVAL(-1, rvalue);
149 }
150 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000151
Lev Walkinb45e0672004-08-18 05:42:05 +0000152 switch((arg->mod->module_flags & MSF_MASK_TAGS)) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000153 case MSF_NOFLAGS:
154 case MSF_EXPLICIT_TAGS:
155 case MSF_IMPLICIT_TAGS:
156 case MSF_AUTOMATIC_TAGS:
157 break;
158 default:
159 FATAL("Module %s defined with ambiguous global tagging mode",
Lev Walkinb36317c2005-08-12 10:09:10 +0000160 arg->mod->ModuleName);
Lev Walkinf15320b2004-06-03 03:38:44 +0000161 RET2RVAL(-1, rvalue);
162 }
163
Lev Walkinb45e0672004-08-18 05:42:05 +0000164 switch((arg->mod->module_flags & MSF_MASK_INSTRUCTIONS)) {
165 case MSF_NOFLAGS:
Lev Walkin4ec3b4c2004-08-22 03:09:24 +0000166 /*
167 * arg->mod->module_flags |= MSF_TAG_INSTRUCTIONS;
168 */
Lev Walkinb45e0672004-08-18 05:42:05 +0000169 break;
170 case MSF_unk_INSTRUCTIONS:
171 WARNING("Module %s defined with unrecognized "
Lev Walkinb36317c2005-08-12 10:09:10 +0000172 "encoding reference", arg->mod->ModuleName);
Lev Walkinb45e0672004-08-18 05:42:05 +0000173 RET2RVAL(1, rvalue);
174 /* Fall through */
175 case MSF_TAG_INSTRUCTIONS:
176 case MSF_XER_INSTRUCTIONS:
177 break;
178 default:
179 FATAL("Module %s defined with ambiguous encoding reference",
Lev Walkinb36317c2005-08-12 10:09:10 +0000180 arg->mod->ModuleName);
Lev Walkinb45e0672004-08-18 05:42:05 +0000181 RET2RVAL(-1, rvalue);
182 }
183
Lev Walkinf15320b2004-06-03 03:38:44 +0000184 /*
185 * Do various non-recursive transformations.
Lev Walkinf15320b2004-06-03 03:38:44 +0000186 */
187 TQ_FOR(expr, &(arg->mod->members), next) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000188 arg->expr = expr;
Lev Walkina00d6b32006-03-21 03:40:38 +0000189 ret = phase_1_1(arg, 0);
Lev Walkinf593f102005-02-22 07:59:59 +0000190 RET2RVAL(ret, rvalue);
Lev Walkinf15320b2004-06-03 03:38:44 +0000191 /*
192 * Make sure everybody's behaving well.
193 */
194 assert(arg->expr == expr);
195 }
Lev Walkina00d6b32006-03-21 03:40:38 +0000196 TQ_FOR(expr, &(arg->mod->members), next) {
197 arg->expr = expr;
198 ret = phase_1_1(arg, 1);
199 RET2RVAL(ret, rvalue);
200 assert(arg->expr == expr);
201 }
202
203
Lev Walkinf15320b2004-06-03 03:38:44 +0000204
205 /*
206 * 5. Automatic tagging
207 */
208 TQ_FOR(expr, &(arg->mod->members), next) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000209
210 arg->expr = expr;
211
212 ret = asn1f_recurse_expr(arg, asn1f_fix_constr_autotag);
213 RET2RVAL(ret, rvalue);
214
215 assert(arg->expr == expr);
216 }
217
218 /*
219 * 8. fix BIT STRING
220 * 9. fix spaces in cstrings
221 */
222 TQ_FOR(expr, &(arg->mod->members), next) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000223 arg->expr = expr;
224
225 ret = asn1f_recurse_expr(arg, asn1f_fix_bit_string);
226 RET2RVAL(ret, rvalue);
227
228 ret = asn1f_recurse_expr(arg, asn1f_fix_cstring);
229 RET2RVAL(ret, rvalue);
230
231 assert(arg->expr == expr);
232 }
233
234 /*
235 * ... Check for tags distinctness.
236 */
237 TQ_FOR(expr, &(arg->mod->members), next) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000238 arg->expr = expr;
239
240 ret = asn1f_recurse_expr(arg, asn1f_check_constr_tags_distinct);
241 RET2RVAL(ret, rvalue);
242
243 assert(arg->expr == expr);
244 }
245
Lev Walkind24c62d2004-09-15 11:47:23 +0000246 return rvalue;
247}
248
249static int
250asn1f_fix_module__phase_2(arg_t *arg) {
251 asn1p_expr_t *expr;
252 int rvalue = 0;
253 int ret;
254
Lev Walkin1ef05162004-08-25 00:42:25 +0000255 TQ_FOR(expr, &(arg->mod->members), next) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800256
Lev Walkin1ef05162004-08-25 00:42:25 +0000257 arg->expr = expr;
258
Lev Walkinb25fa062004-09-29 13:17:06 +0000259 /*
Lev Walkin3645c1c2004-10-31 00:11:50 +0000260 * Dereference DEFAULT values.
261 */
262 ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_defaults);
263 RET2RVAL(ret, rvalue);
264
265 /*
Bi-Ruei, Chiu50934ba2017-09-11 08:50:59 +0800266 * Resolve references in constraints (the second pass).
267 */
268 ret = asn1f_recurse_expr(arg, asn1f_resolve_constraints);
269 RET2RVAL(ret, rvalue);
270
271 /*
Lev Walkinb25fa062004-09-29 13:17:06 +0000272 * Check semantic validity of constraints.
273 */
Lev Walkin1ef05162004-08-25 00:42:25 +0000274 ret = asn1f_recurse_expr(arg, asn1f_check_constraints);
275 RET2RVAL(ret, rvalue);
276
Lev Walkin1dec5802005-03-04 09:02:27 +0000277 /*
278 * Uniquely tag each inner type.
279 */
280 asn1f_apply_unique_index(0);
281 ret = asn1f_recurse_expr(arg, asn1f_apply_unique_index);
282 RET2RVAL(ret, rvalue);
283
Lev Walkin1ef05162004-08-25 00:42:25 +0000284 assert(arg->expr == expr);
285 }
286
Lev Walkinf15320b2004-06-03 03:38:44 +0000287 return rvalue;
288}
289
Lev Walkinf15320b2004-06-03 03:38:44 +0000290static int
Lev Walkina00d6b32006-03-21 03:40:38 +0000291phase_1_1(arg_t *arg, int prm2) {
292 asn1p_expr_t *expr = arg->expr;
293 int rvalue = 0;
294 int ret;
295
296 if(expr->lhs_params && expr->spec_index == -1) {
297 int i;
298 if(!prm2)
299 /* Do not process the parameterized type just yet */
300 return 0;
301 for(i = 0; i < expr->specializations.pspecs_count; i++) {
302 arg->expr = expr->specializations.pspec[i].my_clone;
303 ret = phase_1_1(arg, 0);
304 RET2RVAL(ret, rvalue);
305 }
306 arg->expr = expr; /* revert */
307 return rvalue;
308 } else if(prm2) {
309 return 0; /* Already done! */
310 }
311
312 /* Check whether this type is a duplicate */
313 if(!expr->lhs_params) {
314 ret = asn1f_check_duplicate(arg);
315 RET2RVAL(ret, rvalue);
316 }
317
318 DEBUG("=== Now processing \"%s\" (%d/0x%x) at line %d ===",
319 expr->Identifier, expr->meta_type, expr->expr_type,
320 expr->_lineno);
321 assert(expr->meta_type != AMT_INVALID);
322
323 /*
324 * 2.1 Pre-process simple types (ENUMERATED, INTEGER, etc).
325 */
326 ret = asn1f_recurse_expr(arg, asn1f_fix_simple);
327 RET2RVAL(ret, rvalue);
328
329 /*
330 * 2.5.4
331 */
332 ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_types);
333 RET2RVAL(ret, rvalue);
334
335 /*
336 * Fix tagging of top-level types.
337 */
338 ret = asn1f_fix_constr_tag(arg, 1);
339 RET2RVAL(ret, rvalue);
340
341 /*
342 * 2.[234] Process SEQUENCE/SET/CHOICE types.
343 */
344 ret = asn1f_recurse_expr(arg, asn1f_fix_constructed);
345 RET2RVAL(ret, rvalue);
346
347 /*
348 * 2.5.5
349 */
350 ret = asn1f_recurse_expr(arg, asn1f_fix_dereference_values);
351 RET2RVAL(ret, rvalue);
352
353 /*
Lev Walkina00d6b32006-03-21 03:40:38 +0000354 * Resolve references in constraints.
355 */
356 ret = asn1f_recurse_expr(arg, asn1f_resolve_constraints);
357 RET2RVAL(ret, rvalue);
358
359 /*
Lev Walkinea6635b2017-08-06 23:23:04 -0700360 * Parse class information object sets.
361 */
362 ret = asn1f_parse_class_object(arg);
363 RET2RVAL(ret, rvalue);
364
365 /*
Lev Walkina00d6b32006-03-21 03:40:38 +0000366 * 6. INTEGER value processed at 2.5.4.
367 */
368
369 return rvalue;
370}
371
372static int
Lev Walkinf15320b2004-06-03 03:38:44 +0000373asn1f_fix_simple(arg_t *arg) {
374 int rvalue = 0;
375 int ret;
376
377 ret = asn1f_fix_enum(arg);
378 RET2RVAL(ret, rvalue);
379
380 ret = asn1f_fix_integer(arg);
381 RET2RVAL(ret, rvalue);
382
383 return rvalue;
384}
385
386static int
387asn1f_fix_constructed(arg_t *arg) {
388 int rvalue = 0;
389 int ret;
390
391 switch(arg->expr->expr_type) {
392 case ASN_CONSTR_SEQUENCE:
393 case ASN_CONSTR_SET:
394 case ASN_CONSTR_CHOICE:
395 break;
396 default:
397 return 0;
398 }
399
400 /* Check identifier distinctness */
Lev Walkinfbfc7bc2006-08-28 02:45:44 +0000401 ret = asn1f_check_unique_expr(arg);
Lev Walkinf15320b2004-06-03 03:38:44 +0000402 RET2RVAL(ret, rvalue);
403
404 /* Fix extensibility */
405 ret = asn1f_fix_constr_ext(arg);
406 RET2RVAL(ret, rvalue);
407
408 /* Fix tagging */
Lev Walkind541c252004-09-05 10:36:22 +0000409 ret = asn1f_fix_constr_tag(arg, 0);
Lev Walkinf15320b2004-06-03 03:38:44 +0000410 RET2RVAL(ret, rvalue);
411
Lev Walkin4ec3b4c2004-08-22 03:09:24 +0000412 /* Import COMPONENTS OF stuff */
413 ret = asn1f_pull_components_of(arg);
414 RET2RVAL(ret, rvalue);
415
Lev Walkinf15320b2004-06-03 03:38:44 +0000416 return rvalue;
417}
418
419static int
Lev Walkin1ef05162004-08-25 00:42:25 +0000420asn1f_resolve_constraints(arg_t *arg) {
Lev Walkinb45e0672004-08-18 05:42:05 +0000421 asn1p_expr_t *top_parent;
Lev Walkin5253da42004-08-20 13:25:56 +0000422 asn1p_expr_type_e etype;
Lev Walkinf15320b2004-06-03 03:38:44 +0000423 int rvalue = 0;
424 int ret;
425
Lev Walkin4ec3b4c2004-08-22 03:09:24 +0000426 top_parent = asn1f_find_terminal_type(arg, arg->expr);
Lev Walkin5253da42004-08-20 13:25:56 +0000427 if(top_parent)
428 etype = top_parent->expr_type;
429 else etype = A1TC_INVALID;
430
Lev Walkin03850182005-03-10 10:02:50 +0000431 DEBUG("(%s)", arg->expr->Identifier);
Lev Walkind541c252004-09-05 10:36:22 +0000432
Lev Walkinc0e03b92017-08-22 01:48:23 -0700433 ret = asn1constraint_resolve(arg, arg->expr->constraints, etype, 0);
434 RET2RVAL(ret, rvalue);
Lev Walkinf15320b2004-06-03 03:38:44 +0000435
Lev Walkin1ef05162004-08-25 00:42:25 +0000436 return rvalue;
437}
438
439static int
440asn1f_check_constraints(arg_t *arg) {
441 static enum asn1p_constraint_type_e test_types[] = {
442 ACT_EL_RANGE, ACT_CT_SIZE, ACT_CT_FROM };
443 asn1p_expr_t *top_parent;
444 asn1cnst_range_t *range;
445 asn1p_expr_type_e etype;
446 unsigned int i;
447 int rvalue = 0;
448 int ret;
449
Lev Walkin03850182005-03-10 10:02:50 +0000450 DEBUG("(%s{%d/%d})",
Lev Walkind541c252004-09-05 10:36:22 +0000451 arg->expr->Identifier,
452 arg->expr->meta_type, arg->expr->expr_type);
453
Lev Walkin1ef05162004-08-25 00:42:25 +0000454 top_parent = asn1f_find_terminal_type(arg, arg->expr);
455 if(!top_parent)
456 return 0;
457 etype = top_parent->expr_type;
458
Lev Walkinb45e0672004-08-18 05:42:05 +0000459 ret = asn1constraint_pullup(arg);
460 RET2RVAL(ret, rvalue);
461
Lev Walkin1ef05162004-08-25 00:42:25 +0000462 for(i = 0; i < sizeof(test_types)/sizeof(test_types[0]); i++) {
Lev Walkina28cbb92017-07-31 20:20:17 -0700463 range = asn1constraint_compute_constraint_range(
464 arg->expr->Identifier,
Lev Walkinb9fa7802004-08-25 02:04:39 +0000465 etype,
Lev Walkin1ef05162004-08-25 00:42:25 +0000466 arg->expr->combined_constraints,
Lev Walkin4b553412005-08-14 14:45:44 +0000467 test_types[i], 0, 0,
468 CPR_noflags /* ignore -fbless-SIZE */);
Lev Walkind541c252004-09-05 10:36:22 +0000469 if(!range && errno == EPERM) {
Lev Walkin9288d1c2005-03-10 11:27:13 +0000470 FATAL("This error happened for \"%s\" (meta %d) "
471 "at line %d",
Lev Walkind541c252004-09-05 10:36:22 +0000472 arg->expr->Identifier,
473 arg->expr->meta_type,
474 arg->expr->_lineno);
Lev Walkin1ef05162004-08-25 00:42:25 +0000475 return -1;
Lev Walkind541c252004-09-05 10:36:22 +0000476 }
Lev Walkin1ef05162004-08-25 00:42:25 +0000477 asn1constraint_range_free(range);
Lev Walkinb45e0672004-08-18 05:42:05 +0000478 }
Lev Walkin1ef05162004-08-25 00:42:25 +0000479
Lev Walkinf15320b2004-06-03 03:38:44 +0000480 return rvalue;
481}
482
Lev Walkinf593f102005-02-22 07:59:59 +0000483static int
484asn1f_check_duplicate(arg_t *arg) {
485 arg_t tmparg = *arg;
Lev Walkin9c2285a2006-03-09 08:49:26 +0000486 int rvalue = 0;
Lev Walkinf593f102005-02-22 07:59:59 +0000487
488 /*
489 * This is a linear scan in search of a similar type.
490 * The linear scan is just fine for the task, no need to over-optimize.
491 */
492 TQ_FOR(tmparg.mod, &arg->asn->modules, mod_next) {
Lev Walkin1a7cbd72006-03-07 10:39:42 +0000493 int critical = 1; /* FATAL */
494
495 if((arg->mod->_tags & MT_STANDARD_MODULE)
496 != (tmparg.mod->_tags & MT_STANDARD_MODULE)) {
497 /* Ignore clashes with standard module */
498 critical = 0; /* WARNING */
499 }
500
Lev Walkinf593f102005-02-22 07:59:59 +0000501 TQ_FOR(tmparg.expr, &(tmparg.mod->members), next) {
Lev Walkin1a7cbd72006-03-07 10:39:42 +0000502 int diff_files; /* different files */
503
Lev Walkinf593f102005-02-22 07:59:59 +0000504 assert(tmparg.expr->Identifier);
505 assert(arg->expr->Identifier);
Lev Walkin1a7cbd72006-03-07 10:39:42 +0000506
Lev Walkin0c0bca62006-03-21 04:48:15 +0000507 if(arg->expr->spec_index != -1)
508 continue;
509
Lev Walkinf593f102005-02-22 07:59:59 +0000510 if(tmparg.expr == arg->expr) break;
511
512 if(strcmp(tmparg.expr->Identifier,
Lev Walkin1a7cbd72006-03-07 10:39:42 +0000513 arg->expr->Identifier))
514 continue;
515
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800516 /* resolve clash of Identifier in different modules */
517 int oid_exist = (tmparg.expr->module->module_oid && arg->expr->module->module_oid);
518 if ((!oid_exist && strcmp(tmparg.expr->module->ModuleName, arg->expr->module->ModuleName)) ||
519 (oid_exist && !asn1p_oid_compare(tmparg.expr->module->module_oid, arg->expr->module->module_oid))) {
520
521 tmparg.expr->_mark |= TM_NAMECLASH;
522 arg->expr->_mark |= TM_NAMECLASH;
523 continue;
524 }
525
Lev Walkin1a7cbd72006-03-07 10:39:42 +0000526 diff_files = strcmp(arg->mod->source_file_name,
527 tmparg.mod->source_file_name) ? 1 : 0;
528
529 LOG(critical,
530 "ASN.1 expression \"%s\" at line %d of module %s\n"
531 "clashes with expression \"%s\" at line %d of module %s"
532 "%s%s%s.\n"
Lev Walkin41635d32006-03-18 05:06:57 +0000533 "Rename or remove either instance "
534 "to resolve the conflict",
Lev Walkin1a7cbd72006-03-07 10:39:42 +0000535 arg->expr->Identifier,
536 arg->expr->_lineno,
537 arg->mod->ModuleName,
538 tmparg.expr->Identifier,
539 tmparg.expr->_lineno,
540 tmparg.mod->ModuleName,
541 diff_files ? " (" : "",
542 diff_files ? tmparg.mod->source_file_name : "",
543 diff_files ? ")" : "");
544 if(critical)
Lev Walkinf593f102005-02-22 07:59:59 +0000545 return -1;
Lev Walkin9c2285a2006-03-09 08:49:26 +0000546 RET2RVAL(1, rvalue);
Lev Walkinf593f102005-02-22 07:59:59 +0000547 }
548 if(tmparg.mod == arg->mod) break;
549 }
550
Lev Walkin9c2285a2006-03-09 08:49:26 +0000551 return rvalue;
Lev Walkinf593f102005-02-22 07:59:59 +0000552}
553
Lev Walkin1dec5802005-03-04 09:02:27 +0000554static int
555asn1f_apply_unique_index(arg_t *arg) {
556 static int unique_index;
557 if(!arg) { unique_index = 0; return 0; }
558
Lev Walkin1dec5802005-03-04 09:02:27 +0000559 arg->expr->_type_unique_index = ++unique_index;
560
561 return 0;
562}
563
Lev Walkinf15320b2004-06-03 03:38:44 +0000564/*
565 * Print everything to stderr
566 */
567static void
568_default_error_logger(int _severity, const char *fmt, ...) {
569 va_list ap;
570 char *pfx = "";
571
572 switch(_severity) {
573 case -1: pfx = "DEBUG: "; break;
574 case 0: pfx = "WARNING: "; break;
575 case 1: pfx = "FATAL: "; break;
576 }
577
578 fprintf(stderr, "%s", pfx);
579 va_start(ap, fmt);
580 vfprintf(stderr, fmt, ap);
581 va_end(ap);
582 fprintf(stderr, "\n");
583}