1 /* 2 * Copyright (c) 1997 - 2005 Kungliga Tekniska H�gskolan 3 * (Royal Institute of Technology, Stockholm, Sweden). 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * 3. Neither the name of the Institute nor the names of its contributors 18 * may be used to endorse or promote products derived from this software 19 * without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 */ 33 34 #include "gen_locl.h" 35 36 RCSID("$Id: gen.c 22429 2008-01-13 10:25:50Z lha $"); 37 38 FILE *headerfile, *codefile, *logfile; 39 40 #define STEM "asn1" 41 42 static const char *orig_filename; 43 static char *header; 44 static const char *headerbase = STEM; 45 46 /* 47 * list of all IMPORTs 48 */ 49 50 struct import { 51 const char *module; 52 struct import *next; 53 }; 54 55 static struct import *imports = NULL; 56 57 void 58 add_import (const char *module) 59 { 60 struct import *tmp = emalloc (sizeof(*tmp)); 61 62 tmp->module = module; 63 tmp->next = imports; 64 imports = tmp; 65 66 fprintf (headerfile, "#include <%s_asn1.h>\n", module); 67 } 68 69 const char * 70 get_filename (void) 71 { 72 return orig_filename; 73 } 74 75 void 76 init_generate (const char *filename, const char *base) 77 { 78 char *fn; 79 80 orig_filename = filename; 81 if (base != NULL) { 82 headerbase = strdup(base); 83 if (headerbase == NULL) 84 errx(1, "strdup"); 85 } 86 asprintf(&header, "%s.h", headerbase); 87 if (header == NULL) 88 errx(1, "malloc"); 89 headerfile = fopen (header, "w"); 90 if (headerfile == NULL) 91 err (1, "open %s", header); 92 fprintf (headerfile, 93 "/* Generated from %s */\n" 94 "/* Do not edit */\n\n", 95 filename); 96 fprintf (headerfile, 97 "#ifndef __%s_h__\n" 98 "#define __%s_h__\n\n", headerbase, headerbase); 99 fprintf (headerfile, 100 "#include <stddef.h>\n" 101 "#include <time.h>\n\n"); 102 fprintf (headerfile, 103 "#ifndef __asn1_common_definitions__\n" 104 "#define __asn1_common_definitions__\n\n"); 105 fprintf (headerfile, 106 "typedef struct heim_integer {\n" 107 " size_t length;\n" 108 " void *data;\n" 109 " int negative;\n" 110 "} heim_integer;\n\n"); 111 fprintf (headerfile, 112 "typedef struct heim_octet_string {\n" 113 " size_t length;\n" 114 " void *data;\n" 115 "} heim_octet_string;\n\n"); 116 fprintf (headerfile, 117 "typedef char *heim_general_string;\n\n" 118 ); 119 fprintf (headerfile, 120 "typedef char *heim_utf8_string;\n\n" 121 ); 122 fprintf (headerfile, 123 "typedef char *heim_printable_string;\n\n" 124 ); 125 fprintf (headerfile, 126 "typedef char *heim_ia5_string;\n\n" 127 ); 128 fprintf (headerfile, 129 "typedef struct heim_bmp_string {\n" 130 " size_t length;\n" 131 " uint16_t *data;\n" 132 "} heim_bmp_string;\n\n"); 133 fprintf (headerfile, 134 "typedef struct heim_universal_string {\n" 135 " size_t length;\n" 136 " uint32_t *data;\n" 137 "} heim_universal_string;\n\n"); 138 fprintf (headerfile, 139 "typedef char *heim_visible_string;\n\n" 140 ); 141 fprintf (headerfile, 142 "typedef struct heim_oid {\n" 143 " size_t length;\n" 144 " unsigned *components;\n" 145 "} heim_oid;\n\n"); 146 fprintf (headerfile, 147 "typedef struct heim_bit_string {\n" 148 " size_t length;\n" 149 " void *data;\n" 150 "} heim_bit_string;\n\n"); 151 fprintf (headerfile, 152 "typedef struct heim_octet_string heim_any;\n" 153 "typedef struct heim_octet_string heim_any_set;\n\n"); 154 fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \\\n" 155 " do { \\\n" 156 " (BL) = length_##T((S)); \\\n" 157 " (B) = malloc((BL)); \\\n" 158 " if((B) == NULL) { \\\n" 159 " (R) = ENOMEM; \\\n" 160 " } else { \\\n" 161 " (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \\\n" 162 " (S), (L)); \\\n" 163 " if((R) != 0) { \\\n" 164 " free((B)); \\\n" 165 " (B) = NULL; \\\n" 166 " } \\\n" 167 " } \\\n" 168 " } while (0)\n\n", 169 headerfile); 170 fprintf (headerfile, "struct units;\n\n"); 171 fprintf (headerfile, "#endif\n\n"); 172 asprintf(&fn, "%s_files", base); 173 if (fn == NULL) 174 errx(1, "malloc"); 175 logfile = fopen(fn, "w"); 176 if (logfile == NULL) 177 err (1, "open %s", fn); 178 } 179 180 void 181 close_generate (void) 182 { 183 fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase); 184 185 fclose (headerfile); 186 fprintf (logfile, "\n"); 187 fclose (logfile); 188 } 189 190 void 191 gen_assign_defval(const char *var, struct value *val) 192 { 193 switch(val->type) { 194 case stringvalue: 195 fprintf(codefile, "if((%s = strdup(\"%s\")) == NULL)\nreturn ENOMEM;\n", var, val->u.stringvalue); 196 break; 197 case integervalue: 198 fprintf(codefile, "%s = %d;\n", var, val->u.integervalue); 199 break; 200 case booleanvalue: 201 if(val->u.booleanvalue) 202 fprintf(codefile, "%s = TRUE;\n", var); 203 else 204 fprintf(codefile, "%s = FALSE;\n", var); 205 break; 206 default: 207 abort(); 208 } 209 } 210 211 void 212 gen_compare_defval(const char *var, struct value *val) 213 { 214 switch(val->type) { 215 case stringvalue: 216 fprintf(codefile, "if(strcmp(%s, \"%s\") != 0)\n", var, val->u.stringvalue); 217 break; 218 case integervalue: 219 fprintf(codefile, "if(%s != %d)\n", var, val->u.integervalue); 220 break; 221 case booleanvalue: 222 if(val->u.booleanvalue) 223 fprintf(codefile, "if(!%s)\n", var); 224 else 225 fprintf(codefile, "if(%s)\n", var); 226 break; 227 default: 228 abort(); 229 } 230 } 231 232 static void 233 generate_header_of_codefile(const char *name) 234 { 235 char *filename; 236 237 if (codefile != NULL) 238 abort(); 239 240 asprintf (&filename, "%s_%s.x", STEM, name); 241 if (filename == NULL) 242 errx(1, "malloc"); 243 codefile = fopen (filename, "w"); 244 if (codefile == NULL) 245 err (1, "fopen %s", filename); 246 fprintf(logfile, "%s ", filename); 247 free(filename); 248 fprintf (codefile, 249 "/* Generated from %s */\n" 250 "/* Do not edit */\n\n" 251 "#include <stdio.h>\n" 252 "#include <stdlib.h>\n" 253 "#include <time.h>\n" 254 "#include <string.h>\n" 255 "#include <errno.h>\n" 256 "#include <limits.h>\n" 257 "#include <krb5-types.h>\n", 258 orig_filename); 259 260 fprintf (codefile, 261 "#include <%s.h>\n", 262 headerbase); 263 fprintf (codefile, 264 "#include <asn1_err.h>\n" 265 "#include <der.h>\n" 266 "#include <parse_units.h>\n\n"); 267 268 } 269 270 static void 271 close_codefile(void) 272 { 273 if (codefile == NULL) 274 abort(); 275 276 fclose(codefile); 277 codefile = NULL; 278 } 279 280 281 void 282 generate_constant (const Symbol *s) 283 { 284 switch(s->value->type) { 285 case booleanvalue: 286 break; 287 case integervalue: 288 fprintf (headerfile, "enum { %s = %d };\n\n", 289 s->gen_name, s->value->u.integervalue); 290 break; 291 case nullvalue: 292 break; 293 case stringvalue: 294 break; 295 case objectidentifiervalue: { 296 struct objid *o, **list; 297 int i, len; 298 299 generate_header_of_codefile(s->gen_name); 300 301 len = 0; 302 for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next) 303 len++; 304 list = emalloc(sizeof(*list) * len); 305 306 i = 0; 307 for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next) 308 list[i++] = o; 309 310 fprintf (headerfile, "/* OBJECT IDENTIFIER %s ::= { ", s->name); 311 for (i = len - 1 ; i >= 0; i--) { 312 o = list[i]; 313 fprintf(headerfile, "%s(%d) ", 314 o->label ? o->label : "label-less", o->value); 315 } 316 317 fprintf (headerfile, "} */\n"); 318 fprintf (headerfile, "const heim_oid *oid_%s(void);\n\n", 319 s->gen_name); 320 321 fprintf (codefile, "static unsigned oid_%s_variable_num[%d] = {", 322 s->gen_name, len); 323 for (i = len - 1 ; i >= 0; i--) { 324 fprintf(codefile, "%d%s ", list[i]->value, i > 0 ? "," : ""); 325 } 326 fprintf(codefile, "};\n"); 327 328 fprintf (codefile, "static const heim_oid oid_%s_variable = " 329 "{ %d, oid_%s_variable_num };\n\n", 330 s->gen_name, len, s->gen_name); 331 332 fprintf (codefile, "const heim_oid *oid_%s(void)\n" 333 "{\n" 334 "return &oid_%s_variable;\n" 335 "}\n\n", 336 s->gen_name, s->gen_name); 337 338 close_codefile(); 339 340 break; 341 } 342 default: 343 abort(); 344 } 345 } 346 347 static void 348 space(int level) 349 { 350 while(level-- > 0) 351 fprintf(headerfile, " "); 352 } 353 354 static const char * 355 last_member_p(struct member *m) 356 { 357 struct member *n = ASN1_TAILQ_NEXT(m, members); 358 if (n == NULL) 359 return ""; 360 if (n->ellipsis && ASN1_TAILQ_NEXT(n, members) == NULL) 361 return ""; 362 return ","; 363 } 364 365 static struct member * 366 have_ellipsis(Type *t) 367 { 368 struct member *m; 369 ASN1_TAILQ_FOREACH(m, t->members, members) { 370 if (m->ellipsis) 371 return m; 372 } 373 return NULL; 374 } 375 376 static void 377 define_asn1 (int level, Type *t) 378 { 379 switch (t->type) { 380 case TType: 381 fprintf (headerfile, "%s", t->symbol->name); 382 break; 383 case TInteger: 384 if(t->members == NULL) { 385 fprintf (headerfile, "INTEGER"); 386 if (t->range) 387 fprintf (headerfile, " (%d..%d)", 388 t->range->min, t->range->max); 389 } else { 390 Member *m; 391 fprintf (headerfile, "INTEGER {\n"); 392 ASN1_TAILQ_FOREACH(m, t->members, members) { 393 space (level + 1); 394 fprintf(headerfile, "%s(%d)%s\n", m->gen_name, m->val, 395 last_member_p(m)); 396 } 397 space(level); 398 fprintf (headerfile, "}"); 399 } 400 break; 401 case TBoolean: 402 fprintf (headerfile, "BOOLEAN"); 403 break; 404 case TOctetString: 405 fprintf (headerfile, "OCTET STRING"); 406 break; 407 case TEnumerated : 408 case TBitString: { 409 Member *m; 410 411 space(level); 412 if(t->type == TBitString) 413 fprintf (headerfile, "BIT STRING {\n"); 414 else 415 fprintf (headerfile, "ENUMERATED {\n"); 416 ASN1_TAILQ_FOREACH(m, t->members, members) { 417 space(level + 1); 418 fprintf (headerfile, "%s(%d)%s\n", m->name, m->val, 419 last_member_p(m)); 420 } 421 space(level); 422 fprintf (headerfile, "}"); 423 break; 424 } 425 case TChoice: 426 case TSet: 427 case TSequence: { 428 Member *m; 429 int max_width = 0; 430 431 if(t->type == TChoice) 432 fprintf(headerfile, "CHOICE {\n"); 433 else if(t->type == TSet) 434 fprintf(headerfile, "SET {\n"); 435 else 436 fprintf(headerfile, "SEQUENCE {\n"); 437 ASN1_TAILQ_FOREACH(m, t->members, members) { 438 if(strlen(m->name) > max_width) 439 max_width = strlen(m->name); 440 } 441 max_width += 3; 442 if(max_width < 16) max_width = 16; 443 ASN1_TAILQ_FOREACH(m, t->members, members) { 444 int width = max_width; 445 space(level + 1); 446 if (m->ellipsis) { 447 fprintf (headerfile, "..."); 448 } else { 449 width -= fprintf(headerfile, "%s", m->name); 450 fprintf(headerfile, "%*s", width, ""); 451 define_asn1(level + 1, m->type); 452 if(m->optional) 453 fprintf(headerfile, " OPTIONAL"); 454 } 455 if(last_member_p(m)) 456 fprintf (headerfile, ","); 457 fprintf (headerfile, "\n"); 458 } 459 space(level); 460 fprintf (headerfile, "}"); 461 break; 462 } 463 case TSequenceOf: 464 fprintf (headerfile, "SEQUENCE OF "); 465 define_asn1 (0, t->subtype); 466 break; 467 case TSetOf: 468 fprintf (headerfile, "SET OF "); 469 define_asn1 (0, t->subtype); 470 break; 471 case TGeneralizedTime: 472 fprintf (headerfile, "GeneralizedTime"); 473 break; 474 case TGeneralString: 475 fprintf (headerfile, "GeneralString"); 476 break; 477 case TTag: { 478 const char *classnames[] = { "UNIVERSAL ", "APPLICATION ", 479 "" /* CONTEXT */, "PRIVATE " }; 480 if(t->tag.tagclass != ASN1_C_UNIV) 481 fprintf (headerfile, "[%s%d] ", 482 classnames[t->tag.tagclass], 483 t->tag.tagvalue); 484 if(t->tag.tagenv == TE_IMPLICIT) 485 fprintf (headerfile, "IMPLICIT "); 486 define_asn1 (level, t->subtype); 487 break; 488 } 489 case TUTCTime: 490 fprintf (headerfile, "UTCTime"); 491 break; 492 case TUTF8String: 493 space(level); 494 fprintf (headerfile, "UTF8String"); 495 break; 496 case TPrintableString: 497 space(level); 498 fprintf (headerfile, "PrintableString"); 499 break; 500 case TIA5String: 501 space(level); 502 fprintf (headerfile, "IA5String"); 503 break; 504 case TBMPString: 505 space(level); 506 fprintf (headerfile, "BMPString"); 507 break; 508 case TUniversalString: 509 space(level); 510 fprintf (headerfile, "UniversalString"); 511 break; 512 case TVisibleString: 513 space(level); 514 fprintf (headerfile, "VisibleString"); 515 break; 516 case TOID : 517 space(level); 518 fprintf(headerfile, "OBJECT IDENTIFIER"); 519 break; 520 case TNull: 521 space(level); 522 fprintf (headerfile, "NULL"); 523 break; 524 default: 525 abort (); 526 } 527 } 528 529 static void 530 define_type (int level, const char *name, Type *t, int typedefp, int preservep) 531 { 532 switch (t->type) { 533 case TType: 534 space(level); 535 fprintf (headerfile, "%s %s;\n", t->symbol->gen_name, name); 536 break; 537 case TInteger: 538 space(level); 539 if(t->members) { 540 Member *m; 541 fprintf (headerfile, "enum %s {\n", typedefp ? name : ""); 542 ASN1_TAILQ_FOREACH(m, t->members, members) { 543 space (level + 1); 544 fprintf(headerfile, "%s = %d%s\n", m->gen_name, m->val, 545 last_member_p(m)); 546 } 547 fprintf (headerfile, "} %s;\n", name); 548 } else if (t->range == NULL) { 549 fprintf (headerfile, "heim_integer %s;\n", name); 550 } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) { 551 fprintf (headerfile, "int %s;\n", name); 552 } else if (t->range->min == 0 && t->range->max == UINT_MAX) { 553 fprintf (headerfile, "unsigned int %s;\n", name); 554 } else if (t->range->min == 0 && t->range->max == INT_MAX) { 555 fprintf (headerfile, "unsigned int %s;\n", name); 556 } else 557 errx(1, "%s: unsupported range %d -> %d", 558 name, t->range->min, t->range->max); 559 break; 560 case TBoolean: 561 space(level); 562 fprintf (headerfile, "int %s;\n", name); 563 break; 564 case TOctetString: 565 space(level); 566 fprintf (headerfile, "heim_octet_string %s;\n", name); 567 break; 568 case TBitString: { 569 Member *m; 570 Type i; 571 struct range range = { 0, INT_MAX }; 572 573 i.type = TInteger; 574 i.range = ⦥ 575 i.members = NULL; 576 i.constraint = NULL; 577 578 space(level); 579 if(ASN1_TAILQ_EMPTY(t->members)) 580 fprintf (headerfile, "heim_bit_string %s;\n", name); 581 else { 582 fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); 583 ASN1_TAILQ_FOREACH(m, t->members, members) { 584 char *n; 585 586 asprintf (&n, "%s:1", m->gen_name); 587 if (n == NULL) 588 errx(1, "malloc"); 589 define_type (level + 1, n, &i, FALSE, FALSE); 590 free (n); 591 } 592 space(level); 593 fprintf (headerfile, "} %s;\n\n", name); 594 } 595 break; 596 } 597 case TEnumerated: { 598 Member *m; 599 600 space(level); 601 fprintf (headerfile, "enum %s {\n", typedefp ? name : ""); 602 ASN1_TAILQ_FOREACH(m, t->members, members) { 603 space(level + 1); 604 if (m->ellipsis) 605 fprintf (headerfile, "/* ... */\n"); 606 else 607 fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val, 608 last_member_p(m)); 609 } 610 space(level); 611 fprintf (headerfile, "} %s;\n\n", name); 612 break; 613 } 614 case TSet: 615 case TSequence: { 616 Member *m; 617 618 space(level); 619 fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); 620 if (t->type == TSequence && preservep) { 621 space(level + 1); 622 fprintf(headerfile, "heim_octet_string _save;\n"); 623 } 624 ASN1_TAILQ_FOREACH(m, t->members, members) { 625 if (m->ellipsis) { 626 ; 627 } else if (m->optional) { 628 char *n; 629 630 asprintf (&n, "*%s", m->gen_name); 631 if (n == NULL) 632 errx(1, "malloc"); 633 define_type (level + 1, n, m->type, FALSE, FALSE); 634 free (n); 635 } else 636 define_type (level + 1, m->gen_name, m->type, FALSE, FALSE); 637 } 638 space(level); 639 fprintf (headerfile, "} %s;\n", name); 640 break; 641 } 642 case TSetOf: 643 case TSequenceOf: { 644 Type i; 645 struct range range = { 0, INT_MAX }; 646 647 i.type = TInteger; 648 i.range = ⦥ 649 i.members = NULL; 650 i.constraint = NULL; 651 652 space(level); 653 fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); 654 define_type (level + 1, "len", &i, FALSE, FALSE); 655 define_type (level + 1, "*val", t->subtype, FALSE, FALSE); 656 space(level); 657 fprintf (headerfile, "} %s;\n", name); 658 break; 659 } 660 case TGeneralizedTime: 661 space(level); 662 fprintf (headerfile, "time_t %s;\n", name); 663 break; 664 case TGeneralString: 665 space(level); 666 fprintf (headerfile, "heim_general_string %s;\n", name); 667 break; 668 case TTag: 669 define_type (level, name, t->subtype, typedefp, preservep); 670 break; 671 case TChoice: { 672 int first = 1; 673 Member *m; 674 675 space(level); 676 fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); 677 if (preservep) { 678 space(level + 1); 679 fprintf(headerfile, "heim_octet_string _save;\n"); 680 } 681 space(level + 1); 682 fprintf (headerfile, "enum {\n"); 683 m = have_ellipsis(t); 684 if (m) { 685 space(level + 2); 686 fprintf (headerfile, "%s = 0,\n", m->label); 687 first = 0; 688 } 689 ASN1_TAILQ_FOREACH(m, t->members, members) { 690 space(level + 2); 691 if (m->ellipsis) 692 fprintf (headerfile, "/* ... */\n"); 693 else 694 fprintf (headerfile, "%s%s%s\n", m->label, 695 first ? " = 1" : "", 696 last_member_p(m)); 697 first = 0; 698 } 699 space(level + 1); 700 fprintf (headerfile, "} element;\n"); 701 space(level + 1); 702 fprintf (headerfile, "union {\n"); 703 ASN1_TAILQ_FOREACH(m, t->members, members) { 704 if (m->ellipsis) { 705 space(level + 2); 706 fprintf(headerfile, "heim_octet_string asn1_ellipsis;\n"); 707 } else if (m->optional) { 708 char *n; 709 710 asprintf (&n, "*%s", m->gen_name); 711 if (n == NULL) 712 errx(1, "malloc"); 713 define_type (level + 2, n, m->type, FALSE, FALSE); 714 free (n); 715 } else 716 define_type (level + 2, m->gen_name, m->type, FALSE, FALSE); 717 } 718 space(level + 1); 719 fprintf (headerfile, "} u;\n"); 720 space(level); 721 fprintf (headerfile, "} %s;\n", name); 722 break; 723 } 724 case TUTCTime: 725 space(level); 726 fprintf (headerfile, "time_t %s;\n", name); 727 break; 728 case TUTF8String: 729 space(level); 730 fprintf (headerfile, "heim_utf8_string %s;\n", name); 731 break; 732 case TPrintableString: 733 space(level); 734 fprintf (headerfile, "heim_printable_string %s;\n", name); 735 break; 736 case TIA5String: 737 space(level); 738 fprintf (headerfile, "heim_ia5_string %s;\n", name); 739 break; 740 case TBMPString: 741 space(level); 742 fprintf (headerfile, "heim_bmp_string %s;\n", name); 743 break; 744 case TUniversalString: 745 space(level); 746 fprintf (headerfile, "heim_universal_string %s;\n", name); 747 break; 748 case TVisibleString: 749 space(level); 750 fprintf (headerfile, "heim_visible_string %s;\n", name); 751 break; 752 case TOID : 753 space(level); 754 fprintf (headerfile, "heim_oid %s;\n", name); 755 break; 756 case TNull: 757 space(level); 758 fprintf (headerfile, "int %s;\n", name); 759 break; 760 default: 761 abort (); 762 } 763 } 764 765 static void 766 generate_type_header (const Symbol *s) 767 { 768 int preservep = preserve_type(s->name) ? TRUE : FALSE; 769 770 fprintf (headerfile, "/*\n"); 771 fprintf (headerfile, "%s ::= ", s->name); 772 define_asn1 (0, s->type); 773 fprintf (headerfile, "\n*/\n\n"); 774 775 fprintf (headerfile, "typedef "); 776 define_type (0, s->gen_name, s->type, TRUE, preservep); 777 778 fprintf (headerfile, "\n"); 779 } 780 781 782 void 783 generate_type (const Symbol *s) 784 { 785 generate_header_of_codefile(s->gen_name); 786 787 generate_type_header (s); 788 generate_type_encode (s); 789 generate_type_decode (s); 790 generate_type_free (s); 791 generate_type_length (s); 792 generate_type_copy (s); 793 generate_type_seq (s); 794 generate_glue (s->type, s->gen_name); 795 fprintf(headerfile, "\n\n"); 796 close_codefile(); 797 } 798