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