first stange of asn1 table driven compiler

This commit is contained in:
Love Hornquist Astrand
2009-11-21 10:24:56 -08:00
parent ae56d6eede
commit b939943b07
35 changed files with 3572 additions and 240 deletions

View File

@@ -3,6 +3,8 @@
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
* Portions Copyright (c) 2009 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
@@ -35,12 +37,12 @@
RCSID("$Id$");
FILE *headerfile, *codefile, *logfile;
FILE *privheaderfile, *headerfile, *codefile, *logfile, *templatefile;
#define STEM "asn1"
static const char *orig_filename;
static char *header;
static char *privheader, *header, *template;
static const char *headerbase = STEM;
/*
@@ -66,6 +68,45 @@ add_import (const char *module)
fprintf (headerfile, "#include <%s_asn1.h>\n", module);
}
/*
* List of all exported symbols
*/
struct sexport {
const char *name;
int defined;
struct sexport *next;
};
static struct sexport *exports = NULL;
void
add_export (const char *name)
{
struct sexport *tmp = emalloc (sizeof(*tmp));
tmp->name = name;
tmp->next = exports;
exports = tmp;
}
int
is_export(const char *name)
{
struct sexport *tmp;
if (exports == NULL) /* no export list, all exported */
return 1;
for (tmp = exports; tmp != NULL; tmp = tmp->next) {
if (strcmp(tmp->name, name) == 0) {
tmp->defined = 1;
return 1;
}
}
return 0;
}
const char *
get_filename (void)
{
@@ -96,6 +137,23 @@ init_generate (const char *filename, const char *base)
err (1, "open %s", fn);
free(fn);
/* private header file */
asprintf(&privheader, "%s-priv.h", headerbase);
if (privheader == NULL)
errx(1, "malloc");
asprintf(&fn, "%s-priv.hx", headerbase);
if (fn == NULL)
errx(1, "malloc");
privheaderfile = fopen (fn, "w");
if (privheaderfile == NULL)
err (1, "open %s", fn);
free(fn);
/* template file */
asprintf(&template, "%s-template.c", headerbase);
if (template == NULL)
errx(1, "malloc");
fprintf (headerfile,
"/* Generated from %s */\n"
"/* Do not edit */\n\n",
@@ -182,6 +240,36 @@ init_generate (const char *filename, const char *base)
logfile = fopen(fn, "w");
if (logfile == NULL)
err (1, "open %s", fn);
/* if one code file, write into the one codefile */
if (one_code_file)
return;
templatefile = fopen (template, "w");
if (templatefile == NULL)
err (1, "open %s", template);
fprintf (templatefile,
"/* Generated from %s */\n"
"/* Do not edit */\n\n"
"#include <stdio.h>\n"
"#include <stdlib.h>\n"
"#include <time.h>\n"
"#include <string.h>\n"
"#include <errno.h>\n"
"#include <limits.h>\n"
"#include <krb5-types.h>\n",
filename);
fprintf (templatefile,
"#include <%s>\n"
"#include <%s>\n"
"#include <der.h>\n"
"#include <der-private.h>\n"
"#include <asn1-template.h>\n",
header, privheader);
}
void
@@ -190,6 +278,8 @@ close_generate (void)
fprintf (headerfile, "#endif /* __%s_h__ */\n", headerbase);
fclose (headerfile);
fclose (privheaderfile);
fclose (templatefile);
fprintf (logfile, "\n");
fclose (logfile);
}
@@ -265,11 +355,14 @@ generate_header_of_codefile(const char *name)
orig_filename);
fprintf (codefile,
"#include <%s.h>\n",
headerbase);
"#include <%s>\n"
"#include <%s>\n",
header, privheader);
fprintf (codefile,
"#include <asn1_err.h>\n"
"#include <der.h>\n"
"#include <der-private.h>\n"
"#include <asn1-template.h>\n"
"#include <parse_units.h>\n\n");
}
@@ -328,8 +421,6 @@ generate_constant (const Symbol *s)
}
fprintf (headerfile, "} */\n");
fprintf (headerfile, "const heim_oid *oid_%s(void);\n",
s->gen_name);
fprintf (headerfile,
"extern const heim_oid asn1_oid_%s;\n\n",
s->gen_name);
@@ -346,12 +437,6 @@ generate_constant (const Symbol *s)
"{ %d, oid_%s_variable_num };\n\n",
s->gen_name, len, s->gen_name);
fprintf (codefile, "const heim_oid *oid_%s(void)\n"
"{\n"
"return &asn1_oid_%s;\n"
"}\n\n",
s->gen_name, s->gen_name);
free(list);
if (!one_code_file)
@@ -364,6 +449,33 @@ generate_constant (const Symbol *s)
}
}
int
is_primitive_type(int type)
{
switch(type) {
case TInteger:
case TBoolean:
case TOctetString:
case TBitString:
case TEnumerated:
case TGeneralizedTime:
case TGeneralString:
case TTeletexString:
case TOID:
case TUTCTime:
case TUTF8String:
case TPrintableString:
case TIA5String:
case TBMPString:
case TUniversalString:
case TVisibleString:
case TNull:
return 1;
default:
return 0;
}
}
static void
space(int level)
{
@@ -550,8 +662,24 @@ define_asn1 (int level, Type *t)
}
static void
define_type (int level, const char *name, Type *t, int typedefp, int preservep)
getnewbasename(char **newbasename, int typedefp, const char *basename, const char *name)
{
if (typedefp)
*newbasename = strdup(name);
else {
if (name[0] == '*')
name++;
asprintf(newbasename, "%s_%s", basename, name);
}
if (*newbasename == NULL)
err(1, "malloc");
}
static void
define_type (int level, const char *name, const char *basename, Type *t, int typedefp, int preservep)
{
char *newbasename = NULL;
switch (t->type) {
case TType:
space(level);
@@ -602,16 +730,37 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
if(ASN1_TAILQ_EMPTY(t->members))
fprintf (headerfile, "heim_bit_string %s;\n", name);
else {
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
int pos = 0;
getnewbasename(&newbasename, typedefp, basename, name);
fprintf (headerfile, "struct %s {\n", newbasename);
ASN1_TAILQ_FOREACH(m, t->members, members) {
char *n;
/* pad unused */
while (pos < m->val) {
asprintf (&n, "_unused%d:1;", pos);
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
free(n);
pos++;
}
asprintf (&n, "%s:1", m->gen_name);
if (n == NULL)
errx(1, "malloc");
define_type (level + 1, n, &i, FALSE, FALSE);
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
free (n);
pos++;
}
/* pad to 32 elements */
while (pos < 32) {
char *n;
asprintf (&n, "_unused%d:1;", pos);
define_type (level + 1, n, newbasename, &i, FALSE, FALSE);
free(n);
pos++;
}
space(level);
fprintf (headerfile, "} %s;\n\n", name);
}
@@ -638,8 +787,10 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
case TSequence: {
Member *m;
getnewbasename(&newbasename, typedefp, basename, name);
space(level);
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
fprintf (headerfile, "struct %s {\n", newbasename);
if (t->type == TSequence && preservep) {
space(level + 1);
fprintf(headerfile, "heim_octet_string _save;\n");
@@ -653,10 +804,10 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
asprintf (&n, "*%s", m->gen_name);
if (n == NULL)
errx(1, "malloc");
define_type (level + 1, n, m->type, FALSE, FALSE);
define_type (level + 1, n, newbasename, m->type, FALSE, FALSE);
free (n);
} else
define_type (level + 1, m->gen_name, m->type, FALSE, FALSE);
define_type (level + 1, m->gen_name, newbasename, m->type, FALSE, FALSE);
}
space(level);
fprintf (headerfile, "} %s;\n", name);
@@ -667,15 +818,17 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
Type i;
struct range range = { 0, INT_MAX };
getnewbasename(&newbasename, typedefp, basename, name);
i.type = TInteger;
i.range = &range;
i.members = NULL;
i.constraint = NULL;
space(level);
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
define_type (level + 1, "len", &i, FALSE, FALSE);
define_type (level + 1, "*val", t->subtype, FALSE, FALSE);
fprintf (headerfile, "struct %s {\n", newbasename);
define_type (level + 1, "len", newbasename, &i, FALSE, FALSE);
define_type (level + 1, "*val", newbasename, t->subtype, FALSE, FALSE);
space(level);
fprintf (headerfile, "} %s;\n", name);
break;
@@ -693,14 +846,16 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
fprintf (headerfile, "heim_general_string %s;\n", name);
break;
case TTag:
define_type (level, name, t->subtype, typedefp, preservep);
define_type (level, name, basename, t->subtype, typedefp, preservep);
break;
case TChoice: {
int first = 1;
Member *m;
getnewbasename(&newbasename, typedefp, basename, name);
space(level);
fprintf (headerfile, "struct %s {\n", typedefp ? name : "");
fprintf (headerfile, "struct %s {\n", newbasename);
if (preservep) {
space(level + 1);
fprintf(headerfile, "heim_octet_string _save;\n");
@@ -737,10 +892,10 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
asprintf (&n, "*%s", m->gen_name);
if (n == NULL)
errx(1, "malloc");
define_type (level + 2, n, m->type, FALSE, FALSE);
define_type (level + 2, n, newbasename, m->type, FALSE, FALSE);
free (n);
} else
define_type (level + 2, m->gen_name, m->type, FALSE, FALSE);
define_type (level + 2, m->gen_name, newbasename, m->type, FALSE, FALSE);
}
space(level + 1);
fprintf (headerfile, "} u;\n");
@@ -787,6 +942,8 @@ define_type (int level, const char *name, Type *t, int typedefp, int preservep)
default:
abort ();
}
if (newbasename)
free(newbasename);
}
static void
@@ -800,27 +957,61 @@ generate_type_header (const Symbol *s)
fprintf (headerfile, "\n*/\n\n");
fprintf (headerfile, "typedef ");
define_type (0, s->gen_name, s->type, TRUE, preservep);
define_type (0, s->gen_name, s->gen_name, s->type, TRUE, preservep);
fprintf (headerfile, "\n");
}
void
generate_type (const Symbol *s)
{
FILE *h;
if (!one_code_file)
generate_header_of_codefile(s->gen_name);
generate_type_header (s);
generate_type_encode (s);
generate_type_decode (s);
generate_type_free (s);
generate_type_length (s);
generate_type_copy (s);
if (template_flag)
generate_template(s);
if (template_flag == 0 || is_template_compat(s) == 0) {
generate_type_encode (s);
generate_type_decode (s);
generate_type_free (s);
generate_type_length (s);
generate_type_copy (s);
}
generate_type_seq (s);
generate_glue (s->type, s->gen_name);
fprintf(headerfile, "\n\n");
/* generate prototypes */
if (is_export(s->name))
h = headerfile;
else
h = privheaderfile;
fprintf (h,
"int "
"decode_%s(const unsigned char *, size_t, %s *, size_t *);\n",
s->gen_name, s->gen_name);
fprintf (h,
"int "
"encode_%s(unsigned char *, size_t, const %s *, size_t *);\n",
s->gen_name, s->gen_name);
fprintf (h,
"size_t length_%s(const %s *);\n",
s->gen_name, s->gen_name);
fprintf (h,
"int copy_%s (const %s *, %s *);\n",
s->gen_name, s->gen_name, s->gen_name);
fprintf (h,
"void free_%s (%s *);\n",
s->gen_name, s->gen_name);
fprintf(h, "\n\n");
if (!one_code_file) {
fprintf(codefile, "\n\n");