xref: /freebsd-src/crypto/heimdal/lib/asn1/gen.c (revision 219b6e442308d5353b2af5f0771ce9b887b70754)
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 = &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 = &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