blob: 68a090da8a01325eea1b73323566e4f83251da7b [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) {
9 char *fname;
10 int i;
11
12 if(!deps || !data || !*data)
13 return 0;
14 if(!cur) cur = deps;
15
16 if(cur->used_somewhere)
17 return 1; /* Already activated */
18
19 (const char *)fname = data;
20 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) {
30 fname = alloca((end - start) + 1);
31 memcpy(fname, start, end - start);
32 fname[end-start] = '\0';
33 } else {
34 return 0;
35 }
36 }
37
38 if(cur->filename && strcmp(cur->filename, fname) == 0) {
39 cur->used_somewhere = 1;
40
41 /* Activate subdependencies */
42 for(i = 0; i < cur->el_count; i++) {
43 asn1c_activate_dependency(deps,
44 cur->elements[i],
45 cur->elements[i]->filename);
46 }
47
48 /*
49 * This might be a link to someplace else.
50 */
51 return asn1c_activate_dependency(deps, NULL, fname);
52 } else {
53 for(i = 0; i < cur->el_count; i++) {
54 asn1c_activate_dependency(deps,
55 cur->elements[i], fname);
56 }
57 }
58
59 return 0;
60}
61
62asn1c_fdeps_t *
63asn1c_read_file_dependencies(arg_t *arg, const char *datadir) {
64 asn1c_fdeps_t *deps;
65 asn1c_fdeps_t *cur;
66 char buf[4096];
67 FILE *f;
68 int hit_COMMON_FILES = 0;
69
70 (void)arg;
71
72 if(!datadir || strlen(datadir) > sizeof(buf) / 2) {
73 errno = EINVAL;
74 return NULL;
75 } else {
76 sprintf(buf, "%s/file-dependencies", datadir);
77 }
78
79 f = fopen(buf, "r");
80 if(!f) return NULL;
81
82 deps = asn1c_new_dep(0);
83 assert(deps);
84
85 while(fgets(buf, sizeof(buf), f)) {
86 char *p = strchr(buf, '#');
87 if(p) *p = '\0'; /* Remove comments */
88
89 cur = deps;
90 for(p = strtok(buf, " \t\r\n"); p;
91 p = strtok(NULL, " \t\r\n")) {
92 asn1c_fdeps_t *d;
93 /*
94 * If hit "COMMON-FILES:", treat everything else
95 * as a huge dependency.
96 */
97 if(strcmp(p, "COMMON-FILES:") == 0) {
98 hit_COMMON_FILES = 1;
99 break;
100 }
101 d = asn1c_new_dep(p);
102 assert(d);
103 d->used_somewhere = hit_COMMON_FILES;
104
105 if(asn1c_dep_add(cur, d) == 1)
106 cur = d;
107 }
108 }
109
110 fclose(f);
111
112 return deps;
113}
114
115static asn1c_fdeps_t *
116asn1c_new_dep(const char *filename) {
117 asn1c_fdeps_t *d;
118
119 d = calloc(1, sizeof(*d));
120 if(filename) {
121 d->filename = strdup(filename);
122 if(!d->filename) return NULL;
123 }
124
125 return d;
126}
127
128static int
129asn1c_dep_add(asn1c_fdeps_t *deps, asn1c_fdeps_t *d) {
130 int n;
131
132 /* Check for duplicates */
133 for(n = 0; n < deps->el_count; n++) {
134 if(strcmp(deps->elements[n]->filename, d->filename) == 0)
135 return 0;
136 }
137
138 if(deps->el_count == deps->el_size) {
Lev Walkin3441a8b2004-08-19 13:45:27 +0000139 void *p;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000140 n = deps->el_size?deps->el_size << 2:16;
Lev Walkin3441a8b2004-08-19 13:45:27 +0000141 p = realloc(deps->elements,
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000142 n * sizeof(deps->elements[0]));
143 assert(p);
144 deps->elements = p;
145 deps->el_size = n;
146 }
147
148 deps->elements[deps->el_count++] = d;
149 return 1;
150}
151
152asn1c_fdeps_t *
153asn1c_deps_makelist(asn1c_fdeps_t *deps) {
154 asn1c_fdeps_t *dlist;
155 asn1c_fdeps_t *d;
156 int i;
157
158 if(!deps) {
159 errno = EINVAL;
160 return 0;
161 }
162
163 dlist = asn1c_new_dep(0);
164
165 if(deps->filename && deps->used_somewhere) {
166 d = asn1c_new_dep(deps->filename);
167 asn1c_dep_add(dlist, d);
168 }
169
170 for(i = 0; i < deps->el_count; i++) {
171 int j;
172 d = asn1c_deps_makelist(deps->elements[i]);
173 assert(!d->filename);
174 for(j = 0; j < d->el_count; j++) {
175 asn1c_dep_add(dlist, d->elements[j]);
176 }
177 }
178
179 return dlist;
180}
181