155682Smarkm/* 2233294Sstas * Copyright (c) 1997 - 2005 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "gen_locl.h" 3555682Smarkm 36233294SstasRCSID("$Id$"); 3755682Smarkm 3855682Smarkmstatic void 3955682Smarkmfree_primitive (const char *typename, const char *name) 4055682Smarkm{ 41178825Sdfr fprintf (codefile, "der_free_%s(%s);\n", typename, name); 4255682Smarkm} 4355682Smarkm 4455682Smarkmstatic void 45178825Sdfrfree_type (const char *name, const Type *t, int preserve) 4655682Smarkm{ 47178825Sdfr switch (t->type) { 48178825Sdfr case TType: 4955682Smarkm#if 0 50178825Sdfr free_type (name, t->symbol->type, preserve); 5155682Smarkm#endif 52178825Sdfr fprintf (codefile, "free_%s(%s);\n", t->symbol->gen_name, name); 53178825Sdfr break; 54178825Sdfr case TInteger: 55178825Sdfr if (t->range == NULL && t->members == NULL) { 56178825Sdfr free_primitive ("heim_integer", name); 57178825Sdfr break; 58178825Sdfr } 59178825Sdfr case TBoolean: 60178825Sdfr case TEnumerated : 61178825Sdfr case TNull: 62178825Sdfr case TGeneralizedTime: 63178825Sdfr case TUTCTime: 64178825Sdfr break; 65178825Sdfr case TBitString: 66178825Sdfr if (ASN1_TAILQ_EMPTY(t->members)) 67178825Sdfr free_primitive("bit_string", name); 68178825Sdfr break; 69178825Sdfr case TOctetString: 70178825Sdfr free_primitive ("octet_string", name); 71178825Sdfr break; 72178825Sdfr case TChoice: 73178825Sdfr case TSet: 74178825Sdfr case TSequence: { 75178825Sdfr Member *m, *have_ellipsis = NULL; 7655682Smarkm 77178825Sdfr if (t->members == NULL) 78178825Sdfr break; 79178825Sdfr 80178825Sdfr if ((t->type == TSequence || t->type == TChoice) && preserve) 81178825Sdfr fprintf(codefile, "der_free_octet_string(&data->_save);\n"); 82178825Sdfr 83178825Sdfr if(t->type == TChoice) 84178825Sdfr fprintf(codefile, "switch((%s)->element) {\n", name); 85233294Sstas 86178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 87178825Sdfr char *s; 8855682Smarkm 89178825Sdfr if (m->ellipsis){ 90178825Sdfr have_ellipsis = m; 91178825Sdfr continue; 92178825Sdfr } 9355682Smarkm 94178825Sdfr if(t->type == TChoice) 95178825Sdfr fprintf(codefile, "case %s:\n", m->label); 96233294Sstas if (asprintf (&s, "%s(%s)->%s%s", 97233294Sstas m->optional ? "" : "&", name, 98233294Sstas t->type == TChoice ? "u." : "", m->gen_name) < 0 || s == NULL) 99178825Sdfr errx(1, "malloc"); 100178825Sdfr if(m->optional) 101178825Sdfr fprintf(codefile, "if(%s) {\n", s); 102178825Sdfr free_type (s, m->type, FALSE); 103178825Sdfr if(m->optional) 104233294Sstas fprintf(codefile, 105178825Sdfr "free(%s);\n" 106178825Sdfr "%s = NULL;\n" 107178825Sdfr "}\n",s, s); 108178825Sdfr free (s); 109178825Sdfr if(t->type == TChoice) 110178825Sdfr fprintf(codefile, "break;\n"); 111178825Sdfr } 112233294Sstas 113178825Sdfr if(t->type == TChoice) { 114178825Sdfr if (have_ellipsis) 115178825Sdfr fprintf(codefile, 116178825Sdfr "case %s:\n" 117178825Sdfr "der_free_octet_string(&(%s)->u.%s);\n" 118178825Sdfr "break;", 119178825Sdfr have_ellipsis->label, 120178825Sdfr name, have_ellipsis->gen_name); 121178825Sdfr fprintf(codefile, "}\n"); 122178825Sdfr } 123178825Sdfr break; 124178825Sdfr } 125178825Sdfr case TSetOf: 126178825Sdfr case TSequenceOf: { 127178825Sdfr char *n; 128178825Sdfr 129178825Sdfr fprintf (codefile, "while((%s)->len){\n", name); 130233294Sstas if (asprintf (&n, "&(%s)->val[(%s)->len-1]", name, name) < 0 || n == NULL) 131178825Sdfr errx(1, "malloc"); 132178825Sdfr free_type(n, t->subtype, FALSE); 133233294Sstas fprintf(codefile, 134178825Sdfr "(%s)->len--;\n" 135178825Sdfr "}\n", 136178825Sdfr name); 137178825Sdfr fprintf(codefile, 138178825Sdfr "free((%s)->val);\n" 139178825Sdfr "(%s)->val = NULL;\n", name, name); 140178825Sdfr free(n); 141178825Sdfr break; 142178825Sdfr } 143178825Sdfr case TGeneralString: 144178825Sdfr free_primitive ("general_string", name); 145178825Sdfr break; 146233294Sstas case TTeletexString: 147233294Sstas free_primitive ("general_string", name); 148233294Sstas break; 149178825Sdfr case TUTF8String: 150178825Sdfr free_primitive ("utf8string", name); 151178825Sdfr break; 152178825Sdfr case TPrintableString: 153178825Sdfr free_primitive ("printable_string", name); 154178825Sdfr break; 155178825Sdfr case TIA5String: 156178825Sdfr free_primitive ("ia5_string", name); 157178825Sdfr break; 158178825Sdfr case TBMPString: 159178825Sdfr free_primitive ("bmp_string", name); 160178825Sdfr break; 161178825Sdfr case TUniversalString: 162178825Sdfr free_primitive ("universal_string", name); 163178825Sdfr break; 164178825Sdfr case TVisibleString: 165178825Sdfr free_primitive ("visible_string", name); 166178825Sdfr break; 167178825Sdfr case TTag: 168178825Sdfr free_type (name, t->subtype, preserve); 169178825Sdfr break; 170178825Sdfr case TOID : 171178825Sdfr free_primitive ("oid", name); 172178825Sdfr break; 173178825Sdfr default : 174178825Sdfr abort (); 175178825Sdfr } 17655682Smarkm} 17755682Smarkm 17855682Smarkmvoid 17955682Smarkmgenerate_type_free (const Symbol *s) 18055682Smarkm{ 181233294Sstas int preserve = preserve_type(s->name) ? TRUE : FALSE; 182178825Sdfr 183233294Sstas fprintf (codefile, "void ASN1CALL\n" 184233294Sstas "free_%s(%s *data)\n" 185233294Sstas "{\n", 186233294Sstas s->gen_name, s->gen_name); 18755682Smarkm 188233294Sstas free_type ("data", s->type, preserve); 189233294Sstas fprintf (codefile, "}\n\n"); 19055682Smarkm} 19155682Smarkm 192