diff options
author | Lev Walkin <vlm@lionet.info> | 2004-08-19 13:29:03 +0000 |
---|---|---|
committer | Lev Walkin <vlm@lionet.info> | 2004-08-19 13:29:03 +0000 |
commit | acd9f8b3668896d6d37f34965870ae04a989a4ff (patch) | |
tree | 484264a8095ba9de0ce3791ececf8c81b8af719f /libasn1compiler/asn1c_fdeps.c | |
parent | cb636964c64d8ce5df19e8eaaa2026eae7273388 (diff) |
file dependencies
Diffstat (limited to 'libasn1compiler/asn1c_fdeps.c')
-rw-r--r-- | libasn1compiler/asn1c_fdeps.c | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/libasn1compiler/asn1c_fdeps.c b/libasn1compiler/asn1c_fdeps.c new file mode 100644 index 00000000..cb53b3ce --- /dev/null +++ b/libasn1compiler/asn1c_fdeps.c @@ -0,0 +1,180 @@ +#include "asn1c_internal.h" +#include "asn1c_fdeps.h" + +static asn1c_fdeps_t *asn1c_new_dep(const char *filename); +static int asn1c_dep_add(asn1c_fdeps_t *deps, asn1c_fdeps_t *d); + +int +asn1c_activate_dependency(asn1c_fdeps_t *deps, asn1c_fdeps_t *cur, const char *data) { + char *fname; + int i; + + if(!deps || !data || !*data) + return 0; + if(!cur) cur = deps; + + if(cur->used_somewhere) + return 1; /* Already activated */ + + (const char *)fname = data; + if(*data == '#') { + const char *start = data; + const char *end = 0; + + start = strchr(data, '<'); + if(start) { + start++; + end = strchr(start, '>'); + } + if(end) { + fname = alloca((end - start) + 1); + memcpy(fname, start, end - start); + fname[end-start] = '\0'; + } else { + return 0; + } + } + + if(cur->filename && strcmp(cur->filename, fname) == 0) { + cur->used_somewhere = 1; + + /* Activate subdependencies */ + for(i = 0; i < cur->el_count; i++) { + asn1c_activate_dependency(deps, + cur->elements[i], + cur->elements[i]->filename); + } + + /* + * This might be a link to someplace else. + */ + return asn1c_activate_dependency(deps, NULL, fname); + } else { + for(i = 0; i < cur->el_count; i++) { + asn1c_activate_dependency(deps, + cur->elements[i], fname); + } + } + + return 0; +} + +asn1c_fdeps_t * +asn1c_read_file_dependencies(arg_t *arg, const char *datadir) { + asn1c_fdeps_t *deps; + asn1c_fdeps_t *cur; + char buf[4096]; + FILE *f; + int hit_COMMON_FILES = 0; + + (void)arg; + + if(!datadir || strlen(datadir) > sizeof(buf) / 2) { + errno = EINVAL; + return NULL; + } else { + sprintf(buf, "%s/file-dependencies", datadir); + } + + f = fopen(buf, "r"); + if(!f) return NULL; + + deps = asn1c_new_dep(0); + assert(deps); + + while(fgets(buf, sizeof(buf), f)) { + char *p = strchr(buf, '#'); + if(p) *p = '\0'; /* Remove comments */ + + cur = deps; + for(p = strtok(buf, " \t\r\n"); p; + p = strtok(NULL, " \t\r\n")) { + asn1c_fdeps_t *d; + /* + * If hit "COMMON-FILES:", treat everything else + * as a huge dependency. + */ + if(strcmp(p, "COMMON-FILES:") == 0) { + hit_COMMON_FILES = 1; + break; + } + d = asn1c_new_dep(p); + assert(d); + d->used_somewhere = hit_COMMON_FILES; + + if(asn1c_dep_add(cur, d) == 1) + cur = d; + } + } + + fclose(f); + + return deps; +} + +static asn1c_fdeps_t * +asn1c_new_dep(const char *filename) { + asn1c_fdeps_t *d; + + d = calloc(1, sizeof(*d)); + if(filename) { + d->filename = strdup(filename); + if(!d->filename) return NULL; + } + + return d; +} + +static int +asn1c_dep_add(asn1c_fdeps_t *deps, asn1c_fdeps_t *d) { + int n; + + /* Check for duplicates */ + for(n = 0; n < deps->el_count; n++) { + if(strcmp(deps->elements[n]->filename, d->filename) == 0) + return 0; + } + + if(deps->el_count == deps->el_size) { + n = deps->el_size?deps->el_size << 2:16; + void *p = realloc(deps->elements, + n * sizeof(deps->elements[0])); + assert(p); + deps->elements = p; + deps->el_size = n; + } + + deps->elements[deps->el_count++] = d; + return 1; +} + +asn1c_fdeps_t * +asn1c_deps_makelist(asn1c_fdeps_t *deps) { + asn1c_fdeps_t *dlist; + asn1c_fdeps_t *d; + int i; + + if(!deps) { + errno = EINVAL; + return 0; + } + + dlist = asn1c_new_dep(0); + + if(deps->filename && deps->used_somewhere) { + d = asn1c_new_dep(deps->filename); + asn1c_dep_add(dlist, d); + } + + for(i = 0; i < deps->el_count; i++) { + int j; + d = asn1c_deps_makelist(deps->elements[i]); + assert(!d->filename); + for(j = 0; j < d->el_count; j++) { + asn1c_dep_add(dlist, d->elements[j]); + } + } + + return dlist; +} + |