155682Smarkm/* 2178825Sdfr * Copyright (c) 1997 - 2005 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "gen_locl.h" 3555682Smarkm 36178825SdfrRCSID("$Id: gen.c 22429 2008-01-13 10:25:50Z lha $"); 3755682Smarkm 3855682SmarkmFILE *headerfile, *codefile, *logfile; 3955682Smarkm 4055682Smarkm#define STEM "asn1" 4155682Smarkm 4272445Sassarstatic const char *orig_filename; 43120945Snectarstatic char *header; 44178825Sdfrstatic const char *headerbase = STEM; 4555682Smarkm 4690926Snectar/* 4790926Snectar * list of all IMPORTs 4890926Snectar */ 4990926Snectar 5090926Snectarstruct import { 5190926Snectar const char *module; 5290926Snectar struct import *next; 5390926Snectar}; 5490926Snectar 5590926Snectarstatic struct import *imports = NULL; 5690926Snectar 5790926Snectarvoid 5890926Snectaradd_import (const char *module) 5990926Snectar{ 6090926Snectar struct import *tmp = emalloc (sizeof(*tmp)); 6190926Snectar 6290926Snectar tmp->module = module; 6390926Snectar tmp->next = imports; 6490926Snectar imports = tmp; 65178825Sdfr 66178825Sdfr fprintf (headerfile, "#include <%s_asn1.h>\n", module); 6790926Snectar} 6890926Snectar 6972445Sassarconst char * 70178825Sdfrget_filename (void) 7172445Sassar{ 7272445Sassar return orig_filename; 7372445Sassar} 7472445Sassar 7555682Smarkmvoid 7672445Sassarinit_generate (const char *filename, const char *base) 7755682Smarkm{ 78178825Sdfr char *fn; 79178825Sdfr 8055682Smarkm orig_filename = filename; 81178825Sdfr if (base != NULL) { 82178825Sdfr headerbase = strdup(base); 83178825Sdfr if (headerbase == NULL) 84178825Sdfr errx(1, "strdup"); 85178825Sdfr } 86120945Snectar asprintf(&header, "%s.h", headerbase); 87178825Sdfr if (header == NULL) 88178825Sdfr errx(1, "malloc"); 8955682Smarkm headerfile = fopen (header, "w"); 9055682Smarkm if (headerfile == NULL) 9155682Smarkm err (1, "open %s", header); 9255682Smarkm fprintf (headerfile, 9355682Smarkm "/* Generated from %s */\n" 9455682Smarkm "/* Do not edit */\n\n", 9555682Smarkm filename); 9655682Smarkm fprintf (headerfile, 9755682Smarkm "#ifndef __%s_h__\n" 9855682Smarkm "#define __%s_h__\n\n", headerbase, headerbase); 9955682Smarkm fprintf (headerfile, 10055682Smarkm "#include <stddef.h>\n" 10155682Smarkm "#include <time.h>\n\n"); 10255682Smarkm fprintf (headerfile, 10355682Smarkm "#ifndef __asn1_common_definitions__\n" 10455682Smarkm "#define __asn1_common_definitions__\n\n"); 10555682Smarkm fprintf (headerfile, 106178825Sdfr "typedef struct heim_integer {\n" 10755682Smarkm " size_t length;\n" 10855682Smarkm " void *data;\n" 109178825Sdfr " int negative;\n" 110178825Sdfr "} heim_integer;\n\n"); 11155682Smarkm fprintf (headerfile, 112178825Sdfr "typedef struct heim_octet_string {\n" 113178825Sdfr " size_t length;\n" 114178825Sdfr " void *data;\n" 115178825Sdfr "} heim_octet_string;\n\n"); 116178825Sdfr fprintf (headerfile, 117178825Sdfr "typedef char *heim_general_string;\n\n" 11855682Smarkm ); 11990926Snectar fprintf (headerfile, 120178825Sdfr "typedef char *heim_utf8_string;\n\n" 121178825Sdfr ); 122178825Sdfr fprintf (headerfile, 123178825Sdfr "typedef char *heim_printable_string;\n\n" 124178825Sdfr ); 125178825Sdfr fprintf (headerfile, 126178825Sdfr "typedef char *heim_ia5_string;\n\n" 127178825Sdfr ); 128178825Sdfr fprintf (headerfile, 129178825Sdfr "typedef struct heim_bmp_string {\n" 13090926Snectar " size_t length;\n" 131178825Sdfr " uint16_t *data;\n" 132178825Sdfr "} heim_bmp_string;\n\n"); 133178825Sdfr fprintf (headerfile, 134178825Sdfr "typedef struct heim_universal_string {\n" 135178825Sdfr " size_t length;\n" 136178825Sdfr " uint32_t *data;\n" 137178825Sdfr "} heim_universal_string;\n\n"); 138178825Sdfr fprintf (headerfile, 139178825Sdfr "typedef char *heim_visible_string;\n\n" 140178825Sdfr ); 141178825Sdfr fprintf (headerfile, 142178825Sdfr "typedef struct heim_oid {\n" 143178825Sdfr " size_t length;\n" 14490926Snectar " unsigned *components;\n" 145178825Sdfr "} heim_oid;\n\n"); 146178825Sdfr fprintf (headerfile, 147178825Sdfr "typedef struct heim_bit_string {\n" 148178825Sdfr " size_t length;\n" 149178825Sdfr " void *data;\n" 150178825Sdfr "} heim_bit_string;\n\n"); 151178825Sdfr fprintf (headerfile, 152178825Sdfr "typedef struct heim_octet_string heim_any;\n" 153178825Sdfr "typedef struct heim_octet_string heim_any_set;\n\n"); 154103423Snectar fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R) \\\n" 155103423Snectar " do { \\\n" 156103423Snectar " (BL) = length_##T((S)); \\\n" 157103423Snectar " (B) = malloc((BL)); \\\n" 158103423Snectar " if((B) == NULL) { \\\n" 159103423Snectar " (R) = ENOMEM; \\\n" 160103423Snectar " } else { \\\n" 161103423Snectar " (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \\\n" 162103423Snectar " (S), (L)); \\\n" 163103423Snectar " if((R) != 0) { \\\n" 164103423Snectar " free((B)); \\\n" 165103423Snectar " (B) = NULL; \\\n" 166103423Snectar " } \\\n" 167103423Snectar " } \\\n" 168103423Snectar " } while (0)\n\n", 169103423Snectar headerfile); 170178825Sdfr fprintf (headerfile, "struct units;\n\n"); 17155682Smarkm fprintf (headerfile, "#endif\n\n"); 172178825Sdfr asprintf(&fn, "%s_files", base); 173178825Sdfr if (fn == NULL) 174178825Sdfr errx(1, "malloc"); 175178825Sdfr logfile = fopen(fn, "w"); 17655682Smarkm if (logfile == NULL) 177178825Sdfr err (1, "open %s", fn); 17855682Smarkm} 17955682Smarkm 18055682Smarkmvoid 18172445Sassarclose_generate (void) 18255682Smarkm{ 18355682Smarkm fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase); 18455682Smarkm 18555682Smarkm fclose (headerfile); 18655682Smarkm fprintf (logfile, "\n"); 18755682Smarkm fclose (logfile); 18855682Smarkm} 18955682Smarkm 19055682Smarkmvoid 191178825Sdfrgen_assign_defval(const char *var, struct value *val) 192178825Sdfr{ 193178825Sdfr switch(val->type) { 194178825Sdfr case stringvalue: 195178825Sdfr fprintf(codefile, "if((%s = strdup(\"%s\")) == NULL)\nreturn ENOMEM;\n", var, val->u.stringvalue); 196178825Sdfr break; 197178825Sdfr case integervalue: 198178825Sdfr fprintf(codefile, "%s = %d;\n", var, val->u.integervalue); 199178825Sdfr break; 200178825Sdfr case booleanvalue: 201178825Sdfr if(val->u.booleanvalue) 202178825Sdfr fprintf(codefile, "%s = TRUE;\n", var); 203178825Sdfr else 204178825Sdfr fprintf(codefile, "%s = FALSE;\n", var); 205178825Sdfr break; 206178825Sdfr default: 207178825Sdfr abort(); 208178825Sdfr } 209178825Sdfr} 210178825Sdfr 211178825Sdfrvoid 212178825Sdfrgen_compare_defval(const char *var, struct value *val) 213178825Sdfr{ 214178825Sdfr switch(val->type) { 215178825Sdfr case stringvalue: 216178825Sdfr fprintf(codefile, "if(strcmp(%s, \"%s\") != 0)\n", var, val->u.stringvalue); 217178825Sdfr break; 218178825Sdfr case integervalue: 219178825Sdfr fprintf(codefile, "if(%s != %d)\n", var, val->u.integervalue); 220178825Sdfr break; 221178825Sdfr case booleanvalue: 222178825Sdfr if(val->u.booleanvalue) 223178825Sdfr fprintf(codefile, "if(!%s)\n", var); 224178825Sdfr else 225178825Sdfr fprintf(codefile, "if(%s)\n", var); 226178825Sdfr break; 227178825Sdfr default: 228178825Sdfr abort(); 229178825Sdfr } 230178825Sdfr} 231178825Sdfr 232178825Sdfrstatic void 233178825Sdfrgenerate_header_of_codefile(const char *name) 234178825Sdfr{ 235178825Sdfr char *filename; 236178825Sdfr 237178825Sdfr if (codefile != NULL) 238178825Sdfr abort(); 239178825Sdfr 240178825Sdfr asprintf (&filename, "%s_%s.x", STEM, name); 241178825Sdfr if (filename == NULL) 242178825Sdfr errx(1, "malloc"); 243178825Sdfr codefile = fopen (filename, "w"); 244178825Sdfr if (codefile == NULL) 245178825Sdfr err (1, "fopen %s", filename); 246178825Sdfr fprintf(logfile, "%s ", filename); 247178825Sdfr free(filename); 248178825Sdfr fprintf (codefile, 249178825Sdfr "/* Generated from %s */\n" 250178825Sdfr "/* Do not edit */\n\n" 251178825Sdfr "#include <stdio.h>\n" 252178825Sdfr "#include <stdlib.h>\n" 253178825Sdfr "#include <time.h>\n" 254178825Sdfr "#include <string.h>\n" 255178825Sdfr "#include <errno.h>\n" 256178825Sdfr "#include <limits.h>\n" 257178825Sdfr "#include <krb5-types.h>\n", 258178825Sdfr orig_filename); 259178825Sdfr 260178825Sdfr fprintf (codefile, 261178825Sdfr "#include <%s.h>\n", 262178825Sdfr headerbase); 263178825Sdfr fprintf (codefile, 264178825Sdfr "#include <asn1_err.h>\n" 265178825Sdfr "#include <der.h>\n" 266178825Sdfr "#include <parse_units.h>\n\n"); 267178825Sdfr 268178825Sdfr} 269178825Sdfr 270178825Sdfrstatic void 271178825Sdfrclose_codefile(void) 272178825Sdfr{ 273178825Sdfr if (codefile == NULL) 274178825Sdfr abort(); 275178825Sdfr 276178825Sdfr fclose(codefile); 277178825Sdfr codefile = NULL; 278178825Sdfr} 279178825Sdfr 280178825Sdfr 281178825Sdfrvoid 28255682Smarkmgenerate_constant (const Symbol *s) 28355682Smarkm{ 284178825Sdfr switch(s->value->type) { 285178825Sdfr case booleanvalue: 286178825Sdfr break; 287178825Sdfr case integervalue: 288178825Sdfr fprintf (headerfile, "enum { %s = %d };\n\n", 289178825Sdfr s->gen_name, s->value->u.integervalue); 290178825Sdfr break; 291178825Sdfr case nullvalue: 292178825Sdfr break; 293178825Sdfr case stringvalue: 294178825Sdfr break; 295178825Sdfr case objectidentifiervalue: { 296178825Sdfr struct objid *o, **list; 297178825Sdfr int i, len; 298178825Sdfr 299178825Sdfr generate_header_of_codefile(s->gen_name); 300178825Sdfr 301178825Sdfr len = 0; 302178825Sdfr for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next) 303178825Sdfr len++; 304178825Sdfr list = emalloc(sizeof(*list) * len); 305178825Sdfr 306178825Sdfr i = 0; 307178825Sdfr for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next) 308178825Sdfr list[i++] = o; 309178825Sdfr 310178825Sdfr fprintf (headerfile, "/* OBJECT IDENTIFIER %s ::= { ", s->name); 311178825Sdfr for (i = len - 1 ; i >= 0; i--) { 312178825Sdfr o = list[i]; 313178825Sdfr fprintf(headerfile, "%s(%d) ", 314178825Sdfr o->label ? o->label : "label-less", o->value); 315178825Sdfr } 316178825Sdfr 317178825Sdfr fprintf (headerfile, "} */\n"); 318178825Sdfr fprintf (headerfile, "const heim_oid *oid_%s(void);\n\n", 319178825Sdfr s->gen_name); 320178825Sdfr 321178825Sdfr fprintf (codefile, "static unsigned oid_%s_variable_num[%d] = {", 322178825Sdfr s->gen_name, len); 323178825Sdfr for (i = len - 1 ; i >= 0; i--) { 324178825Sdfr fprintf(codefile, "%d%s ", list[i]->value, i > 0 ? "," : ""); 325178825Sdfr } 326178825Sdfr fprintf(codefile, "};\n"); 327178825Sdfr 328178825Sdfr fprintf (codefile, "static const heim_oid oid_%s_variable = " 329178825Sdfr "{ %d, oid_%s_variable_num };\n\n", 330178825Sdfr s->gen_name, len, s->gen_name); 331178825Sdfr 332178825Sdfr fprintf (codefile, "const heim_oid *oid_%s(void)\n" 333178825Sdfr "{\n" 334178825Sdfr "return &oid_%s_variable;\n" 335178825Sdfr "}\n\n", 336178825Sdfr s->gen_name, s->gen_name); 337178825Sdfr 338178825Sdfr close_codefile(); 339178825Sdfr 340178825Sdfr break; 341178825Sdfr } 342178825Sdfr default: 343178825Sdfr abort(); 344178825Sdfr } 34555682Smarkm} 34655682Smarkm 34755682Smarkmstatic void 34855682Smarkmspace(int level) 34955682Smarkm{ 35055682Smarkm while(level-- > 0) 35155682Smarkm fprintf(headerfile, " "); 35255682Smarkm} 35355682Smarkm 354178825Sdfrstatic const char * 355178825Sdfrlast_member_p(struct member *m) 356178825Sdfr{ 357178825Sdfr struct member *n = ASN1_TAILQ_NEXT(m, members); 358178825Sdfr if (n == NULL) 359178825Sdfr return ""; 360178825Sdfr if (n->ellipsis && ASN1_TAILQ_NEXT(n, members) == NULL) 361178825Sdfr return ""; 362178825Sdfr return ","; 363178825Sdfr} 364178825Sdfr 365178825Sdfrstatic struct member * 366178825Sdfrhave_ellipsis(Type *t) 367178825Sdfr{ 368178825Sdfr struct member *m; 369178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 370178825Sdfr if (m->ellipsis) 371178825Sdfr return m; 372178825Sdfr } 373178825Sdfr return NULL; 374178825Sdfr} 375178825Sdfr 37655682Smarkmstatic void 37755682Smarkmdefine_asn1 (int level, Type *t) 37855682Smarkm{ 37955682Smarkm switch (t->type) { 38055682Smarkm case TType: 38155682Smarkm fprintf (headerfile, "%s", t->symbol->name); 38255682Smarkm break; 38355682Smarkm case TInteger: 384178825Sdfr if(t->members == NULL) { 385178825Sdfr fprintf (headerfile, "INTEGER"); 386178825Sdfr if (t->range) 387178825Sdfr fprintf (headerfile, " (%d..%d)", 388178825Sdfr t->range->min, t->range->max); 389178825Sdfr } else { 390178825Sdfr Member *m; 391178825Sdfr fprintf (headerfile, "INTEGER {\n"); 392178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 393178825Sdfr space (level + 1); 394178825Sdfr fprintf(headerfile, "%s(%d)%s\n", m->gen_name, m->val, 395178825Sdfr last_member_p(m)); 396178825Sdfr } 397178825Sdfr space(level); 398178825Sdfr fprintf (headerfile, "}"); 399178825Sdfr } 40055682Smarkm break; 401178825Sdfr case TBoolean: 402178825Sdfr fprintf (headerfile, "BOOLEAN"); 40372445Sassar break; 40455682Smarkm case TOctetString: 40555682Smarkm fprintf (headerfile, "OCTET STRING"); 40655682Smarkm break; 407178825Sdfr case TEnumerated : 40855682Smarkm case TBitString: { 40955682Smarkm Member *m; 41055682Smarkm 41155682Smarkm space(level); 412178825Sdfr if(t->type == TBitString) 413178825Sdfr fprintf (headerfile, "BIT STRING {\n"); 414178825Sdfr else 415178825Sdfr fprintf (headerfile, "ENUMERATED {\n"); 416178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 41755682Smarkm space(level + 1); 41855682Smarkm fprintf (headerfile, "%s(%d)%s\n", m->name, m->val, 419178825Sdfr last_member_p(m)); 42055682Smarkm } 42155682Smarkm space(level); 42255682Smarkm fprintf (headerfile, "}"); 42355682Smarkm break; 42455682Smarkm } 425178825Sdfr case TChoice: 426178825Sdfr case TSet: 42755682Smarkm case TSequence: { 42855682Smarkm Member *m; 42955682Smarkm int max_width = 0; 43055682Smarkm 431178825Sdfr if(t->type == TChoice) 432178825Sdfr fprintf(headerfile, "CHOICE {\n"); 433178825Sdfr else if(t->type == TSet) 434178825Sdfr fprintf(headerfile, "SET {\n"); 435178825Sdfr else 436178825Sdfr fprintf(headerfile, "SEQUENCE {\n"); 437178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 438178825Sdfr if(strlen(m->name) > max_width) 439178825Sdfr max_width = strlen(m->name); 44055682Smarkm } 441178825Sdfr max_width += 3; 44255682Smarkm if(max_width < 16) max_width = 16; 443178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 444178825Sdfr int width = max_width; 44555682Smarkm space(level + 1); 446178825Sdfr if (m->ellipsis) { 447178825Sdfr fprintf (headerfile, "..."); 448178825Sdfr } else { 449178825Sdfr width -= fprintf(headerfile, "%s", m->name); 450178825Sdfr fprintf(headerfile, "%*s", width, ""); 451178825Sdfr define_asn1(level + 1, m->type); 452178825Sdfr if(m->optional) 453178825Sdfr fprintf(headerfile, " OPTIONAL"); 454178825Sdfr } 455178825Sdfr if(last_member_p(m)) 45655682Smarkm fprintf (headerfile, ","); 45755682Smarkm fprintf (headerfile, "\n"); 45855682Smarkm } 45955682Smarkm space(level); 46055682Smarkm fprintf (headerfile, "}"); 46155682Smarkm break; 46255682Smarkm } 463178825Sdfr case TSequenceOf: 46455682Smarkm fprintf (headerfile, "SEQUENCE OF "); 46555682Smarkm define_asn1 (0, t->subtype); 46655682Smarkm break; 467178825Sdfr case TSetOf: 468178825Sdfr fprintf (headerfile, "SET OF "); 469178825Sdfr define_asn1 (0, t->subtype); 470178825Sdfr break; 47155682Smarkm case TGeneralizedTime: 47255682Smarkm fprintf (headerfile, "GeneralizedTime"); 47355682Smarkm break; 47455682Smarkm case TGeneralString: 47555682Smarkm fprintf (headerfile, "GeneralString"); 47655682Smarkm break; 477178825Sdfr case TTag: { 478178825Sdfr const char *classnames[] = { "UNIVERSAL ", "APPLICATION ", 479178825Sdfr "" /* CONTEXT */, "PRIVATE " }; 480178825Sdfr if(t->tag.tagclass != ASN1_C_UNIV) 481178825Sdfr fprintf (headerfile, "[%s%d] ", 482178825Sdfr classnames[t->tag.tagclass], 483178825Sdfr t->tag.tagvalue); 484178825Sdfr if(t->tag.tagenv == TE_IMPLICIT) 485178825Sdfr fprintf (headerfile, "IMPLICIT "); 48655682Smarkm define_asn1 (level, t->subtype); 48755682Smarkm break; 488178825Sdfr } 489178825Sdfr case TUTCTime: 490178825Sdfr fprintf (headerfile, "UTCTime"); 491178825Sdfr break; 492178825Sdfr case TUTF8String: 493178825Sdfr space(level); 494178825Sdfr fprintf (headerfile, "UTF8String"); 495178825Sdfr break; 496178825Sdfr case TPrintableString: 497178825Sdfr space(level); 498178825Sdfr fprintf (headerfile, "PrintableString"); 499178825Sdfr break; 500178825Sdfr case TIA5String: 501178825Sdfr space(level); 502178825Sdfr fprintf (headerfile, "IA5String"); 503178825Sdfr break; 504178825Sdfr case TBMPString: 505178825Sdfr space(level); 506178825Sdfr fprintf (headerfile, "BMPString"); 507178825Sdfr break; 508178825Sdfr case TUniversalString: 509178825Sdfr space(level); 510178825Sdfr fprintf (headerfile, "UniversalString"); 511178825Sdfr break; 512178825Sdfr case TVisibleString: 513178825Sdfr space(level); 514178825Sdfr fprintf (headerfile, "VisibleString"); 515178825Sdfr break; 516178825Sdfr case TOID : 517178825Sdfr space(level); 518178825Sdfr fprintf(headerfile, "OBJECT IDENTIFIER"); 519178825Sdfr break; 520178825Sdfr case TNull: 521178825Sdfr space(level); 522178825Sdfr fprintf (headerfile, "NULL"); 523178825Sdfr break; 52455682Smarkm default: 52555682Smarkm abort (); 52655682Smarkm } 52755682Smarkm} 52855682Smarkm 52955682Smarkmstatic void 530178825Sdfrdefine_type (int level, const char *name, Type *t, int typedefp, int preservep) 53155682Smarkm{ 53255682Smarkm switch (t->type) { 53355682Smarkm case TType: 53455682Smarkm space(level); 53555682Smarkm fprintf (headerfile, "%s %s;\n", t->symbol->gen_name, name); 53655682Smarkm break; 53755682Smarkm case TInteger: 53855682Smarkm space(level); 539178825Sdfr if(t->members) { 54072445Sassar Member *m; 54172445Sassar fprintf (headerfile, "enum %s {\n", typedefp ? name : ""); 542178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 54372445Sassar space (level + 1); 54472445Sassar fprintf(headerfile, "%s = %d%s\n", m->gen_name, m->val, 545178825Sdfr last_member_p(m)); 54672445Sassar } 54772445Sassar fprintf (headerfile, "} %s;\n", name); 548178825Sdfr } else if (t->range == NULL) { 549178825Sdfr fprintf (headerfile, "heim_integer %s;\n", name); 550178825Sdfr } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) { 551178825Sdfr fprintf (headerfile, "int %s;\n", name); 552178825Sdfr } else if (t->range->min == 0 && t->range->max == UINT_MAX) { 553178825Sdfr fprintf (headerfile, "unsigned int %s;\n", name); 554178825Sdfr } else if (t->range->min == 0 && t->range->max == INT_MAX) { 555178825Sdfr fprintf (headerfile, "unsigned int %s;\n", name); 556178825Sdfr } else 557178825Sdfr errx(1, "%s: unsupported range %d -> %d", 558178825Sdfr name, t->range->min, t->range->max); 55955682Smarkm break; 560178825Sdfr case TBoolean: 56155682Smarkm space(level); 562178825Sdfr fprintf (headerfile, "int %s;\n", name); 56355682Smarkm break; 56455682Smarkm case TOctetString: 56555682Smarkm space(level); 566178825Sdfr fprintf (headerfile, "heim_octet_string %s;\n", name); 56755682Smarkm break; 56855682Smarkm case TBitString: { 56955682Smarkm Member *m; 57055682Smarkm Type i; 571178825Sdfr struct range range = { 0, INT_MAX }; 57255682Smarkm 573178825Sdfr i.type = TInteger; 574178825Sdfr i.range = ⦥ 575178825Sdfr i.members = NULL; 576178825Sdfr i.constraint = NULL; 577178825Sdfr 57855682Smarkm space(level); 579178825Sdfr if(ASN1_TAILQ_EMPTY(t->members)) 580178825Sdfr fprintf (headerfile, "heim_bit_string %s;\n", name); 581178825Sdfr else { 582178825Sdfr fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); 583178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 584178825Sdfr char *n; 585178825Sdfr 586178825Sdfr asprintf (&n, "%s:1", m->gen_name); 587178825Sdfr if (n == NULL) 588178825Sdfr errx(1, "malloc"); 589178825Sdfr define_type (level + 1, n, &i, FALSE, FALSE); 590178825Sdfr free (n); 591178825Sdfr } 592178825Sdfr space(level); 593178825Sdfr fprintf (headerfile, "} %s;\n\n", name); 59455682Smarkm } 59555682Smarkm break; 59655682Smarkm } 59790926Snectar case TEnumerated: { 59890926Snectar Member *m; 59990926Snectar 60090926Snectar space(level); 60190926Snectar fprintf (headerfile, "enum %s {\n", typedefp ? name : ""); 602178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 60390926Snectar space(level + 1); 604178825Sdfr if (m->ellipsis) 605178825Sdfr fprintf (headerfile, "/* ... */\n"); 606178825Sdfr else 607178825Sdfr fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val, 608178825Sdfr last_member_p(m)); 60990926Snectar } 61090926Snectar space(level); 61190926Snectar fprintf (headerfile, "} %s;\n\n", name); 61290926Snectar break; 61390926Snectar } 614178825Sdfr case TSet: 61555682Smarkm case TSequence: { 61655682Smarkm Member *m; 61755682Smarkm 61855682Smarkm space(level); 61955682Smarkm fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); 620178825Sdfr if (t->type == TSequence && preservep) { 621178825Sdfr space(level + 1); 622178825Sdfr fprintf(headerfile, "heim_octet_string _save;\n"); 623178825Sdfr } 624178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 625178825Sdfr if (m->ellipsis) { 626178825Sdfr ; 627178825Sdfr } else if (m->optional) { 62855682Smarkm char *n; 62955682Smarkm 63055682Smarkm asprintf (&n, "*%s", m->gen_name); 631178825Sdfr if (n == NULL) 632178825Sdfr errx(1, "malloc"); 633178825Sdfr define_type (level + 1, n, m->type, FALSE, FALSE); 63455682Smarkm free (n); 63555682Smarkm } else 636178825Sdfr define_type (level + 1, m->gen_name, m->type, FALSE, FALSE); 63755682Smarkm } 63855682Smarkm space(level); 63955682Smarkm fprintf (headerfile, "} %s;\n", name); 64055682Smarkm break; 64155682Smarkm } 642178825Sdfr case TSetOf: 64355682Smarkm case TSequenceOf: { 64455682Smarkm Type i; 645178825Sdfr struct range range = { 0, INT_MAX }; 64655682Smarkm 647178825Sdfr i.type = TInteger; 648178825Sdfr i.range = ⦥ 649178825Sdfr i.members = NULL; 650178825Sdfr i.constraint = NULL; 65155682Smarkm 65255682Smarkm space(level); 65355682Smarkm fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); 654178825Sdfr define_type (level + 1, "len", &i, FALSE, FALSE); 655178825Sdfr define_type (level + 1, "*val", t->subtype, FALSE, FALSE); 65655682Smarkm space(level); 65755682Smarkm fprintf (headerfile, "} %s;\n", name); 65855682Smarkm break; 65955682Smarkm } 66055682Smarkm case TGeneralizedTime: 66155682Smarkm space(level); 66255682Smarkm fprintf (headerfile, "time_t %s;\n", name); 66355682Smarkm break; 66455682Smarkm case TGeneralString: 66555682Smarkm space(level); 666178825Sdfr fprintf (headerfile, "heim_general_string %s;\n", name); 66755682Smarkm break; 668178825Sdfr case TTag: 669178825Sdfr define_type (level, name, t->subtype, typedefp, preservep); 67055682Smarkm break; 671178825Sdfr case TChoice: { 672178825Sdfr int first = 1; 673178825Sdfr Member *m; 674178825Sdfr 675178825Sdfr space(level); 676178825Sdfr fprintf (headerfile, "struct %s {\n", typedefp ? name : ""); 677178825Sdfr if (preservep) { 678178825Sdfr space(level + 1); 679178825Sdfr fprintf(headerfile, "heim_octet_string _save;\n"); 680178825Sdfr } 681178825Sdfr space(level + 1); 682178825Sdfr fprintf (headerfile, "enum {\n"); 683178825Sdfr m = have_ellipsis(t); 684178825Sdfr if (m) { 685178825Sdfr space(level + 2); 686178825Sdfr fprintf (headerfile, "%s = 0,\n", m->label); 687178825Sdfr first = 0; 688178825Sdfr } 689178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 690178825Sdfr space(level + 2); 691178825Sdfr if (m->ellipsis) 692178825Sdfr fprintf (headerfile, "/* ... */\n"); 693178825Sdfr else 694178825Sdfr fprintf (headerfile, "%s%s%s\n", m->label, 695178825Sdfr first ? " = 1" : "", 696178825Sdfr last_member_p(m)); 697178825Sdfr first = 0; 698178825Sdfr } 699178825Sdfr space(level + 1); 700178825Sdfr fprintf (headerfile, "} element;\n"); 701178825Sdfr space(level + 1); 702178825Sdfr fprintf (headerfile, "union {\n"); 703178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 704178825Sdfr if (m->ellipsis) { 705178825Sdfr space(level + 2); 706178825Sdfr fprintf(headerfile, "heim_octet_string asn1_ellipsis;\n"); 707178825Sdfr } else if (m->optional) { 708178825Sdfr char *n; 709178825Sdfr 710178825Sdfr asprintf (&n, "*%s", m->gen_name); 711178825Sdfr if (n == NULL) 712178825Sdfr errx(1, "malloc"); 713178825Sdfr define_type (level + 2, n, m->type, FALSE, FALSE); 714178825Sdfr free (n); 715178825Sdfr } else 716178825Sdfr define_type (level + 2, m->gen_name, m->type, FALSE, FALSE); 717178825Sdfr } 718178825Sdfr space(level + 1); 719178825Sdfr fprintf (headerfile, "} u;\n"); 720178825Sdfr space(level); 721178825Sdfr fprintf (headerfile, "} %s;\n", name); 722178825Sdfr break; 723178825Sdfr } 724178825Sdfr case TUTCTime: 725178825Sdfr space(level); 726178825Sdfr fprintf (headerfile, "time_t %s;\n", name); 727178825Sdfr break; 728178825Sdfr case TUTF8String: 729178825Sdfr space(level); 730178825Sdfr fprintf (headerfile, "heim_utf8_string %s;\n", name); 731178825Sdfr break; 732178825Sdfr case TPrintableString: 733178825Sdfr space(level); 734178825Sdfr fprintf (headerfile, "heim_printable_string %s;\n", name); 735178825Sdfr break; 736178825Sdfr case TIA5String: 737178825Sdfr space(level); 738178825Sdfr fprintf (headerfile, "heim_ia5_string %s;\n", name); 739178825Sdfr break; 740178825Sdfr case TBMPString: 741178825Sdfr space(level); 742178825Sdfr fprintf (headerfile, "heim_bmp_string %s;\n", name); 743178825Sdfr break; 744178825Sdfr case TUniversalString: 745178825Sdfr space(level); 746178825Sdfr fprintf (headerfile, "heim_universal_string %s;\n", name); 747178825Sdfr break; 748178825Sdfr case TVisibleString: 749178825Sdfr space(level); 750178825Sdfr fprintf (headerfile, "heim_visible_string %s;\n", name); 751178825Sdfr break; 752178825Sdfr case TOID : 753178825Sdfr space(level); 754178825Sdfr fprintf (headerfile, "heim_oid %s;\n", name); 755178825Sdfr break; 756178825Sdfr case TNull: 757178825Sdfr space(level); 758178825Sdfr fprintf (headerfile, "int %s;\n", name); 759178825Sdfr break; 76055682Smarkm default: 76155682Smarkm abort (); 76255682Smarkm } 76355682Smarkm} 76455682Smarkm 76555682Smarkmstatic void 76655682Smarkmgenerate_type_header (const Symbol *s) 76755682Smarkm{ 768178825Sdfr int preservep = preserve_type(s->name) ? TRUE : FALSE; 769178825Sdfr 77055682Smarkm fprintf (headerfile, "/*\n"); 77155682Smarkm fprintf (headerfile, "%s ::= ", s->name); 77255682Smarkm define_asn1 (0, s->type); 77355682Smarkm fprintf (headerfile, "\n*/\n\n"); 77455682Smarkm 77555682Smarkm fprintf (headerfile, "typedef "); 776178825Sdfr define_type (0, s->gen_name, s->type, TRUE, preservep); 77755682Smarkm 77855682Smarkm fprintf (headerfile, "\n"); 77955682Smarkm} 78055682Smarkm 78155682Smarkm 78255682Smarkmvoid 78355682Smarkmgenerate_type (const Symbol *s) 78455682Smarkm{ 785178825Sdfr generate_header_of_codefile(s->gen_name); 78655682Smarkm 78755682Smarkm generate_type_header (s); 78855682Smarkm generate_type_encode (s); 78955682Smarkm generate_type_decode (s); 79055682Smarkm generate_type_free (s); 79155682Smarkm generate_type_length (s); 79255682Smarkm generate_type_copy (s); 793178825Sdfr generate_type_seq (s); 794178825Sdfr generate_glue (s->type, s->gen_name); 79555682Smarkm fprintf(headerfile, "\n\n"); 796178825Sdfr close_codefile(); 79755682Smarkm} 798