LTP GCOV extension - code coverage report
Current view: directory - lib/asn1 - gen_encode.c
Test: samba_4_0_test.lcov.info
Date: 2010-08-06 Instrumented lines: 205
Code covered: 90.2 % Executed lines: 185

       1                 : /*
       2                 :  * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan
       3                 :  * (Royal Institute of Technology, Stockholm, Sweden).
       4                 :  * All rights reserved.
       5                 :  *
       6                 :  * Redistribution and use in source and binary forms, with or without
       7                 :  * modification, are permitted provided that the following conditions
       8                 :  * are met:
       9                 :  *
      10                 :  * 1. Redistributions of source code must retain the above copyright
      11                 :  *    notice, this list of conditions and the following disclaimer.
      12                 :  *
      13                 :  * 2. Redistributions in binary form must reproduce the above copyright
      14                 :  *    notice, this list of conditions and the following disclaimer in the
      15                 :  *    documentation and/or other materials provided with the distribution.
      16                 :  *
      17                 :  * 3. Neither the name of the Institute nor the names of its contributors
      18                 :  *    may be used to endorse or promote products derived from this software
      19                 :  *    without specific prior written permission.
      20                 :  *
      21                 :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22                 :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23                 :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24                 :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25                 :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26                 :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27                 :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28                 :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29                 :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30                 :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31                 :  * SUCH DAMAGE.
      32                 :  */
      33                 : 
      34                 : #include "gen_locl.h"
      35                 : 
      36                 : RCSID("$Id$");
      37                 : 
      38                 : static void
      39                 : encode_primitive (const char *typename, const char *name)
      40             288 : {
      41             288 :     fprintf (codefile,
      42                 :              "e = der_put_%s(p, len, %s, &l);\n"
      43                 :              "if (e) return e;\np -= l; len -= l; ret += l;\n\n",
      44                 :              typename,
      45                 :              name);
      46             288 : }
      47                 : 
      48                 : const char *
      49                 : classname(Der_class class)
      50            2061 : {
      51                 :     const char *cn[] = { "ASN1_C_UNIV", "ASN1_C_APPL",
      52            2061 :                          "ASN1_C_CONTEXT", "ASN1_C_PRIV" };
      53            2061 :     if(class < ASN1_C_UNIV || class > ASN1_C_PRIVATE)
      54               0 :         return "???";
      55            2061 :     return cn[class];
      56                 : }
      57                 : 
      58                 : 
      59                 : const char *
      60                 : valuename(Der_class class, int value)
      61            2061 : {
      62                 :     static char s[32];
      63                 :     struct {
      64                 :         int value;
      65                 :         const char *s;
      66                 :     } *p, values[] = {
      67                 : #define X(Y) { Y, #Y }
      68                 :         X(UT_BMPString),
      69                 :         X(UT_BitString),
      70                 :         X(UT_Boolean),
      71                 :         X(UT_EmbeddedPDV),
      72                 :         X(UT_Enumerated),
      73                 :         X(UT_External),
      74                 :         X(UT_GeneralString),
      75                 :         X(UT_GeneralizedTime),
      76                 :         X(UT_GraphicString),
      77                 :         X(UT_IA5String),
      78                 :         X(UT_Integer),
      79                 :         X(UT_Null),
      80                 :         X(UT_NumericString),
      81                 :         X(UT_OID),
      82                 :         X(UT_ObjectDescriptor),
      83                 :         X(UT_OctetString),
      84                 :         X(UT_PrintableString),
      85                 :         X(UT_Real),
      86                 :         X(UT_RelativeOID),
      87                 :         X(UT_Sequence),
      88                 :         X(UT_Set),
      89                 :         X(UT_TeletexString),
      90                 :         X(UT_UTCTime),
      91                 :         X(UT_UTF8String),
      92                 :         X(UT_UniversalString),
      93                 :         X(UT_VideotexString),
      94                 :         X(UT_VisibleString),
      95                 : #undef X
      96                 :         { -1, NULL }
      97            2061 :     };
      98            2061 :     if(class == ASN1_C_UNIV) {
      99           16616 :         for(p = values; p->value != -1; p++)
     100           16616 :             if(p->value == value)
     101            1014 :                 return p->s;
     102                 :     }
     103            1047 :     snprintf(s, sizeof(s), "%d", value);
     104            1047 :     return s;
     105                 : }
     106                 : 
     107                 : static int
     108                 : encode_type (const char *name, const Type *t, const char *tmpstr)
     109            2007 : {
     110            2007 :     int constructed = 1;
     111                 : 
     112            2007 :     switch (t->type) {
     113                 :     case TType:
     114                 : #if 0
     115                 :         encode_type (name, t->symbol->type);
     116                 : #endif
     117             444 :         fprintf (codefile,
     118                 :                  "e = encode_%s(p, len, %s, &l);\n"
     119                 :                  "if (e) return e;\np -= l; len -= l; ret += l;\n\n",
     120                 :                  t->symbol->gen_name, name);
     121             444 :         break;
     122                 :     case TInteger:
     123              83 :         if(t->members) {
     124              16 :             fprintf(codefile,
     125                 :                     "{\n"
     126                 :                     "int enumint = (int)*%s;\n",
     127                 :                     name);
     128              16 :             encode_primitive ("integer", "&enumint");
     129              16 :             fprintf(codefile, "}\n;");
     130              67 :         } else if (t->range == NULL) {
     131              35 :             encode_primitive ("heim_integer", name);
     132              39 :         } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
     133               7 :             encode_primitive ("integer", name);
     134              50 :         } else if (t->range->min == 0 && t->range->max == UINT_MAX) {
     135              25 :             encode_primitive ("unsigned", name);
     136               0 :         } else if (t->range->min == 0 && t->range->max == INT_MAX) {
     137               0 :             encode_primitive ("unsigned", name);
     138                 :         } else
     139               0 :             errx(1, "%s: unsupported range %d -> %d",
     140                 :                  name, t->range->min, t->range->max);
     141              83 :         constructed = 0;
     142              83 :         break;
     143                 :     case TBoolean:
     144               8 :         encode_primitive ("boolean", name);
     145               8 :         constructed = 0;
     146               8 :         break;
     147                 :     case TOctetString:
     148              96 :         encode_primitive ("octet_string", name);
     149              96 :         constructed = 0;
     150              96 :         break;
     151                 :     case TBitString: {
     152                 :         Member *m;
     153                 :         int pos;
     154                 : 
     155              22 :         if (ASN1_TAILQ_EMPTY(t->members)) {
     156              12 :             encode_primitive("bit_string", name);
     157              12 :             constructed = 0;
     158              12 :             break;
     159                 :         }
     160                 : 
     161              10 :         fprintf (codefile, "{\n"
     162                 :                  "unsigned char c = 0;\n");
     163              10 :         if (!rfc1510_bitstring)
     164               5 :             fprintf (codefile,
     165                 :                      "int rest = 0;\n"
     166                 :                      "int bit_set = 0;\n");
     167                 : #if 0
     168                 :         pos = t->members->prev->val;
     169                 :         /* fix for buggy MIT (and OSF?) code */
     170                 :         if (pos > 31)
     171                 :             abort ();
     172                 : #endif
     173                 :         /*
     174                 :          * It seems that if we do not always set pos to 31 here, the MIT
     175                 :          * code will do the wrong thing.
     176                 :          *
     177                 :          * I hate ASN.1 (and DER), but I hate it even more when everybody
     178                 :          * has to screw it up differently.
     179                 :          */
     180              10 :         pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
     181              10 :         if (rfc1510_bitstring) {
     182               5 :             if (pos < 31)
     183               4 :                 pos = 31;
     184                 :         }
     185                 : 
     186              99 :         ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
     187             197 :             while (m->val / 8 < pos / 8) {
     188              19 :                 if (!rfc1510_bitstring)
     189               4 :                     fprintf (codefile,
     190                 :                              "if (c != 0 || bit_set) {\n");
     191              19 :                 fprintf (codefile,
     192                 :                          "if (len < 1) return ASN1_OVERFLOW;\n"
     193                 :                          "*p-- = c; len--; ret++;\n");
     194              19 :                 if (!rfc1510_bitstring)
     195               4 :                     fprintf (codefile,
     196                 :                              "if (!bit_set) {\n"
     197                 :                              "rest = 0;\n"
     198                 :                              "while(c) { \n"
     199                 :                              "if (c & 1) break;\n"
     200                 :                              "c = c >> 1;\n"
     201                 :                              "rest++;\n"
     202                 :                              "}\n"
     203                 :                              "bit_set = 1;\n"
     204                 :                              "}\n"
     205                 :                              "}\n");
     206              19 :                 fprintf (codefile,
     207                 :                          "c = 0;\n");
     208              19 :                 pos -= 8;
     209                 :             }
     210              89 :             fprintf (codefile,
     211                 :                      "if((%s)->%s) {\n"
     212                 :                      "c |= 1<<%d;\n",
     213                 :                      name, m->gen_name, 7 - m->val % 8);
     214              89 :             fprintf (codefile,
     215                 :                      "}\n");
     216                 :         }
     217                 : 
     218              10 :         if (!rfc1510_bitstring)
     219               5 :             fprintf (codefile,
     220                 :                      "if (c != 0 || bit_set) {\n");
     221              10 :         fprintf (codefile,
     222                 :                  "if (len < 1) return ASN1_OVERFLOW;\n"
     223                 :                  "*p-- = c; len--; ret++;\n");
     224              10 :         if (!rfc1510_bitstring)
     225               5 :             fprintf (codefile,
     226                 :                      "if (!bit_set) {\n"
     227                 :                      "rest = 0;\n"
     228                 :                      "if(c) { \n"
     229                 :                      "while(c) { \n"
     230                 :                      "if (c & 1) break;\n"
     231                 :                      "c = c >> 1;\n"
     232                 :                      "rest++;\n"
     233                 :                      "}\n"
     234                 :                      "}\n"
     235                 :                      "}\n"
     236                 :                      "}\n");
     237                 : 
     238              10 :         fprintf (codefile,
     239                 :                  "if (len < 1) return ASN1_OVERFLOW;\n"
     240                 :                  "*p-- = %s;\n"
     241                 :                  "len -= 1;\n"
     242                 :                  "ret += 1;\n"
     243                 :                  "}\n\n",
     244                 :                  rfc1510_bitstring ? "0" : "rest");
     245              10 :         constructed = 0;
     246              10 :         break;
     247                 :     }
     248                 :     case TEnumerated : {
     249               0 :         encode_primitive ("enumerated", name);
     250               0 :         constructed = 0;
     251               0 :         break;
     252                 :     }
     253                 : 
     254                 :     case TSet:
     255                 :     case TSequence: {
     256                 :         Member *m;
     257                 : 
     258             168 :         if (t->members == NULL)
     259               0 :             break;
     260                 : 
     261             795 :         ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
     262                 :             char *s;
     263                 : 
     264             627 :             if (m->ellipsis)
     265              26 :                 continue;
     266                 : 
     267             601 :             asprintf (&s, "%s(%s)->%s", m->optional ? "" : "&", name, m->gen_name);
     268             601 :             if (s == NULL)
     269               0 :                 errx(1, "malloc");
     270             601 :             fprintf(codefile, "/* %s */\n", m->name);
     271             601 :             if (m->optional)
     272             228 :                 fprintf (codefile,
     273                 :                          "if(%s) ",
     274                 :                          s);
     275             373 :             else if(m->defval)
     276               0 :                 gen_compare_defval(s + 1, m->defval);
     277             601 :             fprintf (codefile, "{\n");
     278             601 :             fprintf (codefile, "size_t %s_oldret = ret;\n", tmpstr);
     279             601 :             fprintf (codefile, "ret = 0;\n");
     280             601 :             encode_type (s, m->type, m->gen_name);
     281             601 :             fprintf (codefile, "ret += %s_oldret;\n", tmpstr);
     282             601 :             fprintf (codefile, "}\n");
     283             601 :             free (s);
     284                 :         }
     285             168 :         break;
     286                 :     }
     287                 :     case TSetOf: {
     288                 : 
     289              18 :         fprintf(codefile,
     290                 :                 "{\n"
     291                 :                 "struct heim_octet_string *val;\n"
     292                 :                 "size_t elen, totallen = 0;\n"
     293                 :                 "int eret;\n");
     294                 : 
     295              18 :         fprintf(codefile,
     296                 :                 "if ((%s)->len > UINT_MAX/sizeof(val[0]))\n"
     297                 :                 "return ERANGE;\n",
     298                 :                 name);
     299                 : 
     300              18 :         fprintf(codefile,
     301                 :                 "val = malloc(sizeof(val[0]) * (%s)->len);\n"
     302                 :                 "if (val == NULL && (%s)->len != 0) return ENOMEM;\n",
     303                 :                 name, name);
     304                 : 
     305              18 :         fprintf(codefile,
     306                 :                 "for(i = 0; i < (%s)->len; i++) {\n",
     307                 :                 name);
     308                 : 
     309              18 :         fprintf(codefile,
     310                 :                 "ASN1_MALLOC_ENCODE(%s, val[i].data, "
     311                 :                 "val[i].length, &(%s)->val[i], &elen, eret);\n",
     312                 :                 t->subtype->symbol->gen_name,
     313                 :                 name);
     314                 : 
     315              18 :         fprintf(codefile,
     316                 :                 "if(eret) {\n"
     317                 :                 "i--;\n"
     318                 :                 "while (i >= 0) {\n"
     319                 :                 "free(val[i].data);\n"
     320                 :                 "i--;\n"
     321                 :                 "}\n"
     322                 :                 "free(val);\n"
     323                 :                 "return eret;\n"
     324                 :                 "}\n"
     325                 :                 "totallen += elen;\n"
     326                 :                 "}\n");
     327                 : 
     328              18 :         fprintf(codefile,
     329                 :                 "if (totallen > len) {\n"
     330                 :                 "for (i = 0; i < (%s)->len; i++) {\n"
     331                 :                 "free(val[i].data);\n"
     332                 :                 "}\n"
     333                 :                 "free(val);\n"
     334                 :                 "return ASN1_OVERFLOW;\n"
     335                 :                 "}\n",
     336                 :                 name);
     337                 : 
     338              18 :         fprintf(codefile,
     339                 :                 "qsort(val, (%s)->len, sizeof(val[0]), _heim_der_set_sort);\n",
     340                 :                 name);
     341                 : 
     342              18 :         fprintf (codefile,
     343                 :                  "for(i = (%s)->len - 1; i >= 0; --i) {\n"
     344                 :                  "p -= val[i].length;\n"
     345                 :                  "ret += val[i].length;\n"
     346                 :                  "memcpy(p + 1, val[i].data, val[i].length);\n"
     347                 :                  "free(val[i].data);\n"
     348                 :                  "}\n"
     349                 :                  "free(val);\n"
     350                 :                  "}\n",
     351                 :                  name);
     352              18 :         break;
     353                 :     }
     354                 :     case TSequenceOf: {
     355                 :         char *n;
     356                 :         char *sname;
     357                 : 
     358              54 :         fprintf (codefile,
     359                 :                  "for(i = (%s)->len - 1; i >= 0; --i) {\n"
     360                 :                  "size_t %s_for_oldret = ret;\n"
     361                 :                  "ret = 0;\n",
     362                 :                  name, tmpstr);
     363              54 :         asprintf (&n, "&(%s)->val[i]", name);
     364              54 :         if (n == NULL)
     365               0 :             errx(1, "malloc");
     366              54 :         asprintf (&sname, "%s_S_Of", tmpstr);
     367              54 :         if (sname == NULL)
     368               0 :             errx(1, "malloc");
     369              54 :         encode_type (n, t->subtype, sname);
     370              54 :         fprintf (codefile,
     371                 :                  "ret += %s_for_oldret;\n"
     372                 :                  "}\n",
     373                 :                  tmpstr);
     374              54 :         free (n);
     375              54 :         free (sname);
     376              54 :         break;
     377                 :     }
     378                 :     case TGeneralizedTime:
     379               6 :         encode_primitive ("generalized_time", name);
     380               6 :         constructed = 0;
     381               6 :         break;
     382                 :     case TGeneralString:
     383              14 :         encode_primitive ("general_string", name);
     384              14 :         constructed = 0;
     385              14 :         break;
     386                 :     case TTeletexString:
     387               1 :         encode_primitive ("general_string", name);
     388               1 :         constructed = 0;
     389               1 :         break;
     390                 :     case TTag: {
     391                 :         char *tname;
     392                 :         int c;
     393            1002 :         asprintf (&tname, "%s_tag", tmpstr);
     394            1002 :         if (tname == NULL)
     395               0 :             errx(1, "malloc");
     396            1002 :         c = encode_type (name, t->subtype, tname);
     397            1002 :         fprintf (codefile,
     398                 :                  "e = der_put_length_and_tag (p, len, ret, %s, %s, %s, &l);\n"
     399                 :                  "if (e) return e;\np -= l; len -= l; ret += l;\n\n",
     400                 :                  classname(t->tag.tagclass),
     401                 :                  c ? "CONS" : "PRIM",
     402                 :                  valuename(t->tag.tagclass, t->tag.tagvalue));
     403            1002 :         free (tname);
     404            1002 :         break;
     405                 :     }
     406                 :     case TChoice:{
     407              20 :         Member *m, *have_ellipsis = NULL;
     408                 :         char *s;
     409                 : 
     410              20 :         if (t->members == NULL)
     411               0 :             break;
     412                 : 
     413              20 :         fprintf(codefile, "\n");
     414                 : 
     415              20 :         asprintf (&s, "(%s)", name);
     416              20 :         if (s == NULL)
     417               0 :             errx(1, "malloc");
     418              20 :         fprintf(codefile, "switch(%s->element) {\n", s);
     419                 : 
     420              82 :         ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
     421                 :             char *s2;
     422                 : 
     423              62 :             if (m->ellipsis) {
     424               5 :                 have_ellipsis = m;
     425               5 :                 continue;
     426                 :             }
     427                 : 
     428              57 :             fprintf (codefile, "case %s: {", m->label);
     429              57 :             asprintf(&s2, "%s(%s)->u.%s", m->optional ? "" : "&",
     430                 :                      s, m->gen_name);
     431              57 :             if (s2 == NULL)
     432               0 :                 errx(1, "malloc");
     433              57 :             if (m->optional)
     434               0 :                 fprintf (codefile, "if(%s) {\n", s2);
     435              57 :             fprintf (codefile, "size_t %s_oldret = ret;\n", tmpstr);
     436              57 :             fprintf (codefile, "ret = 0;\n");
     437              57 :             constructed = encode_type (s2, m->type, m->gen_name);
     438              57 :             fprintf (codefile, "ret += %s_oldret;\n", tmpstr);
     439              57 :             if(m->optional)
     440               0 :                 fprintf (codefile, "}\n");
     441              57 :             fprintf(codefile, "break;\n");
     442              57 :             fprintf(codefile, "}\n");
     443              57 :             free (s2);
     444                 :         }
     445              20 :         free (s);
     446              20 :         if (have_ellipsis) {
     447               5 :             fprintf(codefile,
     448                 :                     "case %s: {\n"
     449                 :                     "if (len < (%s)->u.%s.length)\n"
     450                 :                     "return ASN1_OVERFLOW;\n"
     451                 :                     "p -= (%s)->u.%s.length;\n"
     452                 :                     "ret += (%s)->u.%s.length;\n"
     453                 :                     "memcpy(p + 1, (%s)->u.%s.data, (%s)->u.%s.length);\n"
     454                 :                     "break;\n"
     455                 :                     "}\n",
     456                 :                     have_ellipsis->label,
     457                 :                     name, have_ellipsis->gen_name,
     458                 :                     name, have_ellipsis->gen_name,
     459                 :                     name, have_ellipsis->gen_name,
     460                 :                     name, have_ellipsis->gen_name,
     461                 :                     name, have_ellipsis->gen_name);
     462                 :         }
     463              20 :         fprintf(codefile, "};\n");
     464              20 :         break;
     465                 :     }
     466                 :     case TOID:
     467              19 :         encode_primitive ("oid", name);
     468              19 :         constructed = 0;
     469              19 :         break;
     470                 :     case TUTCTime:
     471               1 :         encode_primitive ("utctime", name);
     472               1 :         constructed = 0;
     473               1 :         break;
     474                 :     case TUTF8String:
     475              39 :         encode_primitive ("utf8string", name);
     476              39 :         constructed = 0;
     477              39 :         break;
     478                 :     case TPrintableString:
     479               1 :         encode_primitive ("printable_string", name);
     480               1 :         constructed = 0;
     481               1 :         break;
     482                 :     case TIA5String:
     483               4 :         encode_primitive ("ia5_string", name);
     484               4 :         constructed = 0;
     485               4 :         break;
     486                 :     case TBMPString:
     487               2 :         encode_primitive ("bmp_string", name);
     488               2 :         constructed = 0;
     489               2 :         break;
     490                 :     case TUniversalString:
     491               1 :         encode_primitive ("universal_string", name);
     492               1 :         constructed = 0;
     493               1 :         break;
     494                 :     case TVisibleString:
     495               1 :         encode_primitive ("visible_string", name);
     496               1 :         constructed = 0;
     497               1 :         break;
     498                 :     case TNull:
     499               3 :         fprintf (codefile, "/* NULL */\n");
     500               3 :         constructed = 0;
     501               3 :         break;
     502                 :     default:
     503               0 :         abort ();
     504                 :     }
     505            2007 :     return constructed;
     506                 : }
     507                 : 
     508                 : void
     509                 : generate_type_encode (const Symbol *s)
     510             293 : {
     511             293 :     fprintf (codefile, "int\n"
     512                 :              "encode_%s(unsigned char *p, size_t len,"
     513                 :              " const %s *data, size_t *size)\n"
     514                 :              "{\n",
     515                 :              s->gen_name, s->gen_name);
     516                 : 
     517             293 :     switch (s->type->type) {
     518                 :     case TInteger:
     519                 :     case TBoolean:
     520                 :     case TOctetString:
     521                 :     case TGeneralizedTime:
     522                 :     case TGeneralString:
     523                 :     case TTeletexString:
     524                 :     case TUTCTime:
     525                 :     case TUTF8String:
     526                 :     case TPrintableString:
     527                 :     case TIA5String:
     528                 :     case TBMPString:
     529                 :     case TUniversalString:
     530                 :     case TVisibleString:
     531                 :     case TNull:
     532                 :     case TBitString:
     533                 :     case TEnumerated:
     534                 :     case TOID:
     535                 :     case TSequence:
     536                 :     case TSequenceOf:
     537                 :     case TSet:
     538                 :     case TSetOf:
     539                 :     case TTag:
     540                 :     case TType:
     541                 :     case TChoice:
     542             293 :         fprintf (codefile,
     543                 :                  "size_t ret = 0;\n"
     544                 :                  "size_t l;\n"
     545                 :                  "int i, e;\n\n");
     546             293 :         fprintf(codefile, "i = 0;\n"); /* hack to avoid `unused variable' */
     547                 : 
     548             293 :         encode_type("data", s->type, "Top");
     549                 : 
     550             293 :         fprintf (codefile, "*size = ret;\n"
     551                 :                  "return 0;\n");
     552                 :         break;
     553                 :     default:
     554               0 :         abort ();
     555                 :     }
     556             293 :     fprintf (codefile, "}\n\n");
     557             293 : }

Generated by: LTP GCOV extension version 1.6