1 : /*
2 : * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan
3 : * (Royal Institute of Technology, Stockholm, Sweden).
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions
8 : * are met:
9 : *
10 : * 1. Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : *
13 : * 2. Redistributions in binary form must reproduce the above copyright
14 : * notice, this list of conditions and the following disclaimer in the
15 : * documentation and/or other materials provided with the distribution.
16 : *
17 : * 3. Neither the name of the Institute nor the names of its contributors
18 : * may be used to endorse or promote products derived from this software
19 : * without specific prior written permission.
20 : *
21 : * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
22 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 : * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
25 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 : * SUCH DAMAGE.
32 : */
33 :
34 : #include "gen_locl.h"
35 :
36 : RCSID("$Id$");
37 :
38 : static int used_fail;
39 :
40 : static void
41 : copy_primitive (const char *typename, const char *from, const char *to)
42 225 : {
43 225 : fprintf (codefile, "if(der_copy_%s(%s, %s)) goto fail;\n",
44 : typename, from, to);
45 225 : used_fail++;
46 225 : }
47 :
48 : static void
49 : copy_type (const char *from, const char *to, const Type *t, int preserve)
50 2025 : {
51 2025 : switch (t->type) {
52 : case TType:
53 : #if 0
54 : copy_type (from, to, t->symbol->type, preserve);
55 : #endif
56 462 : fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n",
57 : t->symbol->gen_name, from, to);
58 462 : used_fail++;
59 462 : break;
60 : case TInteger:
61 83 : if (t->range == NULL && t->members == NULL) {
62 35 : copy_primitive ("heim_integer", from, to);
63 35 : break;
64 : }
65 : case TBoolean:
66 : case TEnumerated :
67 56 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
68 56 : break;
69 : case TOctetString:
70 96 : copy_primitive ("octet_string", from, to);
71 96 : break;
72 : case TBitString:
73 22 : if (ASN1_TAILQ_EMPTY(t->members))
74 12 : copy_primitive ("bit_string", from, to);
75 : else
76 10 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
77 22 : break;
78 : case TSet:
79 : case TSequence:
80 : case TChoice: {
81 188 : Member *m, *have_ellipsis = NULL;
82 :
83 188 : if(t->members == NULL)
84 0 : break;
85 :
86 188 : if ((t->type == TSequence || t->type == TChoice) && preserve) {
87 6 : fprintf(codefile,
88 : "{ int ret;\n"
89 : "ret = der_copy_octet_string(&(%s)->_save, &(%s)->_save);\n"
90 : "if (ret) goto fail;\n"
91 : "}\n",
92 : from, to);
93 6 : used_fail++;
94 : }
95 :
96 188 : if(t->type == TChoice) {
97 20 : fprintf(codefile, "(%s)->element = (%s)->element;\n", to, from);
98 20 : fprintf(codefile, "switch((%s)->element) {\n", from);
99 : }
100 :
101 877 : ASN1_TAILQ_FOREACH(m, t->members, members) {
102 : char *fs;
103 : char *ts;
104 :
105 689 : if (m->ellipsis) {
106 31 : have_ellipsis = m;
107 31 : continue;
108 : }
109 :
110 658 : if(t->type == TChoice)
111 57 : fprintf(codefile, "case %s:\n", m->label);
112 :
113 658 : asprintf (&fs, "%s(%s)->%s%s",
114 : m->optional ? "" : "&", from,
115 : t->type == TChoice ? "u." : "", m->gen_name);
116 658 : if (fs == NULL)
117 0 : errx(1, "malloc");
118 658 : asprintf (&ts, "%s(%s)->%s%s",
119 : m->optional ? "" : "&", to,
120 : t->type == TChoice ? "u." : "", m->gen_name);
121 658 : if (ts == NULL)
122 0 : errx(1, "malloc");
123 658 : if(m->optional){
124 228 : fprintf(codefile, "if(%s) {\n", fs);
125 228 : fprintf(codefile, "%s = malloc(sizeof(*%s));\n", ts, ts);
126 228 : fprintf(codefile, "if(%s == NULL) goto fail;\n", ts);
127 228 : used_fail++;
128 : }
129 658 : copy_type (fs, ts, m->type, FALSE);
130 658 : if(m->optional){
131 228 : fprintf(codefile, "}else\n");
132 228 : fprintf(codefile, "%s = NULL;\n", ts);
133 : }
134 658 : free (fs);
135 658 : free (ts);
136 658 : if(t->type == TChoice)
137 57 : fprintf(codefile, "break;\n");
138 : }
139 188 : if(t->type == TChoice) {
140 20 : if (have_ellipsis) {
141 5 : fprintf(codefile, "case %s: {\n"
142 : "int ret;\n"
143 : "ret=der_copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n"
144 : "if (ret) goto fail;\n"
145 : "break;\n"
146 : "}\n",
147 : have_ellipsis->label,
148 : from, have_ellipsis->gen_name,
149 : to, have_ellipsis->gen_name);
150 5 : used_fail++;
151 : }
152 20 : fprintf(codefile, "}\n");
153 : }
154 188 : break;
155 : }
156 : case TSetOf:
157 : case TSequenceOf: {
158 : char *f;
159 : char *T;
160 :
161 72 : fprintf (codefile, "if(((%s)->val = "
162 : "malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n",
163 : to, from, to, from);
164 72 : fprintf (codefile, "goto fail;\n");
165 72 : used_fail++;
166 72 : fprintf(codefile,
167 : "for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
168 : to, to, from, to);
169 72 : asprintf(&f, "&(%s)->val[(%s)->len]", from, to);
170 72 : if (f == NULL)
171 0 : errx(1, "malloc");
172 72 : asprintf(&T, "&(%s)->val[(%s)->len]", to, to);
173 72 : if (T == NULL)
174 0 : errx(1, "malloc");
175 72 : copy_type(f, T, t->subtype, FALSE);
176 72 : fprintf(codefile, "}\n");
177 72 : free(f);
178 72 : free(T);
179 72 : break;
180 : }
181 : case TGeneralizedTime:
182 6 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
183 6 : break;
184 : case TGeneralString:
185 14 : copy_primitive ("general_string", from, to);
186 14 : break;
187 : case TTeletexString:
188 1 : copy_primitive ("general_string", from, to);
189 1 : break;
190 : case TUTCTime:
191 1 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
192 1 : break;
193 : case TUTF8String:
194 39 : copy_primitive ("utf8string", from, to);
195 39 : break;
196 : case TPrintableString:
197 1 : copy_primitive ("printable_string", from, to);
198 1 : break;
199 : case TIA5String:
200 4 : copy_primitive ("ia5_string", from, to);
201 4 : break;
202 : case TBMPString:
203 2 : copy_primitive ("bmp_string", from, to);
204 2 : break;
205 : case TUniversalString:
206 1 : copy_primitive ("universal_string", from, to);
207 1 : break;
208 : case TVisibleString:
209 1 : copy_primitive ("visible_string", from, to);
210 1 : break;
211 : case TTag:
212 1002 : copy_type (from, to, t->subtype, preserve);
213 1002 : break;
214 : case TOID:
215 19 : copy_primitive ("oid", from, to);
216 19 : break;
217 : case TNull:
218 3 : break;
219 : default :
220 0 : abort ();
221 : }
222 2025 : }
223 :
224 : void
225 : generate_type_copy (const Symbol *s)
226 293 : {
227 293 : int preserve = preserve_type(s->name) ? TRUE : FALSE;
228 :
229 293 : used_fail = 0;
230 :
231 293 : fprintf (codefile, "int\n"
232 : "copy_%s(const %s *from, %s *to)\n"
233 : "{\n"
234 : "memset(to, 0, sizeof(*to));\n",
235 : s->gen_name, s->gen_name, s->gen_name);
236 293 : copy_type ("from", "to", s->type, preserve);
237 293 : fprintf (codefile, "return 0;\n");
238 :
239 293 : if (used_fail)
240 264 : fprintf (codefile, "fail:\n"
241 : "free_%s(to);\n"
242 : "return ENOMEM;\n",
243 : s->gen_name);
244 :
245 293 : fprintf(codefile,
246 : "}\n\n");
247 293 : }
248 :
|