blob: e8281df66c73adae266263a17700175cd9fe5db1 [file] [log] [blame]
vlmfa67ddc2004-06-03 03:38:44 +00001#include <stdio.h>
2#include <string.h>
3#include <errno.h>
4#include <assert.h>
5
6#include <asn1parser.h>
vlm4808c702004-08-18 04:50:37 +00007#include <asn1fix_export.h>
vlm04a79e62004-08-18 05:41:05 +00008#include <asn1fix_crange.h>
vlmfa67ddc2004-06-03 03:38:44 +00009
10#include "asn1print.h"
11
12#define INDENT(fmt, args...) do { \
13 int __i = level; while(__i--) putchar(' '); \
14 printf(fmt, ##args); \
15 } while(0)
16
vlm4808c702004-08-18 04:50:37 +000017static int asn1print_module(asn1p_t *asn, asn1p_module_t *mod, enum asn1print_flags flags);
18static int asn1print_oid(asn1p_oid_t *oid, enum asn1print_flags flags);
19static int asn1print_ref(asn1p_ref_t *ref, enum asn1print_flags flags);
20static int asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags);
21static int asn1print_params(asn1p_paramlist_t *pl,enum asn1print_flags flags);
22static int asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags);
23static int asn1print_constraint(asn1p_constraint_t *, enum asn1print_flags);
24static int asn1print_value(asn1p_value_t *val, enum asn1print_flags flags);
25static int asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1print_flags flags,
vlmfa67ddc2004-06-03 03:38:44 +000026 int level);
27
28/*
29 * Print the contents of the parsed ASN tree.
30 */
31int
vlm4808c702004-08-18 04:50:37 +000032asn1print(asn1p_t *asn, enum asn1print_flags flags) {
vlmfa67ddc2004-06-03 03:38:44 +000033 asn1p_module_t *mod;
34
35 if(asn == NULL) {
36 errno = EINVAL;
37 return -1;
38 }
39
40 TQ_FOR(mod, &(asn->modules), mod_next) {
vlm4808c702004-08-18 04:50:37 +000041 asn1print_module(asn, mod, flags);
vlmfa67ddc2004-06-03 03:38:44 +000042 }
43
44 return 0;
45}
46
47static int
vlm4808c702004-08-18 04:50:37 +000048asn1print_module(asn1p_t *asn, asn1p_module_t *mod, enum asn1print_flags flags) {
vlmfa67ddc2004-06-03 03:38:44 +000049 asn1p_expr_t *tc;
50
vlmfa67ddc2004-06-03 03:38:44 +000051 printf("\n%s ", mod->Identifier);
52 if(mod->module_oid) {
53 asn1print_oid(mod->module_oid, flags);
54 printf("\n");
55 }
56
57 printf("DEFINITIONS");
58
vlm4808c702004-08-18 04:50:37 +000059 if(mod->module_flags & MSF_TAG_INSTRUCTIONS)
60 printf(" TAG INSTRUCTIONS");
61 if(mod->module_flags & MSF_XER_INSTRUCTIONS)
62 printf(" XER INSTRUCTIONS");
vlmfa67ddc2004-06-03 03:38:44 +000063 if(mod->module_flags & MSF_EXPLICIT_TAGS)
64 printf(" EXPLICIT TAGS");
65 if(mod->module_flags & MSF_IMPLICIT_TAGS)
66 printf(" IMPLICIT TAGS");
67 if(mod->module_flags & MSF_AUTOMATIC_TAGS)
68 printf(" AUTOMATIC TAGS");
69 if(mod->module_flags & MSF_EXTENSIBILITY_IMPLIED)
70 printf(" EXTENSIBILITY IMPLIED");
71
72 printf(" ::=\n");
73 printf("BEGIN\n\n");
74
75 TQ_FOR(tc, &(mod->members), next) {
vlm4808c702004-08-18 04:50:37 +000076 asn1print_expr(asn, mod, tc, flags, 0);
vlm00ad2822004-08-20 13:24:28 +000077 if(flags & APF_DEBUG_CONSTRAINTS)
78 printf("\n");
79 else
80 printf("\n\n");
vlmfa67ddc2004-06-03 03:38:44 +000081 }
82
83 printf("END\n");
84
85 return 0;
86}
87
88static int
vlm4808c702004-08-18 04:50:37 +000089asn1print_oid(asn1p_oid_t *oid, enum asn1print_flags flags) {
vlmfa67ddc2004-06-03 03:38:44 +000090 int ac;
91 int accum = 0;
92
vlmb42843a2004-06-05 08:17:50 +000093 (void)flags; /* Unused argument */
94
vlmfa67ddc2004-06-03 03:38:44 +000095 printf("{");
96 for(ac = 0; ac < oid->arcs_count; ac++) {
97 if(accum + strlen(oid->arcs[ac].name?:"") > 50) {
98 printf("\n\t");
99 accum = 0;
100 } else if(ac) printf(" ");
101
102 if(oid->arcs[ac].name) {
vlmdc4d95a2004-09-05 10:38:50 +0000103 printf("%s", oid->arcs[ac].name);
104 if(oid->arcs[ac].number >= 0) {
105 printf("(%lld)",
106 (long long)oid->arcs[ac].number);
107 }
vlmfa67ddc2004-06-03 03:38:44 +0000108 accum += strlen(oid->arcs[ac].name);
109 } else {
110 printf("%d",
111 (int)oid->arcs[ac].number);
112 }
113 accum += 4;
114 }
115 printf(" }");
116
117 return 0;
118}
119
120static int
vlm4808c702004-08-18 04:50:37 +0000121asn1print_ref(asn1p_ref_t *ref, enum asn1print_flags flags) {
vlmfa67ddc2004-06-03 03:38:44 +0000122 int cc;
123
vlmb42843a2004-06-05 08:17:50 +0000124 (void)flags; /* Unused argument */
125
vlmfa67ddc2004-06-03 03:38:44 +0000126 for(cc = 0; cc < ref->comp_count; cc++) {
127 if(cc) printf(".");
128 printf("%s", ref->components[cc].name);
129 }
130
131 return 0;
132}
133
134static int
vlm4808c702004-08-18 04:50:37 +0000135asn1print_tag(asn1p_expr_t *tc, enum asn1print_flags flags) {
vlmfa67ddc2004-06-03 03:38:44 +0000136 struct asn1p_type_tag_s *tag = &tc->tag;
137
vlmb42843a2004-06-05 08:17:50 +0000138 (void)flags; /* Unused argument */
139
vlmfa67ddc2004-06-03 03:38:44 +0000140 if(tag->tag_class == TC_NOCLASS)
141 return 0;
142
143 printf("[");
144 switch(tag->tag_class) {
145 case TC_NOCLASS:
146 assert(tag->tag_class != TC_NOCLASS);
147 break;
148 case TC_UNIVERSAL: printf("UNIVERSAL "); break;
149 case TC_PRIVATE: printf("PRIVATE "); break;
150 case TC_APPLICATION: printf("APPLICATION "); break;
151 case TC_CONTEXT_SPECIFIC:
152 break;
153 }
154 printf("%lld]", (long long)tag->tag_value);
155
156 switch(tag->tag_mode) {
157 case TM_DEFAULT: break;
158 case TM_IMPLICIT: printf(" IMPLICIT"); break;
159 case TM_EXPLICIT: printf(" EXPLICIT"); break;
160 }
161
162 return 0;
163}
164
165static int
vlm4808c702004-08-18 04:50:37 +0000166asn1print_value(asn1p_value_t *val, enum asn1print_flags flags) {
vlmfa67ddc2004-06-03 03:38:44 +0000167
168 if(val == NULL)
169 return 0;
170
171 switch(val->type) {
172 case ATV_NOVALUE:
173 break;
174 case ATV_REFERENCED:
175 return asn1print_ref(val->value.reference, flags);
176 case ATV_INTEGER:
177 printf("%lld", (long long)val->value.v_integer);
178 return 0;
179 case ATV_MIN: printf("MIN"); return 0;
180 case ATV_MAX: printf("MAX"); return 0;
181 case ATV_FALSE: printf("FALSE"); return 0;
182 case ATV_TRUE: printf("TRUE"); return 0;
183 case ATV_REAL:
184 printf("%f", val->value.v_double);
185 return 0;
186 case ATV_STRING:
187 {
188 char *p = val->value.string.buf;
189 putchar('"');
190 if(strchr(p, '"')) {
191 /* Mask quotes */
192 for(; *p; p++) {
193 if(*p == '"')
194 putchar(*p);
195 putchar(*p);
196 }
197 } else {
198 fputs(p, stdout);
199 }
200 putchar('"');
201 }
202 return 0;
203 case ATV_UNPARSED:
204 fputs(val->value.string.buf, stdout);
205 return 0;
206 case ATV_BITVECTOR:
207 {
208 uint8_t *bitvector;
209 int bits;
210 int i;
211
212 bitvector = val->value.binary_vector.bits;
213 bits = val->value.binary_vector.size_in_bits;
214
215 printf("'");
216 if(bits%8) {
217 for(i = 0; i < bits; i++) {
218 uint8_t uc;
219 uc = bitvector[i>>3];
220 putchar(((uc >> (7-(i%8)))&1)?'1':'0');
221 }
222 printf("'B");
223 } else {
224 char hextable[16] = "0123456789ABCDEF";
225 for(i = 0; i < (bits>>3); i++) {
226 putchar(hextable[bitvector[i] >> 4]);
227 putchar(hextable[bitvector[i] & 0x0f]);
228 }
229 printf("'H");
230 }
231 }
232 }
233
234 assert(val->type || !"Unknown");
235
236 return 0;
237}
238
239static int
vlm4808c702004-08-18 04:50:37 +0000240asn1print_constraint(asn1p_constraint_t *ct, enum asn1print_flags flags) {
vlmfa67ddc2004-06-03 03:38:44 +0000241 int symno = 0;
242
243 if(ct == 0) return 0;
244
245 if(ct->type == ACT_CA_SET)
246 printf("(");
247
248 switch(ct->type) {
249 case ACT_EL_VALUE:
250 asn1print_value(ct->value, flags);
251 break;
252 case ACT_EL_RANGE:
253 case ACT_EL_LLRANGE:
254 case ACT_EL_RLRANGE:
255 case ACT_EL_ULRANGE:
256 asn1print_value(ct->range_start, flags);
257 switch(ct->type) {
258 case ACT_EL_RANGE: printf(".."); break;
259 case ACT_EL_LLRANGE: printf("<.."); break;
260 case ACT_EL_RLRANGE: printf("..<"); break;
261 case ACT_EL_ULRANGE: printf("<..<"); break;
262 default: printf("?..?"); break;
263 }
264 asn1print_value(ct->range_stop, flags);
265 break;
266 case ACT_EL_EXT:
267 printf("...");
268 break;
269 case ACT_CT_SIZE:
270 case ACT_CT_FROM:
271 switch(ct->type) {
vlm4808c702004-08-18 04:50:37 +0000272 case ACT_CT_SIZE: printf("SIZE("); break;
273 case ACT_CT_FROM: printf("FROM("); break;
vlmfa67ddc2004-06-03 03:38:44 +0000274 default: printf("??? ("); break;
275 }
276 assert(ct->el_count != 0);
277 assert(ct->el_count == 1);
278 asn1print_constraint(ct->elements[0], flags);
279 printf(")");
280 break;
281 case ACT_CT_WCOMP:
282 case ACT_CT_WCOMPS:
283 printf("???");
284 break;
285 case ACT_CA_SET: symno++;
286 case ACT_CA_CRC: symno++;
287 case ACT_CA_CSV: symno++;
288 case ACT_CA_UNI: symno++;
289 case ACT_CA_INT: symno++;
290 case ACT_CA_EXC:
291 {
vlm4808c702004-08-18 04:50:37 +0000292 char *symtable[] = { " EXCEPT ", " ^ ", " | ", ",",
vlmfa67ddc2004-06-03 03:38:44 +0000293 "", "(" };
vlmdc4d95a2004-09-05 10:38:50 +0000294 unsigned int i;
vlmfa67ddc2004-06-03 03:38:44 +0000295 for(i = 0; i < ct->el_count; i++) {
vlm4808c702004-08-18 04:50:37 +0000296 enum asn1print_flags nflags = flags;
vlmfa67ddc2004-06-03 03:38:44 +0000297 if(i) fputs(symtable[symno], stdout);
298 if(ct->type == ACT_CA_CRC) fputs("{", stdout);
299 asn1print_constraint(ct->elements[i], nflags);
300 if(ct->type == ACT_CA_CRC) fputs("}", stdout);
301 if(i+1 < ct->el_count
302 && ct->type == ACT_CA_SET)
303 fputs(")", stdout);
304 }
305 }
306 break;
307 case ACT_INVALID:
308 assert(ct->type != ACT_INVALID);
309 break;
310 }
311
312 if(ct->type == ACT_CA_SET)
313 printf(")");
314
315 return 0;
316}
317
318static int
vlm4808c702004-08-18 04:50:37 +0000319asn1print_params(asn1p_paramlist_t *pl, enum asn1print_flags flags) {
vlmfa67ddc2004-06-03 03:38:44 +0000320 if(pl) {
321 int i;
322 printf("{");
323 for(i = 0; i < pl->params_count; i++) {
324 if(i) printf(", ");
325 if(pl->params[i].governor) {
326 asn1print_ref(pl->params[i].governor, flags);
327 printf(":");
328 }
329 printf("%s", pl->params[i].argument);
330 }
331 printf("}");
332 }
333
334 return 0;
335}
336
337static int
vlm4808c702004-08-18 04:50:37 +0000338asn1print_with_syntax(asn1p_wsyntx_t *wx, enum asn1print_flags flags) {
vlmfa67ddc2004-06-03 03:38:44 +0000339 if(wx) {
340 asn1p_wsyntx_chunk_t *wc;
341 printf(" WITH SYNTAX {");
342 TQ_FOR(wc, &(wx->chunks), next) {
343 if(wc->ref) {
344 asn1print_ref(wc->ref, flags);
345 } else {
346 fwrite(wc->buf, 1, wc->len, stdout);
347 }
348 }
349 printf("}\n");
350 }
351
352 return 0;
353}
354
355static int
vlm4808c702004-08-18 04:50:37 +0000356asn1print_crange_value(asn1cnst_edge_t *edge, int as_char) {
357 switch(edge->type) {
358 case ARE_MIN: printf("MIN"); break;
359 case ARE_MAX: printf("MAX"); break;
360 case ARE_VALUE:
361 if(as_char) {
362 printf("\"%c\"", (unsigned char)edge->value);
363 } else {
364 printf("%lld", (long long)edge->value);
365 }
366 }
367 return 0;
368}
369
370static int
vlmeeca98f2004-08-25 02:00:03 +0000371asn1print_constraint_explain_type(asn1p_expr_type_e expr_type, asn1p_constraint_t *ct, enum asn1p_constraint_type_e type, int strict_PER_visible) {
vlm4808c702004-08-18 04:50:37 +0000372 asn1cnst_range_t *range;
373 int as_char = (type==ACT_CT_FROM);
374 int i;
375
vlmeeca98f2004-08-25 02:00:03 +0000376 range = asn1constraint_compute_PER_range(expr_type, ct, type,
377 0, 0, strict_PER_visible);
vlm4808c702004-08-18 04:50:37 +0000378 if(!range) return -1;
379
vlmeeca98f2004-08-25 02:00:03 +0000380 if(range->incompatible
381 || (strict_PER_visible && range->not_PER_visible)) {
382 asn1constraint_range_free(range);
383 return 0;
384 }
385
vlm4808c702004-08-18 04:50:37 +0000386 switch(type) {
387 case ACT_CT_FROM: printf("(FROM("); break;
388 case ACT_CT_SIZE: printf("(SIZE("); break;
389 default: printf("("); break;
390 }
391 for(i = -1; i < range->el_count; i++) {
392 asn1cnst_range_t *r;
393 if(i == -1) {
394 if(range->el_count) continue;
395 r = range;
396 } else {
397 r = range->elements[i];
398 }
399 if(i > 0) {
400 printf(" | ");
401 }
402 asn1print_crange_value(&r->left, as_char);
403 if(r->left.type != r->right.type
404 || r->left.value != r->right.value) {
405 printf("..");
406 asn1print_crange_value(&r->right, as_char);
407 }
408 }
409 if(range->extensible)
410 printf(",...");
411 printf(type==ACT_EL_RANGE?")":"))");
412
413 if(range->empty_constraint)
414 printf(":Empty!");
415
416 asn1constraint_range_free(range);
417 return 0;
418}
419
420static int
421asn1print_constraint_explain(asn1p_expr_type_e expr_type,
vlmeeca98f2004-08-25 02:00:03 +0000422 asn1p_constraint_t *ct, int s_PV) {
vlm4808c702004-08-18 04:50:37 +0000423
vlmeeca98f2004-08-25 02:00:03 +0000424 asn1print_constraint_explain_type(expr_type, ct, ACT_EL_RANGE, s_PV);
vlm4808c702004-08-18 04:50:37 +0000425 printf(" ");
vlmeeca98f2004-08-25 02:00:03 +0000426 asn1print_constraint_explain_type(expr_type, ct, ACT_CT_SIZE, s_PV);
vlm4808c702004-08-18 04:50:37 +0000427 printf(" ");
vlmeeca98f2004-08-25 02:00:03 +0000428 asn1print_constraint_explain_type(expr_type, ct, ACT_CT_FROM, s_PV);
vlm4808c702004-08-18 04:50:37 +0000429
430 return 0;
431}
432
433static int
434asn1print_expr(asn1p_t *asn, asn1p_module_t *mod, asn1p_expr_t *tc, enum asn1print_flags flags, int level) {
vlm00ad2822004-08-20 13:24:28 +0000435 int SEQ_OF = 0;
vlmfa67ddc2004-06-03 03:38:44 +0000436
437 if(flags & APF_LINE_COMMENTS)
438 INDENT("-- #line %d\n", tc->_lineno);
439 if(tc->Identifier)
440 INDENT("%s", tc->Identifier);
441
442 if(tc->params) {
443 asn1print_params(tc->params, flags);
444 }
445
446 if(tc->meta_type != AMT_VALUE
vlmda4df3f2004-08-25 02:27:47 +0000447 && tc->meta_type != AMT_VALUESET
vlmfa67ddc2004-06-03 03:38:44 +0000448 && tc->expr_type != A1TC_EXTENSIBLE) {
449 if(level) {
450 if(tc->Identifier)
451 printf("\t");
452 } else {
453 printf(" ::=");
454 }
455 }
456
457 if(tc->tag.tag_class) {
458 printf(" ");
459 asn1print_tag(tc, flags);
460 }
461
462 switch(tc->expr_type) {
463 case A1TC_EXTENSIBLE:
464 if(tc->value) {
465 printf("!");
466 asn1print_value(tc->value, flags);
467 }
468 break;
vlmddd6fd12004-08-22 03:08:51 +0000469 case A1TC_COMPONENTS_OF:
470 SEQ_OF = 1; /* Equivalent to SET OF for printint purposes */
471 printf(" COMPONENTS OF");
472 break;
vlmfa67ddc2004-06-03 03:38:44 +0000473 case A1TC_REFERENCE:
474 case A1TC_UNIVERVAL:
475 case A1TC_PARAMETRIZED:
476 break;
477 case A1TC_CLASSDEF:
478 printf(" CLASS");
479 break;
480 case A1TC_CLASSFIELD:
481 /* Nothing to print here */
482 break;
vlm00ad2822004-08-20 13:24:28 +0000483 case ASN_CONSTR_SET_OF:
484 case ASN_CONSTR_SEQUENCE_OF:
485 SEQ_OF = 1;
486 if(tc->expr_type == ASN_CONSTR_SET_OF)
487 printf(" SET");
488 else
489 printf(" SEQUENCE");
490 if(tc->constraints) {
491 printf(" ");
492 asn1print_constraint(tc->constraints, flags);
493 }
494 printf(" OF");
495 break;
vlmfa67ddc2004-06-03 03:38:44 +0000496 default:
497 {
498 char *p = ASN_EXPR_TYPE2STR(tc->expr_type);
499 printf(" %s", p?p:"<unknown type!>");
500 }
501 break;
502 }
503
504 if(tc->reference) {
505 printf(" ");
506 asn1print_ref(tc->reference, flags);
507 }
508
vlmda4df3f2004-08-25 02:27:47 +0000509 if(tc->meta_type == AMT_VALUESET)
510 printf(" ::=");
511
vlmfa67ddc2004-06-03 03:38:44 +0000512 /*
513 * Display the descendants (children) of the current type.
514 */
vlmda4df3f2004-08-25 02:27:47 +0000515 if(TQ_FIRST(&(tc->members))
516 || (tc->expr_type & ASN_CONSTR_MASK)
517 || tc->meta_type == AMT_VALUESET
518 || tc->meta_type == AMT_OBJECT
519 || tc->meta_type == AMT_OBJECTSET
520 ) {
vlmfa67ddc2004-06-03 03:38:44 +0000521 asn1p_expr_t *se; /* SubExpression */
vlmddd6fd12004-08-22 03:08:51 +0000522 int put_braces = !SEQ_OF; /* Don't need 'em, if SET OF... */
vlmfa67ddc2004-06-03 03:38:44 +0000523
vlmda4df3f2004-08-25 02:27:47 +0000524 if(put_braces) {
525 printf(" {");
526 if(TQ_FIRST(&tc->members))
527 printf("\n");
528 else printf(" }");
529 }
vlmfa67ddc2004-06-03 03:38:44 +0000530
531 TQ_FOR(se, &(tc->members), next) {
532 /*
vlmddd6fd12004-08-22 03:08:51 +0000533 * Print the expression as it were a stand-alone type.
vlmfa67ddc2004-06-03 03:38:44 +0000534 */
vlm4808c702004-08-18 04:50:37 +0000535 asn1print_expr(asn, mod, se, flags, level + 4);
vlmfa67ddc2004-06-03 03:38:44 +0000536 switch(se->marker) {
537 case EM_NOMARK: break;
538 case EM_OPTIONAL: printf(" OPTIONAL"); break;
539 case EM_DEFAULT: printf(" DEFAULT <?>"); break;
540 }
541 if(TQ_NEXT(se, next)) {
542 printf(",");
543 INDENT("\n");
544 }
545 }
546
vlmda4df3f2004-08-25 02:27:47 +0000547 if(put_braces && TQ_FIRST(&tc->members)) {
vlmfa67ddc2004-06-03 03:38:44 +0000548 printf("\n");
549 INDENT("}");
550 }
551 }
552
553 if(tc->with_syntax)
554 asn1print_with_syntax(tc->with_syntax, flags);
555
vlm00ad2822004-08-20 13:24:28 +0000556 if(!SEQ_OF && tc->constraints) {
vlmfa67ddc2004-06-03 03:38:44 +0000557 printf(" ");
558 asn1print_constraint(tc->constraints, flags);
559 }
vlm4808c702004-08-18 04:50:37 +0000560
vlmfa67ddc2004-06-03 03:38:44 +0000561 if(tc->unique) {
562 printf(" UNIQUE");
563 }
564
565 if(tc->meta_type == AMT_VALUE
566 && tc->expr_type != A1TC_EXTENSIBLE) {
vlmdc4d95a2004-09-05 10:38:50 +0000567 if(tc->expr_type == A1TC_UNIVERVAL) {
vlmfa67ddc2004-06-03 03:38:44 +0000568 printf("(");
vlmdc4d95a2004-09-05 10:38:50 +0000569 asn1print_value(tc->value, flags);
vlmfa67ddc2004-06-03 03:38:44 +0000570 printf(")");
vlmdc4d95a2004-09-05 10:38:50 +0000571 } else {
572 printf(" ::= ");
573 asn1print_value(tc->value, flags);
574 }
vlmfa67ddc2004-06-03 03:38:44 +0000575 }
576
vlmddd6fd12004-08-22 03:08:51 +0000577 /*
578 * The following section exists entirely for debugging only.
579 */
vlm00ad2822004-08-20 13:24:28 +0000580 if(flags & APF_DEBUG_CONSTRAINTS
581 && tc->expr_type != A1TC_EXTENSIBLE) {
vlm4808c702004-08-18 04:50:37 +0000582 asn1p_expr_t *top_parent;
583
584 if(tc->combined_constraints) {
585 printf("\n-- Combined constraints: ");
586 asn1print_constraint(tc->combined_constraints, flags);
587 }
588
vlmddd6fd12004-08-22 03:08:51 +0000589 top_parent = asn1f_find_terminal_type_ex(asn, mod, tc);
vlm4808c702004-08-18 04:50:37 +0000590 if(top_parent) {
vlmeeca98f2004-08-25 02:00:03 +0000591 printf("\n-- Practical constraints (%s): ",
592 top_parent->Identifier);
593 asn1print_constraint_explain(top_parent->expr_type,
594 tc->combined_constraints, 0);
vlm00ad2822004-08-20 13:24:28 +0000595 printf("\n-- PER-visible constraints (%s): ",
596 top_parent->Identifier);
vlm4808c702004-08-18 04:50:37 +0000597 asn1print_constraint_explain(top_parent->expr_type,
vlmeeca98f2004-08-25 02:00:03 +0000598 tc->combined_constraints, 1);
vlm4808c702004-08-18 04:50:37 +0000599 }
vlm00ad2822004-08-20 13:24:28 +0000600 printf("\n");
vlm4808c702004-08-18 04:50:37 +0000601 }
602
vlmfa67ddc2004-06-03 03:38:44 +0000603 return 0;
604}
vlm4808c702004-08-18 04:50:37 +0000605