blob: 1ecc313f4a3837b8343d062882b57e4d5e865cfb [file] [log] [blame]
Lev Walkinacd9f8b2004-08-19 13:29:03 +00001#include "asn1c_internal.h"
2#include "asn1c_fdeps.h"
3
4static asn1c_fdeps_t *asn1c_new_dep(const char *filename);
5static int asn1c_dep_add(asn1c_fdeps_t *deps, asn1c_fdeps_t *d);
6
7int
8asn1c_activate_dependency(asn1c_fdeps_t *deps, asn1c_fdeps_t *cur, const char *data) {
Lev Walkinafa35b42005-06-15 18:12:48 +00009 const char *fname;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000010 int i;
11
12 if(!deps || !data || !*data)
13 return 0;
14 if(!cur) cur = deps;
15
Lev Walkin0e89d102006-09-12 06:37:17 +000016 if(cur->usage > FDEP_NOTUSED)
Lev Walkinacd9f8b2004-08-19 13:29:03 +000017 return 1; /* Already activated */
18
Lev Walkinafa35b42005-06-15 18:12:48 +000019 fname = data;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000020 if(*data == '#') {
21 const char *start = data;
22 const char *end = 0;
23
24 start = strchr(data, '<');
25 if(start) {
26 start++;
27 end = strchr(start, '>');
Lev Walkin34944f22010-10-07 08:25:37 +000028 } else if((start = strchr(data, '\"'))) {
29 start++;
30 end = strchr(start, '\"');
Lev Walkinacd9f8b2004-08-19 13:29:03 +000031 }
32 if(end) {
Lev Walkinafa35b42005-06-15 18:12:48 +000033 char *p = alloca((end - start) + 1);
34 memcpy(p, start, end - start);
35 p[end-start] = '\0';
36 fname = p;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000037 } else {
38 return 0;
39 }
40 }
41
42 if(cur->filename && strcmp(cur->filename, fname) == 0) {
Lev Walkinf218e782006-09-12 06:21:18 +000043 cur->usage = FDEP_REFERRED;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000044
45 /* Activate subdependencies */
46 for(i = 0; i < cur->el_count; i++) {
47 asn1c_activate_dependency(deps,
48 cur->elements[i],
49 cur->elements[i]->filename);
50 }
51
52 /*
53 * This might be a link to someplace else.
54 */
55 return asn1c_activate_dependency(deps, NULL, fname);
56 } else {
57 for(i = 0; i < cur->el_count; i++) {
58 asn1c_activate_dependency(deps,
59 cur->elements[i], fname);
60 }
61 }
62
63 return 0;
64}
65
66asn1c_fdeps_t *
67asn1c_read_file_dependencies(arg_t *arg, const char *datadir) {
Lev Walkinf218e782006-09-12 06:21:18 +000068 char buf[4096];
Lev Walkinacd9f8b2004-08-19 13:29:03 +000069 asn1c_fdeps_t *deps;
70 asn1c_fdeps_t *cur;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000071 FILE *f;
Lev Walkin0e89d102006-09-12 06:37:17 +000072 enum fdep_usage special_section = FDEP_NOTUSED;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000073
74 (void)arg;
75
76 if(!datadir || strlen(datadir) > sizeof(buf) / 2) {
77 errno = EINVAL;
78 return NULL;
79 } else {
80 sprintf(buf, "%s/file-dependencies", datadir);
81 }
82
83 f = fopen(buf, "r");
84 if(!f) return NULL;
85
86 deps = asn1c_new_dep(0);
87 assert(deps);
88
89 while(fgets(buf, sizeof(buf), f)) {
90 char *p = strchr(buf, '#');
91 if(p) *p = '\0'; /* Remove comments */
92
93 cur = deps;
94 for(p = strtok(buf, " \t\r\n"); p;
95 p = strtok(NULL, " \t\r\n")) {
96 asn1c_fdeps_t *d;
Lev Walkin59b176e2005-11-26 11:25:14 +000097
Lev Walkinacd9f8b2004-08-19 13:29:03 +000098 /*
Lev Walkin59b176e2005-11-26 11:25:14 +000099 * Special "prefix" section.
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000100 */
Lev Walkin59b176e2005-11-26 11:25:14 +0000101 if(strchr(p, ':')) {
Lev Walkinf218e782006-09-12 06:21:18 +0000102 special_section = FDEP_IGNORE;
Lev Walkin59b176e2005-11-26 11:25:14 +0000103 if(strcmp(p, "COMMON-FILES:") == 0) {
Lev Walkinf218e782006-09-12 06:21:18 +0000104 special_section = FDEP_COMMON_FILES;
105 } else if(strcmp(p, "CONVERTER:") == 0) {
106 special_section = FDEP_CONVERTER;
Lev Walkin59b176e2005-11-26 11:25:14 +0000107 } else if((arg->flags & A1C_GEN_PER)
108 && strcmp(p, "CODEC-PER:") == 0) {
Lev Walkinf218e782006-09-12 06:21:18 +0000109 special_section = FDEP_CODEC_PER;
Lev Walkin59b176e2005-11-26 11:25:14 +0000110 }
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000111 break;
112 }
Lev Walkin59b176e2005-11-26 11:25:14 +0000113
Lev Walkinf218e782006-09-12 06:21:18 +0000114 if(special_section == FDEP_IGNORE)
Lev Walkin59b176e2005-11-26 11:25:14 +0000115 continue;
116
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000117 d = asn1c_new_dep(p);
Lev Walkinf218e782006-09-12 06:21:18 +0000118 d->usage = special_section;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000119
120 if(asn1c_dep_add(cur, d) == 1)
121 cur = d;
122 }
123 }
124
125 fclose(f);
126
127 return deps;
128}
129
130static asn1c_fdeps_t *
131asn1c_new_dep(const char *filename) {
132 asn1c_fdeps_t *d;
133
134 d = calloc(1, sizeof(*d));
135 if(filename) {
136 d->filename = strdup(filename);
137 if(!d->filename) return NULL;
138 }
139
140 return d;
141}
142
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800143static void
144asn1c_free_dep(asn1c_fdeps_t *d) {
145
146 if(d) {
147 if(d->filename) free(d->filename);
148 d->filename = 0;
149 free(d);
150 }
151}
152
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000153static int
154asn1c_dep_add(asn1c_fdeps_t *deps, asn1c_fdeps_t *d) {
155 int n;
156
157 /* Check for duplicates */
158 for(n = 0; n < deps->el_count; n++) {
159 if(strcmp(deps->elements[n]->filename, d->filename) == 0)
160 return 0;
161 }
162
163 if(deps->el_count == deps->el_size) {
Lev Walkin3441a8b2004-08-19 13:45:27 +0000164 void *p;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000165 n = deps->el_size?deps->el_size << 2:16;
Lev Walkin3441a8b2004-08-19 13:45:27 +0000166 p = realloc(deps->elements,
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000167 n * sizeof(deps->elements[0]));
168 assert(p);
169 deps->elements = p;
170 deps->el_size = n;
171 }
172
173 deps->elements[deps->el_count++] = d;
174 return 1;
175}
176
177asn1c_fdeps_t *
178asn1c_deps_makelist(asn1c_fdeps_t *deps) {
179 asn1c_fdeps_t *dlist;
180 asn1c_fdeps_t *d;
181 int i;
182
183 if(!deps) {
184 errno = EINVAL;
185 return 0;
186 }
187
188 dlist = asn1c_new_dep(0);
189
Lev Walkinf218e782006-09-12 06:21:18 +0000190 if(deps->filename && deps->usage != FDEP_NOTUSED) {
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000191 d = asn1c_new_dep(deps->filename);
Lev Walkinf218e782006-09-12 06:21:18 +0000192 d->usage = deps->usage;
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800193 if(!asn1c_dep_add(dlist, d)) {
194 asn1c_free_dep(d);
195 }
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000196 }
197
198 for(i = 0; i < deps->el_count; i++) {
199 int j;
200 d = asn1c_deps_makelist(deps->elements[i]);
201 assert(!d->filename);
202 for(j = 0; j < d->el_count; j++) {
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800203 if(asn1c_dep_add(dlist, d->elements[j])) {
204 d->elements[j] = 0;
205 }
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000206 }
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800207 asn1c_deps_freelist(d);
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000208 }
209
210 return dlist;
211}
212
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800213void
214asn1c_deps_freelist(asn1c_fdeps_t *deps) {
215 if(deps) {
216 int i;
217 if(deps->elements) {
218 for(i = 0; i < deps->el_count; i++) {
219 asn1c_deps_freelist(deps->elements[i]);
220 deps->elements[i] = 0;
221 }
222 free(deps->elements);
223 deps->elements = 0;
224 }
225 asn1c_free_dep(deps);
226 }
227}