LCOV - code coverage report
Current view: top level - lib/asn1 - gen.c (source / functions) Hit Total Coverage
Test: samba_4_0_test.lcov.info Lines: 462 547 84.5 %
Date: 2014-04-02 Functions: 17 20 85.0 %
Branches: 207 293 70.6 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
       3                 :            :  * (Royal Institute of Technology, Stockholm, Sweden).
       4                 :            :  * All rights reserved.
       5                 :            :  *
       6                 :            :  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
       7                 :            :  *
       8                 :            :  * Redistribution and use in source and binary forms, with or without
       9                 :            :  * modification, are permitted provided that the following conditions
      10                 :            :  * are met:
      11                 :            :  *
      12                 :            :  * 1. Redistributions of source code must retain the above copyright
      13                 :            :  *    notice, this list of conditions and the following disclaimer.
      14                 :            :  *
      15                 :            :  * 2. Redistributions in binary form must reproduce the above copyright
      16                 :            :  *    notice, this list of conditions and the following disclaimer in the
      17                 :            :  *    documentation and/or other materials provided with the distribution.
      18                 :            :  *
      19                 :            :  * 3. Neither the name of the Institute nor the names of its contributors
      20                 :            :  *    may be used to endorse or promote products derived from this software
      21                 :            :  *    without specific prior written permission.
      22                 :            :  *
      23                 :            :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      24                 :            :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      25                 :            :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      26                 :            :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      27                 :            :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      28                 :            :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      29                 :            :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      30                 :            :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      31                 :            :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      32                 :            :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      33                 :            :  * SUCH DAMAGE.
      34                 :            :  */
      35                 :            : 
      36                 :            : #include "gen_locl.h"
      37                 :            : 
      38                 :            : RCSID("$Id$");
      39                 :            : 
      40                 :            : FILE *privheaderfile, *headerfile, *codefile, *logfile, *templatefile;
      41                 :            : 
      42                 :            : #define STEM "asn1"
      43                 :            : 
      44                 :            : static const char *orig_filename;
      45                 :            : static char *privheader, *header, *template;
      46                 :            : static const char *headerbase = STEM;
      47                 :            : 
      48                 :            : /*
      49                 :            :  * list of all IMPORTs
      50                 :            :  */
      51                 :            : 
      52                 :            : struct import {
      53                 :            :     const char *module;
      54                 :            :     struct import *next;
      55                 :            : };
      56                 :            : 
      57                 :            : static struct import *imports = NULL;
      58                 :            : 
      59                 :            : void
      60                 :         17 : add_import (const char *module)
      61                 :            : {
      62                 :         17 :     struct import *tmp = emalloc (sizeof(*tmp));
      63                 :            : 
      64                 :         17 :     tmp->module = module;
      65                 :         17 :     tmp->next   = imports;
      66                 :         17 :     imports     = tmp;
      67                 :            : 
      68                 :         17 :     fprintf (headerfile, "#include <%s_asn1.h>\n", module);
      69                 :         17 : }
      70                 :            : 
      71                 :            : /*
      72                 :            :  * List of all exported symbols
      73                 :            :  */
      74                 :            : 
      75                 :            : struct sexport {
      76                 :            :     const char *name;
      77                 :            :     int defined;
      78                 :            :     struct sexport *next;
      79                 :            : };
      80                 :            : 
      81                 :            : static struct sexport *exports = NULL;
      82                 :            : 
      83                 :            : void
      84                 :         70 : add_export (const char *name)
      85                 :            : {
      86                 :         70 :     struct sexport *tmp = emalloc (sizeof(*tmp));
      87                 :            : 
      88                 :         70 :     tmp->name   = name;
      89                 :         70 :     tmp->next   = exports;
      90                 :         70 :     exports     = tmp;
      91                 :         70 : }
      92                 :            : 
      93                 :            : int
      94                 :        296 : is_export(const char *name)
      95                 :            : {
      96                 :            :     struct sexport *tmp;
      97                 :            : 
      98         [ +  + ]:        296 :     if (exports == NULL) /* no export list, all exported */
      99                 :        203 :         return 1;
     100                 :            : 
     101         [ +  + ]:       4161 :     for (tmp = exports; tmp != NULL; tmp = tmp->next) {
     102         [ +  + ]:       4137 :         if (strcmp(tmp->name, name) == 0) {
     103                 :         69 :             tmp->defined = 1;
     104                 :         69 :             return 1;
     105                 :            :         }
     106                 :            :     }
     107                 :        296 :     return 0;
     108                 :            : }
     109                 :            : 
     110                 :            : const char *
     111                 :          0 : get_filename (void)
     112                 :            : {
     113                 :          0 :     return orig_filename;
     114                 :            : }
     115                 :            : 
     116                 :            : void
     117                 :         14 : init_generate (const char *filename, const char *base)
     118                 :            : {
     119                 :         14 :     char *fn = NULL;
     120                 :            : 
     121                 :         14 :     orig_filename = filename;
     122         [ +  - ]:         14 :     if (base != NULL) {
     123                 :         14 :         headerbase = strdup(base);
     124         [ -  + ]:         14 :         if (headerbase == NULL)
     125                 :          0 :             errx(1, "strdup");
     126                 :            :     }
     127                 :            : 
     128                 :            :     /* public header file */
     129 [ +  - ][ -  + ]:         14 :     if (asprintf(&header, "%s.h", headerbase) < 0 || header == NULL)
     130                 :          0 :         errx(1, "malloc");
     131 [ +  - ][ -  + ]:         14 :     if (asprintf(&fn, "%s.hx", headerbase) < 0 || fn == NULL)
     132                 :          0 :         errx(1, "malloc");
     133                 :         14 :     headerfile = fopen (fn, "w");
     134         [ -  + ]:         14 :     if (headerfile == NULL)
     135                 :          0 :         err (1, "open %s", fn);
     136                 :         14 :     free(fn);
     137                 :         14 :     fn = NULL;
     138                 :            : 
     139                 :            :     /* private header file */
     140 [ +  - ][ -  + ]:         14 :     if (asprintf(&privheader, "%s-priv.h", headerbase) < 0 || privheader == NULL)
     141                 :          0 :         errx(1, "malloc");
     142 [ +  - ][ -  + ]:         14 :     if (asprintf(&fn, "%s-priv.hx", headerbase) < 0 || fn == NULL)
     143                 :          0 :         errx(1, "malloc");
     144                 :         14 :     privheaderfile = fopen (fn, "w");
     145         [ -  + ]:         14 :     if (privheaderfile == NULL)
     146                 :          0 :         err (1, "open %s", fn);
     147                 :         14 :     free(fn);
     148                 :         14 :     fn = NULL;
     149                 :            : 
     150                 :            :     /* template file */
     151 [ +  - ][ -  + ]:         14 :     if (asprintf(&template, "%s-template.c", headerbase) < 0 || template == NULL)
     152                 :          0 :         errx(1, "malloc");
     153                 :         14 :     fprintf (headerfile,
     154                 :            :              "/* Generated from %s */\n"
     155                 :            :              "/* Do not edit */\n\n",
     156                 :            :              filename);
     157                 :         14 :     fprintf (headerfile,
     158                 :            :              "#ifndef __%s_h__\n"
     159                 :            :              "#define __%s_h__\n\n", headerbase, headerbase);
     160                 :         14 :     fprintf (headerfile,
     161                 :            :              "#include <stddef.h>\n"
     162                 :            :              "#include <time.h>\n\n");
     163                 :         14 :     fprintf (headerfile,
     164                 :            :              "#ifndef __asn1_common_definitions__\n"
     165                 :            :              "#define __asn1_common_definitions__\n\n");
     166                 :         14 :     fprintf (headerfile,
     167                 :            :              "typedef struct heim_integer {\n"
     168                 :            :              "  size_t length;\n"
     169                 :            :              "  void *data;\n"
     170                 :            :              "  int negative;\n"
     171                 :            :              "} heim_integer;\n\n");
     172                 :         14 :     fprintf (headerfile,
     173                 :            :              "typedef struct heim_octet_string {\n"
     174                 :            :              "  size_t length;\n"
     175                 :            :              "  void *data;\n"
     176                 :            :              "} heim_octet_string;\n\n");
     177                 :         14 :     fprintf (headerfile,
     178                 :            :              "typedef char *heim_general_string;\n\n"
     179                 :            :              );
     180                 :         14 :     fprintf (headerfile,
     181                 :            :              "typedef char *heim_utf8_string;\n\n"
     182                 :            :              );
     183                 :         14 :     fprintf (headerfile,
     184                 :            :              "typedef struct heim_octet_string heim_printable_string;\n\n"
     185                 :            :              );
     186                 :         14 :     fprintf (headerfile,
     187                 :            :              "typedef struct heim_octet_string heim_ia5_string;\n\n"
     188                 :            :              );
     189                 :         14 :     fprintf (headerfile,
     190                 :            :              "typedef struct heim_bmp_string {\n"
     191                 :            :              "  size_t length;\n"
     192                 :            :              "  uint16_t *data;\n"
     193                 :            :              "} heim_bmp_string;\n\n");
     194                 :         14 :     fprintf (headerfile,
     195                 :            :              "typedef struct heim_universal_string {\n"
     196                 :            :              "  size_t length;\n"
     197                 :            :              "  uint32_t *data;\n"
     198                 :            :              "} heim_universal_string;\n\n");
     199                 :         14 :     fprintf (headerfile,
     200                 :            :              "typedef char *heim_visible_string;\n\n"
     201                 :            :              );
     202                 :         14 :     fprintf (headerfile,
     203                 :            :              "typedef struct heim_oid {\n"
     204                 :            :              "  size_t length;\n"
     205                 :            :              "  unsigned *components;\n"
     206                 :            :              "} heim_oid;\n\n");
     207                 :         14 :     fprintf (headerfile,
     208                 :            :              "typedef struct heim_bit_string {\n"
     209                 :            :              "  size_t length;\n"
     210                 :            :              "  void *data;\n"
     211                 :            :              "} heim_bit_string;\n\n");
     212                 :         14 :     fprintf (headerfile,
     213                 :            :              "typedef struct heim_octet_string heim_any;\n"
     214                 :            :              "typedef struct heim_octet_string heim_any_set;\n\n");
     215                 :         14 :     fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R)                  \\\n"
     216                 :            :           "  do {                                                         \\\n"
     217                 :            :           "    (BL) = length_##T((S));                                    \\\n"
     218                 :            :           "    (B) = malloc((BL));                                        \\\n"
     219                 :            :           "    if((B) == NULL) {                                          \\\n"
     220                 :            :           "      (R) = ENOMEM;                                            \\\n"
     221                 :            :           "    } else {                                                   \\\n"
     222                 :            :           "      (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \\\n"
     223                 :            :           "                       (S), (L));                              \\\n"
     224                 :            :           "      if((R) != 0) {                                           \\\n"
     225                 :            :           "        free((B));                                             \\\n"
     226                 :            :           "        (B) = NULL;                                            \\\n"
     227                 :            :           "      }                                                        \\\n"
     228                 :            :           "    }                                                          \\\n"
     229                 :            :           "  } while (0)\n\n",
     230                 :            :           headerfile);
     231                 :         14 :     fputs("#ifdef _WIN32\n"
     232                 :            :           "#ifndef ASN1_LIB\n"
     233                 :            :           "#define ASN1EXP  __declspec(dllimport)\n"
     234                 :            :           "#else\n"
     235                 :            :           "#define ASN1EXP\n"
     236                 :            :           "#endif\n"
     237                 :            :           "#define ASN1CALL __stdcall\n"
     238                 :            :           "#else\n"
     239                 :            :           "#define ASN1EXP\n"
     240                 :            :           "#define ASN1CALL\n"
     241                 :            :           "#endif\n",
     242                 :            :           headerfile);
     243                 :         14 :     fprintf (headerfile, "struct units;\n\n");
     244                 :         14 :     fprintf (headerfile, "#endif\n\n");
     245 [ +  - ][ -  + ]:         14 :     if (asprintf(&fn, "%s_files", base) < 0 || fn == NULL)
     246                 :          0 :         errx(1, "malloc");
     247                 :         14 :     logfile = fopen(fn, "w");
     248         [ -  + ]:         14 :     if (logfile == NULL)
     249                 :          0 :         err (1, "open %s", fn);
     250                 :            : 
     251                 :            :     /* if one code file, write into the one codefile */
     252         [ +  - ]:         14 :     if (one_code_file)
     253                 :         14 :         return;
     254                 :            : 
     255                 :          0 :     templatefile = fopen (template, "w");
     256         [ #  # ]:          0 :     if (templatefile == NULL)
     257                 :          0 :         err (1, "open %s", template);
     258                 :            : 
     259                 :          0 :     fprintf (templatefile,
     260                 :            :              "/* Generated from %s */\n"
     261                 :            :              "/* Do not edit */\n\n"
     262                 :            :              "#include <stdio.h>\n"
     263                 :            :              "#include <stdlib.h>\n"
     264                 :            :              "#include <time.h>\n"
     265                 :            :              "#include <string.h>\n"
     266                 :            :              "#include <errno.h>\n"
     267                 :            :              "#include <limits.h>\n"
     268                 :            :              "#include <krb5-types.h>\n",
     269                 :            :              filename);
     270                 :            : 
     271                 :         14 :     fprintf (templatefile,
     272                 :            :              "#include <%s>\n"
     273                 :            :              "#include <%s>\n"
     274                 :            :              "#include <der.h>\n"
     275                 :            :              "#include <der-private.h>\n"
     276                 :            :              "#include <asn1-template.h>\n",
     277                 :            :              header, privheader);
     278                 :            : 
     279                 :            : 
     280                 :            : }
     281                 :            : 
     282                 :            : void
     283                 :         14 : close_generate (void)
     284                 :            : {
     285                 :         14 :     fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase);
     286                 :            : 
     287         [ +  - ]:         14 :     if (headerfile)
     288                 :         14 :         fclose (headerfile);
     289         [ +  - ]:         14 :     if (privheaderfile)
     290                 :         14 :         fclose (privheaderfile);
     291         [ -  + ]:         14 :     if (templatefile)
     292                 :          0 :         fclose (templatefile);
     293         [ +  - ]:         14 :     if (logfile)
     294                 :         14 :         fprintf (logfile, "\n");
     295                 :         14 :         fclose (logfile);
     296                 :         14 : }
     297                 :            : 
     298                 :            : void
     299                 :          0 : gen_assign_defval(const char *var, struct value *val)
     300                 :            : {
     301   [ #  #  #  # ]:          0 :     switch(val->type) {
     302                 :            :     case stringvalue:
     303                 :          0 :         fprintf(codefile, "if((%s = strdup(\"%s\")) == NULL)\nreturn ENOMEM;\n", var, val->u.stringvalue);
     304                 :          0 :         break;
     305                 :            :     case integervalue:
     306                 :          0 :         fprintf(codefile, "%s = %d;\n", var, val->u.integervalue);
     307                 :          0 :         break;
     308                 :            :     case booleanvalue:
     309         [ #  # ]:          0 :         if(val->u.booleanvalue)
     310                 :          0 :             fprintf(codefile, "%s = TRUE;\n", var);
     311                 :            :         else
     312                 :          0 :             fprintf(codefile, "%s = FALSE;\n", var);
     313                 :          0 :         break;
     314                 :            :     default:
     315                 :          0 :         abort();
     316                 :            :     }
     317                 :          0 : }
     318                 :            : 
     319                 :            : void
     320                 :          0 : gen_compare_defval(const char *var, struct value *val)
     321                 :            : {
     322   [ #  #  #  # ]:          0 :     switch(val->type) {
     323                 :            :     case stringvalue:
     324                 :          0 :         fprintf(codefile, "if(strcmp(%s, \"%s\") != 0)\n", var, val->u.stringvalue);
     325                 :          0 :         break;
     326                 :            :     case integervalue:
     327                 :          0 :         fprintf(codefile, "if(%s != %d)\n", var, val->u.integervalue);
     328                 :          0 :         break;
     329                 :            :     case booleanvalue:
     330         [ #  # ]:          0 :         if(val->u.booleanvalue)
     331                 :          0 :             fprintf(codefile, "if(!%s)\n", var);
     332                 :            :         else
     333                 :          0 :             fprintf(codefile, "if(%s)\n", var);
     334                 :          0 :         break;
     335                 :            :     default:
     336                 :          0 :         abort();
     337                 :            :     }
     338                 :          0 : }
     339                 :            : 
     340                 :            : void
     341                 :         14 : generate_header_of_codefile(const char *name)
     342                 :            : {
     343                 :         14 :     char *filename = NULL;
     344                 :            : 
     345         [ -  + ]:         14 :     if (codefile != NULL)
     346                 :          0 :         abort();
     347                 :            : 
     348 [ +  - ][ -  + ]:         14 :     if (asprintf (&filename, "%s_%s.x", STEM, name) < 0 || filename == NULL)
     349                 :          0 :         errx(1, "malloc");
     350                 :         14 :     codefile = fopen (filename, "w");
     351         [ -  + ]:         14 :     if (codefile == NULL)
     352                 :          0 :         err (1, "fopen %s", filename);
     353                 :         14 :     fprintf(logfile, "%s ", filename);
     354                 :         14 :     free(filename);
     355                 :         14 :     filename = NULL;
     356                 :         14 :     fprintf (codefile,
     357                 :            :              "/* Generated from %s */\n"
     358                 :            :              "/* Do not edit */\n\n"
     359                 :            :              "#define  ASN1_LIB\n\n"
     360                 :            :              "#include <stdio.h>\n"
     361                 :            :              "#include <stdlib.h>\n"
     362                 :            :              "#include <time.h>\n"
     363                 :            :              "#include <string.h>\n"
     364                 :            :              "#include <errno.h>\n"
     365                 :            :              "#include <limits.h>\n"
     366                 :            :              "#include <krb5-types.h>\n",
     367                 :            :              orig_filename);
     368                 :            : 
     369                 :         14 :     fprintf (codefile,
     370                 :            :              "#include <%s>\n"
     371                 :            :              "#include <%s>\n",
     372                 :            :              header, privheader);
     373                 :         14 :     fprintf (codefile,
     374                 :            :              "#include <asn1_err.h>\n"
     375                 :            :              "#include <der.h>\n"
     376                 :            :              "#include <der-private.h>\n"
     377                 :            :              "#include <asn1-template.h>\n"
     378                 :            :              "#include <parse_units.h>\n\n");
     379                 :            : 
     380                 :         14 : }
     381                 :            : 
     382                 :            : void
     383                 :         14 : close_codefile(void)
     384                 :            : {
     385         [ -  + ]:         14 :     if (codefile == NULL)
     386                 :          0 :         abort();
     387                 :            : 
     388                 :         14 :     fclose(codefile);
     389                 :         14 :     codefile = NULL;
     390                 :         14 : }
     391                 :            : 
     392                 :            : 
     393                 :            : void
     394                 :        170 : generate_constant (const Symbol *s)
     395                 :            : {
     396   [ -  +  -  -  :        170 :     switch(s->value->type) {
                   +  - ]
     397                 :            :     case booleanvalue:
     398                 :          0 :         break;
     399                 :            :     case integervalue:
     400                 :         10 :         fprintf (headerfile, "enum { %s = %d };\n\n",
     401                 :         10 :                  s->gen_name, s->value->u.integervalue);
     402                 :         10 :         break;
     403                 :            :     case nullvalue:
     404                 :          0 :         break;
     405                 :            :     case stringvalue:
     406                 :          0 :         break;
     407                 :            :     case objectidentifiervalue: {
     408                 :            :         struct objid *o, **list;
     409                 :            :         unsigned int i, len;
     410                 :            :         char *gen_upper;
     411                 :            : 
     412         [ -  + ]:        160 :         if (!one_code_file)
     413                 :          0 :             generate_header_of_codefile(s->gen_name);
     414                 :            : 
     415                 :        160 :         len = 0;
     416         [ +  + ]:       1223 :         for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
     417                 :       1063 :             len++;
     418         [ -  + ]:        160 :         if (len == 0) {
     419                 :          0 :             printf("s->gen_name: %s",s->gen_name);
     420                 :          0 :             fflush(stdout);
     421                 :          0 :             break;
     422                 :            :         }
     423                 :        160 :         list = emalloc(sizeof(*list) * len);
     424                 :            : 
     425                 :        160 :         i = 0;
     426         [ +  + ]:       1223 :         for (o = s->value->u.objectidentifiervalue; o != NULL; o = o->next)
     427                 :       1063 :             list[i++] = o;
     428                 :            : 
     429                 :        160 :         fprintf (headerfile, "/* OBJECT IDENTIFIER %s ::= { ", s->name);
     430         [ +  + ]:       1223 :         for (i = len ; i > 0; i--) {
     431                 :       1063 :             o = list[i - 1];
     432         [ +  + ]:       1063 :             fprintf(headerfile, "%s(%d) ",
     433                 :       1063 :                     o->label ? o->label : "label-less", o->value);
     434                 :            :         }
     435                 :            : 
     436                 :        160 :         fprintf (codefile, "static unsigned oid_%s_variable_num[%d] =  {",
     437                 :            :                  s->gen_name, len);
     438         [ +  + ]:       1223 :         for (i = len ; i > 0; i--) {
     439         [ +  + ]:       1063 :             fprintf(codefile, "%d%s ", list[i - 1]->value, i > 1 ? "," : "");
     440                 :            :         }
     441                 :        160 :         fprintf(codefile, "};\n");
     442                 :            : 
     443                 :        160 :         fprintf (codefile, "const heim_oid asn1_oid_%s = "
     444                 :            :                  "{ %d, oid_%s_variable_num };\n\n",
     445                 :            :                  s->gen_name, len, s->gen_name);
     446                 :            : 
     447                 :        160 :         free(list);
     448                 :            : 
     449                 :            :         /* header file */
     450                 :            : 
     451                 :        160 :         gen_upper = strdup(s->gen_name);
     452                 :        160 :         len = strlen(gen_upper);
     453         [ +  + ]:       3306 :         for (i = 0; i < len; i++)
     454                 :       3146 :             gen_upper[i] = toupper((int)s->gen_name[i]);
     455                 :            : 
     456                 :        160 :         fprintf (headerfile, "} */\n");
     457                 :        160 :         fprintf (headerfile,
     458                 :            :                  "extern ASN1EXP const heim_oid asn1_oid_%s;\n"
     459                 :            :                  "#define ASN1_OID_%s (&asn1_oid_%s)\n\n",
     460                 :            :                  s->gen_name,
     461                 :            :                  gen_upper,
     462                 :            :                  s->gen_name);
     463                 :            : 
     464                 :        160 :         free(gen_upper);
     465                 :            : 
     466         [ -  + ]:        160 :         if (!one_code_file)
     467                 :          0 :             close_codefile();
     468                 :            : 
     469                 :        160 :         break;
     470                 :            :     }
     471                 :            :     default:
     472                 :          0 :         abort();
     473                 :            :     }
     474                 :        170 : }
     475                 :            : 
     476                 :            : int
     477                 :       1067 : is_primitive_type(int type)
     478                 :            : {
     479         [ +  + ]:       1067 :     switch(type) {
     480                 :            :     case TInteger:
     481                 :            :     case TBoolean:
     482                 :            :     case TOctetString:
     483                 :            :     case TBitString:
     484                 :            :     case TEnumerated:
     485                 :            :     case TGeneralizedTime:
     486                 :            :     case TGeneralString:
     487                 :            :     case TTeletexString:
     488                 :            :     case TOID:
     489                 :            :     case TUTCTime:
     490                 :            :     case TUTF8String:
     491                 :            :     case TPrintableString:
     492                 :            :     case TIA5String:
     493                 :            :     case TBMPString:
     494                 :            :     case TUniversalString:
     495                 :            :     case TVisibleString:
     496                 :            :     case TNull:
     497                 :        318 :         return 1;
     498                 :            :     default:
     499                 :       1067 :         return 0;
     500                 :            :     }
     501                 :            : }
     502                 :            : 
     503                 :            : static void
     504                 :       3356 : space(int level)
     505                 :            : {
     506         [ +  + ]:       6274 :     while(level-- > 0)
     507                 :       2918 :         fprintf(headerfile, "  ");
     508                 :       3356 : }
     509                 :            : 
     510                 :            : static const char *
     511                 :       1238 : last_member_p(struct member *m)
     512                 :            : {
     513                 :       1238 :     struct member *n = ASN1_TAILQ_NEXT(m, members);
     514         [ +  + ]:       1238 :     if (n == NULL)
     515                 :        246 :         return "";
     516 [ +  + ][ +  + ]:        992 :     if (n->ellipsis && ASN1_TAILQ_NEXT(n, members) == NULL)
     517                 :         35 :         return "";
     518                 :       1238 :     return ",";
     519                 :            : }
     520                 :            : 
     521                 :            : static struct member *
     522                 :         20 : have_ellipsis(Type *t)
     523                 :            : {
     524                 :            :     struct member *m;
     525         [ +  + ]:         81 :     ASN1_TAILQ_FOREACH(m, t->members, members) {
     526         [ +  + ]:         66 :         if (m->ellipsis)
     527                 :          5 :             return m;
     528                 :            :     }
     529                 :         20 :     return NULL;
     530                 :            : }
     531                 :            : 
     532                 :            : static void
     533                 :       2048 : define_asn1 (int level, Type *t)
     534                 :            : {
     535   [ +  +  +  +  :       2048 :     switch (t->type) {
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                +  +  - ]
     536                 :            :     case TType:
     537                 :        466 :         fprintf (headerfile, "%s", t->symbol->name);
     538                 :        466 :         break;
     539                 :            :     case TInteger:
     540         [ +  + ]:         88 :         if(t->members == NULL) {
     541                 :         72 :             fprintf (headerfile, "INTEGER");
     542         [ +  + ]:         72 :             if (t->range)
     543                 :         72 :                 fprintf (headerfile, " (%d..%d)",
     544                 :         68 :                          t->range->min, t->range->max);
     545                 :            :         } else {
     546                 :            :             Member *m;
     547                 :         16 :             fprintf (headerfile, "INTEGER {\n");
     548         [ +  + ]:        210 :             ASN1_TAILQ_FOREACH(m, t->members, members) {
     549                 :        194 :                 space (level + 1);
     550                 :        194 :                 fprintf(headerfile, "%s(%d)%s\n", m->gen_name, m->val,
     551                 :            :                         last_member_p(m));
     552                 :            :             }
     553                 :         16 :             space(level);
     554                 :         16 :             fprintf (headerfile, "}");
     555                 :            :         }
     556                 :         88 :         break;
     557                 :            :     case TBoolean:
     558                 :          8 :         fprintf (headerfile, "BOOLEAN");
     559                 :          8 :         break;
     560                 :            :     case TOctetString:
     561                 :         96 :         fprintf (headerfile, "OCTET STRING");
     562                 :         96 :         break;
     563                 :            :     case TEnumerated :
     564                 :            :     case TBitString: {
     565                 :            :         Member *m;
     566                 :            : 
     567                 :         22 :         space(level);
     568         [ +  - ]:         22 :         if(t->type == TBitString)
     569                 :         22 :             fprintf (headerfile, "BIT STRING {\n");
     570                 :            :         else
     571                 :          0 :             fprintf (headerfile, "ENUMERATED {\n");
     572         [ +  + ]:        113 :         ASN1_TAILQ_FOREACH(m, t->members, members) {
     573                 :         91 :             space(level + 1);
     574                 :         91 :             fprintf (headerfile, "%s(%d)%s\n", m->name, m->val,
     575                 :            :                      last_member_p(m));
     576                 :            :         }
     577                 :         22 :         space(level);
     578                 :         22 :         fprintf (headerfile, "}");
     579                 :         22 :         break;
     580                 :            :     }
     581                 :            :     case TChoice:
     582                 :            :     case TSet:
     583                 :            :     case TSequence: {
     584                 :            :         Member *m;
     585                 :        189 :         int max_width = 0;
     586                 :            : 
     587         [ +  + ]:        189 :         if(t->type == TChoice)
     588                 :         20 :             fprintf(headerfile, "CHOICE {\n");
     589         [ -  + ]:        169 :         else if(t->type == TSet)
     590                 :          0 :             fprintf(headerfile, "SET {\n");
     591                 :            :         else
     592                 :        169 :             fprintf(headerfile, "SEQUENCE {\n");
     593         [ +  + ]:        887 :         ASN1_TAILQ_FOREACH(m, t->members, members) {
     594         [ +  + ]:        698 :             if(strlen(m->name) > max_width)
     595                 :        371 :                 max_width = strlen(m->name);
     596                 :            :         }
     597                 :        189 :         max_width += 3;
     598         [ +  + ]:        189 :         if(max_width < 16) max_width = 16;
     599         [ +  + ]:        887 :         ASN1_TAILQ_FOREACH(m, t->members, members) {
     600                 :        698 :             int width = max_width;
     601                 :        698 :             space(level + 1);
     602         [ +  + ]:        698 :             if (m->ellipsis) {
     603                 :         32 :                 fprintf (headerfile, "...");
     604                 :            :             } else {
     605                 :        666 :                 width -= fprintf(headerfile, "%s", m->name);
     606                 :        666 :                 fprintf(headerfile, "%*s", width, "");
     607                 :        666 :                 define_asn1(level + 1, m->type);
     608         [ +  + ]:        666 :                 if(m->optional)
     609                 :        230 :                     fprintf(headerfile, " OPTIONAL");
     610                 :            :             }
     611         [ +  - ]:        698 :             if(last_member_p(m))
     612                 :        698 :                 fprintf (headerfile, ",");
     613                 :        698 :             fprintf (headerfile, "\n");
     614                 :            :         }
     615                 :        189 :         space(level);
     616                 :        189 :         fprintf (headerfile, "}");
     617                 :        189 :         break;
     618                 :            :     }
     619                 :            :     case TSequenceOf:
     620                 :         54 :         fprintf (headerfile, "SEQUENCE OF ");
     621                 :         54 :         define_asn1 (0, t->subtype);
     622                 :         54 :         break;
     623                 :            :     case TSetOf:
     624                 :         18 :         fprintf (headerfile, "SET OF ");
     625                 :         18 :         define_asn1 (0, t->subtype);
     626                 :         18 :         break;
     627                 :            :     case TGeneralizedTime:
     628                 :          6 :         fprintf (headerfile, "GeneralizedTime");
     629                 :          6 :         break;
     630                 :            :     case TGeneralString:
     631                 :         14 :         fprintf (headerfile, "GeneralString");
     632                 :         14 :         break;
     633                 :            :     case TTeletexString:
     634                 :          1 :         fprintf (headerfile, "TeletexString");
     635                 :          1 :         break;
     636                 :            :     case TTag: {
     637                 :            :         const char *classnames[] = { "UNIVERSAL ", "APPLICATION ",
     638                 :       1014 :                                      "" /* CONTEXT */, "PRIVATE " };
     639         [ +  + ]:       1014 :         if(t->tag.tagclass != ASN1_C_UNIV)
     640                 :        506 :             fprintf (headerfile, "[%s%d] ",
     641                 :        506 :                      classnames[t->tag.tagclass],
     642                 :            :                      t->tag.tagvalue);
     643         [ +  + ]:       1014 :         if(t->tag.tagenv == TE_IMPLICIT)
     644                 :         49 :             fprintf (headerfile, "IMPLICIT ");
     645                 :       1014 :         define_asn1 (level, t->subtype);
     646                 :       1014 :         break;
     647                 :            :     }
     648                 :            :     case TUTCTime:
     649                 :          1 :         fprintf (headerfile, "UTCTime");
     650                 :          1 :         break;
     651                 :            :     case TUTF8String:
     652                 :         40 :         space(level);
     653                 :         40 :         fprintf (headerfile, "UTF8String");
     654                 :         40 :         break;
     655                 :            :     case TPrintableString:
     656                 :          1 :         space(level);
     657                 :          1 :         fprintf (headerfile, "PrintableString");
     658                 :          1 :         break;
     659                 :            :     case TIA5String:
     660                 :          4 :         space(level);
     661                 :          4 :         fprintf (headerfile, "IA5String");
     662                 :          4 :         break;
     663                 :            :     case TBMPString:
     664                 :          2 :         space(level);
     665                 :          2 :         fprintf (headerfile, "BMPString");
     666                 :          2 :         break;
     667                 :            :     case TUniversalString:
     668                 :          1 :         space(level);
     669                 :          1 :         fprintf (headerfile, "UniversalString");
     670                 :          1 :         break;
     671                 :            :     case TVisibleString:
     672                 :          1 :         space(level);
     673                 :          1 :         fprintf (headerfile, "VisibleString");
     674                 :          1 :         break;
     675                 :            :     case TOID :
     676                 :         19 :         space(level);
     677                 :         19 :         fprintf(headerfile, "OBJECT IDENTIFIER");
     678                 :         19 :         break;
     679                 :            :     case TNull:
     680                 :          3 :         space(level);
     681                 :          3 :         fprintf (headerfile, "NULL");
     682                 :          3 :         break;
     683                 :            :     default:
     684                 :          0 :         abort ();
     685                 :            :     }
     686                 :       2048 : }
     687                 :            : 
     688                 :            : static void
     689                 :        271 : getnewbasename(char **newbasename, int typedefp, const char *basename, const char *name)
     690                 :            : {
     691         [ +  + ]:        271 :     if (typedefp)
     692                 :        229 :         *newbasename = strdup(name);
     693                 :            :     else {
     694         [ +  + ]:         42 :         if (name[0] == '*')
     695                 :         26 :             name++;
     696         [ -  + ]:         42 :         if (asprintf(newbasename, "%s_%s", basename, name) < 0)
     697                 :          0 :             errx(1, "malloc");
     698                 :            :     }
     699         [ -  + ]:        271 :     if (*newbasename == NULL)
     700                 :          0 :         err(1, "malloc");
     701                 :        271 : }
     702                 :            : 
     703                 :            : static void
     704                 :       2440 : define_type (int level, const char *name, const char *basename, Type *t, int typedefp, int preservep)
     705                 :            : {
     706                 :       2440 :     char *newbasename = NULL;
     707                 :            : 
     708   [ +  +  +  +  :       2440 :     switch (t->type) {
          +  -  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  - ]
     709                 :            :     case TType:
     710                 :        466 :         space(level);
     711                 :        466 :         fprintf (headerfile, "%s %s;\n", t->symbol->gen_name, name);
     712                 :        466 :         break;
     713                 :            :     case TInteger:
     714                 :        480 :         space(level);
     715         [ +  + ]:        480 :         if(t->members) {
     716                 :            :             Member *m;
     717         [ +  + ]:         16 :             fprintf (headerfile, "enum %s {\n", typedefp ? name : "");
     718         [ +  + ]:        210 :             ASN1_TAILQ_FOREACH(m, t->members, members) {
     719                 :        194 :                 space (level + 1);
     720                 :        194 :                 fprintf(headerfile, "%s = %d%s\n", m->gen_name, m->val,
     721                 :            :                         last_member_p(m));
     722                 :            :             }
     723                 :         16 :             fprintf (headerfile, "} %s;\n", name);
     724         [ +  + ]:        464 :         } else if (t->range == NULL) {
     725                 :         38 :             fprintf (headerfile, "heim_integer %s;\n", name);
     726 [ +  + ][ +  - ]:        433 :         } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
     727                 :          7 :             fprintf (headerfile, "int %s;\n", name);
     728 [ +  - ][ +  + ]:        446 :         } else if (t->range->min == 0 && t->range->max == UINT_MAX) {
     729                 :         27 :             fprintf (headerfile, "unsigned int %s;\n", name);
     730 [ +  - ][ +  - ]:        784 :         } else if (t->range->min == 0 && t->range->max == INT_MAX) {
     731                 :        392 :             fprintf (headerfile, "unsigned int %s;\n", name);
     732                 :            :         } else
     733                 :          0 :             errx(1, "%s: unsupported range %d -> %d",
     734                 :          0 :                  name, t->range->min, t->range->max);
     735                 :        480 :         break;
     736                 :            :     case TBoolean:
     737                 :          8 :         space(level);
     738                 :          8 :         fprintf (headerfile, "int %s;\n", name);
     739                 :          8 :         break;
     740                 :            :     case TOctetString:
     741                 :         96 :         space(level);
     742                 :         96 :         fprintf (headerfile, "heim_octet_string %s;\n", name);
     743                 :         96 :         break;
     744                 :            :     case TBitString: {
     745                 :            :         Member *m;
     746                 :            :         Type i;
     747                 :         22 :         struct range range = { 0, INT_MAX };
     748                 :            : 
     749                 :         22 :         i.type = TInteger;
     750                 :         22 :         i.range = &range;
     751                 :         22 :         i.members = NULL;
     752                 :         22 :         i.constraint = NULL;
     753                 :            : 
     754                 :         22 :         space(level);
     755         [ +  + ]:         22 :         if(ASN1_TAILQ_EMPTY(t->members))
     756                 :         12 :             fprintf (headerfile, "heim_bit_string %s;\n", name);
     757                 :            :         else {
     758                 :         10 :             int pos = 0;
     759                 :         10 :             getnewbasename(&newbasename, typedefp, basename, name);
     760                 :            : 
     761                 :         10 :             fprintf (headerfile, "struct %s {\n", newbasename);
     762         [ +  + ]:        101 :             ASN1_TAILQ_FOREACH(m, t->members, members) {
     763                 :         91 :                 char *n = NULL;
     764                 :            : 
     765                 :            :                 /* pad unused */
     766         [ +  + ]:        134 :                 while (pos < m->val) {
     767 [ +  - ][ -  + ]:         43 :                     if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL)
     768                 :          0 :                         errx(1, "malloc");
     769                 :         43 :                     define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
     770                 :         43 :                     free(n);
     771                 :         43 :                     pos++;
     772                 :            :                 }
     773                 :            : 
     774                 :         91 :                 n = NULL;
     775 [ +  - ][ -  + ]:         91 :                 if (asprintf (&n, "%s:1", m->gen_name) < 0 || n == NULL)
     776                 :          0 :                     errx(1, "malloc");
     777                 :         91 :                 define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
     778                 :         91 :                 free (n);
     779                 :         91 :                 n = NULL;
     780                 :         91 :                 pos++;
     781                 :            :             }
     782                 :            :             /* pad to 32 elements */
     783         [ +  + ]:        196 :             while (pos < 32) {
     784                 :        186 :                 char *n = NULL;
     785 [ +  - ][ -  + ]:        186 :                 if (asprintf (&n, "_unused%d:1", pos) < 0 || n == NULL)
     786                 :          0 :                     errx(1, "malloc");
     787                 :        186 :                 define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
     788                 :        186 :                 free(n);
     789                 :        186 :                 pos++;
     790                 :            :             }
     791                 :            : 
     792                 :         10 :             space(level);
     793                 :         10 :             fprintf (headerfile, "} %s;\n\n", name);
     794                 :            :         }
     795                 :         22 :         break;
     796                 :            :     }
     797                 :            :     case TEnumerated: {
     798                 :            :         Member *m;
     799                 :            : 
     800                 :          0 :         space(level);
     801         [ #  # ]:          0 :         fprintf (headerfile, "enum %s {\n", typedefp ? name : "");
     802         [ #  # ]:          0 :         ASN1_TAILQ_FOREACH(m, t->members, members) {
     803                 :          0 :             space(level + 1);
     804         [ #  # ]:          0 :             if (m->ellipsis)
     805                 :          0 :                 fprintf (headerfile, "/* ... */\n");
     806                 :            :             else
     807                 :          0 :                 fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val,
     808                 :            :                          last_member_p(m));
     809                 :            :         }
     810                 :          0 :         space(level);
     811                 :          0 :         fprintf (headerfile, "} %s;\n\n", name);
     812                 :          0 :         break;
     813                 :            :     }
     814                 :            :     case TSet:
     815                 :            :     case TSequence: {
     816                 :            :         Member *m;
     817                 :            : 
     818                 :        169 :         getnewbasename(&newbasename, typedefp, basename, name);
     819                 :            : 
     820                 :        169 :         space(level);
     821                 :        169 :         fprintf (headerfile, "struct %s {\n", newbasename);
     822 [ +  - ][ +  + ]:        169 :         if (t->type == TSequence && preservep) {
     823                 :          5 :             space(level + 1);
     824                 :          5 :             fprintf(headerfile, "heim_octet_string _save;\n");
     825                 :            :         }
     826         [ +  + ]:        801 :         ASN1_TAILQ_FOREACH(m, t->members, members) {
     827         [ +  + ]:        632 :             if (m->ellipsis) {
     828                 :            :                 ;
     829         [ +  + ]:        605 :             } else if (m->optional) {
     830                 :        230 :                 char *n = NULL;
     831                 :            : 
     832 [ +  - ][ -  + ]:        230 :                 if (asprintf (&n, "*%s", m->gen_name) < 0 || n == NULL)
     833                 :          0 :                     errx(1, "malloc");
     834                 :        230 :                 define_type (level + 1, n, newbasename, m->type, FALSE, FALSE);
     835                 :        230 :                 free (n);
     836                 :            :             } else
     837                 :        375 :                 define_type (level + 1, m->gen_name, newbasename, m->type, FALSE, FALSE);
     838                 :            :         }
     839                 :        169 :         space(level);
     840                 :        169 :         fprintf (headerfile, "} %s;\n", name);
     841                 :        169 :         break;
     842                 :            :     }
     843                 :            :     case TSetOf:
     844                 :            :     case TSequenceOf: {
     845                 :            :         Type i;
     846                 :         72 :         struct range range = { 0, INT_MAX };
     847                 :            : 
     848                 :         72 :         getnewbasename(&newbasename, typedefp, basename, name);
     849                 :            : 
     850                 :         72 :         i.type = TInteger;
     851                 :         72 :         i.range = &range;
     852                 :         72 :         i.members = NULL;
     853                 :         72 :         i.constraint = NULL;
     854                 :            : 
     855                 :         72 :         space(level);
     856                 :         72 :         fprintf (headerfile, "struct %s {\n", newbasename);
     857                 :         72 :         define_type (level + 1, "len", newbasename, &i, FALSE, FALSE);
     858                 :         72 :         define_type (level + 1, "*val", newbasename, t->subtype, FALSE, FALSE);
     859                 :         72 :         space(level);
     860                 :         72 :         fprintf (headerfile, "} %s;\n", name);
     861                 :         72 :         break;
     862                 :            :     }
     863                 :            :     case TGeneralizedTime:
     864                 :          6 :         space(level);
     865                 :          6 :         fprintf (headerfile, "time_t %s;\n", name);
     866                 :          6 :         break;
     867                 :            :     case TGeneralString:
     868                 :         14 :         space(level);
     869                 :         14 :         fprintf (headerfile, "heim_general_string %s;\n", name);
     870                 :         14 :         break;
     871                 :            :     case TTeletexString:
     872                 :          1 :         space(level);
     873                 :          1 :         fprintf (headerfile, "heim_general_string %s;\n", name);
     874                 :          1 :         break;
     875                 :            :     case TTag:
     876                 :       1014 :         define_type (level, name, basename, t->subtype, typedefp, preservep);
     877                 :       1014 :         break;
     878                 :            :     case TChoice: {
     879                 :         20 :         int first = 1;
     880                 :            :         Member *m;
     881                 :            : 
     882                 :         20 :         getnewbasename(&newbasename, typedefp, basename, name);
     883                 :            : 
     884                 :         20 :         space(level);
     885                 :         20 :         fprintf (headerfile, "struct %s {\n", newbasename);
     886         [ +  + ]:         20 :         if (preservep) {
     887                 :          1 :             space(level + 1);
     888                 :          1 :             fprintf(headerfile, "heim_octet_string _save;\n");
     889                 :            :         }
     890                 :         20 :         space(level + 1);
     891                 :         20 :         fprintf (headerfile, "enum {\n");
     892                 :         20 :         m = have_ellipsis(t);
     893         [ +  + ]:         20 :         if (m) {
     894                 :          5 :             space(level + 2);
     895                 :          5 :             fprintf (headerfile, "%s = 0,\n", m->label);
     896                 :          5 :             first = 0;
     897                 :            :         }
     898         [ +  + ]:         86 :         ASN1_TAILQ_FOREACH(m, t->members, members) {
     899                 :         66 :             space(level + 2);
     900         [ +  + ]:         66 :             if (m->ellipsis)
     901                 :          5 :                 fprintf (headerfile, "/* ... */\n");
     902                 :            :             else
     903         [ +  + ]:         61 :                 fprintf (headerfile, "%s%s%s\n", m->label,
     904                 :            :                          first ? " = 1" : "",
     905                 :            :                          last_member_p(m));
     906                 :         66 :             first = 0;
     907                 :            :         }
     908                 :         20 :         space(level + 1);
     909                 :         20 :         fprintf (headerfile, "} element;\n");
     910                 :         20 :         space(level + 1);
     911                 :         20 :         fprintf (headerfile, "union {\n");
     912         [ +  + ]:         86 :         ASN1_TAILQ_FOREACH(m, t->members, members) {
     913         [ +  + ]:         66 :             if (m->ellipsis) {
     914                 :          5 :                 space(level + 2);
     915                 :          5 :                 fprintf(headerfile, "heim_octet_string asn1_ellipsis;\n");
     916         [ -  + ]:         61 :             } else if (m->optional) {
     917                 :          0 :                 char *n = NULL;
     918                 :            : 
     919 [ #  # ][ #  # ]:          0 :                 if (asprintf (&n, "*%s", m->gen_name) < 0 || n == NULL)
     920                 :          0 :                     errx(1, "malloc");
     921                 :          0 :                 define_type (level + 2, n, newbasename, m->type, FALSE, FALSE);
     922                 :          0 :                 free (n);
     923                 :            :             } else
     924                 :         61 :                 define_type (level + 2, m->gen_name, newbasename, m->type, FALSE, FALSE);
     925                 :            :         }
     926                 :         20 :         space(level + 1);
     927                 :         20 :         fprintf (headerfile, "} u;\n");
     928                 :         20 :         space(level);
     929                 :         20 :         fprintf (headerfile, "} %s;\n", name);
     930                 :         20 :         break;
     931                 :            :     }
     932                 :            :     case TUTCTime:
     933                 :          1 :         space(level);
     934                 :          1 :         fprintf (headerfile, "time_t %s;\n", name);
     935                 :          1 :         break;
     936                 :            :     case TUTF8String:
     937                 :         40 :         space(level);
     938                 :         40 :         fprintf (headerfile, "heim_utf8_string %s;\n", name);
     939                 :         40 :         break;
     940                 :            :     case TPrintableString:
     941                 :          1 :         space(level);
     942                 :          1 :         fprintf (headerfile, "heim_printable_string %s;\n", name);
     943                 :          1 :         break;
     944                 :            :     case TIA5String:
     945                 :          4 :         space(level);
     946                 :          4 :         fprintf (headerfile, "heim_ia5_string %s;\n", name);
     947                 :          4 :         break;
     948                 :            :     case TBMPString:
     949                 :          2 :         space(level);
     950                 :          2 :         fprintf (headerfile, "heim_bmp_string %s;\n", name);
     951                 :          2 :         break;
     952                 :            :     case TUniversalString:
     953                 :          1 :         space(level);
     954                 :          1 :         fprintf (headerfile, "heim_universal_string %s;\n", name);
     955                 :          1 :         break;
     956                 :            :     case TVisibleString:
     957                 :          1 :         space(level);
     958                 :          1 :         fprintf (headerfile, "heim_visible_string %s;\n", name);
     959                 :          1 :         break;
     960                 :            :     case TOID :
     961                 :         19 :         space(level);
     962                 :         19 :         fprintf (headerfile, "heim_oid %s;\n", name);
     963                 :         19 :         break;
     964                 :            :     case TNull:
     965                 :          3 :         space(level);
     966                 :          3 :         fprintf (headerfile, "int %s;\n", name);
     967                 :          3 :         break;
     968                 :            :     default:
     969                 :          0 :         abort ();
     970                 :            :     }
     971         [ +  + ]:       2440 :     if (newbasename)
     972                 :        271 :         free(newbasename);
     973                 :       2440 : }
     974                 :            : 
     975                 :            : static void
     976                 :        296 : generate_type_header (const Symbol *s)
     977                 :            : {
     978                 :        296 :     int preservep = preserve_type(s->name) ? TRUE : FALSE;
     979                 :            : 
     980                 :        296 :     fprintf (headerfile, "/*\n");
     981                 :        296 :     fprintf (headerfile, "%s ::= ", s->name);
     982                 :        296 :     define_asn1 (0, s->type);
     983                 :        296 :     fprintf (headerfile, "\n*/\n\n");
     984                 :            : 
     985                 :        296 :     fprintf (headerfile, "typedef ");
     986                 :        296 :     define_type (0, s->gen_name, s->gen_name, s->type, TRUE, preservep);
     987                 :            : 
     988                 :        296 :     fprintf (headerfile, "\n");
     989                 :        296 : }
     990                 :            : 
     991                 :            : void
     992                 :        296 : generate_type (const Symbol *s)
     993                 :            : {
     994                 :            :     FILE *h;
     995                 :            :     const char * exp;
     996                 :            : 
     997         [ -  + ]:        296 :     if (!one_code_file)
     998                 :          0 :         generate_header_of_codefile(s->gen_name);
     999                 :            : 
    1000                 :        296 :     generate_type_header (s);
    1001                 :            : 
    1002         [ -  + ]:        296 :     if (template_flag)
    1003                 :          0 :         generate_template(s);
    1004                 :            : 
    1005 [ -  + ][ #  # ]:        296 :     if (template_flag == 0 || is_template_compat(s) == 0) {
    1006                 :        296 :         generate_type_encode (s);
    1007                 :        296 :         generate_type_decode (s);
    1008                 :        296 :         generate_type_free (s);
    1009                 :        296 :         generate_type_length (s);
    1010                 :        296 :         generate_type_copy (s);
    1011                 :            :     }
    1012                 :        296 :     generate_type_seq (s);
    1013                 :        296 :     generate_glue (s->type, s->gen_name);
    1014                 :            : 
    1015                 :            :     /* generate prototypes */
    1016                 :            : 
    1017         [ +  + ]:        296 :     if (is_export(s->name)) {
    1018                 :        272 :         h = headerfile;
    1019                 :        272 :         exp = "ASN1EXP ";
    1020                 :            :     } else {
    1021                 :         24 :         h = privheaderfile;
    1022                 :         24 :         exp = "";
    1023                 :            :     }
    1024                 :            : 
    1025                 :        296 :     fprintf (h,
    1026                 :            :              "%sint    ASN1CALL "
    1027                 :            :              "decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
    1028                 :            :              exp,
    1029                 :            :              s->gen_name, s->gen_name);
    1030                 :        296 :     fprintf (h,
    1031                 :            :              "%sint    ASN1CALL "
    1032                 :            :              "encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
    1033                 :            :              exp,
    1034                 :            :              s->gen_name, s->gen_name);
    1035                 :        296 :     fprintf (h,
    1036                 :            :              "%ssize_t ASN1CALL length_%s(const %s *);\n",
    1037                 :            :              exp,
    1038                 :            :              s->gen_name, s->gen_name);
    1039                 :        296 :     fprintf (h,
    1040                 :            :              "%sint    ASN1CALL copy_%s  (const %s *, %s *);\n",
    1041                 :            :              exp,
    1042                 :            :              s->gen_name, s->gen_name, s->gen_name);
    1043                 :        296 :     fprintf (h,
    1044                 :            :              "%svoid   ASN1CALL free_%s  (%s *);\n",
    1045                 :            :              exp,
    1046                 :            :              s->gen_name, s->gen_name);
    1047                 :            : 
    1048                 :        296 :     fprintf(h, "\n\n");
    1049                 :            : 
    1050         [ -  + ]:        296 :     if (!one_code_file) {
    1051                 :          0 :         fprintf(codefile, "\n\n");
    1052                 :          0 :         close_codefile();
    1053                 :            :         }
    1054                 :        296 : }

Generated by: LCOV version 1.9