blob: 60a52cbb9ab808c2f18185c9d6e93944b19cd447 [file] [log] [blame]
Lev Walkinacd9f8b2004-08-19 13:29:03 +00001#include "asn1c_internal.h"
2#include "asn1c_fdeps.h"
3
Lev Walkind0ee2b12017-11-14 00:07:05 -08004static asn1c_dep_filename *asn1c_dep_filename_new(const char *filename);
Lev Walkin7d5d9302017-11-13 22:17:20 -08005static void asn1c_dep_add(asn1c_dep_chain *dlist, const char *filename,
6 int lineno, int column);
Lev Walkind0ee2b12017-11-14 00:07:05 -08007static asn1c_dep_chain *asn1c_dep_chain_new(void);
Lev Walkina4f8e942017-10-08 19:28:20 -07008
Lev Walkin7d5d9302017-11-13 22:17:20 -08009static asn1c_dep_chain *
10asn1c_dep_chains_add_new(asn1c_dep_chainset *deps,
11 enum asn1c_dep_section section, int active) {
Lev Walkind0ee2b12017-11-14 00:07:05 -080012 asn1c_dep_chain *dc = asn1c_dep_chain_new();
Lev Walkin7d5d9302017-11-13 22:17:20 -080013 asn1c_tagged_dep_chain *tc = calloc(1, sizeof(*tc));
14 tc->chain = dc;
15 tc->section = section;
16 tc->activated.active = active;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000017
Lev Walkin7d5d9302017-11-13 22:17:20 -080018 deps->chains = realloc(deps->chains,
19 sizeof(deps->chains[0]) * (deps->chains_count + 1));
20 assert(deps->chains);
21 deps->chains[deps->chains_count] = tc;
22 deps->chains_count++;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000023
Lev Walkin7d5d9302017-11-13 22:17:20 -080024 return dc;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000025}
26
Lev Walkin7d5d9302017-11-13 22:17:20 -080027void
28asn1c_activate_dependency(asn1c_dep_chainset *deps, const char *data,
29 const char *by) {
30 char fname_scratch[PATH_MAX];
31
32 if(!deps || !data || !*data) {
33 return;
34 }
35
36 assert(deps->chains_count);
37
38 const char *fname = data;
39 if(*data == '#') {
40 const char *start = data;
41 const char *end = 0;
42
43 start = strchr(data, '<');
44 if(start) {
45 start++;
46 end = strchr(start, '>');
47 } else if((start = strchr(data, '\"'))) {
48 start++;
49 end = strchr(start, '\"');
50 }
51 if(end) {
52 assert((end-start) + 1 < (ssize_t)sizeof(fname_scratch));
53 memcpy(fname_scratch, start, end - start);
54 fname_scratch[end-start] = '\0';
55 fname = fname_scratch;
56 } else {
57 return;
58 }
59 }
60
61 for(size_t i = 0; i < deps->chains_count; i++) {
62 asn1c_tagged_dep_chain *ch = deps->chains[i];
63 if(!ch->activated.active && ch->chain->deps_count > 0
64 && strcmp(ch->chain->deps[0]->filename, fname) == 0) {
65 ch->activated.by = strdup(by);
66 ch->activated.active = 1;
67
68 for(size_t j = 0; j < ch->chain->deps_count; j++) {
69 asn1c_activate_dependency(deps, ch->chain->deps[j]->filename,
70 by);
71 }
72 }
73 }
74}
75
76asn1c_dep_chainset *
Lev Walkinacd9f8b2004-08-19 13:29:03 +000077asn1c_read_file_dependencies(arg_t *arg, const char *datadir) {
Lev Walkinf218e782006-09-12 06:21:18 +000078 char buf[4096];
Lev Walkin7d5d9302017-11-13 22:17:20 -080079 asn1c_dep_chainset *deps;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000080 FILE *f;
Lev Walkin7d5d9302017-11-13 22:17:20 -080081 int lineno = 0;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000082
83 if(!datadir || strlen(datadir) > sizeof(buf) / 2) {
84 errno = EINVAL;
85 return NULL;
86 } else {
87 sprintf(buf, "%s/file-dependencies", datadir);
88 }
89
90 f = fopen(buf, "r");
91 if(!f) return NULL;
92
Lev Walkin7d5d9302017-11-13 22:17:20 -080093 deps = calloc(1, sizeof(*deps));
Lev Walkinacd9f8b2004-08-19 13:29:03 +000094 assert(deps);
Lev Walkin7d5d9302017-11-13 22:17:20 -080095 enum asn1c_dep_section section = FDEP_COMMON_FILES;
96 int activate = 0;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000097
Lev Walkin7d5d9302017-11-13 22:17:20 -080098 while(fgets(buf, sizeof(buf), f)) {
Lev Walkinacd9f8b2004-08-19 13:29:03 +000099 char *p = strchr(buf, '#');
100 if(p) *p = '\0'; /* Remove comments */
101
Lev Walkin7d5d9302017-11-13 22:17:20 -0800102 lineno++;
103
104 asn1c_dep_chain *dc = asn1c_dep_chains_add_new(deps, section, activate);
105
106 for(p = strtok(buf, " \t\r\n"); p;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000107 p = strtok(NULL, " \t\r\n")) {
Lev Walkin59b176e2005-11-26 11:25:14 +0000108
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000109 /*
Lev Walkin59b176e2005-11-26 11:25:14 +0000110 * Special "prefix" section.
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000111 */
Lev Walkin59b176e2005-11-26 11:25:14 +0000112 if(strchr(p, ':')) {
Lev Walkin59b176e2005-11-26 11:25:14 +0000113 if(strcmp(p, "COMMON-FILES:") == 0) {
Lev Walkin7d5d9302017-11-13 22:17:20 -0800114 section = FDEP_COMMON_FILES;
115 activate = 1;
Lev Walkinf218e782006-09-12 06:21:18 +0000116 } else if(strcmp(p, "CONVERTER:") == 0) {
Lev Walkin7d5d9302017-11-13 22:17:20 -0800117 activate = 1;
118 section = FDEP_CONVERTER;
Lev Walkinf573ebb2017-07-24 00:25:51 +0400119 } else if((arg->flags & A1C_GEN_OER)
120 && strcmp(p, "CODEC-OER:") == 0) {
Lev Walkin7d5d9302017-11-13 22:17:20 -0800121 activate = 0;
122 section = FDEP_CODEC_OER;
Lev Walkin59b176e2005-11-26 11:25:14 +0000123 } else if((arg->flags & A1C_GEN_PER)
124 && strcmp(p, "CODEC-PER:") == 0) {
Lev Walkin7d5d9302017-11-13 22:17:20 -0800125 activate = 0;
126 section = FDEP_CODEC_PER;
127 } else {
128 section = FDEP_IGNORE;
129 activate = 0;
130 }
131 break;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000132 }
Lev Walkin59b176e2005-11-26 11:25:14 +0000133
Lev Walkin7d5d9302017-11-13 22:17:20 -0800134 asn1c_dep_add(dc, p, lineno, p - buf);
135 }
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000136 }
137
138 fclose(f);
139
Lev Walkin7d5d9302017-11-13 22:17:20 -0800140 /* A single filename by itself means that we should include that */
141 for(size_t i = 0; i < deps->chains_count; i++) {
142 asn1c_tagged_dep_chain *ch = deps->chains[i];
143 if(!ch->activated.active && ch->chain->deps_count == 1) {
144 asn1c_activate_dependency(deps, ch->chain->deps[0]->filename,
145 "implicit");
146 }
147 }
148
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000149 return deps;
150}
151
Lev Walkin7d5d9302017-11-13 22:17:20 -0800152static asn1c_dep_filename *
Lev Walkind0ee2b12017-11-14 00:07:05 -0800153asn1c_dep_filename_new(const char *filename) {
Lev Walkin7d5d9302017-11-13 22:17:20 -0800154 asn1c_dep_filename *d;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000155
Lev Walkin7d5d9302017-11-13 22:17:20 -0800156 assert(filename);
157
158 d = calloc(1, sizeof(*d));
159 assert(d);
160 d->filename = strdup(filename);
161 assert(d->filename);
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000162
163 return d;
164}
165
Lev Walkin7d5d9302017-11-13 22:17:20 -0800166static asn1c_dep_chain *
Lev Walkind0ee2b12017-11-14 00:07:05 -0800167asn1c_dep_chain_new() {
Lev Walkin7d5d9302017-11-13 22:17:20 -0800168 return calloc(1, sizeof(asn1c_dep_chain));
169}
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800170
Lev Walkin7d5d9302017-11-13 22:17:20 -0800171static void
172asn1c_dep_add(asn1c_dep_chain *dlist, const char *filename, int lineno, int column) {
Lev Walkind0ee2b12017-11-14 00:07:05 -0800173 asn1c_dep_filename *df = asn1c_dep_filename_new(filename);
Lev Walkin7d5d9302017-11-13 22:17:20 -0800174 df->lineno = lineno;
175 df->column = column;
176
177 dlist->deps =
178 realloc(dlist->deps, (dlist->deps_count + 1) * sizeof(dlist->deps[0]));
179 assert(dlist->deps);
180 dlist->deps[dlist->deps_count] = df;
181 dlist->deps_count += 1;
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800182}
183
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000184static int
Lev Walkin7d5d9302017-11-13 22:17:20 -0800185asn1c_dep_has_filename(const asn1c_dep_chain *dlist, const char *filename) {
186 for(size_t i = 0; i < dlist->deps_count; i++) {
187 if(strcmp(dlist->deps[i]->filename, filename) == 0) {
188 return 1;
189 }
190 }
191 return 0;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000192}
193
Lev Walkin7d5d9302017-11-13 22:17:20 -0800194asn1c_dep_chain *
195asn1c_deps_flatten(const asn1c_dep_chainset *deps,
196 enum asn1c_dep_section include_section) {
197 asn1c_dep_chain *dlist;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000198
199 if(!deps) {
200 errno = EINVAL;
201 return 0;
202 }
203
Lev Walkind0ee2b12017-11-14 00:07:05 -0800204 dlist = asn1c_dep_chain_new();
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000205
Lev Walkin7d5d9302017-11-13 22:17:20 -0800206 for(size_t i = 0; i < deps->chains_count; i++) {
207 asn1c_tagged_dep_chain *tc = deps->chains[i];
208 asn1c_dep_chain *dc = tc->chain;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000209
Lev Walkin7d5d9302017-11-13 22:17:20 -0800210 if(!tc->activated.active) {
211 continue;
212 }
213 if((tc->section & include_section) == 0) {
214 continue;
215 }
216
217 for(size_t j = 0; j < dc->deps_count; j++) {
218 if(!asn1c_dep_has_filename(dlist, dc->deps[j]->filename)) {
219 asn1c_dep_add(dlist, dc->deps[j]->filename, dc->deps[j]->lineno,
220 dc->deps[j]->column);
221 }
222 }
223 }
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000224
225 return dlist;
226}
227
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800228void
Lev Walkin7d5d9302017-11-13 22:17:20 -0800229asn1c_dep_chain_free(asn1c_dep_chain *dc) {
230 if(dc) {
231 for(size_t i = 0; i < dc->deps_count; i++) {
232 asn1c_dep_filename *df = dc->deps[i];
233 free(df->filename);
234 free(df);
235 }
236 free(dc->deps);
237 }
238}
239
240void
241asn1c_dep_chainset_free(asn1c_dep_chainset *deps) {
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800242 if(deps) {
Lev Walkin7d5d9302017-11-13 22:17:20 -0800243 for(size_t i = 0; i < deps->chains_count; i++) {
244 asn1c_dep_chain_free(deps->chains[i]->chain);
245 free(deps->chains[i]->activated.by);
246 free(deps->chains[i]);
247 }
248 free(deps->chains);
249 free(deps);
250 }
Bi-Ruei, Chiu6f348942016-11-08 15:41:23 +0800251}