blob: cb53b3cee87370aa51b5f639ecbe966d84edfa59 [file] [log] [blame]
vlmbfb31312004-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) {
139 n = deps->el_size?deps->el_size << 2:16;
140 void *p = realloc(deps->elements,
141 n * sizeof(deps->elements[0]));
142 assert(p);
143 deps->elements = p;
144 deps->el_size = n;
145 }
146
147 deps->elements[deps->el_count++] = d;
148 return 1;
149}
150
151asn1c_fdeps_t *
152asn1c_deps_makelist(asn1c_fdeps_t *deps) {
153 asn1c_fdeps_t *dlist;
154 asn1c_fdeps_t *d;
155 int i;
156
157 if(!deps) {
158 errno = EINVAL;
159 return 0;
160 }
161
162 dlist = asn1c_new_dep(0);
163
164 if(deps->filename && deps->used_somewhere) {
165 d = asn1c_new_dep(deps->filename);
166 asn1c_dep_add(dlist, d);
167 }
168
169 for(i = 0; i < deps->el_count; i++) {
170 int j;
171 d = asn1c_deps_makelist(deps->elements[i]);
172 assert(!d->filename);
173 for(j = 0; j < d->el_count; j++) {
174 asn1c_dep_add(dlist, d->elements[j]);
175 }
176 }
177
178 return dlist;
179}
180