1 #include "asn1c_internal.h"
2 #include "asn1c_fdeps.h"
4 static asn1c_dep_filename *asn1c_dep_filename_new(const char *filename);
5 static void asn1c_dep_add(asn1c_dep_chain *dlist, const char *filename,
6 int lineno, int column);
7 static asn1c_dep_chain *asn1c_dep_chain_new(void);
9 static asn1c_dep_chain *
10 asn1c_dep_chains_add_new(asn1c_dep_chainset *deps,
11 enum asn1c_dep_section section, int active) {
12 asn1c_dep_chain *dc = asn1c_dep_chain_new();
13 asn1c_tagged_dep_chain *tc = calloc(1, sizeof(*tc));
15 tc->section = section;
16 tc->activated.active = active;
18 deps->chains = realloc(deps->chains,
19 sizeof(deps->chains[0]) * (deps->chains_count + 1));
21 deps->chains[deps->chains_count] = tc;
28 asn1c_activate_dependency(asn1c_dep_chainset *deps, const char *data,
30 char fname_scratch[PATH_MAX];
32 if(!deps || !data || !*data) {
36 assert(deps->chains_count);
38 const char *fname = data;
40 const char *start = data;
43 start = strchr(data, '<');
46 end = strchr(start, '>');
47 } else if((start = strchr(data, '\"'))) {
49 end = strchr(start, '\"');
52 assert((end-start) + 1 < (ssize_t)sizeof(fname_scratch));
53 memcpy(fname_scratch, start, end - start);
54 fname_scratch[end-start] = '\0';
55 fname = fname_scratch;
61 for(size_t i = 0; i < deps->chains_count; i++) {
62 asn1c_tagged_dep_chain *ch = deps->chains[i];
63 if(!ch->activated.active && ch->chain->deps_count > 0
64 && strcmp(ch->chain->deps[0]->filename, fname) == 0) {
65 ch->activated.by = strdup(by);
66 ch->activated.active = 1;
68 for(size_t j = 0; j < ch->chain->deps_count; j++) {
69 asn1c_activate_dependency(deps, ch->chain->deps[j]->filename,
77 asn1c_read_file_dependencies(arg_t *arg, const char *datadir) {
79 asn1c_dep_chainset *deps;
83 if(!datadir || strlen(datadir) > sizeof(buf) / 2) {
87 sprintf(buf, "%s/file-dependencies", datadir);
93 deps = calloc(1, sizeof(*deps));
95 enum asn1c_dep_section section = FDEP_COMMON_FILES;
98 while(fgets(buf, sizeof(buf), f)) {
99 char *p = strchr(buf, '#');
100 if(p) *p = '\0'; /* Remove comments */
104 asn1c_dep_chain *dc = asn1c_dep_chains_add_new(deps, section, activate);
106 for(p = strtok(buf, " \t\r\n"); p;
107 p = strtok(NULL, " \t\r\n")) {
110 * Special "prefix" section.
113 if(strcmp(p, "COMMON-FILES:") == 0) {
114 section = FDEP_COMMON_FILES;
116 } else if(strcmp(p, "CONVERTER:") == 0) {
118 section = FDEP_CONVERTER;
119 } else if((arg->flags & A1C_GEN_OER)
120 && strcmp(p, "CODEC-OER:") == 0) {
122 section = FDEP_CODEC_OER;
123 } else if((arg->flags & A1C_GEN_PER)
124 && strcmp(p, "CODEC-PER:") == 0) {
126 section = FDEP_CODEC_PER;
128 section = FDEP_IGNORE;
134 asn1c_dep_add(dc, p, lineno, p - buf);
140 /* A single filename by itself means that we should include that */
141 for(size_t i = 0; i < deps->chains_count; i++) {
142 asn1c_tagged_dep_chain *ch = deps->chains[i];
143 if(!ch->activated.active && ch->chain->deps_count == 1) {
144 asn1c_activate_dependency(deps, ch->chain->deps[0]->filename,
152 static asn1c_dep_filename *
153 asn1c_dep_filename_new(const char *filename) {
154 asn1c_dep_filename *d;
158 d = calloc(1, sizeof(*d));
160 d->filename = strdup(filename);
166 static asn1c_dep_chain *
167 asn1c_dep_chain_new() {
168 return calloc(1, sizeof(asn1c_dep_chain));
172 asn1c_dep_add(asn1c_dep_chain *dlist, const char *filename, int lineno, int column) {
173 asn1c_dep_filename *df = asn1c_dep_filename_new(filename);
178 realloc(dlist->deps, (dlist->deps_count + 1) * sizeof(dlist->deps[0]));
180 dlist->deps[dlist->deps_count] = df;
181 dlist->deps_count += 1;
185 asn1c_dep_has_filename(const asn1c_dep_chain *dlist, const char *filename) {
186 for(size_t i = 0; i < dlist->deps_count; i++) {
187 if(strcmp(dlist->deps[i]->filename, filename) == 0) {
195 asn1c_deps_flatten(const asn1c_dep_chainset *deps,
196 enum asn1c_dep_section include_section) {
197 asn1c_dep_chain *dlist;
204 dlist = asn1c_dep_chain_new();
206 for(size_t i = 0; i < deps->chains_count; i++) {
207 asn1c_tagged_dep_chain *tc = deps->chains[i];
208 asn1c_dep_chain *dc = tc->chain;
210 if(!tc->activated.active) {
213 if((tc->section & include_section) == 0) {
217 for(size_t j = 0; j < dc->deps_count; j++) {
218 if(!asn1c_dep_has_filename(dlist, dc->deps[j]->filename)) {
219 asn1c_dep_add(dlist, dc->deps[j]->filename, dc->deps[j]->lineno,
220 dc->deps[j]->column);
229 asn1c_dep_chain_free(asn1c_dep_chain *dc) {
231 for(size_t i = 0; i < dc->deps_count; i++) {
232 asn1c_dep_filename *df = dc->deps[i];
241 asn1c_dep_chainset_free(asn1c_dep_chainset *deps) {
243 for(size_t i = 0; i < deps->chains_count; i++) {
244 asn1c_dep_chain_free(deps->chains[i]->chain);
245 free(deps->chains[i]->activated.by);
246 free(deps->chains[i]);