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 void
39 : 286 : length_primitive (const char *typename,
40 : : const char *name,
41 : : const char *variable)
42 : : {
43 : 286 : fprintf (codefile, "%s += der_length_%s(%s);\n", variable, typename, name);
44 : 286 : }
45 : :
46 : : /* XXX same as der_length_tag */
47 : : static size_t
48 : 1014 : length_tag(unsigned int tag)
49 : : {
50 : 1014 : size_t len = 0;
51 : :
52 [ + + ]: 1014 : if(tag <= 30)
53 : 1012 : return 1;
54 [ + + ]: 6 : while(tag) {
55 : 4 : tag /= 128;
56 : 4 : len++;
57 : : }
58 : 1014 : return len + 1;
59 : : }
60 : :
61 : :
62 : : static int
63 : 2048 : length_type (const char *name, const Type *t,
64 : : const char *variable, const char *tmpstr)
65 : : {
66 [ + + + - : 2048 : switch (t->type) {
+ + + + +
+ + + + +
+ + + + +
+ + - ]
67 : : case TType:
68 : : #if 0
69 : : length_type (name, t->symbol->type);
70 : : #endif
71 : 466 : fprintf (codefile, "%s += length_%s(%s);\n",
72 : 466 : variable, t->symbol->gen_name, name);
73 : 466 : break;
74 : : case TInteger:
75 [ + + ]: 88 : if(t->members) {
76 : 16 : fprintf(codefile,
77 : : "{\n"
78 : : "int enumint = *%s;\n", name);
79 : 16 : length_primitive ("integer", "&enumint", variable);
80 : 16 : fprintf(codefile, "}\n");
81 [ + + ]: 72 : } else if (t->range == NULL) {
82 : 38 : length_primitive ("heim_integer", name, variable);
83 [ + + ][ + - ]: 41 : } else if (t->range->min == INT_MIN && t->range->max == INT_MAX) {
84 : 7 : length_primitive ("integer", name, variable);
85 [ + - ][ + - ]: 54 : } else if (t->range->min == 0 && t->range->max == UINT_MAX) {
86 : 27 : length_primitive ("unsigned", name, variable);
87 [ # # ][ # # ]: 0 : } else if (t->range->min == 0 && t->range->max == INT_MAX) {
88 : 0 : length_primitive ("unsigned", name, variable);
89 : : } else
90 : 0 : errx(1, "%s: unsupported range %d -> %d",
91 : 0 : name, t->range->min, t->range->max);
92 : :
93 : 88 : break;
94 : : case TBoolean:
95 : 8 : fprintf (codefile, "%s += 1;\n", variable);
96 : 8 : break;
97 : : case TEnumerated :
98 : 0 : length_primitive ("enumerated", name, variable);
99 : 0 : break;
100 : : case TOctetString:
101 : 96 : length_primitive ("octet_string", name, variable);
102 : 96 : break;
103 : : case TBitString: {
104 [ + + ]: 22 : if (ASN1_TAILQ_EMPTY(t->members))
105 : 12 : length_primitive("bit_string", name, variable);
106 : : else {
107 [ + + ]: 10 : if (!rfc1510_bitstring) {
108 : : Member *m;
109 : 5 : int pos = ASN1_TAILQ_LAST(t->members, memhead)->val;
110 : :
111 : 5 : fprintf(codefile,
112 : : "do {\n");
113 [ + + ]: 55 : ASN1_TAILQ_FOREACH_REVERSE(m, t->members, memhead, members) {
114 [ + + ]: 55 : while (m->val / 8 < pos / 8) {
115 : 5 : pos -= 8;
116 : : }
117 : 50 : fprintf (codefile,
118 : : "if((%s)->%s) { %s += %d; break; }\n",
119 : 50 : name, m->gen_name, variable, (pos + 8) / 8);
120 : : }
121 : 5 : fprintf(codefile,
122 : : "} while(0);\n");
123 : 5 : fprintf (codefile, "%s += 1;\n", variable);
124 : : } else {
125 : 5 : fprintf (codefile, "%s += 5;\n", variable);
126 : : }
127 : : }
128 : 22 : break;
129 : : }
130 : : case TSet:
131 : : case TSequence:
132 : : case TChoice: {
133 : 189 : Member *m, *have_ellipsis = NULL;
134 : :
135 [ - + ]: 189 : if (t->members == NULL)
136 : 0 : break;
137 : :
138 [ + + ]: 189 : if(t->type == TChoice)
139 : 20 : fprintf (codefile, "switch((%s)->element) {\n", name);
140 : :
141 [ + + ]: 887 : ASN1_TAILQ_FOREACH(m, t->members, members) {
142 : : char *s;
143 : :
144 [ + + ]: 698 : if (m->ellipsis) {
145 : 32 : have_ellipsis = m;
146 : 32 : continue;
147 : : }
148 : :
149 [ + + ]: 666 : if(t->type == TChoice)
150 : 61 : fprintf(codefile, "case %s:\n", m->label);
151 : :
152 [ + - ][ - + ]: 666 : if (asprintf (&s, "%s(%s)->%s%s",
153 : 666 : m->optional ? "" : "&", name,
154 [ + + ][ + + ]: 666 : t->type == TChoice ? "u." : "", m->gen_name) < 0 || s == NULL)
155 : 0 : errx(1, "malloc");
156 [ + + ]: 666 : if (m->optional)
157 : 230 : fprintf (codefile, "if(%s)", s);
158 [ - + ]: 436 : else if(m->defval)
159 : 0 : gen_compare_defval(s + 1, m->defval);
160 : 666 : fprintf (codefile, "{\n"
161 : : "size_t %s_oldret = %s;\n"
162 : : "%s = 0;\n", tmpstr, variable, variable);
163 : 666 : length_type (s, m->type, "ret", m->gen_name);
164 : 666 : fprintf (codefile, "ret += %s_oldret;\n", tmpstr);
165 : 666 : fprintf (codefile, "}\n");
166 : 666 : free (s);
167 [ + + ]: 666 : if(t->type == TChoice)
168 : 61 : fprintf(codefile, "break;\n");
169 : : }
170 [ + + ]: 189 : if(t->type == TChoice) {
171 [ + + ]: 20 : if (have_ellipsis)
172 : 5 : fprintf(codefile,
173 : : "case %s:\n"
174 : : "ret += (%s)->u.%s.length;\n"
175 : : "break;\n",
176 : : have_ellipsis->label,
177 : : name,
178 : : have_ellipsis->gen_name);
179 : 20 : fprintf (codefile, "}\n"); /* switch */
180 : : }
181 : 189 : break;
182 : : }
183 : : case TSetOf:
184 : : case TSequenceOf: {
185 : 72 : char *n = NULL;
186 : 72 : char *sname = NULL;
187 : :
188 : 72 : fprintf (codefile,
189 : : "{\n"
190 : : "size_t %s_oldret = %s;\n"
191 : : "int i;\n"
192 : : "%s = 0;\n",
193 : : tmpstr, variable, variable);
194 : :
195 : 72 : fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
196 : 72 : fprintf (codefile, "size_t %s_for_oldret = %s;\n"
197 : : "%s = 0;\n", tmpstr, variable, variable);
198 [ + - ][ - + ]: 72 : if (asprintf (&n, "&(%s)->val[i]", name) < 0 || n == NULL)
199 : 0 : errx(1, "malloc");
200 [ + - ][ - + ]: 72 : if (asprintf (&sname, "%s_S_Of", tmpstr) < 0 || sname == NULL)
201 : 0 : errx(1, "malloc");
202 : 72 : length_type(n, t->subtype, variable, sname);
203 : 72 : fprintf (codefile, "%s += %s_for_oldret;\n",
204 : : variable, tmpstr);
205 : 72 : fprintf (codefile, "}\n");
206 : :
207 : 72 : fprintf (codefile,
208 : : "%s += %s_oldret;\n"
209 : : "}\n", variable, tmpstr);
210 : 72 : free(n);
211 : 72 : free(sname);
212 : 72 : break;
213 : : }
214 : : case TGeneralizedTime:
215 : 6 : length_primitive ("generalized_time", name, variable);
216 : 6 : break;
217 : : case TGeneralString:
218 : 14 : length_primitive ("general_string", name, variable);
219 : 14 : break;
220 : : case TTeletexString:
221 : 1 : length_primitive ("general_string", name, variable);
222 : 1 : break;
223 : : case TUTCTime:
224 : 1 : length_primitive ("utctime", name, variable);
225 : 1 : break;
226 : : case TUTF8String:
227 : 40 : length_primitive ("utf8string", name, variable);
228 : 40 : break;
229 : : case TPrintableString:
230 : 1 : length_primitive ("printable_string", name, variable);
231 : 1 : break;
232 : : case TIA5String:
233 : 4 : length_primitive ("ia5_string", name, variable);
234 : 4 : break;
235 : : case TBMPString:
236 : 2 : length_primitive ("bmp_string", name, variable);
237 : 2 : break;
238 : : case TUniversalString:
239 : 1 : length_primitive ("universal_string", name, variable);
240 : 1 : break;
241 : : case TVisibleString:
242 : 1 : length_primitive ("visible_string", name, variable);
243 : 1 : break;
244 : : case TNull:
245 : 3 : fprintf (codefile, "/* NULL */\n");
246 : 3 : break;
247 : : case TTag:{
248 : 1014 : char *tname = NULL;
249 [ + - ][ - + ]: 1014 : if (asprintf(&tname, "%s_tag", tmpstr) < 0 || tname == NULL)
250 : 0 : errx(1, "malloc");
251 : 1014 : length_type (name, t->subtype, variable, tname);
252 : 1014 : fprintf (codefile, "ret += %lu + der_length_len (ret);\n",
253 : 1014 : (unsigned long)length_tag(t->tag.tagvalue));
254 : 1014 : free(tname);
255 : 1014 : break;
256 : : }
257 : : case TOID:
258 : 19 : length_primitive ("oid", name, variable);
259 : 19 : break;
260 : : default :
261 : 0 : abort ();
262 : : }
263 : 2048 : return 0;
264 : : }
265 : :
266 : : void
267 : 296 : generate_type_length (const Symbol *s)
268 : : {
269 : 296 : fprintf (codefile,
270 : : "size_t ASN1CALL\n"
271 : : "length_%s(const %s *data)\n"
272 : : "{\n"
273 : : "size_t ret = 0;\n",
274 : : s->gen_name, s->gen_name);
275 : :
276 : 296 : length_type ("data", s->type, "ret", "Top");
277 : 296 : fprintf (codefile, "return ret;\n}\n\n");
278 : 296 : }
279 : :
|