blob: 231a47ccb937b990405fdbff0e3b1af2c9dd242d [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
143static int
144asn1c_dep_add(asn1c_fdeps_t *deps, asn1c_fdeps_t *d) {
145 int n;
146
147 /* Check for duplicates */
148 for(n = 0; n < deps->el_count; n++) {
149 if(strcmp(deps->elements[n]->filename, d->filename) == 0)
150 return 0;
151 }
152
153 if(deps->el_count == deps->el_size) {
Lev Walkin3441a8b2004-08-19 13:45:27 +0000154 void *p;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000155 n = deps->el_size?deps->el_size << 2:16;
Lev Walkin3441a8b2004-08-19 13:45:27 +0000156 p = realloc(deps->elements,
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000157 n * sizeof(deps->elements[0]));
158 assert(p);
159 deps->elements = p;
160 deps->el_size = n;
161 }
162
163 deps->elements[deps->el_count++] = d;
164 return 1;
165}
166
167asn1c_fdeps_t *
168asn1c_deps_makelist(asn1c_fdeps_t *deps) {
169 asn1c_fdeps_t *dlist;
170 asn1c_fdeps_t *d;
171 int i;
172
173 if(!deps) {
174 errno = EINVAL;
175 return 0;
176 }
177
178 dlist = asn1c_new_dep(0);
179
Lev Walkinf218e782006-09-12 06:21:18 +0000180 if(deps->filename && deps->usage != FDEP_NOTUSED) {
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000181 d = asn1c_new_dep(deps->filename);
Lev Walkinf218e782006-09-12 06:21:18 +0000182 d->usage = deps->usage;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000183 asn1c_dep_add(dlist, d);
184 }
185
186 for(i = 0; i < deps->el_count; i++) {
187 int j;
188 d = asn1c_deps_makelist(deps->elements[i]);
189 assert(!d->filename);
190 for(j = 0; j < d->el_count; j++) {
191 asn1c_dep_add(dlist, d->elements[j]);
192 }
193 }
194
195 return dlist;
196}
197