155682Smarkm/* 2178825Sdfr * Copyright (c) 1997 - 2005 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "gen_locl.h" 3555682Smarkm 36178825SdfrRCSID("$Id: gen_copy.c 19539 2006-12-28 17:15:05Z lha $"); 3755682Smarkm 38178825Sdfrstatic int used_fail; 39178825Sdfr 4055682Smarkmstatic void 4155682Smarkmcopy_primitive (const char *typename, const char *from, const char *to) 4255682Smarkm{ 43178825Sdfr fprintf (codefile, "if(der_copy_%s(%s, %s)) goto fail;\n", 4455682Smarkm typename, from, to); 45178825Sdfr used_fail++; 4655682Smarkm} 4755682Smarkm 4855682Smarkmstatic void 49178825Sdfrcopy_type (const char *from, const char *to, const Type *t, int preserve) 5055682Smarkm{ 51178825Sdfr switch (t->type) { 52178825Sdfr case TType: 5355682Smarkm#if 0 54178825Sdfr copy_type (from, to, t->symbol->type, preserve); 5555682Smarkm#endif 56178825Sdfr fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n", 57178825Sdfr t->symbol->gen_name, from, to); 58178825Sdfr used_fail++; 59178825Sdfr break; 60178825Sdfr case TInteger: 61178825Sdfr if (t->range == NULL && t->members == NULL) { 62178825Sdfr copy_primitive ("heim_integer", from, to); 63178825Sdfr break; 64178825Sdfr } 65178825Sdfr case TBoolean: 66178825Sdfr case TEnumerated : 67178825Sdfr fprintf(codefile, "*(%s) = *(%s);\n", to, from); 68178825Sdfr break; 69178825Sdfr case TOctetString: 70178825Sdfr copy_primitive ("octet_string", from, to); 71178825Sdfr break; 72178825Sdfr case TBitString: 73178825Sdfr if (ASN1_TAILQ_EMPTY(t->members)) 74178825Sdfr copy_primitive ("bit_string", from, to); 75178825Sdfr else 76178825Sdfr fprintf(codefile, "*(%s) = *(%s);\n", to, from); 77178825Sdfr break; 78178825Sdfr case TSet: 79178825Sdfr case TSequence: 80178825Sdfr case TChoice: { 81178825Sdfr Member *m, *have_ellipsis = NULL; 8255682Smarkm 83178825Sdfr if(t->members == NULL) 84178825Sdfr break; 8555682Smarkm 86178825Sdfr if ((t->type == TSequence || t->type == TChoice) && preserve) { 87178825Sdfr fprintf(codefile, 88178825Sdfr "{ int ret;\n" 89178825Sdfr "ret = der_copy_octet_string(&(%s)->_save, &(%s)->_save);\n" 90178825Sdfr "if (ret) goto fail;\n" 91178825Sdfr "}\n", 92178825Sdfr from, to); 93178825Sdfr used_fail++; 94178825Sdfr } 9555682Smarkm 96178825Sdfr if(t->type == TChoice) { 97178825Sdfr fprintf(codefile, "(%s)->element = (%s)->element;\n", to, from); 98178825Sdfr fprintf(codefile, "switch((%s)->element) {\n", from); 99178825Sdfr } 10055682Smarkm 101178825Sdfr ASN1_TAILQ_FOREACH(m, t->members, members) { 102178825Sdfr char *fs; 103178825Sdfr char *ts; 104178825Sdfr 105178825Sdfr if (m->ellipsis) { 106178825Sdfr have_ellipsis = m; 107178825Sdfr continue; 108178825Sdfr } 109178825Sdfr 110178825Sdfr if(t->type == TChoice) 111178825Sdfr fprintf(codefile, "case %s:\n", m->label); 112178825Sdfr 113178825Sdfr asprintf (&fs, "%s(%s)->%s%s", 114178825Sdfr m->optional ? "" : "&", from, 115178825Sdfr t->type == TChoice ? "u." : "", m->gen_name); 116178825Sdfr if (fs == NULL) 117178825Sdfr errx(1, "malloc"); 118178825Sdfr asprintf (&ts, "%s(%s)->%s%s", 119178825Sdfr m->optional ? "" : "&", to, 120178825Sdfr t->type == TChoice ? "u." : "", m->gen_name); 121178825Sdfr if (ts == NULL) 122178825Sdfr errx(1, "malloc"); 123178825Sdfr if(m->optional){ 124178825Sdfr fprintf(codefile, "if(%s) {\n", fs); 125178825Sdfr fprintf(codefile, "%s = malloc(sizeof(*%s));\n", ts, ts); 126178825Sdfr fprintf(codefile, "if(%s == NULL) goto fail;\n", ts); 127178825Sdfr used_fail++; 128178825Sdfr } 129178825Sdfr copy_type (fs, ts, m->type, FALSE); 130178825Sdfr if(m->optional){ 131178825Sdfr fprintf(codefile, "}else\n"); 132178825Sdfr fprintf(codefile, "%s = NULL;\n", ts); 133178825Sdfr } 134178825Sdfr free (fs); 135178825Sdfr free (ts); 136178825Sdfr if(t->type == TChoice) 137178825Sdfr fprintf(codefile, "break;\n"); 138178825Sdfr } 139178825Sdfr if(t->type == TChoice) { 140178825Sdfr if (have_ellipsis) { 141178825Sdfr fprintf(codefile, "case %s: {\n" 142178825Sdfr "int ret;\n" 143178825Sdfr "ret=der_copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n" 144178825Sdfr "if (ret) goto fail;\n" 145178825Sdfr "break;\n" 146178825Sdfr "}\n", 147178825Sdfr have_ellipsis->label, 148178825Sdfr from, have_ellipsis->gen_name, 149178825Sdfr to, have_ellipsis->gen_name); 150178825Sdfr used_fail++; 151178825Sdfr } 152178825Sdfr fprintf(codefile, "}\n"); 153178825Sdfr } 154178825Sdfr break; 155178825Sdfr } 156178825Sdfr case TSetOf: 157178825Sdfr case TSequenceOf: { 158178825Sdfr char *f; 159178825Sdfr char *T; 160178825Sdfr 161178825Sdfr fprintf (codefile, "if(((%s)->val = " 162178825Sdfr "malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n", 163178825Sdfr to, from, to, from); 164178825Sdfr fprintf (codefile, "goto fail;\n"); 165178825Sdfr used_fail++; 166178825Sdfr fprintf(codefile, 167178825Sdfr "for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n", 168178825Sdfr to, to, from, to); 169178825Sdfr asprintf(&f, "&(%s)->val[(%s)->len]", from, to); 170178825Sdfr if (f == NULL) 171178825Sdfr errx(1, "malloc"); 172178825Sdfr asprintf(&T, "&(%s)->val[(%s)->len]", to, to); 173178825Sdfr if (T == NULL) 174178825Sdfr errx(1, "malloc"); 175178825Sdfr copy_type(f, T, t->subtype, FALSE); 176178825Sdfr fprintf(codefile, "}\n"); 177178825Sdfr free(f); 178178825Sdfr free(T); 179178825Sdfr break; 180178825Sdfr } 181178825Sdfr case TGeneralizedTime: 182178825Sdfr fprintf(codefile, "*(%s) = *(%s);\n", to, from); 183178825Sdfr break; 184178825Sdfr case TGeneralString: 185178825Sdfr copy_primitive ("general_string", from, to); 186178825Sdfr break; 187178825Sdfr case TUTCTime: 188178825Sdfr fprintf(codefile, "*(%s) = *(%s);\n", to, from); 189178825Sdfr break; 190178825Sdfr case TUTF8String: 191178825Sdfr copy_primitive ("utf8string", from, to); 192178825Sdfr break; 193178825Sdfr case TPrintableString: 194178825Sdfr copy_primitive ("printable_string", from, to); 195178825Sdfr break; 196178825Sdfr case TIA5String: 197178825Sdfr copy_primitive ("ia5_string", from, to); 198178825Sdfr break; 199178825Sdfr case TBMPString: 200178825Sdfr copy_primitive ("bmp_string", from, to); 201178825Sdfr break; 202178825Sdfr case TUniversalString: 203178825Sdfr copy_primitive ("universal_string", from, to); 204178825Sdfr break; 205178825Sdfr case TVisibleString: 206178825Sdfr copy_primitive ("visible_string", from, to); 207178825Sdfr break; 208178825Sdfr case TTag: 209178825Sdfr copy_type (from, to, t->subtype, preserve); 210178825Sdfr break; 211178825Sdfr case TOID: 212178825Sdfr copy_primitive ("oid", from, to); 213178825Sdfr break; 214178825Sdfr case TNull: 215178825Sdfr break; 216178825Sdfr default : 217178825Sdfr abort (); 218178825Sdfr } 21955682Smarkm} 22055682Smarkm 22155682Smarkmvoid 22255682Smarkmgenerate_type_copy (const Symbol *s) 22355682Smarkm{ 224178825Sdfr int preserve = preserve_type(s->name) ? TRUE : FALSE; 225178825Sdfr 226178825Sdfr used_fail = 0; 227178825Sdfr 22855682Smarkm fprintf (headerfile, 22955682Smarkm "int copy_%s (const %s *, %s *);\n", 23055682Smarkm s->gen_name, s->gen_name, s->gen_name); 23155682Smarkm 23255682Smarkm fprintf (codefile, "int\n" 23355682Smarkm "copy_%s(const %s *from, %s *to)\n" 234178825Sdfr "{\n" 235178825Sdfr "memset(to, 0, sizeof(*to));\n", 23655682Smarkm s->gen_name, s->gen_name, s->gen_name); 237178825Sdfr copy_type ("from", "to", s->type, preserve); 238178825Sdfr fprintf (codefile, "return 0;\n"); 23955682Smarkm 240178825Sdfr if (used_fail) 241178825Sdfr fprintf (codefile, "fail:\n" 242178825Sdfr "free_%s(to);\n" 243178825Sdfr "return ENOMEM;\n", 244178825Sdfr s->gen_name); 245178825Sdfr 246178825Sdfr fprintf(codefile, 247178825Sdfr "}\n\n"); 24855682Smarkm} 24955682Smarkm 250