[BACK]Return to gen.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / asn1_compile

Annotation of src/usr.bin/asn1_compile/gen.c, Revision 1.1

1.1     ! hin         1: /*
        !             2:  * Copyright (c) 1997 - 2002 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: /*
        !            37: RCSID("$KTH: gen.c,v 1.50 2003/04/17 07:09:18 lha Exp $");
        !            38: */
        !            39:
        !            40: FILE *headerfile, *codefile, *logfile;
        !            41:
        !            42: #define STEM "asn1"
        !            43:
        !            44: static const char *orig_filename;
        !            45: static char *header;
        !            46: static 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: {
        !            62:     struct import *tmp = malloc (sizeof(*tmp));
        !            63:     if(tmp == NULL)
        !            64:        errx(1, "Out of memory");
        !            65:
        !            66:     tmp->module = module;
        !            67:     tmp->next   = imports;
        !            68:     imports     = tmp;
        !            69: }
        !            70:
        !            71: const char *
        !            72: filename (void)
        !            73: {
        !            74:     return orig_filename;
        !            75: }
        !            76:
        !            77: void
        !            78: init_generate (const char *filename, const char *base)
        !            79: {
        !            80:     orig_filename = filename;
        !            81:     if(base)
        !            82:        asprintf(&headerbase, "%s", base);
        !            83:     asprintf(&header, "%s.h", headerbase);
        !            84:     headerfile = fopen (header, "w");
        !            85:     if (headerfile == NULL)
        !            86:        err (1, "open %s", header);
        !            87:     fprintf (headerfile,
        !            88:             "/* Generated from %s */\n"
        !            89:             "/* Do not edit */\n\n",
        !            90:             filename);
        !            91:     fprintf (headerfile,
        !            92:             "#ifndef __%s_h__\n"
        !            93:             "#define __%s_h__\n\n", headerbase, headerbase);
        !            94:     fprintf (headerfile,
        !            95:             "#include <stddef.h>\n"
        !            96:             "#include <time.h>\n\n");
        !            97: #ifndef HAVE_TIMEGM
        !            98:     fprintf (headerfile, "time_t timegm (struct tm*);\n\n");
        !            99: #endif
        !           100:     fprintf (headerfile,
        !           101:             "#ifndef __asn1_common_definitions__\n"
        !           102:             "#define __asn1_common_definitions__\n\n");
        !           103:     fprintf (headerfile,
        !           104:             "typedef struct octet_string {\n"
        !           105:             "  size_t length;\n"
        !           106:             "  void *data;\n"
        !           107:             "} octet_string;\n\n");
        !           108:     fprintf (headerfile,
        !           109:             "typedef char *general_string;\n\n"
        !           110:             );
        !           111:     fprintf (headerfile,
        !           112:             "typedef struct oid {\n"
        !           113:             "  size_t length;\n"
        !           114:             "  unsigned *components;\n"
        !           115:             "} oid;\n\n");
        !           116:     fputs("#define ASN1_MALLOC_ENCODE(T, B, BL, S, L, R)                  \\\n"
        !           117:          "  do {                                                         \\\n"
        !           118:          "    (BL) = length_##T((S));                                    \\\n"
        !           119:          "    (B) = malloc((BL));                                        \\\n"
        !           120:          "    if((B) == NULL) {                                          \\\n"
        !           121:          "      (R) = ENOMEM;                                            \\\n"
        !           122:          "    } else {                                                   \\\n"
        !           123:          "      (R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \\\n"
        !           124:          "                       (S), (L));                              \\\n"
        !           125:          "      if((R) != 0) {                                           \\\n"
        !           126:          "        free((B));                                             \\\n"
        !           127:          "        (B) = NULL;                                            \\\n"
        !           128:          "      }                                                        \\\n"
        !           129:          "    }                                                          \\\n"
        !           130:          "  } while (0)\n\n",
        !           131:          headerfile);
        !           132:     fprintf (headerfile, "#endif\n\n");
        !           133:     logfile = fopen(STEM "_files", "w");
        !           134:     if (logfile == NULL)
        !           135:        err (1, "open " STEM "_files");
        !           136: }
        !           137:
        !           138: void
        !           139: close_generate (void)
        !           140: {
        !           141:     fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase);
        !           142:
        !           143:     fclose (headerfile);
        !           144:     fprintf (logfile, "\n");
        !           145:     fclose (logfile);
        !           146: }
        !           147:
        !           148: void
        !           149: generate_constant (const Symbol *s)
        !           150: {
        !           151:   fprintf (headerfile, "enum { %s = %d };\n\n",
        !           152:           s->gen_name, s->constant);
        !           153: }
        !           154:
        !           155: static void
        !           156: space(int level)
        !           157: {
        !           158:     while(level-- > 0)
        !           159:        fprintf(headerfile, "  ");
        !           160: }
        !           161:
        !           162: static void
        !           163: define_asn1 (int level, Type *t)
        !           164: {
        !           165:     switch (t->type) {
        !           166:     case TType:
        !           167:        space(level);
        !           168:        fprintf (headerfile, "%s", t->symbol->name);
        !           169:        break;
        !           170:     case TInteger:
        !           171:        space(level);
        !           172:        fprintf (headerfile, "INTEGER");
        !           173:        break;
        !           174:     case TUInteger:
        !           175:        space(level);
        !           176:        fprintf (headerfile, "UNSIGNED INTEGER");
        !           177:        break;
        !           178:     case TOctetString:
        !           179:        space(level);
        !           180:        fprintf (headerfile, "OCTET STRING");
        !           181:        break;
        !           182:     case TOID :
        !           183:        space(level);
        !           184:        fprintf(headerfile, "OBJECT IDENTIFIER");
        !           185:        break;
        !           186:     case TBitString: {
        !           187:        Member *m;
        !           188:        int tag = -1;
        !           189:
        !           190:        space(level);
        !           191:        fprintf (headerfile, "BIT STRING {\n");
        !           192:        for (m = t->members; m && m->val != tag; m = m->next) {
        !           193:            if (tag == -1)
        !           194:                tag = m->val;
        !           195:            space(level + 1);
        !           196:            fprintf (headerfile, "%s(%d)%s\n", m->name, m->val,
        !           197:                     m->next->val == tag?"":",");
        !           198:
        !           199:        }
        !           200:        space(level);
        !           201:        fprintf (headerfile, "}");
        !           202:        break;
        !           203:     }
        !           204:     case TEnumerated : {
        !           205:        Member *m;
        !           206:        int tag = -1;
        !           207:
        !           208:        space(level);
        !           209:        fprintf (headerfile, "ENUMERATED {\n");
        !           210:        for (m = t->members; m && m->val != tag; m = m->next) {
        !           211:            if (tag == -1)
        !           212:                tag = m->val;
        !           213:            space(level + 1);
        !           214:            fprintf (headerfile, "%s(%d)%s\n", m->name, m->val,
        !           215:                     m->next->val == tag?"":",");
        !           216:
        !           217:        }
        !           218:        space(level);
        !           219:        fprintf (headerfile, "}");
        !           220:        break;
        !           221:     }
        !           222:     case TSequence: {
        !           223:        Member *m;
        !           224:        int tag;
        !           225:        int max_width = 0;
        !           226:
        !           227:        space(level);
        !           228:        fprintf (headerfile, "SEQUENCE {\n");
        !           229:        for (m = t->members, tag = -1; m && m->val != tag; m = m->next) {
        !           230:            if (tag == -1)
        !           231:                tag = m->val;
        !           232:            if(strlen(m->name) + (m->val > 9) > max_width)
        !           233:                max_width = strlen(m->name) + (m->val > 9);
        !           234:        }
        !           235:        max_width += 3 + 2;
        !           236:        if(max_width < 16) max_width = 16;
        !           237:        for (m = t->members, tag = -1 ; m && m->val != tag; m = m->next) {
        !           238:            int width;
        !           239:            if (tag == -1)
        !           240:                tag = m->val;
        !           241:            space(level + 1);
        !           242:            fprintf(headerfile, "%s[%d]", m->name, m->val);
        !           243:            width = max_width - strlen(m->name) - 3 - (m->val > 9) - 2;
        !           244:            fprintf(headerfile, "%*s", width, "");
        !           245:            define_asn1(level + 1, m->type);
        !           246:            if(m->optional)
        !           247:                fprintf(headerfile, " OPTIONAL");
        !           248:            if(m->next->val != tag)
        !           249:                fprintf (headerfile, ",");
        !           250:            fprintf (headerfile, "\n");
        !           251:        }
        !           252:        space(level);
        !           253:        fprintf (headerfile, "}");
        !           254:        break;
        !           255:     }
        !           256:     case TSequenceOf: {
        !           257:        space(level);
        !           258:        fprintf (headerfile, "SEQUENCE OF ");
        !           259:        define_asn1 (0, t->subtype);
        !           260:        break;
        !           261:     }
        !           262:     case TGeneralizedTime:
        !           263:        space(level);
        !           264:        fprintf (headerfile, "GeneralizedTime");
        !           265:        break;
        !           266:     case TGeneralString:
        !           267:        space(level);
        !           268:        fprintf (headerfile, "GeneralString");
        !           269:        break;
        !           270:     case TApplication:
        !           271:        fprintf (headerfile, "[APPLICATION %d] ", t->application);
        !           272:        define_asn1 (level, t->subtype);
        !           273:        break;
        !           274:     default:
        !           275:        abort ();
        !           276:     }
        !           277: }
        !           278:
        !           279: static void
        !           280: define_type (int level, char *name, Type *t, int typedefp)
        !           281: {
        !           282:     switch (t->type) {
        !           283:     case TType:
        !           284:        space(level);
        !           285:        fprintf (headerfile, "%s %s;\n", t->symbol->gen_name, name);
        !           286:        break;
        !           287:     case TInteger:
        !           288:        space(level);
        !           289:         if(t->members == NULL) {
        !           290:             fprintf (headerfile, "int %s;\n", name);
        !           291:         } else {
        !           292:             Member *m;
        !           293:             int tag = -1;
        !           294:             fprintf (headerfile, "enum %s {\n", typedefp ? name : "");
        !           295:            for (m = t->members; m && m->val != tag; m = m->next) {
        !           296:                 if(tag == -1)
        !           297:                     tag = m->val;
        !           298:                 space (level + 1);
        !           299:                 fprintf(headerfile, "%s = %d%s\n", m->gen_name, m->val,
        !           300:                         m->next->val == tag ? "" : ",");
        !           301:             }
        !           302:             fprintf (headerfile, "} %s;\n", name);
        !           303:         }
        !           304:        break;
        !           305:     case TUInteger:
        !           306:        space(level);
        !           307:        fprintf (headerfile, "unsigned int %s;\n", name);
        !           308:        break;
        !           309:     case TOctetString:
        !           310:        space(level);
        !           311:        fprintf (headerfile, "octet_string %s;\n", name);
        !           312:        break;
        !           313:     case TOID :
        !           314:        space(level);
        !           315:        fprintf (headerfile, "oid %s;\n", name);
        !           316:        break;
        !           317:     case TBitString: {
        !           318:        Member *m;
        !           319:        Type i;
        !           320:        int tag = -1;
        !           321:
        !           322:        i.type = TUInteger;
        !           323:        space(level);
        !           324:        fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
        !           325:        for (m = t->members; m && m->val != tag; m = m->next) {
        !           326:            char *n;
        !           327:
        !           328:            asprintf (&n, "%s:1", m->gen_name);
        !           329:            define_type (level + 1, n, &i, FALSE);
        !           330:            free (n);
        !           331:            if (tag == -1)
        !           332:                tag = m->val;
        !           333:        }
        !           334:        space(level);
        !           335:        fprintf (headerfile, "} %s;\n\n", name);
        !           336:        break;
        !           337:     }
        !           338:     case TEnumerated: {
        !           339:        Member *m;
        !           340:        int tag = -1;
        !           341:
        !           342:        space(level);
        !           343:        fprintf (headerfile, "enum %s {\n", typedefp ? name : "");
        !           344:        for (m = t->members; m && m->val != tag; m = m->next) {
        !           345:            if (tag == -1)
        !           346:                tag = m->val;
        !           347:            space(level + 1);
        !           348:            fprintf (headerfile, "%s = %d%s\n", m->gen_name, m->val,
        !           349:                         m->next->val == tag ? "" : ",");
        !           350:        }
        !           351:        space(level);
        !           352:        fprintf (headerfile, "} %s;\n\n", name);
        !           353:        break;
        !           354:     }
        !           355:     case TSequence: {
        !           356:        Member *m;
        !           357:        int tag = -1;
        !           358:
        !           359:        space(level);
        !           360:        fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
        !           361:        for (m = t->members; m && m->val != tag; m = m->next) {
        !           362:            if (m->optional) {
        !           363:                char *n;
        !           364:
        !           365:                asprintf (&n, "*%s", m->gen_name);
        !           366:                define_type (level + 1, n, m->type, FALSE);
        !           367:                free (n);
        !           368:            } else
        !           369:                define_type (level + 1, m->gen_name, m->type, FALSE);
        !           370:            if (tag == -1)
        !           371:                tag = m->val;
        !           372:        }
        !           373:        space(level);
        !           374:        fprintf (headerfile, "} %s;\n", name);
        !           375:        break;
        !           376:     }
        !           377:     case TSequenceOf: {
        !           378:        Type i;
        !           379:
        !           380:        i.type = TUInteger;
        !           381:        i.application = 0;
        !           382:
        !           383:        space(level);
        !           384:        fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
        !           385:        define_type (level + 1, "len", &i, FALSE);
        !           386:        define_type (level + 1, "*val", t->subtype, FALSE);
        !           387:        space(level);
        !           388:        fprintf (headerfile, "} %s;\n", name);
        !           389:        break;
        !           390:     }
        !           391:     case TGeneralizedTime:
        !           392:        space(level);
        !           393:        fprintf (headerfile, "time_t %s;\n", name);
        !           394:        break;
        !           395:     case TGeneralString:
        !           396:        space(level);
        !           397:        fprintf (headerfile, "general_string %s;\n", name);
        !           398:        break;
        !           399:     case TApplication:
        !           400:        define_type (level, name, t->subtype, FALSE);
        !           401:        break;
        !           402:     default:
        !           403:        abort ();
        !           404:     }
        !           405: }
        !           406:
        !           407: static void
        !           408: generate_type_header (const Symbol *s)
        !           409: {
        !           410:     fprintf (headerfile, "/*\n");
        !           411:     fprintf (headerfile, "%s ::= ", s->name);
        !           412:     define_asn1 (0, s->type);
        !           413:     fprintf (headerfile, "\n*/\n\n");
        !           414:
        !           415:     fprintf (headerfile, "typedef ");
        !           416:     define_type (0, s->gen_name, s->type, TRUE);
        !           417:
        !           418:     fprintf (headerfile, "\n");
        !           419: }
        !           420:
        !           421:
        !           422: void
        !           423: generate_type (const Symbol *s)
        !           424: {
        !           425:     struct import *i;
        !           426:     char *filename;
        !           427:
        !           428:     asprintf (&filename, "%s_%s.x", STEM, s->gen_name);
        !           429:     codefile = fopen (filename, "w");
        !           430:     if (codefile == NULL)
        !           431:        err (1, "fopen %s", filename);
        !           432:     fprintf(logfile, "%s ", filename);
        !           433:     free(filename);
        !           434:     fprintf (codefile,
        !           435:             "/* Generated from %s */\n"
        !           436:             "/* Do not edit */\n\n"
        !           437:             "#include <stdio.h>\n"
        !           438:             "#include <stdlib.h>\n"
        !           439:             "#include <time.h>\n"
        !           440:             "#include <string.h>\n"
        !           441:             "#include <errno.h>\n",
        !           442:             orig_filename);
        !           443:
        !           444:     for (i = imports; i != NULL; i = i->next)
        !           445:        fprintf (codefile,
        !           446:                 "#include <%s_asn1.h>\n",
        !           447:                 i->module);
        !           448:     fprintf (codefile,
        !           449:             "#include <%s.h>\n",
        !           450:             headerbase);
        !           451:     fprintf (codefile,
        !           452:             "#include <asn1_err.h>\n"
        !           453:             "#include <der.h>\n"
        !           454:             "#include <parse_units.h>\n\n");
        !           455:     generate_type_header (s);
        !           456:     generate_type_encode (s);
        !           457:     generate_type_decode (s);
        !           458:     generate_type_free (s);
        !           459:     generate_type_length (s);
        !           460:     generate_type_copy (s);
        !           461:     generate_glue (s);
        !           462:     fprintf(headerfile, "\n\n");
        !           463:     fclose(codefile);
        !           464: }