blob: e34cb6f5227aa9fcfdf8be41af3a9151020410a5 [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, '>');
28 }
29 if(end) {
Lev Walkinafa35b42005-06-15 18:12:48 +000030 char *p = alloca((end - start) + 1);
31 memcpy(p, start, end - start);
32 p[end-start] = '\0';
33 fname = p;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000034 } else {
35 return 0;
36 }
37 }
38
39 if(cur->filename && strcmp(cur->filename, fname) == 0) {
Lev Walkinf218e782006-09-12 06:21:18 +000040 cur->usage = FDEP_REFERRED;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000041
42 /* Activate subdependencies */
43 for(i = 0; i < cur->el_count; i++) {
44 asn1c_activate_dependency(deps,
45 cur->elements[i],
46 cur->elements[i]->filename);
47 }
48
49 /*
50 * This might be a link to someplace else.
51 */
52 return asn1c_activate_dependency(deps, NULL, fname);
53 } else {
54 for(i = 0; i < cur->el_count; i++) {
55 asn1c_activate_dependency(deps,
56 cur->elements[i], fname);
57 }
58 }
59
60 return 0;
61}
62
63asn1c_fdeps_t *
64asn1c_read_file_dependencies(arg_t *arg, const char *datadir) {
Lev Walkinf218e782006-09-12 06:21:18 +000065 char buf[4096];
Lev Walkinacd9f8b2004-08-19 13:29:03 +000066 asn1c_fdeps_t *deps;
67 asn1c_fdeps_t *cur;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000068 FILE *f;
Lev Walkin0e89d102006-09-12 06:37:17 +000069 enum fdep_usage special_section = FDEP_NOTUSED;
Lev Walkinacd9f8b2004-08-19 13:29:03 +000070
71 (void)arg;
72
73 if(!datadir || strlen(datadir) > sizeof(buf) / 2) {
74 errno = EINVAL;
75 return NULL;
76 } else {
77 sprintf(buf, "%s/file-dependencies", datadir);
78 }
79
80 f = fopen(buf, "r");
81 if(!f) return NULL;
82
83 deps = asn1c_new_dep(0);
84 assert(deps);
85
86 while(fgets(buf, sizeof(buf), f)) {
87 char *p = strchr(buf, '#');
88 if(p) *p = '\0'; /* Remove comments */
89
90 cur = deps;
91 for(p = strtok(buf, " \t\r\n"); p;
92 p = strtok(NULL, " \t\r\n")) {
93 asn1c_fdeps_t *d;
Lev Walkin59b176e2005-11-26 11:25:14 +000094
Lev Walkinacd9f8b2004-08-19 13:29:03 +000095 /*
Lev Walkin59b176e2005-11-26 11:25:14 +000096 * Special "prefix" section.
Lev Walkinacd9f8b2004-08-19 13:29:03 +000097 */
Lev Walkin59b176e2005-11-26 11:25:14 +000098 if(strchr(p, ':')) {
Lev Walkinf218e782006-09-12 06:21:18 +000099 special_section = FDEP_IGNORE;
Lev Walkin59b176e2005-11-26 11:25:14 +0000100 if(strcmp(p, "COMMON-FILES:") == 0) {
Lev Walkinf218e782006-09-12 06:21:18 +0000101 special_section = FDEP_COMMON_FILES;
102 } else if(strcmp(p, "CONVERTER:") == 0) {
103 special_section = FDEP_CONVERTER;
Lev Walkin59b176e2005-11-26 11:25:14 +0000104 } else if((arg->flags & A1C_GEN_PER)
105 && strcmp(p, "CODEC-PER:") == 0) {
Lev Walkinf218e782006-09-12 06:21:18 +0000106 special_section = FDEP_CODEC_PER;
Lev Walkin59b176e2005-11-26 11:25:14 +0000107 }
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000108 break;
109 }
Lev Walkin59b176e2005-11-26 11:25:14 +0000110
Lev Walkinf218e782006-09-12 06:21:18 +0000111 if(special_section == FDEP_IGNORE)
Lev Walkin59b176e2005-11-26 11:25:14 +0000112 continue;
113
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000114 d = asn1c_new_dep(p);
Lev Walkinf218e782006-09-12 06:21:18 +0000115 d->usage = special_section;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000116
117 if(asn1c_dep_add(cur, d) == 1)
118 cur = d;
119 }
120 }
121
122 fclose(f);
123
124 return deps;
125}
126
127static asn1c_fdeps_t *
128asn1c_new_dep(const char *filename) {
129 asn1c_fdeps_t *d;
130
131 d = calloc(1, sizeof(*d));
132 if(filename) {
133 d->filename = strdup(filename);
134 if(!d->filename) return NULL;
135 }
136
137 return d;
138}
139
140static int
141asn1c_dep_add(asn1c_fdeps_t *deps, asn1c_fdeps_t *d) {
142 int n;
143
144 /* Check for duplicates */
145 for(n = 0; n < deps->el_count; n++) {
146 if(strcmp(deps->elements[n]->filename, d->filename) == 0)
147 return 0;
148 }
149
150 if(deps->el_count == deps->el_size) {
Lev Walkin3441a8b2004-08-19 13:45:27 +0000151 void *p;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000152 n = deps->el_size?deps->el_size << 2:16;
Lev Walkin3441a8b2004-08-19 13:45:27 +0000153 p = realloc(deps->elements,
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000154 n * sizeof(deps->elements[0]));
155 assert(p);
156 deps->elements = p;
157 deps->el_size = n;
158 }
159
160 deps->elements[deps->el_count++] = d;
161 return 1;
162}
163
164asn1c_fdeps_t *
165asn1c_deps_makelist(asn1c_fdeps_t *deps) {
166 asn1c_fdeps_t *dlist;
167 asn1c_fdeps_t *d;
168 int i;
169
170 if(!deps) {
171 errno = EINVAL;
172 return 0;
173 }
174
175 dlist = asn1c_new_dep(0);
176
Lev Walkinf218e782006-09-12 06:21:18 +0000177 if(deps->filename && deps->usage != FDEP_NOTUSED) {
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000178 d = asn1c_new_dep(deps->filename);
Lev Walkinf218e782006-09-12 06:21:18 +0000179 d->usage = deps->usage;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000180 asn1c_dep_add(dlist, d);
181 }
182
183 for(i = 0; i < deps->el_count; i++) {
184 int j;
185 d = asn1c_deps_makelist(deps->elements[i]);
186 assert(!d->filename);
187 for(j = 0; j < d->el_count; j++) {
188 asn1c_dep_add(dlist, d->elements[j]);
189 }
190 }
191
192 return dlist;
193}
194