LTP GCOV extension - code coverage report
Current view: directory - lib/asn1 - gen.c
Test: samba_4_0_test.lcov.info
Date: 2010-08-06 Instrumented lines: 530
Code covered: 84.5 % Executed lines: 448

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

Generated by: LTP GCOV extension version 1.6