Line data Source code
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 476 : copy_primitive (const char *typename, const char *from, const char *to)
42 : {
43 476 : fprintf (codefile, "if(der_copy_%s(%s, %s)) goto fail;\n",
44 : typename, from, to);
45 476 : used_fail++;
46 476 : }
47 :
48 : static void
49 5516 : copy_type (const char *from, const char *to, const Type *t, int preserve)
50 : {
51 5516 : switch (t->type) {
52 1134 : case TType:
53 : #if 0
54 : copy_type (from, to, t->symbol->type, preserve);
55 : #endif
56 1134 : fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n",
57 1134 : t->symbol->gen_name, from, to);
58 1134 : used_fail++;
59 1134 : break;
60 308 : case TInteger:
61 308 : if (t->range == NULL && t->members == NULL) {
62 56 : copy_primitive ("heim_integer", from, to);
63 56 : break;
64 : }
65 : fallthrough;
66 : case TBoolean:
67 : case TEnumerated :
68 280 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
69 280 : break;
70 196 : case TOctetString:
71 196 : copy_primitive ("octet_string", from, to);
72 196 : break;
73 140 : case TBitString:
74 140 : if (HEIM_TAILQ_EMPTY(t->members))
75 98 : copy_primitive ("bit_string", from, to);
76 : else
77 42 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
78 140 : break;
79 532 : case TSet:
80 : case TSequence:
81 : case TChoice: {
82 532 : Member *m, *have_ellipsis = NULL;
83 :
84 532 : if(t->members == NULL)
85 0 : break;
86 :
87 532 : if ((t->type == TSequence || t->type == TChoice) && preserve) {
88 0 : fprintf(codefile,
89 : "{ int ret;\n"
90 : "ret = der_copy_octet_string(&(%s)->_save, &(%s)->_save);\n"
91 : "if (ret) goto fail;\n"
92 : "}\n",
93 : from, to);
94 0 : used_fail++;
95 : }
96 :
97 532 : if(t->type == TChoice) {
98 126 : fprintf(codefile, "(%s)->element = (%s)->element;\n", to, from);
99 126 : fprintf(codefile, "switch((%s)->element) {\n", from);
100 : }
101 :
102 2422 : HEIM_TAILQ_FOREACH(m, t->members, members) {
103 : char *fs;
104 : char *ts;
105 :
106 1890 : if (m->ellipsis) {
107 84 : have_ellipsis = m;
108 84 : continue;
109 : }
110 :
111 1806 : if(t->type == TChoice)
112 462 : fprintf(codefile, "case %s:\n", m->label);
113 :
114 5418 : if (asprintf (&fs, "%s(%s)->%s%s",
115 1806 : m->optional ? "" : "&", from,
116 1806 : t->type == TChoice ? "u." : "", m->gen_name) < 0)
117 0 : errx(1, "malloc");
118 1806 : if (fs == NULL)
119 0 : errx(1, "malloc");
120 5418 : if (asprintf (&ts, "%s(%s)->%s%s",
121 1806 : m->optional ? "" : "&", to,
122 1806 : t->type == TChoice ? "u." : "", m->gen_name) < 0)
123 0 : errx(1, "malloc");
124 1806 : if (ts == NULL)
125 0 : errx(1, "malloc");
126 1806 : if(m->optional){
127 700 : fprintf(codefile, "if(%s) {\n", fs);
128 700 : fprintf(codefile, "%s = calloc(1, sizeof(*%s));\n", ts, ts);
129 700 : fprintf(codefile, "if(%s == NULL) goto fail;\n", ts);
130 700 : used_fail++;
131 : }
132 1806 : copy_type (fs, ts, m->type, FALSE);
133 1806 : if(m->optional){
134 700 : fprintf(codefile, "}else\n");
135 700 : fprintf(codefile, "%s = NULL;\n", ts);
136 : }
137 1806 : free (fs);
138 1806 : free (ts);
139 1806 : if(t->type == TChoice)
140 462 : fprintf(codefile, "break;\n");
141 : }
142 532 : if(t->type == TChoice) {
143 126 : if (have_ellipsis) {
144 14 : fprintf(codefile, "case %s: {\n"
145 : "int ret;\n"
146 : "ret=der_copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n"
147 : "if (ret) goto fail;\n"
148 : "break;\n"
149 : "}\n",
150 : have_ellipsis->label,
151 : from, have_ellipsis->gen_name,
152 : to, have_ellipsis->gen_name);
153 14 : used_fail++;
154 : }
155 126 : fprintf(codefile, "}\n");
156 : }
157 532 : break;
158 : }
159 224 : case TSetOf:
160 : case TSequenceOf: {
161 224 : char *f = NULL, *T = NULL;
162 :
163 224 : fprintf (codefile, "if(((%s)->val = "
164 : "calloc(1, (%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n",
165 : to, from, to, from);
166 224 : fprintf (codefile, "goto fail;\n");
167 224 : used_fail++;
168 224 : fprintf(codefile,
169 : "for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
170 : to, to, from, to);
171 224 : if (asprintf(&f, "&(%s)->val[(%s)->len]", from, to) < 0)
172 0 : errx(1, "malloc");
173 224 : if (f == NULL)
174 0 : errx(1, "malloc");
175 224 : if (asprintf(&T, "&(%s)->val[(%s)->len]", to, to) < 0)
176 0 : errx(1, "malloc");
177 224 : if (T == NULL)
178 0 : errx(1, "malloc");
179 224 : copy_type(f, T, t->subtype, FALSE);
180 224 : fprintf(codefile, "}\n");
181 224 : free(f);
182 224 : free(T);
183 224 : break;
184 : }
185 0 : case TGeneralizedTime:
186 0 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
187 0 : break;
188 14 : case TGeneralString:
189 14 : copy_primitive ("general_string", from, to);
190 14 : break;
191 0 : case TTeletexString:
192 0 : copy_primitive ("general_string", from, to);
193 0 : break;
194 0 : case TUTCTime:
195 0 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
196 0 : break;
197 56 : case TUTF8String:
198 56 : copy_primitive ("utf8string", from, to);
199 56 : break;
200 0 : case TPrintableString:
201 0 : copy_primitive ("printable_string", from, to);
202 0 : break;
203 0 : case TIA5String:
204 0 : copy_primitive ("ia5_string", from, to);
205 0 : break;
206 0 : case TBMPString:
207 0 : copy_primitive ("bmp_string", from, to);
208 0 : break;
209 0 : case TUniversalString:
210 0 : copy_primitive ("universal_string", from, to);
211 0 : break;
212 0 : case TVisibleString:
213 0 : copy_primitive ("visible_string", from, to);
214 0 : break;
215 2814 : case TTag:
216 2814 : copy_type (from, to, t->subtype, preserve);
217 2814 : break;
218 56 : case TOID:
219 56 : copy_primitive ("oid", from, to);
220 56 : break;
221 14 : case TNull:
222 14 : break;
223 0 : default :
224 0 : abort ();
225 : }
226 5516 : }
227 :
228 : void
229 672 : generate_type_copy (const Symbol *s)
230 : {
231 : struct decoration deco;
232 672 : ssize_t more_deco = -1;
233 672 : int preserve = preserve_type(s->name) ? TRUE : FALSE;
234 672 : int save_used_fail = used_fail;
235 :
236 672 : used_fail = 0;
237 :
238 672 : fprintf (codefile, "int ASN1CALL\n"
239 : "copy_%s(const %s *from, %s *to)\n"
240 : "{\n"
241 : "memset(to, 0, sizeof(*to));\n",
242 : s->gen_name, s->gen_name, s->gen_name);
243 672 : copy_type ("from", "to", s->type, preserve);
244 1358 : while (decorate_type(s->gen_name, &deco, &more_deco)) {
245 14 : if (deco.ext && deco.copy_function_name == NULL) {
246 : /* Decorated with field of external type but no copy function */
247 28 : if (deco.ptr)
248 0 : fprintf(codefile, "(to)->%s = 0;\n", deco.field_name);
249 : else
250 14 : fprintf(codefile, "memset(&(to)->%s, 0, sizeof((to)->%s));\n",
251 : deco.field_name, deco.field_name);
252 0 : } else if (deco.ext) {
253 : /* Decorated with field of external type w/ copy function */
254 0 : if (deco.ptr) {
255 0 : fprintf(codefile, "if (from->%s) {\n", deco.field_name);
256 0 : fprintf(codefile, "(to)->%s = calloc(1, sizeof(*(to)->%s));\n",
257 : deco.field_name, deco.field_name);
258 0 : fprintf(codefile, "if (%s((from)->%s, (to)->%s)) goto fail;\n",
259 : deco.copy_function_name, deco.field_name, deco.field_name);
260 0 : fprintf(codefile, "}\n");
261 : } else {
262 0 : fprintf(codefile, "if (%s(&(from)->%s, &(to)->%s)) goto fail;\n",
263 : deco.copy_function_name, deco.field_name, deco.field_name);
264 : }
265 0 : } else if (deco.opt) {
266 : /* Decorated with optional field of ASN.1 type */
267 0 : fprintf(codefile, "if (from->%s) {\n", deco.field_name);
268 0 : fprintf(codefile, "(to)->%s = calloc(1, sizeof(*(to)->%s));\n", deco.field_name, deco.field_name);
269 0 : fprintf(codefile, "if (copy_%s((from)->%s, (to)->%s)) goto fail;\n", deco.field_type, deco.field_name, deco.field_name);
270 0 : fprintf(codefile, "}\n");
271 : } else {
272 : /* Decorated with required field of ASN.1 type */
273 0 : fprintf(codefile, "if (copy_%s(&(from)->%s, &(to)->%s)) goto fail;\n", deco.field_type, deco.field_name, deco.field_name);
274 : }
275 14 : used_fail++;
276 14 : free(deco.field_type);
277 : }
278 672 : fprintf (codefile, "return 0;\n");
279 :
280 672 : if (used_fail)
281 602 : fprintf (codefile, "fail:\n"
282 : "free_%s(to);\n"
283 : "return ENOMEM;\n",
284 : s->gen_name);
285 :
286 672 : fprintf(codefile,
287 : "}\n\n");
288 672 : used_fail = save_used_fail;
289 672 : }
290 :
|