blob: 80ba2f68b6596cafc2847445170945e788d3dc92 [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) {
vlmd0137e12005-06-15 18:12:48 +00009 const char *fname;
vlmbfb31312004-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
vlmd0137e12005-06-15 18:12:48 +000019 fname = data;
vlmbfb31312004-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) {
vlmd0137e12005-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;
vlmbfb31312004-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;
vlm337167e2005-11-26 11:25:14 +000069 enum {
70 SS_DYNAMIC, /* Dynamic list of dependencies */
71 SS_CODEC_PER, /* Use contents only if -gen-PER */
72 SS_COMMON_FILES, /* Section for dependencies */
73 SS_IGNORE /* Ignore contents of this section */
74 } special_section = SS_DYNAMIC;
vlmbfb31312004-08-19 13:29:03 +000075
76 (void)arg;
77
78 if(!datadir || strlen(datadir) > sizeof(buf) / 2) {
79 errno = EINVAL;
80 return NULL;
81 } else {
82 sprintf(buf, "%s/file-dependencies", datadir);
83 }
84
85 f = fopen(buf, "r");
86 if(!f) return NULL;
87
88 deps = asn1c_new_dep(0);
89 assert(deps);
90
91 while(fgets(buf, sizeof(buf), f)) {
92 char *p = strchr(buf, '#');
93 if(p) *p = '\0'; /* Remove comments */
94
95 cur = deps;
96 for(p = strtok(buf, " \t\r\n"); p;
97 p = strtok(NULL, " \t\r\n")) {
98 asn1c_fdeps_t *d;
vlm337167e2005-11-26 11:25:14 +000099
vlmbfb31312004-08-19 13:29:03 +0000100 /*
vlm337167e2005-11-26 11:25:14 +0000101 * Special "prefix" section.
vlmbfb31312004-08-19 13:29:03 +0000102 */
vlm337167e2005-11-26 11:25:14 +0000103 if(strchr(p, ':')) {
104 special_section = SS_IGNORE;
105 if(strcmp(p, "COMMON-FILES:") == 0) {
106 special_section = SS_COMMON_FILES;
107 } else if((arg->flags & A1C_GEN_PER)
108 && strcmp(p, "CODEC-PER:") == 0) {
109 special_section = SS_CODEC_PER;
110 }
vlmbfb31312004-08-19 13:29:03 +0000111 break;
112 }
vlm337167e2005-11-26 11:25:14 +0000113
114 if(special_section == SS_IGNORE)
115 continue;
116
vlmbfb31312004-08-19 13:29:03 +0000117 d = asn1c_new_dep(p);
118 assert(d);
vlm337167e2005-11-26 11:25:14 +0000119 d->used_somewhere = special_section;
vlmbfb31312004-08-19 13:29:03 +0000120
121 if(asn1c_dep_add(cur, d) == 1)
122 cur = d;
123 }
124 }
125
126 fclose(f);
127
128 return deps;
129}
130
131static asn1c_fdeps_t *
132asn1c_new_dep(const char *filename) {
133 asn1c_fdeps_t *d;
134
135 d = calloc(1, sizeof(*d));
136 if(filename) {
137 d->filename = strdup(filename);
138 if(!d->filename) return NULL;
139 }
140
141 return d;
142}
143
144static int
145asn1c_dep_add(asn1c_fdeps_t *deps, asn1c_fdeps_t *d) {
146 int n;
147
148 /* Check for duplicates */
149 for(n = 0; n < deps->el_count; n++) {
150 if(strcmp(deps->elements[n]->filename, d->filename) == 0)
151 return 0;
152 }
153
154 if(deps->el_count == deps->el_size) {
vlm67852f92004-08-19 13:45:27 +0000155 void *p;
vlmbfb31312004-08-19 13:29:03 +0000156 n = deps->el_size?deps->el_size << 2:16;
vlm67852f92004-08-19 13:45:27 +0000157 p = realloc(deps->elements,
vlmbfb31312004-08-19 13:29:03 +0000158 n * sizeof(deps->elements[0]));
159 assert(p);
160 deps->elements = p;
161 deps->el_size = n;
162 }
163
164 deps->elements[deps->el_count++] = d;
165 return 1;
166}
167
168asn1c_fdeps_t *
169asn1c_deps_makelist(asn1c_fdeps_t *deps) {
170 asn1c_fdeps_t *dlist;
171 asn1c_fdeps_t *d;
172 int i;
173
174 if(!deps) {
175 errno = EINVAL;
176 return 0;
177 }
178
179 dlist = asn1c_new_dep(0);
180
181 if(deps->filename && deps->used_somewhere) {
182 d = asn1c_new_dep(deps->filename);
183 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