blob: c6fbe2185153b0263930237d739772e411522ae9 [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
29asn1p_ioc_table_free(asn1p_ioc_table_t *it) {
30 if(it) {
31 for(size_t i = 0; i < it->rows; i++) {
32 asn1p_ioc_row_delete(it->row[i]);
33 }
34 free(it->row);
35 free(it);
36 }
37}
38
39size_t
40asn1p_ioc_table_max_identifier_length(asn1p_ioc_table_t *it) {
41 size_t max_length = 0;
42 if(it) {
43 for(size_t i = 0; i < it->rows; i++) {
44 size_t len = asn1p_ioc_row_max_identifier_length(it->row[i]);
45 if(len > max_length) max_length = len;
46 }
47 }
48 return max_length;
49}
50
51size_t
52asn1p_ioc_row_max_identifier_length(asn1p_ioc_row_t *row) {
53 size_t max_length = 0;
54 if(row) {
55 for(size_t i = 0; i < row->columns; i++) {
56 if(row->column[i].value) {
57 size_t len = strlen(row->column[i].value->Identifier);
58 if(len > max_length) max_length = len;
59 }
60 }
61 }
62 return max_length;
63}
Lev Walkinf15320b2004-06-03 03:38:44 +000064
Lev Walkind370e9f2006-03-16 10:03:35 +000065asn1p_ioc_row_t *
66asn1p_ioc_row_new(asn1p_expr_t *oclass) {
67 asn1p_ioc_row_t *row;
68 asn1p_expr_t *field;
69 int columns = 0;
70
71 assert(oclass->expr_type == A1TC_CLASSDEF);
72
73 row = calloc(1, sizeof *row);
74 if(!row) return NULL;
75
76 TQ_FOR(field, &oclass->members, next)
77 columns++;
78
79 row->column = calloc(columns, sizeof *row->column);
80 if(!row->column) {
81 free(row);
82 return NULL;
83 }
84 row->columns = columns;
85
86 columns = 0;
87 TQ_FOR(field, &oclass->members, next) {
Lev Walkind370e9f2006-03-16 10:03:35 +000088 row->column[columns].field = field;
89 row->column[columns].value = NULL;
90 columns++;
91 }
92
93 return row;
94}
95
96void
97asn1p_ioc_row_delete(asn1p_ioc_row_t *row) {
98 if(row) {
99 if(row->column) {
Lev Walkin62d95d22017-08-06 23:41:11 -0700100 for(size_t i = 0; i < row->columns; i++) {
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800101 if(!row->column[i].new_ref && row->column[i].value) {
102 /*
103 * Field 'reference' comes from asn1fix_cws.c :
104 * TQ_FIRST(&cell->field->members)->reference
105 * so it should not be freed here.
106 */
107 row->column[i].value->reference = NULL;
108 }
109 asn1p_expr_free(row->column[i].value);
110 }
Lev Walkind370e9f2006-03-16 10:03:35 +0000111 free(row->column);
112 }
113 free(row);
114 }
115}
116
Lev Walkinea6635b2017-08-06 23:23:04 -0700117int
118asn1p_ioc_row_match(const asn1p_ioc_row_t *a, const asn1p_ioc_row_t *b) {
119 assert(a && b);
120
121 if(a->columns != b->columns)
122 return -1; /* Bad! */
123
124 for(size_t i = 0; i < a->columns; i++) {
125 assert(a->column[i].field);
126 assert(b->column[i].field);
127 if(strcmp(a->column[i].field->Identifier,
128 b->column[i].field->Identifier)
129 != 0) {
130 return -1; /* Bad! */
131 }
132 if((a->column[i].value && !b->column[i].value)
133 || (!a->column[i].value && b->column[i].value)) {
134 return 1; /* Not match */
135 }
136 if(a->column[i].value && b->column[i].value) {
137 if(asn1p_expr_compare(a->column[i].value, b->column[i].value)
138 != 0) {
139 return 1; /* Not match */
140 }
141 }
142 }
143
144 return 0;
145}
146
Lev Walkind370e9f2006-03-16 10:03:35 +0000147struct asn1p_ioc_cell_s *
148asn1p_ioc_row_cell_fetch(asn1p_ioc_row_t *row, const char *fieldname) {
Lev Walkin62d95d22017-08-06 23:41:11 -0700149 for(size_t i = 0; i < row->columns; i++) {
Lev Walkind370e9f2006-03-16 10:03:35 +0000150 if(strcmp(row->column[i].field->Identifier, fieldname) == 0)
151 return &row->column[i];
152 }
153 errno = ESRCH;
154 return NULL;
155}
156
Lev Walkinf15320b2004-06-03 03:38:44 +0000157asn1p_wsyntx_chunk_t *
158asn1p_wsyntx_chunk_new() {
159 asn1p_wsyntx_chunk_t *wc;
160
161 wc = calloc(1, sizeof(*wc));
162
163 return wc;
164}
165
166void
167asn1p_wsyntx_chunk_free(asn1p_wsyntx_chunk_t *wc) {
168 if(wc) {
Lev Walkin9d542d22006-03-14 16:31:37 +0000169 switch(wc->type) {
Lev Walkin57074f12006-03-16 05:11:14 +0000170 case WC_LITERAL:
171 case WC_WHITESPACE:
Lev Walkind370e9f2006-03-16 10:03:35 +0000172 case WC_FIELD:
Lev Walkin57074f12006-03-16 05:11:14 +0000173 free(wc->content.token); break;
Lev Walkin9d542d22006-03-14 16:31:37 +0000174 case WC_OPTIONALGROUP:
175 asn1p_wsyntx_free(wc->content.syntax);
176 break;
177 }
Lev Walkinf15320b2004-06-03 03:38:44 +0000178 free(wc);
179 }
180}
181
182asn1p_wsyntx_chunk_t *
183asn1p_wsyntx_chunk_clone(asn1p_wsyntx_chunk_t *wc) {
184 asn1p_wsyntx_chunk_t *nc;
185
186 nc = asn1p_wsyntx_chunk_new();
187 if(nc) {
Lev Walkin57074f12006-03-16 05:11:14 +0000188 nc->type = wc->type;
Lev Walkin9d542d22006-03-14 16:31:37 +0000189 switch(wc->type) {
190 case WC_LITERAL:
Lev Walkin57074f12006-03-16 05:11:14 +0000191 case WC_WHITESPACE:
Lev Walkind370e9f2006-03-16 10:03:35 +0000192 case WC_FIELD:
Lev Walkin9d542d22006-03-14 16:31:37 +0000193 nc->content.token = malloc(strlen(wc->content.token)+1);
194 strcpy(nc->content.token, wc->content.token);
195 break;
Lev Walkin9d542d22006-03-14 16:31:37 +0000196 case WC_OPTIONALGROUP:
197 nc->content.syntax = asn1p_wsyntx_clone(wc->content.syntax);
198 break;
Lev Walkinf15320b2004-06-03 03:38:44 +0000199 }
200 }
201
202 return nc;
203}
204
205asn1p_wsyntx_t *
206asn1p_wsyntx_new() {
207 asn1p_wsyntx_t *wx;
208
209 wx = calloc(1, sizeof(*wx));
210 if(wx) {
211 TQ_INIT(&(wx->chunks));
212 }
213
214 return wx;
215}
216
217void
218asn1p_wsyntx_free(asn1p_wsyntx_t *wx) {
219 if(wx) {
220 asn1p_wsyntx_chunk_t *wc;
221 while((wc = TQ_REMOVE(&(wx->chunks), next)))
222 asn1p_wsyntx_chunk_free(wc);
223 free(wx);
224 }
225}
226
227asn1p_wsyntx_t *
228asn1p_wsyntx_clone(asn1p_wsyntx_t *wx) {
229 asn1p_wsyntx_t *nw;
230
231 nw = asn1p_wsyntx_new();
232 if(nw) {
233 asn1p_wsyntx_chunk_t *wc;
234 asn1p_wsyntx_chunk_t *nc;
235 TQ_FOR(wc, &(wx->chunks), next) {
236 nc = asn1p_wsyntx_chunk_clone(wc);
237 if(nc) {
238 TQ_ADD(&(nw->chunks), nc, next);
239 } else {
240 asn1p_wsyntx_free(nw);
241 return NULL;
242 }
243 }
244 }
245
246 return nw;
247}
248
249asn1p_wsyntx_chunk_t *
Lev Walkinc46b7cb2006-08-18 02:27:55 +0000250asn1p_wsyntx_chunk_fromstring(char *token, int do_copy) {
Lev Walkinf15320b2004-06-03 03:38:44 +0000251 asn1p_wsyntx_chunk_t *wc;
252
253 if(do_copy) {
254 static asn1p_wsyntx_chunk_t tmp;
Lev Walkin9d542d22006-03-14 16:31:37 +0000255 tmp.type = WC_LITERAL;
Lev Walkinc46b7cb2006-08-18 02:27:55 +0000256 tmp.content.token = token;
Lev Walkinf15320b2004-06-03 03:38:44 +0000257 wc = asn1p_wsyntx_chunk_clone(&tmp);
258 } else {
259 wc = asn1p_wsyntx_chunk_new();
260 if(wc) {
Lev Walkin9d542d22006-03-14 16:31:37 +0000261 wc->type = WC_LITERAL;
Lev Walkinc46b7cb2006-08-18 02:27:55 +0000262 wc->content.token = token;
Lev Walkinf15320b2004-06-03 03:38:44 +0000263 }
264 }
265
266 return wc;
267}
268
Lev Walkin9d542d22006-03-14 16:31:37 +0000269
270asn1p_wsyntx_chunk_t *
271asn1p_wsyntx_chunk_fromsyntax(asn1p_wsyntx_t *syntax) {
272 asn1p_wsyntx_chunk_t *wc;
273
274 wc = asn1p_wsyntx_chunk_new();
275 if(wc) {
276 wc->type = WC_OPTIONALGROUP;
277 wc->content.syntax = syntax;
Bi-Ruei, Chiu80fd3062017-05-07 21:00:51 +0800278 syntax->parent = wc;
Lev Walkin9d542d22006-03-14 16:31:37 +0000279 }
280
281 return wc;
282}
283