blob: 0066f51a3cca54879661202177656ea027e08bc6 [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
16 if(cur->used_somewhere)
17 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) {
40 cur->used_somewhere = 1;
41
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) {
65 asn1c_fdeps_t *deps;
66 asn1c_fdeps_t *cur;
67 char buf[4096];
68 FILE *f;
69 int hit_COMMON_FILES = 0;
70
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;
94 /*
95 * If hit "COMMON-FILES:", treat everything else
96 * as a huge dependency.
97 */
98 if(strcmp(p, "COMMON-FILES:") == 0) {
99 hit_COMMON_FILES = 1;
100 break;
101 }
102 d = asn1c_new_dep(p);
103 assert(d);
104 d->used_somewhere = hit_COMMON_FILES;
105
106 if(asn1c_dep_add(cur, d) == 1)
107 cur = d;
108 }
109 }
110
111 fclose(f);
112
113 return deps;
114}
115
116static asn1c_fdeps_t *
117asn1c_new_dep(const char *filename) {
118 asn1c_fdeps_t *d;
119
120 d = calloc(1, sizeof(*d));
121 if(filename) {
122 d->filename = strdup(filename);
123 if(!d->filename) return NULL;
124 }
125
126 return d;
127}
128
129static int
130asn1c_dep_add(asn1c_fdeps_t *deps, asn1c_fdeps_t *d) {
131 int n;
132
133 /* Check for duplicates */
134 for(n = 0; n < deps->el_count; n++) {
135 if(strcmp(deps->elements[n]->filename, d->filename) == 0)
136 return 0;
137 }
138
139 if(deps->el_count == deps->el_size) {
Lev Walkin3441a8b2004-08-19 13:45:27 +0000140 void *p;
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000141 n = deps->el_size?deps->el_size << 2:16;
Lev Walkin3441a8b2004-08-19 13:45:27 +0000142 p = realloc(deps->elements,
Lev Walkinacd9f8b2004-08-19 13:29:03 +0000143 n * sizeof(deps->elements[0]));
144 assert(p);
145 deps->elements = p;
146 deps->el_size = n;
147 }
148
149 deps->elements[deps->el_count++] = d;
150 return 1;
151}
152
153asn1c_fdeps_t *
154asn1c_deps_makelist(asn1c_fdeps_t *deps) {
155 asn1c_fdeps_t *dlist;
156 asn1c_fdeps_t *d;
157 int i;
158
159 if(!deps) {
160 errno = EINVAL;
161 return 0;
162 }
163
164 dlist = asn1c_new_dep(0);
165
166 if(deps->filename && deps->used_somewhere) {
167 d = asn1c_new_dep(deps->filename);
168 asn1c_dep_add(dlist, d);
169 }
170
171 for(i = 0; i < deps->el_count; i++) {
172 int j;
173 d = asn1c_deps_makelist(deps->elements[i]);
174 assert(!d->filename);
175 for(j = 0; j < d->el_count; j++) {
176 asn1c_dep_add(dlist, d->elements[j]);
177 }
178 }
179
180 return dlist;
181}
182