remove gcc34
[dragonfly.git] / crypto / heimdal-0.6.3 / lib / asn1 / gen_length.c
1 /*
2  * Copyright (c) 1997 - 2000 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: gen_length.c,v 1.11.6.1 2004/01/26 09:26:10 lha Exp $");
37
38 static void
39 length_primitive (const char *typename,
40                   const char *name,
41                   const char *variable)
42 {
43     fprintf (codefile, "%s += length_%s(%s);\n", variable, typename, name);
44 }
45
46 static void
47 length_type (const char *name, const Type *t, const char *variable)
48 {
49     switch (t->type) {
50     case TType:
51 #if 0
52         length_type (name, t->symbol->type);
53 #endif
54         fprintf (codefile, "%s += length_%s(%s);\n",
55                  variable, t->symbol->gen_name, name);
56         break;
57     case TInteger:
58         if(t->members == NULL)
59             length_primitive ("integer", name, variable);
60         else {
61             char *s;
62             asprintf(&s, "(const int*)%s", name);
63             if(s == NULL)
64                 errx (1, "out of memory");
65             length_primitive ("integer", s, variable);
66             free(s);
67         }
68         break;
69     case TUInteger:
70         length_primitive ("unsigned", name, variable);
71         break;
72     case TEnumerated :
73         length_primitive ("enumerated", name, variable);
74         break;
75     case TOctetString:
76         length_primitive ("octet_string", name, variable);
77         break;
78     case TOID :
79         length_primitive ("oid", name, variable);
80         break;
81     case TBitString: {
82         /*
83          * XXX - Hope this is correct
84          * look at TBitString case in `encode_type'
85          */
86         fprintf (codefile, "%s += 7;\n", variable);
87         break;
88     }
89     case TSequence: {
90         Member *m;
91         int tag = -1;
92
93         if (t->members == NULL)
94             break;
95       
96         for (m = t->members; m && tag != m->val; m = m->next) {
97             char *s;
98
99             asprintf (&s, "%s(%s)->%s",
100                       m->optional ? "" : "&", name, m->gen_name);
101             if (m->optional)
102                 fprintf (codefile, "if(%s)", s);
103             fprintf (codefile, "{\n"
104                      "int oldret = %s;\n"
105                      "%s = 0;\n", variable, variable);
106             length_type (s, m->type, "ret");
107             fprintf (codefile, "%s += 1 + length_len(%s) + oldret;\n",
108                      variable, variable);
109             fprintf (codefile, "}\n");
110             if (tag == -1)
111                 tag = m->val;
112             free (s);
113         }
114         fprintf (codefile,
115                  "%s += 1 + length_len(%s);\n", variable, variable);
116         break;
117     }
118     case TSequenceOf: {
119         char *n;
120
121         fprintf (codefile,
122                  "{\n"
123                  "int oldret = %s;\n"
124                  "int i;\n"
125                  "%s = 0;\n",
126                  variable, variable);
127
128         fprintf (codefile, "for(i = (%s)->len - 1; i >= 0; --i){\n", name);
129         fprintf (codefile, "int oldret = %s;\n"
130                  "%s = 0;\n", variable, variable);
131         asprintf (&n, "&(%s)->val[i]", name);
132         length_type(n, t->subtype, variable);
133         fprintf (codefile, "%s += oldret;\n",
134                  variable);
135         fprintf (codefile, "}\n");
136
137         fprintf (codefile,
138                  "%s += 1 + length_len(%s) + oldret;\n"
139                  "}\n", variable, variable);
140         free(n);
141         break;
142     }
143     case TGeneralizedTime:
144         length_primitive ("generalized_time", name, variable);
145         break;
146     case TGeneralString:
147         length_primitive ("general_string", name, variable);
148         break;
149     case TApplication:
150         length_type (name, t->subtype, variable);
151         fprintf (codefile, "ret += 1 + length_len (ret);\n");
152         break;
153     default :
154         abort ();
155     }
156 }
157
158 void
159 generate_type_length (const Symbol *s)
160 {
161   fprintf (headerfile,
162            "size_t length_%s(const %s *);\n",
163            s->gen_name, s->gen_name);
164
165   fprintf (codefile,
166            "size_t\n"
167            "length_%s(const %s *data)\n"
168            "{\n"
169            "size_t ret = 0;\n",
170            s->gen_name, s->gen_name);
171
172   length_type ("data", s->type, "ret");
173   fprintf (codefile, "return ret;\n}\n\n");
174 }
175