1ae771770SStanislav Sedov /* 2ae771770SStanislav Sedov * Copyright (c) 1997 - 2005 Kungliga Tekniska H�gskolan 3ae771770SStanislav Sedov * (Royal Institute of Technology, Stockholm, Sweden). 4ae771770SStanislav Sedov * All rights reserved. 5ae771770SStanislav Sedov * 6ae771770SStanislav Sedov * Portions Copyright (c) 2009 Apple Inc. All rights reserved. 7ae771770SStanislav Sedov * 8ae771770SStanislav Sedov * Redistribution and use in source and binary forms, with or without 9ae771770SStanislav Sedov * modification, are permitted provided that the following conditions 10ae771770SStanislav Sedov * are met: 11ae771770SStanislav Sedov * 12ae771770SStanislav Sedov * 1. Redistributions of source code must retain the above copyright 13ae771770SStanislav Sedov * notice, this list of conditions and the following disclaimer. 14ae771770SStanislav Sedov * 15ae771770SStanislav Sedov * 2. Redistributions in binary form must reproduce the above copyright 16ae771770SStanislav Sedov * notice, this list of conditions and the following disclaimer in the 17ae771770SStanislav Sedov * documentation and/or other materials provided with the distribution. 18ae771770SStanislav Sedov * 19ae771770SStanislav Sedov * 3. Neither the name of the Institute nor the names of its contributors 20ae771770SStanislav Sedov * may be used to endorse or promote products derived from this software 21ae771770SStanislav Sedov * without specific prior written permission. 22ae771770SStanislav Sedov * 23ae771770SStanislav Sedov * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 24ae771770SStanislav Sedov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25ae771770SStanislav Sedov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26ae771770SStanislav Sedov * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 27ae771770SStanislav Sedov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28ae771770SStanislav Sedov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29ae771770SStanislav Sedov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30ae771770SStanislav Sedov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31ae771770SStanislav Sedov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32ae771770SStanislav Sedov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33ae771770SStanislav Sedov * SUCH DAMAGE. 34ae771770SStanislav Sedov */ 35ae771770SStanislav Sedov 36ae771770SStanislav Sedov #include "gen_locl.h" 37ae771770SStanislav Sedov 38ae771770SStanislav Sedov static const char *symbol_name(const char *, const Type *); 39ae771770SStanislav Sedov static void generate_template_type(const char *, const char **, const char *, const char *, const char *, 40ae771770SStanislav Sedov Type *, int, int, int); 41ae771770SStanislav Sedov 42ae771770SStanislav Sedov static const char * 43ae771770SStanislav Sedov ttype_symbol(const char *basename, const Type *t) 44ae771770SStanislav Sedov { 45ae771770SStanislav Sedov return t->symbol->gen_name; 46ae771770SStanislav Sedov } 47ae771770SStanislav Sedov 48ae771770SStanislav Sedov static const char * 49ae771770SStanislav Sedov integer_symbol(const char *basename, const Type *t) 50ae771770SStanislav Sedov { 51ae771770SStanislav Sedov if (t->members) 52ae771770SStanislav Sedov return "int"; /* XXX enum foo */ 53ae771770SStanislav Sedov else if (t->range == NULL) 54ae771770SStanislav Sedov return "heim_integer"; 55*1b748759SDimitry Andric else if (t->range->min < INT_MIN && t->range->max <= INT64_MAX) 56*1b748759SDimitry Andric return "int64_t"; 57*1b748759SDimitry Andric else if (t->range->min >= 0 && t->range->max > UINT_MAX) 58*1b748759SDimitry Andric return "uint64_t"; 59*1b748759SDimitry Andric else if (t->range->min >= INT_MIN && t->range->max <= INT_MAX) 60ae771770SStanislav Sedov return "int"; 61*1b748759SDimitry Andric else if (t->range->min >= 0 && t->range->max <= UINT_MAX) 62ae771770SStanislav Sedov return "unsigned"; 63ae771770SStanislav Sedov else { 64ae771770SStanislav Sedov abort(); 65ae771770SStanislav Sedov UNREACHABLE(return NULL); 66ae771770SStanislav Sedov } 67ae771770SStanislav Sedov } 68ae771770SStanislav Sedov 69ae771770SStanislav Sedov static const char * 70ae771770SStanislav Sedov boolean_symbol(const char *basename, const Type *t) 71ae771770SStanislav Sedov { 72ae771770SStanislav Sedov return "int"; 73ae771770SStanislav Sedov } 74ae771770SStanislav Sedov 75ae771770SStanislav Sedov 76ae771770SStanislav Sedov static const char * 77ae771770SStanislav Sedov octetstring_symbol(const char *basename, const Type *t) 78ae771770SStanislav Sedov { 79ae771770SStanislav Sedov return "heim_octet_string"; 80ae771770SStanislav Sedov } 81ae771770SStanislav Sedov 82ae771770SStanislav Sedov static const char * 83ae771770SStanislav Sedov sequence_symbol(const char *basename, const Type *t) 84ae771770SStanislav Sedov { 85ae771770SStanislav Sedov return basename; 86ae771770SStanislav Sedov } 87ae771770SStanislav Sedov 88ae771770SStanislav Sedov static const char * 89ae771770SStanislav Sedov time_symbol(const char *basename, const Type *t) 90ae771770SStanislav Sedov { 91ae771770SStanislav Sedov return "time_t"; 92ae771770SStanislav Sedov } 93ae771770SStanislav Sedov 94ae771770SStanislav Sedov static const char * 95ae771770SStanislav Sedov tag_symbol(const char *basename, const Type *t) 96ae771770SStanislav Sedov { 97ae771770SStanislav Sedov return symbol_name(basename, t->subtype); 98ae771770SStanislav Sedov } 99ae771770SStanislav Sedov 100ae771770SStanislav Sedov static const char * 101ae771770SStanislav Sedov generalstring_symbol(const char *basename, const Type *t) 102ae771770SStanislav Sedov { 103ae771770SStanislav Sedov return "heim_general_string"; 104ae771770SStanislav Sedov } 105ae771770SStanislav Sedov 106ae771770SStanislav Sedov static const char * 107ae771770SStanislav Sedov printablestring_symbol(const char *basename, const Type *t) 108ae771770SStanislav Sedov { 109ae771770SStanislav Sedov return "heim_printable_string"; 110ae771770SStanislav Sedov } 111ae771770SStanislav Sedov 112ae771770SStanislav Sedov static const char * 113ae771770SStanislav Sedov ia5string_symbol(const char *basename, const Type *t) 114ae771770SStanislav Sedov { 115ae771770SStanislav Sedov return "heim_ia5_string"; 116ae771770SStanislav Sedov } 117ae771770SStanislav Sedov 118ae771770SStanislav Sedov static const char * 119ae771770SStanislav Sedov visiblestring_symbol(const char *basename, const Type *t) 120ae771770SStanislav Sedov { 121ae771770SStanislav Sedov return "heim_visible_string"; 122ae771770SStanislav Sedov } 123ae771770SStanislav Sedov 124ae771770SStanislav Sedov static const char * 125ae771770SStanislav Sedov utf8string_symbol(const char *basename, const Type *t) 126ae771770SStanislav Sedov { 127ae771770SStanislav Sedov return "heim_utf8_string"; 128ae771770SStanislav Sedov } 129ae771770SStanislav Sedov 130ae771770SStanislav Sedov static const char * 131ae771770SStanislav Sedov bmpstring_symbol(const char *basename, const Type *t) 132ae771770SStanislav Sedov { 133ae771770SStanislav Sedov return "heim_bmp_string"; 134ae771770SStanislav Sedov } 135ae771770SStanislav Sedov 136ae771770SStanislav Sedov static const char * 137ae771770SStanislav Sedov universalstring_symbol(const char *basename, const Type *t) 138ae771770SStanislav Sedov { 139ae771770SStanislav Sedov return "heim_universal_string"; 140ae771770SStanislav Sedov } 141ae771770SStanislav Sedov 142ae771770SStanislav Sedov static const char * 143ae771770SStanislav Sedov oid_symbol(const char *basename, const Type *t) 144ae771770SStanislav Sedov { 145ae771770SStanislav Sedov return "heim_oid"; 146ae771770SStanislav Sedov } 147ae771770SStanislav Sedov 148ae771770SStanislav Sedov static const char * 149ae771770SStanislav Sedov bitstring_symbol(const char *basename, const Type *t) 150ae771770SStanislav Sedov { 151ae771770SStanislav Sedov if (t->members) 152ae771770SStanislav Sedov return basename; 153ae771770SStanislav Sedov return "heim_bit_string"; 154ae771770SStanislav Sedov } 155ae771770SStanislav Sedov 156ae771770SStanislav Sedov 157ae771770SStanislav Sedov 158ae771770SStanislav Sedov struct { 159ae771770SStanislav Sedov enum typetype type; 160ae771770SStanislav Sedov const char *(*symbol_name)(const char *, const Type *); 161ae771770SStanislav Sedov int is_struct; 162ae771770SStanislav Sedov } types[] = { 163ae771770SStanislav Sedov { TBMPString, bmpstring_symbol, 0 }, 164ae771770SStanislav Sedov { TBitString, bitstring_symbol, 0 }, 165ae771770SStanislav Sedov { TBoolean, boolean_symbol, 0 }, 166ae771770SStanislav Sedov { TGeneralString, generalstring_symbol, 0 }, 167ae771770SStanislav Sedov { TGeneralizedTime, time_symbol, 0 }, 168ae771770SStanislav Sedov { TIA5String, ia5string_symbol, 0 }, 169ae771770SStanislav Sedov { TInteger, integer_symbol, 0 }, 170ae771770SStanislav Sedov { TOID, oid_symbol, 0 }, 171ae771770SStanislav Sedov { TOctetString, octetstring_symbol, 0 }, 172ae771770SStanislav Sedov { TPrintableString, printablestring_symbol, 0 }, 173ae771770SStanislav Sedov { TSequence, sequence_symbol, 1 }, 174ae771770SStanislav Sedov { TSequenceOf, tag_symbol, 1 }, 175ae771770SStanislav Sedov { TSetOf, tag_symbol, 1 }, 176ae771770SStanislav Sedov { TTag, tag_symbol, 1 }, 177ae771770SStanislav Sedov { TType, ttype_symbol, 1 }, 178ae771770SStanislav Sedov { TUTCTime, time_symbol, 0 }, 179ae771770SStanislav Sedov { TUniversalString, universalstring_symbol, 0 }, 180ae771770SStanislav Sedov { TVisibleString, visiblestring_symbol, 0 }, 181ae771770SStanislav Sedov { TUTF8String, utf8string_symbol, 0 }, 182ae771770SStanislav Sedov { TChoice, sequence_symbol, 1 }, 183ae771770SStanislav Sedov { TNull, integer_symbol, 1 } 184ae771770SStanislav Sedov }; 185ae771770SStanislav Sedov 186ae771770SStanislav Sedov static FILE * 187ae771770SStanislav Sedov get_code_file(void) 188ae771770SStanislav Sedov { 189ae771770SStanislav Sedov if (!one_code_file) 190ae771770SStanislav Sedov return templatefile; 191ae771770SStanislav Sedov return codefile; 192ae771770SStanislav Sedov } 193ae771770SStanislav Sedov 194ae771770SStanislav Sedov 195ae771770SStanislav Sedov static int 196ae771770SStanislav Sedov is_supported_type_p(const Type *t) 197ae771770SStanislav Sedov { 198ae771770SStanislav Sedov size_t i; 199ae771770SStanislav Sedov 200ae771770SStanislav Sedov for (i = 0; i < sizeof(types)/sizeof(types[0]); i++) 201ae771770SStanislav Sedov if (t->type == types[i].type) 202ae771770SStanislav Sedov return 1; 203ae771770SStanislav Sedov return 0; 204ae771770SStanislav Sedov } 205ae771770SStanislav Sedov 206ae771770SStanislav Sedov int 207ae771770SStanislav Sedov is_template_compat (const Symbol *s) 208ae771770SStanislav Sedov { 209ae771770SStanislav Sedov return is_supported_type_p(s->type); 210ae771770SStanislav Sedov } 211ae771770SStanislav Sedov 212ae771770SStanislav Sedov static const char * 213ae771770SStanislav Sedov symbol_name(const char *basename, const Type *t) 214ae771770SStanislav Sedov { 215ae771770SStanislav Sedov size_t i; 216ae771770SStanislav Sedov 217ae771770SStanislav Sedov for (i = 0; i < sizeof(types)/sizeof(types[0]); i++) 218ae771770SStanislav Sedov if (t->type == types[i].type) 219ae771770SStanislav Sedov return (types[i].symbol_name)(basename, t); 220ae771770SStanislav Sedov printf("unknown der type: %d\n", t->type); 221ae771770SStanislav Sedov exit(1); 222ae771770SStanislav Sedov } 223ae771770SStanislav Sedov 224ae771770SStanislav Sedov 225ae771770SStanislav Sedov static char * 226ae771770SStanislav Sedov partial_offset(const char *basetype, const char *name, int need_offset) 227ae771770SStanislav Sedov { 228ae771770SStanislav Sedov char *str; 229ae771770SStanislav Sedov if (name == NULL || need_offset == 0) 230ae771770SStanislav Sedov return strdup("0"); 231ae771770SStanislav Sedov if (asprintf(&str, "offsetof(struct %s, %s)", basetype, name) < 0 || str == NULL) 232ae771770SStanislav Sedov errx(1, "malloc"); 233ae771770SStanislav Sedov return str; 234ae771770SStanislav Sedov } 235ae771770SStanislav Sedov 236ae771770SStanislav Sedov struct template { 237ae771770SStanislav Sedov char *line; 238ae771770SStanislav Sedov char *tt; 239ae771770SStanislav Sedov char *offset; 240ae771770SStanislav Sedov char *ptr; 241ae771770SStanislav Sedov ASN1_TAILQ_ENTRY(template) members; 242ae771770SStanislav Sedov }; 243ae771770SStanislav Sedov 244ae771770SStanislav Sedov ASN1_TAILQ_HEAD(templatehead, template); 245ae771770SStanislav Sedov 246ae771770SStanislav Sedov struct tlist { 247ae771770SStanislav Sedov char *name; 248ae771770SStanislav Sedov char *header; 249ae771770SStanislav Sedov struct templatehead template; 250ae771770SStanislav Sedov ASN1_TAILQ_ENTRY(tlist) tmembers; 251ae771770SStanislav Sedov }; 252ae771770SStanislav Sedov 253ae771770SStanislav Sedov ASN1_TAILQ_HEAD(tlisthead, tlist); 254ae771770SStanislav Sedov 255ae771770SStanislav Sedov static void tlist_header(struct tlist *, const char *, ...) __attribute__((__format__(__printf__, 2, 3))); 256ae771770SStanislav Sedov static struct template * 257ae771770SStanislav Sedov add_line(struct templatehead *, const char *, ...) __attribute__((__format__(__printf__, 2, 3))); 258ae771770SStanislav Sedov static int tlist_cmp(const struct tlist *, const struct tlist *); 259ae771770SStanislav Sedov 260ae771770SStanislav Sedov static void add_line_pointer(struct templatehead *, const char *, const char *, const char *, ...) 261ae771770SStanislav Sedov __attribute__((__format__(__printf__, 4, 5))); 262ae771770SStanislav Sedov 263ae771770SStanislav Sedov 264ae771770SStanislav Sedov static struct tlisthead tlistmaster = ASN1_TAILQ_HEAD_INITIALIZER(tlistmaster); 265ae771770SStanislav Sedov static unsigned long numdups = 0; 266ae771770SStanislav Sedov 267ae771770SStanislav Sedov static struct tlist * 268ae771770SStanislav Sedov tlist_new(const char *name) 269ae771770SStanislav Sedov { 270ae771770SStanislav Sedov struct tlist *tl = calloc(1, sizeof(*tl)); 271ae771770SStanislav Sedov tl->name = strdup(name); 272ae771770SStanislav Sedov ASN1_TAILQ_INIT(&tl->template); 273ae771770SStanislav Sedov return tl; 274ae771770SStanislav Sedov } 275ae771770SStanislav Sedov 276ae771770SStanislav Sedov static void 277ae771770SStanislav Sedov tlist_header(struct tlist *t, const char *fmt, ...) 278ae771770SStanislav Sedov { 279ae771770SStanislav Sedov va_list ap; 280ae771770SStanislav Sedov va_start(ap, fmt); 281ae771770SStanislav Sedov if (vasprintf(&t->header, fmt, ap) < 0 || t->header == NULL) 282ae771770SStanislav Sedov errx(1, "malloc"); 283ae771770SStanislav Sedov va_end(ap); 284ae771770SStanislav Sedov } 285ae771770SStanislav Sedov 286ae771770SStanislav Sedov static unsigned long 287ae771770SStanislav Sedov tlist_count(struct tlist *tl) 288ae771770SStanislav Sedov { 289ae771770SStanislav Sedov unsigned int count = 0; 290ae771770SStanislav Sedov struct template *q; 291ae771770SStanislav Sedov 292ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(q, &tl->template, members) { 293ae771770SStanislav Sedov count++; 294ae771770SStanislav Sedov } 295ae771770SStanislav Sedov return count; 296ae771770SStanislav Sedov } 297ae771770SStanislav Sedov 298ae771770SStanislav Sedov static void 299ae771770SStanislav Sedov tlist_add(struct tlist *tl) 300ae771770SStanislav Sedov { 301ae771770SStanislav Sedov ASN1_TAILQ_INSERT_TAIL(&tlistmaster, tl, tmembers); 302ae771770SStanislav Sedov } 303ae771770SStanislav Sedov 304ae771770SStanislav Sedov static void 305ae771770SStanislav Sedov tlist_print(struct tlist *tl) 306ae771770SStanislav Sedov { 307ae771770SStanislav Sedov struct template *q; 308ae771770SStanislav Sedov unsigned int i = 1; 309ae771770SStanislav Sedov FILE *f = get_code_file(); 310ae771770SStanislav Sedov 311ae771770SStanislav Sedov fprintf(f, "static const struct asn1_template asn1_%s[] = {\n", tl->name); 312ae771770SStanislav Sedov fprintf(f, "/* 0 */ %s,\n", tl->header); 313ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(q, &tl->template, members) { 314ae771770SStanislav Sedov int last = (ASN1_TAILQ_LAST(&tl->template, templatehead) == q); 315ae771770SStanislav Sedov fprintf(f, "/* %lu */ %s%s\n", (unsigned long)i++, q->line, last ? "" : ","); 316ae771770SStanislav Sedov } 317ae771770SStanislav Sedov fprintf(f, "};\n"); 318ae771770SStanislav Sedov } 319ae771770SStanislav Sedov 320ae771770SStanislav Sedov static struct tlist * 321ae771770SStanislav Sedov tlist_find_by_name(const char *name) 322ae771770SStanislav Sedov { 323ae771770SStanislav Sedov struct tlist *ql; 324ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(ql, &tlistmaster, tmembers) { 325ae771770SStanislav Sedov if (strcmp(ql->name, name) == 0) 326ae771770SStanislav Sedov return ql; 327ae771770SStanislav Sedov } 328ae771770SStanislav Sedov return NULL; 329ae771770SStanislav Sedov } 330ae771770SStanislav Sedov 331ae771770SStanislav Sedov static int 332ae771770SStanislav Sedov tlist_cmp_name(const char *tname, const char *qname) 333ae771770SStanislav Sedov { 334ae771770SStanislav Sedov struct tlist *tl = tlist_find_by_name(tname); 335ae771770SStanislav Sedov struct tlist *ql = tlist_find_by_name(qname); 336ae771770SStanislav Sedov return tlist_cmp(tl, ql); 337ae771770SStanislav Sedov } 338ae771770SStanislav Sedov 339ae771770SStanislav Sedov static int 340ae771770SStanislav Sedov tlist_cmp(const struct tlist *tl, const struct tlist *ql) 341ae771770SStanislav Sedov { 342ae771770SStanislav Sedov int ret; 343ae771770SStanislav Sedov struct template *t, *q; 344ae771770SStanislav Sedov 345ae771770SStanislav Sedov ret = strcmp(tl->header, ql->header); 346ae771770SStanislav Sedov if (ret) return ret; 347ae771770SStanislav Sedov 348ae771770SStanislav Sedov q = ASN1_TAILQ_FIRST(&ql->template); 349ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(t, &tl->template, members) { 350ae771770SStanislav Sedov if (q == NULL) return 1; 351ae771770SStanislav Sedov 352ae771770SStanislav Sedov if (t->ptr == NULL || q->ptr == NULL) { 353ae771770SStanislav Sedov ret = strcmp(t->line, q->line); 354ae771770SStanislav Sedov if (ret) return ret; 355ae771770SStanislav Sedov } else { 356ae771770SStanislav Sedov ret = strcmp(t->tt, q->tt); 357ae771770SStanislav Sedov if (ret) return ret; 358ae771770SStanislav Sedov 359ae771770SStanislav Sedov ret = strcmp(t->offset, q->offset); 360ae771770SStanislav Sedov if (ret) return ret; 361ae771770SStanislav Sedov 362ae771770SStanislav Sedov if ((ret = strcmp(t->ptr, q->ptr)) != 0 || 363ae771770SStanislav Sedov (ret = tlist_cmp_name(t->ptr, q->ptr)) != 0) 364ae771770SStanislav Sedov return ret; 365ae771770SStanislav Sedov } 366ae771770SStanislav Sedov q = ASN1_TAILQ_NEXT(q, members); 367ae771770SStanislav Sedov } 368ae771770SStanislav Sedov if (q != NULL) return -1; 369ae771770SStanislav Sedov return 0; 370ae771770SStanislav Sedov } 371ae771770SStanislav Sedov 372ae771770SStanislav Sedov 373ae771770SStanislav Sedov static const char * 374ae771770SStanislav Sedov tlist_find_dup(const struct tlist *tl) 375ae771770SStanislav Sedov { 376ae771770SStanislav Sedov struct tlist *ql; 377ae771770SStanislav Sedov 378ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(ql, &tlistmaster, tmembers) { 379ae771770SStanislav Sedov if (tlist_cmp(ql, tl) == 0) { 380ae771770SStanislav Sedov numdups++; 381ae771770SStanislav Sedov return ql->name; 382ae771770SStanislav Sedov } 383ae771770SStanislav Sedov } 384ae771770SStanislav Sedov return NULL; 385ae771770SStanislav Sedov } 386ae771770SStanislav Sedov 387ae771770SStanislav Sedov 388ae771770SStanislav Sedov /* 389ae771770SStanislav Sedov * 390ae771770SStanislav Sedov */ 391ae771770SStanislav Sedov 392ae771770SStanislav Sedov static struct template * 393ae771770SStanislav Sedov add_line(struct templatehead *t, const char *fmt, ...) 394ae771770SStanislav Sedov { 395ae771770SStanislav Sedov struct template *q = calloc(1, sizeof(*q)); 396ae771770SStanislav Sedov va_list ap; 397ae771770SStanislav Sedov va_start(ap, fmt); 398ae771770SStanislav Sedov if (vasprintf(&q->line, fmt, ap) < 0 || q->line == NULL) 399ae771770SStanislav Sedov errx(1, "malloc"); 400ae771770SStanislav Sedov va_end(ap); 401ae771770SStanislav Sedov ASN1_TAILQ_INSERT_TAIL(t, q, members); 402ae771770SStanislav Sedov return q; 403ae771770SStanislav Sedov } 404ae771770SStanislav Sedov 405ae771770SStanislav Sedov static void 406ae771770SStanislav Sedov add_line_pointer(struct templatehead *t, 407ae771770SStanislav Sedov const char *ptr, 408ae771770SStanislav Sedov const char *offset, 409ae771770SStanislav Sedov const char *ttfmt, 410ae771770SStanislav Sedov ...) 411ae771770SStanislav Sedov { 412ae771770SStanislav Sedov struct template *q; 413ae771770SStanislav Sedov va_list ap; 414ae771770SStanislav Sedov char *tt = NULL; 415ae771770SStanislav Sedov 416ae771770SStanislav Sedov va_start(ap, ttfmt); 417ae771770SStanislav Sedov if (vasprintf(&tt, ttfmt, ap) < 0 || tt == NULL) 418ae771770SStanislav Sedov errx(1, "malloc"); 419ae771770SStanislav Sedov va_end(ap); 420ae771770SStanislav Sedov 421ae771770SStanislav Sedov q = add_line(t, "{ %s, %s, asn1_%s }", tt, offset, ptr); 422ae771770SStanislav Sedov q->tt = tt; 423ae771770SStanislav Sedov q->offset = strdup(offset); 424ae771770SStanislav Sedov q->ptr = strdup(ptr); 425ae771770SStanislav Sedov } 426ae771770SStanislav Sedov 427ae771770SStanislav Sedov static int 428ae771770SStanislav Sedov use_extern(const Symbol *s) 429ae771770SStanislav Sedov { 430ae771770SStanislav Sedov if (s->type == NULL) 431ae771770SStanislav Sedov return 1; 432ae771770SStanislav Sedov return 0; 433ae771770SStanislav Sedov } 434ae771770SStanislav Sedov 435ae771770SStanislav Sedov static int 436ae771770SStanislav Sedov is_struct(Type *t, int isstruct) 437ae771770SStanislav Sedov { 438ae771770SStanislav Sedov size_t i; 439ae771770SStanislav Sedov 440ae771770SStanislav Sedov if (t->type == TType) 441ae771770SStanislav Sedov return 0; 442ae771770SStanislav Sedov if (t->type == TSequence || t->type == TSet || t->type == TChoice) 443ae771770SStanislav Sedov return 1; 444ae771770SStanislav Sedov if (t->type == TTag) 445ae771770SStanislav Sedov return is_struct(t->subtype, isstruct); 446ae771770SStanislav Sedov 447ae771770SStanislav Sedov for (i = 0; i < sizeof(types)/sizeof(types[0]); i++) { 448ae771770SStanislav Sedov if (t->type == types[i].type) { 449ae771770SStanislav Sedov if (types[i].is_struct == 0) 450ae771770SStanislav Sedov return 0; 451ae771770SStanislav Sedov else 452ae771770SStanislav Sedov break; 453ae771770SStanislav Sedov } 454ae771770SStanislav Sedov } 455ae771770SStanislav Sedov 456ae771770SStanislav Sedov return isstruct; 457ae771770SStanislav Sedov } 458ae771770SStanislav Sedov 459ae771770SStanislav Sedov static const Type * 460ae771770SStanislav Sedov compact_tag(const Type *t) 461ae771770SStanislav Sedov { 462ae771770SStanislav Sedov while (t->type == TTag) 463ae771770SStanislav Sedov t = t->subtype; 464ae771770SStanislav Sedov return t; 465ae771770SStanislav Sedov } 466ae771770SStanislav Sedov 467ae771770SStanislav Sedov static void 468ae771770SStanislav Sedov template_members(struct templatehead *temp, const char *basetype, const char *name, const Type *t, int optional, int isstruct, int need_offset) 469ae771770SStanislav Sedov { 470ae771770SStanislav Sedov char *poffset = NULL; 471ae771770SStanislav Sedov 472ae771770SStanislav Sedov if (optional && t->type != TTag && t->type != TType) 473ae771770SStanislav Sedov errx(1, "%s...%s is optional and not a (TTag or TType)", basetype, name); 474ae771770SStanislav Sedov 475ae771770SStanislav Sedov poffset = partial_offset(basetype, name, need_offset); 476ae771770SStanislav Sedov 477ae771770SStanislav Sedov switch (t->type) { 478ae771770SStanislav Sedov case TType: 479ae771770SStanislav Sedov if (use_extern(t->symbol)) { 480ae771770SStanislav Sedov add_line(temp, "{ A1_OP_TYPE_EXTERN %s, %s, &asn1_extern_%s}", 481ae771770SStanislav Sedov optional ? "|A1_FLAG_OPTIONAL" : "", 482ae771770SStanislav Sedov poffset, t->symbol->gen_name); 483ae771770SStanislav Sedov } else { 484ae771770SStanislav Sedov add_line_pointer(temp, t->symbol->gen_name, poffset, 485ae771770SStanislav Sedov "A1_OP_TYPE %s", optional ? "|A1_FLAG_OPTIONAL" : ""); 486ae771770SStanislav Sedov } 487ae771770SStanislav Sedov break; 488ae771770SStanislav Sedov case TInteger: { 489ae771770SStanislav Sedov char *itype = NULL; 490ae771770SStanislav Sedov 491ae771770SStanislav Sedov if (t->members) 492ae771770SStanislav Sedov itype = "IMEMBER"; 493ae771770SStanislav Sedov else if (t->range == NULL) 494ae771770SStanislav Sedov itype = "HEIM_INTEGER"; 495*1b748759SDimitry Andric else if (t->range->min < INT_MIN && t->range->max <= INT64_MAX) 496*1b748759SDimitry Andric itype = "INTEGER64"; 497*1b748759SDimitry Andric else if (t->range->min >= 0 && t->range->max > UINT_MAX) 498*1b748759SDimitry Andric itype = "UNSIGNED64"; 499*1b748759SDimitry Andric else if (t->range->min >= INT_MIN && t->range->max <= INT_MAX) 500ae771770SStanislav Sedov itype = "INTEGER"; 501*1b748759SDimitry Andric else if (t->range->min >= 0 && t->range->max <= UINT_MAX) 502ae771770SStanislav Sedov itype = "UNSIGNED"; 503ae771770SStanislav Sedov else 504*1b748759SDimitry Andric errx(1, "%s: unsupported range %" PRId64 " -> %" PRId64, 505ae771770SStanislav Sedov name, t->range->min, t->range->max); 506ae771770SStanislav Sedov 507ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_%s), %s, NULL }", itype, poffset); 508ae771770SStanislav Sedov break; 509ae771770SStanislav Sedov } 510ae771770SStanislav Sedov case TGeneralString: 511ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_GENERAL_STRING), %s, NULL }", poffset); 512ae771770SStanislav Sedov break; 513ae771770SStanislav Sedov case TTeletexString: 514ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_TELETEX_STRING), %s, NULL }", poffset); 515ae771770SStanislav Sedov break; 516ae771770SStanislav Sedov case TPrintableString: 517ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_PRINTABLE_STRING), %s, NULL }", poffset); 518ae771770SStanislav Sedov break; 519ae771770SStanislav Sedov case TOctetString: 520ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_OCTET_STRING), %s, NULL }", poffset); 521ae771770SStanislav Sedov break; 522ae771770SStanislav Sedov case TIA5String: 523ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_IA5_STRING), %s, NULL }", poffset); 524ae771770SStanislav Sedov break; 525ae771770SStanislav Sedov case TBMPString: 526ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_BMP_STRING), %s, NULL }", poffset); 527ae771770SStanislav Sedov break; 528ae771770SStanislav Sedov case TUniversalString: 529ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_UNIVERSAL_STRING), %s, NULL }", poffset); 530ae771770SStanislav Sedov break; 531ae771770SStanislav Sedov case TVisibleString: 532ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_VISIBLE_STRING), %s, NULL }", poffset); 533ae771770SStanislav Sedov break; 534ae771770SStanislav Sedov case TUTF8String: 535ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_UTF8_STRING), %s, NULL }", poffset); 536ae771770SStanislav Sedov break; 537ae771770SStanislav Sedov case TGeneralizedTime: 538ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_GENERALIZED_TIME), %s, NULL }", poffset); 539ae771770SStanislav Sedov break; 540ae771770SStanislav Sedov case TUTCTime: 541ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_UTC_TIME), %s, NULL }", poffset); 542ae771770SStanislav Sedov break; 543ae771770SStanislav Sedov case TBoolean: 544ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_BOOLEAN), %s, NULL }", poffset); 545ae771770SStanislav Sedov break; 546ae771770SStanislav Sedov case TOID: 547ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_OID), %s, NULL }", poffset); 548ae771770SStanislav Sedov break; 549ae771770SStanislav Sedov case TNull: 550ae771770SStanislav Sedov break; 551ae771770SStanislav Sedov case TBitString: { 552ae771770SStanislav Sedov struct templatehead template = ASN1_TAILQ_HEAD_INITIALIZER(template); 553ae771770SStanislav Sedov struct template *q; 554ae771770SStanislav Sedov Member *m; 555ae771770SStanislav Sedov size_t count = 0, i; 556ae771770SStanislav Sedov char *bname = NULL; 557ae771770SStanislav Sedov FILE *f = get_code_file(); 558ae771770SStanislav Sedov 559ae771770SStanislav Sedov if (ASN1_TAILQ_EMPTY(t->members)) { 560ae771770SStanislav Sedov add_line(temp, "{ A1_PARSE_T(A1T_HEIM_BIT_STRING), %s, NULL }", poffset); 561ae771770SStanislav Sedov break; 562ae771770SStanislav Sedov } 563ae771770SStanislav Sedov 564ae771770SStanislav Sedov if (asprintf(&bname, "bmember_%s_%p", name ? name : "", t) < 0 || bname == NULL) 565ae771770SStanislav Sedov errx(1, "malloc"); 566ae771770SStanislav Sedov output_name(bname); 567ae771770SStanislav Sedov 568ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(m, t->members, members) { 569ae771770SStanislav Sedov add_line(&template, "{ 0, %d, 0 } /* %s */", m->val, m->gen_name); 570ae771770SStanislav Sedov } 571ae771770SStanislav Sedov 572ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(q, &template, members) { 573ae771770SStanislav Sedov count++; 574ae771770SStanislav Sedov } 575ae771770SStanislav Sedov 576ae771770SStanislav Sedov fprintf(f, "static const struct asn1_template asn1_%s_%s[] = {\n", basetype, bname); 577ae771770SStanislav Sedov fprintf(f, "/* 0 */ { 0%s, sizeof(%s), ((void *)%lu) },\n", 578ae771770SStanislav Sedov rfc1510_bitstring ? "|A1_HBF_RFC1510" : "", 579ae771770SStanislav Sedov basetype, (unsigned long)count); 580ae771770SStanislav Sedov i = 1; 581ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(q, &template, members) { 582ae771770SStanislav Sedov int last = (ASN1_TAILQ_LAST(&template, templatehead) == q); 583ae771770SStanislav Sedov fprintf(f, "/* %lu */ %s%s\n", (unsigned long)i++, q->line, last ? "" : ","); 584ae771770SStanislav Sedov } 585ae771770SStanislav Sedov fprintf(f, "};\n"); 586ae771770SStanislav Sedov 587ae771770SStanislav Sedov add_line(temp, "{ A1_OP_BMEMBER, %s, asn1_%s_%s }", poffset, basetype, bname); 588ae771770SStanislav Sedov 589ae771770SStanislav Sedov free(bname); 590ae771770SStanislav Sedov 591ae771770SStanislav Sedov break; 592ae771770SStanislav Sedov } 593ae771770SStanislav Sedov case TSequence: { 594ae771770SStanislav Sedov Member *m; 595ae771770SStanislav Sedov 596ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(m, t->members, members) { 597ae771770SStanislav Sedov char *newbasename = NULL; 598ae771770SStanislav Sedov 599ae771770SStanislav Sedov if (m->ellipsis) 600ae771770SStanislav Sedov continue; 601ae771770SStanislav Sedov 602ae771770SStanislav Sedov if (name) { 603ae771770SStanislav Sedov if (asprintf(&newbasename, "%s_%s", basetype, name) < 0) 604ae771770SStanislav Sedov errx(1, "malloc"); 605ae771770SStanislav Sedov } else 606ae771770SStanislav Sedov newbasename = strdup(basetype); 607ae771770SStanislav Sedov if (newbasename == NULL) 608ae771770SStanislav Sedov errx(1, "malloc"); 609ae771770SStanislav Sedov 610ae771770SStanislav Sedov template_members(temp, newbasename, m->gen_name, m->type, m->optional, isstruct, 1); 611ae771770SStanislav Sedov 612ae771770SStanislav Sedov free(newbasename); 613ae771770SStanislav Sedov } 614ae771770SStanislav Sedov 615ae771770SStanislav Sedov break; 616ae771770SStanislav Sedov } 617ae771770SStanislav Sedov case TTag: { 618ae771770SStanislav Sedov char *tname = NULL, *elname = NULL; 619ae771770SStanislav Sedov const char *sename, *dupname; 620ae771770SStanislav Sedov int subtype_is_struct = is_struct(t->subtype, isstruct); 621ae771770SStanislav Sedov 622ae771770SStanislav Sedov if (subtype_is_struct) 623ae771770SStanislav Sedov sename = basetype; 624ae771770SStanislav Sedov else 625ae771770SStanislav Sedov sename = symbol_name(basetype, t->subtype); 626ae771770SStanislav Sedov 627ae771770SStanislav Sedov if (asprintf(&tname, "tag_%s_%p", name ? name : "", t) < 0 || tname == NULL) 628ae771770SStanislav Sedov errx(1, "malloc"); 629ae771770SStanislav Sedov output_name(tname); 630ae771770SStanislav Sedov 631ae771770SStanislav Sedov if (asprintf(&elname, "%s_%s", basetype, tname) < 0 || elname == NULL) 632ae771770SStanislav Sedov errx(1, "malloc"); 633ae771770SStanislav Sedov 634ae771770SStanislav Sedov generate_template_type(elname, &dupname, NULL, sename, name, 635ae771770SStanislav Sedov t->subtype, 0, subtype_is_struct, 0); 636ae771770SStanislav Sedov 637ae771770SStanislav Sedov add_line_pointer(temp, dupname, poffset, 638ae771770SStanislav Sedov "A1_TAG_T(%s,%s,%s)%s", 639ae771770SStanislav Sedov classname(t->tag.tagclass), 640ae771770SStanislav Sedov is_primitive_type(t->subtype->type) ? "PRIM" : "CONS", 641ae771770SStanislav Sedov valuename(t->tag.tagclass, t->tag.tagvalue), 642ae771770SStanislav Sedov optional ? "|A1_FLAG_OPTIONAL" : ""); 643ae771770SStanislav Sedov 644ae771770SStanislav Sedov free(tname); 645ae771770SStanislav Sedov free(elname); 646ae771770SStanislav Sedov 647ae771770SStanislav Sedov break; 648ae771770SStanislav Sedov } 649ae771770SStanislav Sedov case TSetOf: 650ae771770SStanislav Sedov case TSequenceOf: { 651ae771770SStanislav Sedov const char *type = NULL, *tname, *dupname; 652ae771770SStanislav Sedov char *sename = NULL, *elname = NULL; 653ae771770SStanislav Sedov int subtype_is_struct = is_struct(t->subtype, 0); 654ae771770SStanislav Sedov 655ae771770SStanislav Sedov if (name && subtype_is_struct) { 656ae771770SStanislav Sedov tname = "seofTstruct"; 657ae771770SStanislav Sedov if (asprintf(&sename, "%s_%s_val", basetype, name) < 0) 658ae771770SStanislav Sedov errx(1, "malloc"); 659ae771770SStanislav Sedov } else if (subtype_is_struct) { 660ae771770SStanislav Sedov tname = "seofTstruct"; 661ae771770SStanislav Sedov if (asprintf(&sename, "%s_val", symbol_name(basetype, t->subtype)) < 0) 662ae771770SStanislav Sedov errx(1, "malloc"); 663ae771770SStanislav Sedov } else { 664ae771770SStanislav Sedov if (name) 665ae771770SStanislav Sedov tname = name; 666ae771770SStanislav Sedov else 667ae771770SStanislav Sedov tname = "seofTstruct"; 668ae771770SStanislav Sedov sename = strdup(symbol_name(basetype, t->subtype)); 669ae771770SStanislav Sedov } 670ae771770SStanislav Sedov if (sename == NULL) 671ae771770SStanislav Sedov errx(1, "malloc"); 672ae771770SStanislav Sedov 673ae771770SStanislav Sedov if (t->type == TSetOf) type = "A1_OP_SETOF"; 674ae771770SStanislav Sedov else if (t->type == TSequenceOf) type = "A1_OP_SEQOF"; 675ae771770SStanislav Sedov else abort(); 676ae771770SStanislav Sedov 677ae771770SStanislav Sedov if (asprintf(&elname, "%s_%s_%p", basetype, tname, t) < 0 || elname == NULL) 678ae771770SStanislav Sedov errx(1, "malloc"); 679ae771770SStanislav Sedov 680ae771770SStanislav Sedov generate_template_type(elname, &dupname, NULL, sename, NULL, t->subtype, 681ae771770SStanislav Sedov 0, subtype_is_struct, need_offset); 682ae771770SStanislav Sedov 683ae771770SStanislav Sedov add_line(temp, "{ %s, %s, asn1_%s }", type, poffset, dupname); 684ae771770SStanislav Sedov free(sename); 685ae771770SStanislav Sedov break; 686ae771770SStanislav Sedov } 687ae771770SStanislav Sedov case TChoice: { 688ae771770SStanislav Sedov struct templatehead template = ASN1_TAILQ_HEAD_INITIALIZER(template); 689ae771770SStanislav Sedov struct template *q; 690ae771770SStanislav Sedov size_t count = 0, i; 691ae771770SStanislav Sedov char *tname = NULL; 692ae771770SStanislav Sedov FILE *f = get_code_file(); 693ae771770SStanislav Sedov Member *m; 694ae771770SStanislav Sedov int ellipsis = 0; 695ae771770SStanislav Sedov char *e; 696ae771770SStanislav Sedov 697ae771770SStanislav Sedov if (asprintf(&tname, "asn1_choice_%s_%s%x", 698ae771770SStanislav Sedov basetype, name ? name : "", (unsigned int)(uintptr_t)t) < 0 || tname == NULL) 699ae771770SStanislav Sedov errx(1, "malloc"); 700ae771770SStanislav Sedov 701ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(m, t->members, members) { 702ae771770SStanislav Sedov const char *dupname; 703ae771770SStanislav Sedov char *elname = NULL; 704ae771770SStanislav Sedov char *newbasename = NULL; 705ae771770SStanislav Sedov int subtype_is_struct; 706ae771770SStanislav Sedov 707ae771770SStanislav Sedov if (m->ellipsis) { 708ae771770SStanislav Sedov ellipsis = 1; 709ae771770SStanislav Sedov continue; 710ae771770SStanislav Sedov } 711ae771770SStanislav Sedov 712ae771770SStanislav Sedov subtype_is_struct = is_struct(m->type, 0); 713ae771770SStanislav Sedov 714ae771770SStanislav Sedov if (asprintf(&elname, "%s_choice_%s", basetype, m->gen_name) < 0 || elname == NULL) 715ae771770SStanislav Sedov errx(1, "malloc"); 716ae771770SStanislav Sedov 717ae771770SStanislav Sedov if (subtype_is_struct) { 718ae771770SStanislav Sedov if (asprintf(&newbasename, "%s_%s", basetype, m->gen_name) < 0) 719ae771770SStanislav Sedov errx(1, "malloc"); 720ae771770SStanislav Sedov } else 721ae771770SStanislav Sedov newbasename = strdup(basetype); 722ae771770SStanislav Sedov 723ae771770SStanislav Sedov if (newbasename == NULL) 724ae771770SStanislav Sedov errx(1, "malloc"); 725ae771770SStanislav Sedov 726ae771770SStanislav Sedov 727ae771770SStanislav Sedov generate_template_type(elname, &dupname, NULL, 728ae771770SStanislav Sedov symbol_name(newbasename, m->type), 729ae771770SStanislav Sedov NULL, m->type, 0, subtype_is_struct, 1); 730ae771770SStanislav Sedov 731ae771770SStanislav Sedov add_line(&template, "{ %s, offsetof(%s%s, u.%s), asn1_%s }", 732ae771770SStanislav Sedov m->label, isstruct ? "struct " : "", 733ae771770SStanislav Sedov basetype, m->gen_name, 734ae771770SStanislav Sedov dupname); 735ae771770SStanislav Sedov 736ae771770SStanislav Sedov free(elname); 737ae771770SStanislav Sedov free(newbasename); 738ae771770SStanislav Sedov } 739ae771770SStanislav Sedov 740ae771770SStanislav Sedov e = NULL; 741ae771770SStanislav Sedov if (ellipsis) { 742ae771770SStanislav Sedov if (asprintf(&e, "offsetof(%s%s, u.asn1_ellipsis)", isstruct ? "struct " : "", basetype) < 0 || e == NULL) 743ae771770SStanislav Sedov errx(1, "malloc"); 744ae771770SStanislav Sedov } 745ae771770SStanislav Sedov 746ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(q, &template, members) { 747ae771770SStanislav Sedov count++; 748ae771770SStanislav Sedov } 749ae771770SStanislav Sedov 750ae771770SStanislav Sedov fprintf(f, "static const struct asn1_template %s[] = {\n", tname); 751ae771770SStanislav Sedov fprintf(f, "/* 0 */ { %s, offsetof(%s%s, element), ((void *)%lu) },\n", 752ae771770SStanislav Sedov e ? e : "0", isstruct ? "struct " : "", basetype, (unsigned long)count); 753ae771770SStanislav Sedov i = 1; 754ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(q, &template, members) { 755ae771770SStanislav Sedov int last = (ASN1_TAILQ_LAST(&template, templatehead) == q); 756ae771770SStanislav Sedov fprintf(f, "/* %lu */ %s%s\n", (unsigned long)i++, q->line, last ? "" : ","); 757ae771770SStanislav Sedov } 758ae771770SStanislav Sedov fprintf(f, "};\n"); 759ae771770SStanislav Sedov 760ae771770SStanislav Sedov add_line(temp, "{ A1_OP_CHOICE, %s, %s }", poffset, tname); 761ae771770SStanislav Sedov 762ae771770SStanislav Sedov free(e); 763ae771770SStanislav Sedov free(tname); 764ae771770SStanislav Sedov break; 765ae771770SStanislav Sedov } 766ae771770SStanislav Sedov default: 767ae771770SStanislav Sedov abort (); 768ae771770SStanislav Sedov } 769ae771770SStanislav Sedov if (poffset) 770ae771770SStanislav Sedov free(poffset); 771ae771770SStanislav Sedov } 772ae771770SStanislav Sedov 773ae771770SStanislav Sedov static void 774ae771770SStanislav Sedov gen_extern_stubs(FILE *f, const char *name) 775ae771770SStanislav Sedov { 776ae771770SStanislav Sedov fprintf(f, 777ae771770SStanislav Sedov "static const struct asn1_type_func asn1_extern_%s = {\n" 778ae771770SStanislav Sedov "\t(asn1_type_encode)encode_%s,\n" 779ae771770SStanislav Sedov "\t(asn1_type_decode)decode_%s,\n" 780ae771770SStanislav Sedov "\t(asn1_type_length)length_%s,\n" 781ae771770SStanislav Sedov "\t(asn1_type_copy)copy_%s,\n" 782ae771770SStanislav Sedov "\t(asn1_type_release)free_%s,\n" 783ae771770SStanislav Sedov "\tsizeof(%s)\n" 784ae771770SStanislav Sedov "};\n", 785ae771770SStanislav Sedov name, name, name, name, 786ae771770SStanislav Sedov name, name, name); 787ae771770SStanislav Sedov } 788ae771770SStanislav Sedov 789ae771770SStanislav Sedov void 790ae771770SStanislav Sedov gen_template_import(const Symbol *s) 791ae771770SStanislav Sedov { 792ae771770SStanislav Sedov FILE *f = get_code_file(); 793ae771770SStanislav Sedov 794ae771770SStanislav Sedov if (template_flag == 0) 795ae771770SStanislav Sedov return; 796ae771770SStanislav Sedov 797ae771770SStanislav Sedov gen_extern_stubs(f, s->gen_name); 798ae771770SStanislav Sedov } 799ae771770SStanislav Sedov 800ae771770SStanislav Sedov static void 801ae771770SStanislav Sedov generate_template_type(const char *varname, 802ae771770SStanislav Sedov const char **dupname, 803ae771770SStanislav Sedov const char *symname, 804ae771770SStanislav Sedov const char *basetype, 805ae771770SStanislav Sedov const char *name, 806ae771770SStanislav Sedov Type *type, 807ae771770SStanislav Sedov int optional, int isstruct, int need_offset) 808ae771770SStanislav Sedov { 809ae771770SStanislav Sedov struct tlist *tl; 810ae771770SStanislav Sedov const char *dup; 811ae771770SStanislav Sedov int have_ellipsis = 0; 812ae771770SStanislav Sedov 813ae771770SStanislav Sedov tl = tlist_new(varname); 814ae771770SStanislav Sedov 815ae771770SStanislav Sedov template_members(&tl->template, basetype, name, type, optional, isstruct, need_offset); 816ae771770SStanislav Sedov 817ae771770SStanislav Sedov /* if its a sequence or set type, check if there is a ellipsis */ 818ae771770SStanislav Sedov if (type->type == TSequence || type->type == TSet) { 819ae771770SStanislav Sedov Member *m; 820ae771770SStanislav Sedov ASN1_TAILQ_FOREACH(m, type->members, members) { 821ae771770SStanislav Sedov if (m->ellipsis) 822ae771770SStanislav Sedov have_ellipsis = 1; 823ae771770SStanislav Sedov } 824ae771770SStanislav Sedov } 825ae771770SStanislav Sedov 826ae771770SStanislav Sedov if (ASN1_TAILQ_EMPTY(&tl->template) && compact_tag(type)->type != TNull) 827ae771770SStanislav Sedov errx(1, "Tag %s...%s with no content ?", basetype, name ? name : ""); 828ae771770SStanislav Sedov 829ae771770SStanislav Sedov tlist_header(tl, "{ 0%s%s, sizeof(%s%s), ((void *)%lu) }", 830ae771770SStanislav Sedov (symname && preserve_type(symname)) ? "|A1_HF_PRESERVE" : "", 831ae771770SStanislav Sedov have_ellipsis ? "|A1_HF_ELLIPSIS" : "", 832ae771770SStanislav Sedov isstruct ? "struct " : "", basetype, tlist_count(tl)); 833ae771770SStanislav Sedov 834ae771770SStanislav Sedov dup = tlist_find_dup(tl); 835ae771770SStanislav Sedov if (dup) { 836ae771770SStanislav Sedov if (strcmp(dup, tl->name) == 0) 837ae771770SStanislav Sedov errx(1, "found dup of ourself"); 838ae771770SStanislav Sedov *dupname = dup; 839ae771770SStanislav Sedov } else { 840ae771770SStanislav Sedov *dupname = tl->name; 841ae771770SStanislav Sedov tlist_print(tl); 842ae771770SStanislav Sedov tlist_add(tl); 843ae771770SStanislav Sedov } 844ae771770SStanislav Sedov } 845ae771770SStanislav Sedov 846ae771770SStanislav Sedov 847ae771770SStanislav Sedov void 848ae771770SStanislav Sedov generate_template(const Symbol *s) 849ae771770SStanislav Sedov { 850ae771770SStanislav Sedov FILE *f = get_code_file(); 851ae771770SStanislav Sedov const char *dupname; 852ae771770SStanislav Sedov 853ae771770SStanislav Sedov if (use_extern(s)) { 854ae771770SStanislav Sedov gen_extern_stubs(f, s->gen_name); 855ae771770SStanislav Sedov return; 856ae771770SStanislav Sedov } 857ae771770SStanislav Sedov 858ae771770SStanislav Sedov generate_template_type(s->gen_name, &dupname, s->name, s->gen_name, NULL, s->type, 0, 0, 1); 859ae771770SStanislav Sedov 860ae771770SStanislav Sedov fprintf(f, 861ae771770SStanislav Sedov "\n" 862ae771770SStanislav Sedov "int\n" 863ae771770SStanislav Sedov "decode_%s(const unsigned char *p, size_t len, %s *data, size_t *size)\n" 864ae771770SStanislav Sedov "{\n" 865ae771770SStanislav Sedov " return _asn1_decode_top(asn1_%s, 0|%s, p, len, data, size);\n" 866ae771770SStanislav Sedov "}\n" 867ae771770SStanislav Sedov "\n", 868ae771770SStanislav Sedov s->gen_name, 869ae771770SStanislav Sedov s->gen_name, 870ae771770SStanislav Sedov dupname, 871ae771770SStanislav Sedov support_ber ? "A1_PF_ALLOW_BER" : "0"); 872ae771770SStanislav Sedov 873ae771770SStanislav Sedov fprintf(f, 874ae771770SStanislav Sedov "\n" 875ae771770SStanislav Sedov "int\n" 876ae771770SStanislav Sedov "encode_%s(unsigned char *p, size_t len, const %s *data, size_t *size)\n" 877ae771770SStanislav Sedov "{\n" 878ae771770SStanislav Sedov " return _asn1_encode(asn1_%s, p, len, data, size);\n" 879ae771770SStanislav Sedov "}\n" 880ae771770SStanislav Sedov "\n", 881ae771770SStanislav Sedov s->gen_name, 882ae771770SStanislav Sedov s->gen_name, 883ae771770SStanislav Sedov dupname); 884ae771770SStanislav Sedov 885ae771770SStanislav Sedov fprintf(f, 886ae771770SStanislav Sedov "\n" 887ae771770SStanislav Sedov "size_t\n" 888ae771770SStanislav Sedov "length_%s(const %s *data)\n" 889ae771770SStanislav Sedov "{\n" 890ae771770SStanislav Sedov " return _asn1_length(asn1_%s, data);\n" 891ae771770SStanislav Sedov "}\n" 892ae771770SStanislav Sedov "\n", 893ae771770SStanislav Sedov s->gen_name, 894ae771770SStanislav Sedov s->gen_name, 895ae771770SStanislav Sedov dupname); 896ae771770SStanislav Sedov 897ae771770SStanislav Sedov 898ae771770SStanislav Sedov fprintf(f, 899ae771770SStanislav Sedov "\n" 900ae771770SStanislav Sedov "void\n" 901ae771770SStanislav Sedov "free_%s(%s *data)\n" 902ae771770SStanislav Sedov "{\n" 903ae771770SStanislav Sedov " _asn1_free(asn1_%s, data);\n" 904ae771770SStanislav Sedov "}\n" 905ae771770SStanislav Sedov "\n", 906ae771770SStanislav Sedov s->gen_name, 907ae771770SStanislav Sedov s->gen_name, 908ae771770SStanislav Sedov dupname); 909ae771770SStanislav Sedov 910ae771770SStanislav Sedov fprintf(f, 911ae771770SStanislav Sedov "\n" 912ae771770SStanislav Sedov "int\n" 913ae771770SStanislav Sedov "copy_%s(const %s *from, %s *to)\n" 914ae771770SStanislav Sedov "{\n" 915ae771770SStanislav Sedov " return _asn1_copy_top(asn1_%s, from, to);\n" 916ae771770SStanislav Sedov "}\n" 917ae771770SStanislav Sedov "\n", 918ae771770SStanislav Sedov s->gen_name, 919ae771770SStanislav Sedov s->gen_name, 920ae771770SStanislav Sedov s->gen_name, 921ae771770SStanislav Sedov dupname); 922ae771770SStanislav Sedov } 923