Branch data 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 : 229 : copy_primitive (const char *typename, const char *from, const char *to)
42 : : {
43 : 229 : fprintf (codefile, "if(der_copy_%s(%s, %s)) goto fail;\n",
44 : : typename, from, to);
45 : 229 : used_fail++;
46 : 229 : }
47 : :
48 : : static void
49 : 2048 : copy_type (const char *from, const char *to, const Type *t, int preserve)
50 : : {
51 [ + + + + : 2048 : switch (t->type) {
+ + + + +
+ + + + +
+ + + + +
+ - ]
52 : : case TType:
53 : : #if 0
54 : : copy_type (from, to, t->symbol->type, preserve);
55 : : #endif
56 : 466 : fprintf (codefile, "if(copy_%s(%s, %s)) goto fail;\n",
57 : 466 : t->symbol->gen_name, from, to);
58 : 466 : used_fail++;
59 : 466 : break;
60 : : case TInteger:
61 [ + + ][ + + ]: 88 : if (t->range == NULL && t->members == NULL) {
62 : 38 : copy_primitive ("heim_integer", from, to);
63 : 38 : break;
64 : : }
65 : : case TBoolean:
66 : : case TEnumerated :
67 : 58 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
68 : 58 : 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 : 189 : Member *m, *have_ellipsis = NULL;
82 : :
83 [ - + ]: 189 : if(t->members == NULL)
84 : 0 : break;
85 : :
86 [ + + ][ + - ]: 189 : 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 [ + + ]: 189 : 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 [ + + ]: 887 : ASN1_TAILQ_FOREACH(m, t->members, members) {
102 : : char *fs;
103 : : char *ts;
104 : :
105 [ + + ]: 698 : if (m->ellipsis) {
106 : 32 : have_ellipsis = m;
107 : 32 : continue;
108 : : }
109 : :
110 [ + + ]: 666 : if(t->type == TChoice)
111 : 61 : fprintf(codefile, "case %s:\n", m->label);
112 : :
113 [ + + ][ + + ]: 666 : if (asprintf (&fs, "%s(%s)->%s%s",
[ - + ]
114 : 666 : m->optional ? "" : "&", from,
115 : 666 : t->type == TChoice ? "u." : "", m->gen_name) < 0)
116 : 0 : errx(1, "malloc");
117 [ - + ]: 666 : if (fs == NULL)
118 : 0 : errx(1, "malloc");
119 [ + + ][ + + ]: 666 : if (asprintf (&ts, "%s(%s)->%s%s",
[ - + ]
120 : 666 : m->optional ? "" : "&", to,
121 : 666 : t->type == TChoice ? "u." : "", m->gen_name) < 0)
122 : 0 : errx(1, "malloc");
123 [ - + ]: 666 : if (ts == NULL)
124 : 0 : errx(1, "malloc");
125 [ + + ]: 666 : if(m->optional){
126 : 230 : fprintf(codefile, "if(%s) {\n", fs);
127 : 230 : fprintf(codefile, "%s = malloc(sizeof(*%s));\n", ts, ts);
128 : 230 : fprintf(codefile, "if(%s == NULL) goto fail;\n", ts);
129 : 230 : used_fail++;
130 : : }
131 : 666 : copy_type (fs, ts, m->type, FALSE);
132 [ + + ]: 666 : if(m->optional){
133 : 230 : fprintf(codefile, "}else\n");
134 : 230 : fprintf(codefile, "%s = NULL;\n", ts);
135 : : }
136 : 666 : free (fs);
137 : 666 : free (ts);
138 [ + + ]: 666 : if(t->type == TChoice)
139 : 61 : fprintf(codefile, "break;\n");
140 : : }
141 [ + + ]: 189 : if(t->type == TChoice) {
142 [ + + ]: 20 : if (have_ellipsis) {
143 : 5 : fprintf(codefile, "case %s: {\n"
144 : : "int ret;\n"
145 : : "ret=der_copy_octet_string(&(%s)->u.%s, &(%s)->u.%s);\n"
146 : : "if (ret) goto fail;\n"
147 : : "break;\n"
148 : : "}\n",
149 : : have_ellipsis->label,
150 : : from, have_ellipsis->gen_name,
151 : : to, have_ellipsis->gen_name);
152 : 5 : used_fail++;
153 : : }
154 : 20 : fprintf(codefile, "}\n");
155 : : }
156 : 189 : break;
157 : : }
158 : : case TSetOf:
159 : : case TSequenceOf: {
160 : 72 : char *f = NULL, *T = NULL;
161 : :
162 : 72 : fprintf (codefile, "if(((%s)->val = "
163 : : "malloc((%s)->len * sizeof(*(%s)->val))) == NULL && (%s)->len != 0)\n",
164 : : to, from, to, from);
165 : 72 : fprintf (codefile, "goto fail;\n");
166 : 72 : used_fail++;
167 : 72 : fprintf(codefile,
168 : : "for((%s)->len = 0; (%s)->len < (%s)->len; (%s)->len++){\n",
169 : : to, to, from, to);
170 [ - + ]: 72 : if (asprintf(&f, "&(%s)->val[(%s)->len]", from, to) < 0)
171 : 0 : errx(1, "malloc");
172 [ - + ]: 72 : if (f == NULL)
173 : 0 : errx(1, "malloc");
174 [ - + ]: 72 : if (asprintf(&T, "&(%s)->val[(%s)->len]", to, to) < 0)
175 : 0 : errx(1, "malloc");
176 [ - + ]: 72 : if (T == NULL)
177 : 0 : errx(1, "malloc");
178 : 72 : copy_type(f, T, t->subtype, FALSE);
179 : 72 : fprintf(codefile, "}\n");
180 : 72 : free(f);
181 : 72 : free(T);
182 : 72 : break;
183 : : }
184 : : case TGeneralizedTime:
185 : 6 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
186 : 6 : break;
187 : : case TGeneralString:
188 : 14 : copy_primitive ("general_string", from, to);
189 : 14 : break;
190 : : case TTeletexString:
191 : 1 : copy_primitive ("general_string", from, to);
192 : 1 : break;
193 : : case TUTCTime:
194 : 1 : fprintf(codefile, "*(%s) = *(%s);\n", to, from);
195 : 1 : break;
196 : : case TUTF8String:
197 : 40 : copy_primitive ("utf8string", from, to);
198 : 40 : break;
199 : : case TPrintableString:
200 : 1 : copy_primitive ("printable_string", from, to);
201 : 1 : break;
202 : : case TIA5String:
203 : 4 : copy_primitive ("ia5_string", from, to);
204 : 4 : break;
205 : : case TBMPString:
206 : 2 : copy_primitive ("bmp_string", from, to);
207 : 2 : break;
208 : : case TUniversalString:
209 : 1 : copy_primitive ("universal_string", from, to);
210 : 1 : break;
211 : : case TVisibleString:
212 : 1 : copy_primitive ("visible_string", from, to);
213 : 1 : break;
214 : : case TTag:
215 : 1014 : copy_type (from, to, t->subtype, preserve);
216 : 1014 : break;
217 : : case TOID:
218 : 19 : copy_primitive ("oid", from, to);
219 : 19 : break;
220 : : case TNull:
221 : 3 : break;
222 : : default :
223 : 0 : abort ();
224 : : }
225 : 2048 : }
226 : :
227 : : void
228 : 296 : generate_type_copy (const Symbol *s)
229 : : {
230 : 296 : int preserve = preserve_type(s->name) ? TRUE : FALSE;
231 : :
232 : 296 : used_fail = 0;
233 : :
234 : 296 : fprintf (codefile, "int ASN1CALL\n"
235 : : "copy_%s(const %s *from, %s *to)\n"
236 : : "{\n"
237 : : "memset(to, 0, sizeof(*to));\n",
238 : : s->gen_name, s->gen_name, s->gen_name);
239 : 296 : copy_type ("from", "to", s->type, preserve);
240 : 296 : fprintf (codefile, "return 0;\n");
241 : :
242 [ + + ]: 296 : if (used_fail)
243 : 267 : fprintf (codefile, "fail:\n"
244 : : "free_%s(to);\n"
245 : : "return ENOMEM;\n",
246 : : s->gen_name);
247 : :
248 : 296 : fprintf(codefile,
249 : : "}\n\n");
250 : 296 : }
251 : :
|