blob: 4376089eaa31c13df84fb3d2b1e205a8614a8241 [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include <stdio.h>
2#include <string.h>
3#include <stdlib.h>
4#include <errno.h>
5#include <assert.h>
6
7#include "asn1parser.h"
Lev Walkin4dcf8362017-08-07 20:10:05 -07008#include "asn1p_class.h"
9
10asn1p_ioc_table_t *
11asn1p_ioc_table_new() {
12 asn1p_ioc_table_t *it = calloc(1, sizeof(*it));
13 assert(it);
14 return it;
15}
16
17void
18asn1p_ioc_table_add(asn1p_ioc_table_t *it, asn1p_ioc_row_t *row) {
19 assert(it);
20
21 asn1p_ioc_row_t **new_rows =
22 realloc(it->row, (it->rows + 1) * sizeof(it->row[0]));
23 assert(new_rows);
24 it->row = new_rows;
25 it->row[it->rows++] = row;
26}
27
28void
Bi-Ruei, Chiu50934ba2017-09-11 08:50:59 +080029asn1p_ioc_table_append(asn1p_ioc_table_t *it, asn1p_ioc_table_t *src) {
30
31 if(!src) return;
32
33 for(size_t i = 0; i < src->rows; i++) {
34 asn1p_ioc_table_add(it, asn1p_ioc_row_clone(src->row[i]));
35 }
36}
37
38void
Lev Walkin4dcf8362017-08-07 20:10:05 -070039asn1p_ioc_table_free(asn1p_ioc_table_t *it) {
40 if(it) {
41 for(size_t i = 0; i < it->rows; i++) {
42 asn1p_ioc_row_delete(it->row[i]);
43 }
44 free(it->row);
45 free(it);
46 }
47}
48
49size_t
50asn1p_ioc_table_max_identifier_length(asn1p_ioc_table_t *it) {
51 size_t max_length = 0;
52 if(it) {
53 for(size_t i = 0; i < it->rows; i++) {
54 size_t len = asn1p_ioc_row_max_identifier_length(it->row[i]);
55 if(len > max_length) max_length = len;
56 }
57 }
58 return max_length;
59}
60
61size_t
62asn1p_ioc_row_max_identifier_length(asn1p_ioc_row_t *row) {
63 size_t max_length = 0;
64 if(row) {
65 for(size_t i = 0; i < row->columns; i++) {
66 if(row->column[i].value) {
67 size_t len = strlen(row->column[i].value->Identifier);
68 if(len > max_length) max_length = len;
69 }
70 }
71 }
72 return max_length;
73}
Lev Walkinf15320b2004-06-03 03:38:44 +000074
Lev Walkind370e9f2006-03-16 10:03:35 +000075asn1p_ioc_row_t *
76asn1p_ioc_row_new(asn1p_expr_t *oclass) {
77 asn1p_ioc_row_t *row;
78 asn1p_expr_t *field;
79 int columns = 0;
80
81 assert(oclass->expr_type == A1TC_CLASSDEF);
82
83 row = calloc(1, sizeof *row);
84 if(!row) return NULL;
85
86 TQ_FOR(field, &oclass->members, next)
87 columns++;
88
89 row->column = calloc(columns, sizeof *row->column);
90 if(!row->column) {
91 free(row);
92 return NULL;
93 }
94 row->columns = columns;
95
96 columns = 0;
97 TQ_FOR(field, &oclass->members, next) {
Lev Walkind370e9f2006-03-16 10:03:35 +000098 row->column[columns].field = field;
99 row->column[columns].value = NULL;
100 columns++;
101 }
102
103 return row;
104}
105
Bi-Ruei, Chiu50934ba2017-09-11 08:50:59 +0800106asn1p_ioc_row_t *
107asn1p_ioc_row_clone(asn1p_ioc_row_t *src) {
108 asn1p_ioc_row_t *row;
109
110 row = calloc(1, sizeof *row);
111 if(!row) return NULL;
112
113 row->column = calloc(src->columns, sizeof *src->column);
114 if(!row->column) {
115 free(row);
116 return NULL;
117 }
118 row->columns = src->columns;
119
120 for(size_t i = 0; i < src->columns; i++) {
121 row->column[i].field = src->column[i].field;
122 row->column[i].value = src->column[i].value ? asn1p_expr_clone(src->column[i].value, 0) : 0;
123 row->column[i].new_ref = 1;
124 }
125
126 return row;
127}
128
Lev Walkind370e9f2006-03-16 10:03:35 +0000129void
130asn1p_ioc_row_delete(asn1p_ioc_row_t *row) {
131 if(row) {
132 if(row->column) {
Lev Walkin62d95d22017-08-06 23:41:11 -0700133 for(size_t i = 0; i < row->columns; i++) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800134 if(!row->column[i].new_ref && row->column[i].value) {
135 /*
136 * Field 'reference' comes from asn1fix_cws.c :
137 * TQ_FIRST(&cell->field->members)->reference
138 * so it should not be freed here.
139 */
140 row->column[i].value->reference = NULL;
141 }
142 asn1p_expr_free(row->column[i].value);
143 }
Lev Walkind370e9f2006-03-16 10:03:35 +0000144 free(row->column);
145 }
146 free(row);
147 }
148}
149
Lev Walkinea6635b2017-08-06 23:23:04 -0700150int
151asn1p_ioc_row_match(const asn1p_ioc_row_t *a, const asn1p_ioc_row_t *b) {
152 assert(a && b);
153
154 if(a->columns != b->columns)
155 return -1; /* Bad! */
156
157 for(size_t i = 0; i < a->columns; i++) {
158 assert(a->column[i].field);
159 assert(b->column[i].field);
160 if(strcmp(a->column[i].field->Identifier,
161 b->column[i].field->Identifier)
162 != 0) {
163 return -1; /* Bad! */
164 }
165 if((a->column[i].value && !b->column[i].value)
166 || (!a->column[i].value && b->column[i].value)) {
167 return 1; /* Not match */
168 }
169 if(a->column[i].value && b->column[i].value) {
170 if(asn1p_expr_compare(a->column[i].value, b->column[i].value)
171 != 0) {
172 return 1; /* Not match */
173 }
174 }
175 }
176
177 return 0;
178}
179
Lev Walkind370e9f2006-03-16 10:03:35 +0000180struct asn1p_ioc_cell_s *
181asn1p_ioc_row_cell_fetch(asn1p_ioc_row_t *row, const char *fieldname) {
Lev Walkin62d95d22017-08-06 23:41:11 -0700182 for(size_t i = 0; i < row->columns; i++) {
Lev Walkind370e9f2006-03-16 10:03:35 +0000183 if(strcmp(row->column[i].field->Identifier, fieldname) == 0)
184 return &row->column[i];
185 }
186 errno = ESRCH;
187 return NULL;
188}
189
Lev Walkinf15320b2004-06-03 03:38:44 +0000190asn1p_wsyntx_chunk_t *
191asn1p_wsyntx_chunk_new() {
192 asn1p_wsyntx_chunk_t *wc;
193
194 wc = calloc(1, sizeof(*wc));
195
196 return wc;
197}
198
199void
200asn1p_wsyntx_chunk_free(asn1p_wsyntx_chunk_t *wc) {
201 if(wc) {
Lev Walkin9d542d22006-03-14 16:31:37 +0000202 switch(wc->type) {
Lev Walkin57074f12006-03-16 05:11:14 +0000203 case WC_LITERAL:
204 case WC_WHITESPACE:
Lev Walkind370e9f2006-03-16 10:03:35 +0000205 case WC_FIELD:
Lev Walkin57074f12006-03-16 05:11:14 +0000206 free(wc->content.token); break;
Lev Walkin9d542d22006-03-14 16:31:37 +0000207 case WC_OPTIONALGROUP:
208 asn1p_wsyntx_free(wc->content.syntax);
209 break;
210 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000211 free(wc);
212 }
213}
214
215asn1p_wsyntx_chunk_t *
216asn1p_wsyntx_chunk_clone(asn1p_wsyntx_chunk_t *wc) {
217 asn1p_wsyntx_chunk_t *nc;
218
219 nc = asn1p_wsyntx_chunk_new();
220 if(nc) {
Lev Walkin57074f12006-03-16 05:11:14 +0000221 nc->type = wc->type;
Lev Walkin9d542d22006-03-14 16:31:37 +0000222 switch(wc->type) {
223 case WC_LITERAL:
Lev Walkin57074f12006-03-16 05:11:14 +0000224 case WC_WHITESPACE:
Lev Walkind370e9f2006-03-16 10:03:35 +0000225 case WC_FIELD:
Lev Walkin9d542d22006-03-14 16:31:37 +0000226 nc->content.token = malloc(strlen(wc->content.token)+1);
227 strcpy(nc->content.token, wc->content.token);
228 break;
Lev Walkin9d542d22006-03-14 16:31:37 +0000229 case WC_OPTIONALGROUP:
230 nc->content.syntax = asn1p_wsyntx_clone(wc->content.syntax);
231 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000232 }
233 }
234
235 return nc;
236}
237
238asn1p_wsyntx_t *
239asn1p_wsyntx_new() {
240 asn1p_wsyntx_t *wx;
241
242 wx = calloc(1, sizeof(*wx));
243 if(wx) {
244 TQ_INIT(&(wx->chunks));
245 }
246
247 return wx;
248}
249
250void
251asn1p_wsyntx_free(asn1p_wsyntx_t *wx) {
252 if(wx) {
253 asn1p_wsyntx_chunk_t *wc;
254 while((wc = TQ_REMOVE(&(wx->chunks), next)))
255 asn1p_wsyntx_chunk_free(wc);
256 free(wx);
257 }
258}
259
260asn1p_wsyntx_t *
261asn1p_wsyntx_clone(asn1p_wsyntx_t *wx) {
262 asn1p_wsyntx_t *nw;
263
264 nw = asn1p_wsyntx_new();
265 if(nw) {
266 asn1p_wsyntx_chunk_t *wc;
267 asn1p_wsyntx_chunk_t *nc;
268 TQ_FOR(wc, &(wx->chunks), next) {
269 nc = asn1p_wsyntx_chunk_clone(wc);
270 if(nc) {
271 TQ_ADD(&(nw->chunks), nc, next);
272 } else {
273 asn1p_wsyntx_free(nw);
274 return NULL;
275 }
276 }
277 }
278
279 return nw;
280}
281
282asn1p_wsyntx_chunk_t *
Lev Walkinc46b7cb2006-08-18 02:27:55 +0000283asn1p_wsyntx_chunk_fromstring(char *token, int do_copy) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000284 asn1p_wsyntx_chunk_t *wc;
285
286 if(do_copy) {
287 static asn1p_wsyntx_chunk_t tmp;
Lev Walkin9d542d22006-03-14 16:31:37 +0000288 tmp.type = WC_LITERAL;
Lev Walkinc46b7cb2006-08-18 02:27:55 +0000289 tmp.content.token = token;
Lev Walkinf15320b2004-06-03 03:38:44 +0000290 wc = asn1p_wsyntx_chunk_clone(&tmp);
291 } else {
292 wc = asn1p_wsyntx_chunk_new();
293 if(wc) {
Lev Walkin9d542d22006-03-14 16:31:37 +0000294 wc->type = WC_LITERAL;
Lev Walkinc46b7cb2006-08-18 02:27:55 +0000295 wc->content.token = token;
Lev Walkinf15320b2004-06-03 03:38:44 +0000296 }
297 }
298
299 return wc;
300}
301
Lev Walkin9d542d22006-03-14 16:31:37 +0000302
303asn1p_wsyntx_chunk_t *
304asn1p_wsyntx_chunk_fromsyntax(asn1p_wsyntx_t *syntax) {
305 asn1p_wsyntx_chunk_t *wc;
306
307 wc = asn1p_wsyntx_chunk_new();
308 if(wc) {
309 wc->type = WC_OPTIONALGROUP;
310 wc->content.syntax = syntax;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800311 syntax->parent = wc;
Lev Walkin9d542d22006-03-14 16:31:37 +0000312 }
313
314 return wc;
315}
316