blob: a025f369a75d34803024322c1e8e9baf89927fac [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) {
Bi-Ruei, Chiu5bdb5552017-10-23 15:20:55 +080030 int base_idx;
Bi-Ruei, Chiu50934ba2017-09-11 08:50:59 +080031
Bi-Ruei, Chiu5bdb5552017-10-23 15:20:55 +080032 if(!src || !it) return;
Bi-Ruei, Chiu50934ba2017-09-11 08:50:59 +080033
Bi-Ruei, Chiu5bdb5552017-10-23 15:20:55 +080034 base_idx = it->rows;
Bi-Ruei, Chiu50934ba2017-09-11 08:50:59 +080035 for(size_t i = 0; i < src->rows; i++) {
Bi-Ruei, Chiu5bdb5552017-10-23 15:20:55 +080036 asn1p_ioc_table_add(it, asn1p_ioc_row_clone(src->row[i], base_idx));
Bi-Ruei, Chiu50934ba2017-09-11 08:50:59 +080037 }
38}
39
40void
Lev Walkin4dcf8362017-08-07 20:10:05 -070041asn1p_ioc_table_free(asn1p_ioc_table_t *it) {
42 if(it) {
43 for(size_t i = 0; i < it->rows; i++) {
44 asn1p_ioc_row_delete(it->row[i]);
45 }
46 free(it->row);
47 free(it);
48 }
49}
50
51size_t
52asn1p_ioc_table_max_identifier_length(asn1p_ioc_table_t *it) {
53 size_t max_length = 0;
54 if(it) {
55 for(size_t i = 0; i < it->rows; i++) {
56 size_t len = asn1p_ioc_row_max_identifier_length(it->row[i]);
57 if(len > max_length) max_length = len;
58 }
59 }
60 return max_length;
61}
62
63size_t
64asn1p_ioc_row_max_identifier_length(asn1p_ioc_row_t *row) {
65 size_t max_length = 0;
66 if(row) {
67 for(size_t i = 0; i < row->columns; i++) {
68 if(row->column[i].value) {
69 size_t len = strlen(row->column[i].value->Identifier);
70 if(len > max_length) max_length = len;
71 }
72 }
73 }
74 return max_length;
75}
Lev Walkinf15320b2004-06-03 03:38:44 +000076
Lev Walkind370e9f2006-03-16 10:03:35 +000077asn1p_ioc_row_t *
78asn1p_ioc_row_new(asn1p_expr_t *oclass) {
79 asn1p_ioc_row_t *row;
80 asn1p_expr_t *field;
81 int columns = 0;
82
83 assert(oclass->expr_type == A1TC_CLASSDEF);
84
85 row = calloc(1, sizeof *row);
86 if(!row) return NULL;
87
88 TQ_FOR(field, &oclass->members, next)
89 columns++;
90
91 row->column = calloc(columns, sizeof *row->column);
92 if(!row->column) {
93 free(row);
94 return NULL;
95 }
96 row->columns = columns;
97
98 columns = 0;
99 TQ_FOR(field, &oclass->members, next) {
Lev Walkind370e9f2006-03-16 10:03:35 +0000100 row->column[columns].field = field;
101 row->column[columns].value = NULL;
102 columns++;
103 }
104
105 return row;
106}
107
Bi-Ruei, Chiu50934ba2017-09-11 08:50:59 +0800108asn1p_ioc_row_t *
Bi-Ruei, Chiu5bdb5552017-10-23 15:20:55 +0800109asn1p_ioc_row_clone(asn1p_ioc_row_t *src, int base_idx) {
Bi-Ruei, Chiu50934ba2017-09-11 08:50:59 +0800110 asn1p_ioc_row_t *row;
111
112 row = calloc(1, sizeof *row);
113 if(!row) return NULL;
114
115 row->column = calloc(src->columns, sizeof *src->column);
116 if(!row->column) {
117 free(row);
118 return NULL;
119 }
120 row->columns = src->columns;
121
122 for(size_t i = 0; i < src->columns; i++) {
123 row->column[i].field = src->column[i].field;
Bi-Ruei, Chiu5bdb5552017-10-23 15:20:55 +0800124 row->column[i].value = 0;
125 if(src->column[i].value) {
126 row->column[i].value = asn1p_expr_clone(src->column[i].value, 0);
127 row->column[i].value->_type_unique_index += base_idx;
128 }
Bi-Ruei, Chiu50934ba2017-09-11 08:50:59 +0800129 row->column[i].new_ref = 1;
130 }
131
132 return row;
133}
134
Lev Walkind370e9f2006-03-16 10:03:35 +0000135void
136asn1p_ioc_row_delete(asn1p_ioc_row_t *row) {
137 if(row) {
138 if(row->column) {
Lev Walkin62d95d22017-08-06 23:41:11 -0700139 for(size_t i = 0; i < row->columns; i++) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800140 if(!row->column[i].new_ref && row->column[i].value) {
141 /*
142 * Field 'reference' comes from asn1fix_cws.c :
143 * TQ_FIRST(&cell->field->members)->reference
144 * so it should not be freed here.
145 */
146 row->column[i].value->reference = NULL;
147 }
148 asn1p_expr_free(row->column[i].value);
149 }
Lev Walkind370e9f2006-03-16 10:03:35 +0000150 free(row->column);
151 }
152 free(row);
153 }
154}
155
Lev Walkinea6635b2017-08-06 23:23:04 -0700156int
157asn1p_ioc_row_match(const asn1p_ioc_row_t *a, const asn1p_ioc_row_t *b) {
158 assert(a && b);
159
160 if(a->columns != b->columns)
161 return -1; /* Bad! */
162
163 for(size_t i = 0; i < a->columns; i++) {
164 assert(a->column[i].field);
165 assert(b->column[i].field);
166 if(strcmp(a->column[i].field->Identifier,
167 b->column[i].field->Identifier)
168 != 0) {
169 return -1; /* Bad! */
170 }
171 if((a->column[i].value && !b->column[i].value)
172 || (!a->column[i].value && b->column[i].value)) {
173 return 1; /* Not match */
174 }
175 if(a->column[i].value && b->column[i].value) {
176 if(asn1p_expr_compare(a->column[i].value, b->column[i].value)
177 != 0) {
178 return 1; /* Not match */
179 }
180 }
181 }
182
183 return 0;
184}
185
Lev Walkind370e9f2006-03-16 10:03:35 +0000186struct asn1p_ioc_cell_s *
187asn1p_ioc_row_cell_fetch(asn1p_ioc_row_t *row, const char *fieldname) {
Lev Walkin62d95d22017-08-06 23:41:11 -0700188 for(size_t i = 0; i < row->columns; i++) {
Lev Walkind370e9f2006-03-16 10:03:35 +0000189 if(strcmp(row->column[i].field->Identifier, fieldname) == 0)
190 return &row->column[i];
191 }
192 errno = ESRCH;
193 return NULL;
194}
195
Lev Walkinf15320b2004-06-03 03:38:44 +0000196asn1p_wsyntx_chunk_t *
197asn1p_wsyntx_chunk_new() {
198 asn1p_wsyntx_chunk_t *wc;
199
200 wc = calloc(1, sizeof(*wc));
201
202 return wc;
203}
204
205void
206asn1p_wsyntx_chunk_free(asn1p_wsyntx_chunk_t *wc) {
207 if(wc) {
Lev Walkin9d542d22006-03-14 16:31:37 +0000208 switch(wc->type) {
Lev Walkin57074f12006-03-16 05:11:14 +0000209 case WC_LITERAL:
210 case WC_WHITESPACE:
Lev Walkind370e9f2006-03-16 10:03:35 +0000211 case WC_FIELD:
Lev Walkin57074f12006-03-16 05:11:14 +0000212 free(wc->content.token); break;
Lev Walkin9d542d22006-03-14 16:31:37 +0000213 case WC_OPTIONALGROUP:
214 asn1p_wsyntx_free(wc->content.syntax);
215 break;
216 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000217 free(wc);
218 }
219}
220
221asn1p_wsyntx_chunk_t *
222asn1p_wsyntx_chunk_clone(asn1p_wsyntx_chunk_t *wc) {
223 asn1p_wsyntx_chunk_t *nc;
224
225 nc = asn1p_wsyntx_chunk_new();
226 if(nc) {
Lev Walkin57074f12006-03-16 05:11:14 +0000227 nc->type = wc->type;
Lev Walkin9d542d22006-03-14 16:31:37 +0000228 switch(wc->type) {
229 case WC_LITERAL:
Lev Walkin57074f12006-03-16 05:11:14 +0000230 case WC_WHITESPACE:
Lev Walkind370e9f2006-03-16 10:03:35 +0000231 case WC_FIELD:
Lev Walkin9d542d22006-03-14 16:31:37 +0000232 nc->content.token = malloc(strlen(wc->content.token)+1);
233 strcpy(nc->content.token, wc->content.token);
234 break;
Lev Walkin9d542d22006-03-14 16:31:37 +0000235 case WC_OPTIONALGROUP:
236 nc->content.syntax = asn1p_wsyntx_clone(wc->content.syntax);
237 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000238 }
239 }
240
241 return nc;
242}
243
244asn1p_wsyntx_t *
245asn1p_wsyntx_new() {
246 asn1p_wsyntx_t *wx;
247
248 wx = calloc(1, sizeof(*wx));
249 if(wx) {
250 TQ_INIT(&(wx->chunks));
251 }
252
253 return wx;
254}
255
256void
257asn1p_wsyntx_free(asn1p_wsyntx_t *wx) {
258 if(wx) {
259 asn1p_wsyntx_chunk_t *wc;
260 while((wc = TQ_REMOVE(&(wx->chunks), next)))
261 asn1p_wsyntx_chunk_free(wc);
262 free(wx);
263 }
264}
265
266asn1p_wsyntx_t *
267asn1p_wsyntx_clone(asn1p_wsyntx_t *wx) {
268 asn1p_wsyntx_t *nw;
269
270 nw = asn1p_wsyntx_new();
271 if(nw) {
272 asn1p_wsyntx_chunk_t *wc;
273 asn1p_wsyntx_chunk_t *nc;
274 TQ_FOR(wc, &(wx->chunks), next) {
275 nc = asn1p_wsyntx_chunk_clone(wc);
276 if(nc) {
277 TQ_ADD(&(nw->chunks), nc, next);
278 } else {
279 asn1p_wsyntx_free(nw);
280 return NULL;
281 }
282 }
283 }
284
285 return nw;
286}
287
288asn1p_wsyntx_chunk_t *
Lev Walkinc46b7cb2006-08-18 02:27:55 +0000289asn1p_wsyntx_chunk_fromstring(char *token, int do_copy) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000290 asn1p_wsyntx_chunk_t *wc;
291
292 if(do_copy) {
293 static asn1p_wsyntx_chunk_t tmp;
Lev Walkin9d542d22006-03-14 16:31:37 +0000294 tmp.type = WC_LITERAL;
Lev Walkinc46b7cb2006-08-18 02:27:55 +0000295 tmp.content.token = token;
Lev Walkinf15320b2004-06-03 03:38:44 +0000296 wc = asn1p_wsyntx_chunk_clone(&tmp);
297 } else {
298 wc = asn1p_wsyntx_chunk_new();
299 if(wc) {
Lev Walkin9d542d22006-03-14 16:31:37 +0000300 wc->type = WC_LITERAL;
Lev Walkinc46b7cb2006-08-18 02:27:55 +0000301 wc->content.token = token;
Lev Walkinf15320b2004-06-03 03:38:44 +0000302 }
303 }
304
305 return wc;
306}
307
Lev Walkin9d542d22006-03-14 16:31:37 +0000308
309asn1p_wsyntx_chunk_t *
310asn1p_wsyntx_chunk_fromsyntax(asn1p_wsyntx_t *syntax) {
311 asn1p_wsyntx_chunk_t *wc;
312
313 wc = asn1p_wsyntx_chunk_new();
314 if(wc) {
315 wc->type = WC_OPTIONALGROUP;
316 wc->content.syntax = syntax;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800317 syntax->parent = wc;
Lev Walkin9d542d22006-03-14 16:31:37 +0000318 }
319
320 return wc;
321}
322