df6054e76224938978a7de2223a0d7dc08765ab3
[com/asn1c.git] / libasn1parser / asn1p_param.c
1 #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 parameters list.
11  */
12 asn1p_paramlist_t *
13 asn1p_paramlist_new(int _lineno) {
14         asn1p_paramlist_t *pl;
15
16         pl = calloc(1, sizeof *pl);
17         if(pl) {
18                 pl->_lineno = _lineno;
19         }
20
21         return pl;
22 }
23
24 void
25 asn1p_paramlist_free(asn1p_paramlist_t *pl) {
26         if(pl) {
27                 if(pl->params) {
28                         int i = pl->params_count;
29                         while(i--) {
30                                 asn1p_ref_free(pl->params[i].governor);
31                                 free(pl->params[i].argument);
32                                 pl->params[i].governor = 0;
33                                 pl->params[i].argument = 0;
34                         }
35                         free(pl->params);
36                         pl->params = 0;
37                 }
38
39                 free(pl);
40         }
41 }
42
43 int
44 asn1p_paramlist_add_param(asn1p_paramlist_t *pl, asn1p_ref_t *gov, char *arg) {
45
46         if(!pl || !arg) {
47                 errno = EINVAL;
48                 return -1;
49         }
50
51         /*
52          * Make sure there's enough space to insert a new element.
53          */
54         if(pl->params_count == pl->params_size) {
55                 int newsize = pl->params_size?pl->params_size<<2:4;
56                 void *p;
57                 p = realloc(pl->params,
58                         newsize * sizeof(pl->params[0]));
59                 if(p) {
60                         pl->params = p;
61                         pl->params_size = newsize;
62                         memset(&pl->params[pl->params_count], 0,
63                                 (newsize - pl->params_size)
64                                 * sizeof(pl->params[0]));
65                 } else {
66                         return -1;
67                 }
68
69         }
70
71         if(gov) {
72                 pl->params[pl->params_count].governor = asn1p_ref_clone(gov);
73                 if(pl->params[pl->params_count].governor == NULL)
74                         return -1;
75         } else {
76                 pl->params[pl->params_count].governor = 0;
77         }
78
79         pl->params[pl->params_count].argument = strdup(arg);
80         if(pl->params[pl->params_count].argument) {
81                 pl->params_count++;
82                 return 0;
83         } else {
84                 asn1p_ref_free(pl->params[pl->params_count].governor);
85                 return -1;
86         }
87 }
88
89 asn1p_paramlist_t *
90 asn1p_paramlist_clone(asn1p_paramlist_t *pl) {
91         asn1p_paramlist_t *newpl;
92
93         newpl = asn1p_paramlist_new(pl->_lineno);
94         if(newpl) {
95                 int i;
96                 for(i = 0; i < pl->params_count; i++) {
97                         if(asn1p_paramlist_add_param(newpl,
98                                 pl->params[i].governor,
99                                 pl->params[i].argument
100                         )) {
101                                 asn1p_paramlist_free(newpl);
102                                 newpl = NULL;
103                                 break;
104                         }
105                 }
106         }
107
108         return newpl;
109 }
110