blob: c0882bee9ebd3d07fcb3871cdc15e24c6230c6ef [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 Walkinf573ebb2017-07-24 00:25:51 +0400107 } else if((arg->flags & A1C_GEN_OER)
108 && strcmp(p, "CODEC-OER:") == 0) {
109 special_section = FDEP_CODEC_OER;
Lev Walkin59b176e2005-11-26 11:25:14 +0000110 } else if((arg->flags & A1C_GEN_PER)
111 && strcmp(p, "CODEC-PER:") == 0) {
Lev Walkinf218e782006-09-12 06:21:18 +0000112 special_section = FDEP_CODEC_PER;
Lev Walkin59b176e2005-11-26 11:25:14 +0000113 }
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000114 break;
115 }
Lev Walkin59b176e2005-11-26 11:25:14 +0000116
Lev Walkinf218e782006-09-12 06:21:18 +0000117 if(special_section == FDEP_IGNORE)
Lev Walkin59b176e2005-11-26 11:25:14 +0000118 continue;
119
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000120 d = asn1c_new_dep(p);
Lev Walkinf218e782006-09-12 06:21:18 +0000121 d->usage = special_section;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000122
123 if(asn1c_dep_add(cur, d) == 1)
124 cur = d;
125 }
126 }
127
128 fclose(f);
129
130 return deps;
131}
132
133static asn1c_fdeps_t *
134asn1c_new_dep(const char *filename) {
135 asn1c_fdeps_t *d;
136
137 d = calloc(1, sizeof(*d));
138 if(filename) {
139 d->filename = strdup(filename);
140 if(!d->filename) return NULL;
141 }
142
143 return d;
144}
145
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800146static void
147asn1c_free_dep(asn1c_fdeps_t *d) {
148
149 if(d) {
150 if(d->filename) free(d->filename);
151 d->filename = 0;
152 free(d);
153 }
154}
155
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000156static int
157asn1c_dep_add(asn1c_fdeps_t *deps, asn1c_fdeps_t *d) {
158 int n;
159
160 /* Check for duplicates */
161 for(n = 0; n < deps->el_count; n++) {
162 if(strcmp(deps->elements[n]->filename, d->filename) == 0)
163 return 0;
164 }
165
166 if(deps->el_count == deps->el_size) {
Lev Walkin3441a8b2004-08-19 13:45:27 +0000167 void *p;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000168 n = deps->el_size?deps->el_size << 2:16;
Lev Walkin3441a8b2004-08-19 13:45:27 +0000169 p = realloc(deps->elements,
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000170 n * sizeof(deps->elements[0]));
171 assert(p);
172 deps->elements = p;
173 deps->el_size = n;
174 }
175
176 deps->elements[deps->el_count++] = d;
177 return 1;
178}
179
180asn1c_fdeps_t *
181asn1c_deps_makelist(asn1c_fdeps_t *deps) {
182 asn1c_fdeps_t *dlist;
183 asn1c_fdeps_t *d;
184 int i;
185
186 if(!deps) {
187 errno = EINVAL;
188 return 0;
189 }
190
191 dlist = asn1c_new_dep(0);
192
Lev Walkinf218e782006-09-12 06:21:18 +0000193 if(deps->filename && deps->usage != FDEP_NOTUSED) {
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000194 d = asn1c_new_dep(deps->filename);
Lev Walkinf218e782006-09-12 06:21:18 +0000195 d->usage = deps->usage;
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800196 if(!asn1c_dep_add(dlist, d)) {
197 asn1c_free_dep(d);
198 }
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000199 }
200
201 for(i = 0; i < deps->el_count; i++) {
202 int j;
203 d = asn1c_deps_makelist(deps->elements[i]);
204 assert(!d->filename);
205 for(j = 0; j < d->el_count; j++) {
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800206 if(asn1c_dep_add(dlist, d->elements[j])) {
207 d->elements[j] = 0;
208 }
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000209 }
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800210 asn1c_deps_freelist(d);
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000211 }
212
213 return dlist;
214}
215
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800216void
217asn1c_deps_freelist(asn1c_fdeps_t *deps) {
218 if(deps) {
219 int i;
220 if(deps->elements) {
221 for(i = 0; i < deps->el_count; i++) {
222 asn1c_deps_freelist(deps->elements[i]);
223 deps->elements[i] = 0;
224 }
225 free(deps->elements);
226 deps->elements = 0;
227 }
228 asn1c_free_dep(deps);
229 }
230}