diff options
author | Lev Walkin <vlm@lionet.info> | 2004-06-03 03:38:44 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2004-06-03 03:38:44 +0000 |
commit | f15320bf6b50a0c02636405561ac8323ae901abd (patch) | |
tree | 33461d45122896c6dde35f82f5c7d19b62004a6b /libasn1parser/asn1p_expr.c | |
parent | 746cb60bbccf47019563665f4aec4b6c462c4163 (diff) |
Initial revision
Diffstat (limited to 'libasn1parser/asn1p_expr.c')
-rw-r--r-- | libasn1parser/asn1p_expr.c | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/libasn1parser/asn1p_expr.c b/libasn1parser/asn1p_expr.c new file mode 100644 index 00000000..23ab4cb3 --- /dev/null +++ b/libasn1parser/asn1p_expr.c @@ -0,0 +1,112 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <assert.h> + +#include "asn1parser.h" + +/* + * Construct a new empty types collection. + */ +asn1p_expr_t * +asn1p_expr_new(int _lineno) { + asn1p_expr_t *expr; + + expr = calloc(1, sizeof *expr); + if(expr) { + TQ_INIT(&(expr->members)); + expr->_lineno = _lineno; + } + + return expr; +} + +asn1p_expr_t * +asn1p_expr_clone(asn1p_expr_t *expr) { + asn1p_expr_t *clone; + asn1p_expr_t *tcmemb; /* Child of tc */ + + clone = asn1p_expr_new(expr->_lineno); + if(clone == NULL) return NULL; + +#define CLCOPY(field) do { clone->field = expr->field; } while(0) +#define CLCLONE(field, func) do { if(expr->field) { \ + clone->field = func(expr->field); \ + if(clone->field == NULL) { \ + asn1p_expr_free(clone); \ + return NULL; \ + } \ + } } while(0) + + /* + * Copy simple fields. + */ + CLCOPY(meta_type); + CLCOPY(expr_type); + CLCOPY(tag); + CLCOPY(marker); + CLCOPY(_mark); + + clone->data = 0; /* Do not clone this */ + clone->data_free = 0; /* Do not clone this */ + + /* + * Clone complex fields. + */ + CLCLONE(Identifier, strdup); + CLCLONE(reference, asn1p_ref_clone); + CLCLONE(constraints, asn1p_constraint_clone); + CLCLONE(params, asn1p_paramlist_clone); + CLCLONE(value, asn1p_value_clone); + CLCLONE(with_syntax, asn1p_wsyntx_clone); + + /* + * Copy all the children of this expr. + */ + TQ_FOR(tcmemb, &(expr->members), next) { + asn1p_expr_t *cmemb = asn1p_expr_clone(tcmemb); + if(cmemb == NULL) { + asn1p_expr_free(clone); + return NULL; + } + TQ_ADD(&(clone->members), cmemb, next); + } + + return clone; +} + +/* + * Destruct the types collection structure. + */ +void +asn1p_expr_free(asn1p_expr_t *expr) { + if(expr) { + asn1p_expr_t *tm; + + if(expr->Identifier) + free(expr->Identifier); + if(expr->reference) + asn1p_ref_free(expr->reference); + if(expr->constraints) + asn1p_constraint_free(expr->constraints); + if(expr->params) + asn1p_paramlist_free(expr->params); + if(expr->value) + asn1p_value_free(expr->value); + if(expr->with_syntax) + asn1p_wsyntx_free(expr->with_syntax); + + /* Remove all children */ + while((tm = TQ_REMOVE(&(expr->members), next))) { + asn1p_expr_free(tm); + } + + if(expr->data && expr->data_free) + expr->data_free(expr->data); + + memset(expr, 0, sizeof(*expr)); + free(expr); + } +} + |