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