blob: c3c31f2c3f772aec24a131018eefa05e93a5fb8f [file] [log] [blame]
Lev Walkinf15320b2004-06-03 03:38:44 +00001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <errno.h>
5#include <assert.h>
6
7#include "asn1parser.h"
8
9/*
10 * Construct a new empty types collection.
11 */
12asn1p_expr_t *
13asn1p_expr_new(int _lineno) {
14 asn1p_expr_t *expr;
15
16 expr = calloc(1, sizeof *expr);
17 if(expr) {
18 TQ_INIT(&(expr->members));
19 expr->_lineno = _lineno;
20 }
21
22 return expr;
23}
24
25asn1p_expr_t *
Lev Walkin070a52d2004-08-22 03:19:54 +000026asn1p_expr_clone(asn1p_expr_t *expr, int skip_extensions) {
Lev Walkinf15320b2004-06-03 03:38:44 +000027 asn1p_expr_t *clone;
28 asn1p_expr_t *tcmemb; /* Child of tc */
Lev Walkin070a52d2004-08-22 03:19:54 +000029 int hit_ext = 0;
Lev Walkinf15320b2004-06-03 03:38:44 +000030
31 clone = asn1p_expr_new(expr->_lineno);
32 if(clone == NULL) return NULL;
33
34#define CLCOPY(field) do { clone->field = expr->field; } while(0)
35#define CLCLONE(field, func) do { if(expr->field) { \
36 clone->field = func(expr->field); \
37 if(clone->field == NULL) { \
38 asn1p_expr_free(clone); \
39 return NULL; \
40 } \
41 } } while(0)
42
43 /*
44 * Copy simple fields.
45 */
46 CLCOPY(meta_type);
47 CLCOPY(expr_type);
48 CLCOPY(tag);
Lev Walkin5498f2d2004-09-15 11:59:30 +000049 CLCOPY(marker.flags); /* OPTIONAL/DEFAULT */
Lev Walkin070a52d2004-08-22 03:19:54 +000050 CLCOPY(module);
Lev Walkinf15320b2004-06-03 03:38:44 +000051 CLCOPY(_mark);
52
53 clone->data = 0; /* Do not clone this */
54 clone->data_free = 0; /* Do not clone this */
55
56 /*
57 * Clone complex fields.
58 */
59 CLCLONE(Identifier, strdup);
60 CLCLONE(reference, asn1p_ref_clone);
61 CLCLONE(constraints, asn1p_constraint_clone);
Lev Walkinf59d0752004-08-18 04:59:12 +000062 CLCLONE(combined_constraints, asn1p_constraint_clone);
Lev Walkinf15320b2004-06-03 03:38:44 +000063 CLCLONE(params, asn1p_paramlist_clone);
64 CLCLONE(value, asn1p_value_clone);
Lev Walkin5498f2d2004-09-15 11:59:30 +000065 CLCLONE(marker.default_value, asn1p_value_clone);
Lev Walkinf15320b2004-06-03 03:38:44 +000066 CLCLONE(with_syntax, asn1p_wsyntx_clone);
67
68 /*
69 * Copy all the children of this expr.
70 */
71 TQ_FOR(tcmemb, &(expr->members), next) {
Lev Walkin070a52d2004-08-22 03:19:54 +000072 asn1p_expr_t *cmemb;
73
74 if(skip_extensions
75 && tcmemb->expr_type == A1TC_EXTENSIBLE) {
76 hit_ext++; /* Even if hit_ext wraps around, we're OK. */
77 continue;
78 }
79 if(hit_ext == 1) continue; /* Skip between ...'s */
80
81 cmemb = asn1p_expr_clone(tcmemb, skip_extensions);
Lev Walkinf15320b2004-06-03 03:38:44 +000082 if(cmemb == NULL) {
83 asn1p_expr_free(clone);
84 return NULL;
85 }
Lev Walkin1004aa92004-09-08 00:28:11 +000086 asn1p_expr_add(clone, cmemb);
Lev Walkinf15320b2004-06-03 03:38:44 +000087 }
88
89 return clone;
90}
91
92/*
Lev Walkin1004aa92004-09-08 00:28:11 +000093 * Add expression as a member of another.
94 */
95void
96asn1p_expr_add(asn1p_expr_t *to, asn1p_expr_t *what) {
97 TQ_ADD(&(to->members), what, next);
98 what->parent_expr = to;
99}
100
101
102/*
Lev Walkinf15320b2004-06-03 03:38:44 +0000103 * Destruct the types collection structure.
104 */
105void
106asn1p_expr_free(asn1p_expr_t *expr) {
107 if(expr) {
108 asn1p_expr_t *tm;
109
Lev Walkin1004aa92004-09-08 00:28:11 +0000110 /* Remove all children */
111 while((tm = TQ_REMOVE(&(expr->members), next))) {
112 if(tm->parent_expr != expr)
113 printf("<%s:%p !-> %s:%p>\n",
114 tm->Identifier, tm->parent_expr,
115 expr->Identifier, expr);
116 assert(tm->parent_expr == expr);
117 asn1p_expr_free(tm);
118 }
119
Lev Walkinf15320b2004-06-03 03:38:44 +0000120 if(expr->Identifier)
121 free(expr->Identifier);
122 if(expr->reference)
123 asn1p_ref_free(expr->reference);
124 if(expr->constraints)
125 asn1p_constraint_free(expr->constraints);
Lev Walkinf59d0752004-08-18 04:59:12 +0000126 if(expr->combined_constraints)
127 asn1p_constraint_free(expr->combined_constraints);
Lev Walkinf15320b2004-06-03 03:38:44 +0000128 if(expr->params)
129 asn1p_paramlist_free(expr->params);
130 if(expr->value)
131 asn1p_value_free(expr->value);
Lev Walkin5498f2d2004-09-15 11:59:30 +0000132 if(expr->marker.default_value)
133 asn1p_value_free(expr->marker.default_value);
Lev Walkinf15320b2004-06-03 03:38:44 +0000134 if(expr->with_syntax)
135 asn1p_wsyntx_free(expr->with_syntax);
136
Lev Walkinf15320b2004-06-03 03:38:44 +0000137 if(expr->data && expr->data_free)
138 expr->data_free(expr->data);
139
140 memset(expr, 0, sizeof(*expr));
141 free(expr);
142 }
143}
144