file dependencies

This commit is contained in:
Lev Walkin 2004-08-19 13:29:03 +00:00
parent cb636964c6
commit acd9f8b366
4 changed files with 278 additions and 74 deletions

View File

@ -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;
}

View File

@ -0,0 +1,22 @@
#ifndef _ASN1C_FDEPS_H_
#define _ASN1C_FDEPS_H_
typedef struct asn1c_fdeps_s {
char *filename; /* Or 0, if root. */
int used_somewhere; /* Somefile refers to it */
struct asn1c_fdeps_s **elements;
int el_size;
int el_count;
} asn1c_fdeps_t;
asn1c_fdeps_t *asn1c_read_file_dependencies(arg_t *arg, const char *datadir);
/* Data may be a filename or an "#include <>" string. */
int asn1c_activate_dependency(asn1c_fdeps_t *deps, asn1c_fdeps_t *cur,
const char *data);
asn1c_fdeps_t *asn1c_deps_makelist(asn1c_fdeps_t *deps);
#endif /* _ASN1C_FDEPS_H_ */

View File

@ -1,21 +1,29 @@
#include "asn1c_internal.h"
#include "asn1c_compat.h"
#include "asn1c_fdeps.h"
static int asn1c_dump_streams(arg_t *arg);
static int asn1c_dump_streams(arg_t *arg, asn1c_fdeps_t *);
static int asn1c_print_streams(arg_t *arg);
static int asn1c_save_streams(arg_t *arg);
static int asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *);
static int asn1c_copy_over(arg_t *arg, char *path);
int
asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
asn1c_fdeps_t *deps = 0;
FILE *mkf;
asn1c_fdeps_t *dlist;
(void)datadir;
deps = asn1c_read_file_dependencies(arg, datadir);
if(!deps && datadir) {
WARNING("Cannot read file-dependencies information "
"from %s\n", datadir);
}
TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
TQ_FOR(arg->expr, &(arg->mod->members), next) {
if(asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb) {
if(asn1c_dump_streams(arg))
if(asn1c_dump_streams(arg, deps))
return -1;
}
}
@ -24,68 +32,65 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
/*
* Dump out the Makefile template and the rest of the support code.
*/
if((arg->flags & A1C_PRINT_COMPILED) == 0
&& (arg->flags & A1C_OMIT_SUPPORT_CODE) == 0) {
glob_t pg;
FILE *mkf;
char *p;
int i;
if((arg->flags & A1C_PRINT_COMPILED)
|| (arg->flags & A1C_OMIT_SUPPORT_CODE)) {
return 0; /* Finished */
}
i = strlen(datadir) + sizeof("/*.[ch]");
p = alloca(i);
snprintf(p, i, "%s/*.[ch]", datadir);
mkf = asn1c_open_file("Makefile.am", ".sample");
if(mkf == NULL) {
perror("Makefile.am.sample");
return -1;
}
memset(&pg, 0, sizeof(pg));
if(glob(p, GLOB_ERR
#ifdef GLOB_TILDE
| GLOB_TILDE
#endif /* GLOB_TILDE */
, NULL, &pg)) {
fprintf(stderr,
"Bad skeletons directory (-S) %s: %s\n",
datadir, strerror(errno));
return -1;
}
mkf = asn1c_open_file(arg, "Makefile.am", ".sample");
if(mkf == NULL) {
globfree(&pg);
perror("Makefile.am.sample");
return -1;
}
fprintf(mkf, "ASN_SRCS=");
TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
TQ_FOR(arg->expr, &(arg->mod->members), next) {
if(asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb) {
fprintf(mkf, "\t\\\n\t%s.c %s.h",
arg->expr->Identifier,
arg->expr->Identifier);
}
fprintf(mkf, "ASN_MODULE_SOURCES=");
TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
TQ_FOR(arg->expr, &(arg->mod->members), next) {
if(asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb) {
fprintf(mkf, "\t\\\n\t%s.c %s.h",
arg->expr->Identifier,
arg->expr->Identifier);
}
}
}
for(i = 0; i < pg.gl_pathc; i++) {
if(asn1c_copy_over(arg, pg.gl_pathv[i])) {
/*
* Move necessary skeleton files and add them to Makefile.am.sample.
*/
dlist = asn1c_deps_makelist(deps);
if(dlist) {
char buf[8129];
char *dir_end;
int i = strlen(datadir);
assert(i < (int)(sizeof(buf) / 2 - 2));
memcpy(buf, datadir, i);
dir_end = buf + i;
*dir_end++ = '/';
for(i = 0; i < dlist->el_count; i++) {
char *fname = dlist->elements[i]->filename;
assert(strlen(fname) < (sizeof(buf) / 2));
strcpy(dir_end, fname);
if(asn1c_copy_over(arg, buf) == -1) {
fprintf(mkf, ">>>ABORTED<<<");
fclose(mkf);
globfree(&pg);
return -1;
} else {
fprintf(mkf, "\t\\\n\t%s",
a1c_basename(pg.gl_pathv[i]));
fprintf(mkf, "\t\\\n\t%s", fname);
}
}
fprintf(mkf, "\n\n");
fprintf(mkf, "lib_LTLIBRARIES=libsomething.la\n");
fprintf(mkf, "libsomething_la_SOURCES=${ASN_SRCS}\n");
fclose(mkf);
fprintf(stderr, "Generated Makefile.am.sample\n");
globfree(&pg);
}
fprintf(mkf, "\n\n");
fprintf(mkf, "lib_LTLIBRARIES=libsomething.la\n");
fprintf(mkf, "libsomething_la_SOURCES=$(ASN_MODULE_SOURCES)\n");
fclose(mkf);
fprintf(stderr, "Generated Makefile.am.sample\n");
return 0;
}
@ -93,11 +98,11 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
* Dump the streams.
*/
static int
asn1c_dump_streams(arg_t *arg) {
asn1c_dump_streams(arg_t *arg, asn1c_fdeps_t *deps) {
if(arg->flags & A1C_PRINT_COMPILED) {
return asn1c_print_streams(arg);
} else {
return asn1c_save_streams(arg);
return asn1c_save_streams(arg, deps);
}
}
@ -125,7 +130,7 @@ asn1c_print_streams(arg_t *arg) {
}
static int
asn1c_save_streams(arg_t *arg) {
asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
asn1p_expr_t *expr = arg->expr;
compiler_streams_t *cs = expr->data;
out_chunk_t *ot;
@ -138,8 +143,8 @@ asn1c_save_streams(arg_t *arg) {
return -1;
}
fp_c = asn1c_open_file(arg, expr->Identifier, ".c");
fp_h = asn1c_open_file(arg, expr->Identifier, ".h");
fp_c = asn1c_open_file(expr->Identifier, ".c");
fp_h = asn1c_open_file(expr->Identifier, ".h");
if(fp_c == NULL || fp_h == NULL) {
if(fp_c) fclose(fp_c); /* lacks unlink() */
if(fp_h) fclose(fp_h); /* lacks unlink() */
@ -163,15 +168,7 @@ asn1c_save_streams(arg_t *arg) {
arg->mod->source_file_name
);
header_id = alloca(strlen(expr->Identifier) + 1);
if(1) {
char *src, *dst;
for(src = expr->Identifier, dst = header_id;
(*dst=*src); src++, dst++)
if(!isalnum(*src)) *dst = '_';
*dst = '\0';
}
header_id = asn1c_make_identifier(0, expr->Identifier, NULL);
fprintf(fp_h,
"#ifndef\t_%s_H_\n"
"#define\t_%s_H_\n"
@ -181,8 +178,10 @@ asn1c_save_streams(arg_t *arg) {
fprintf(fp_h, "#include <constr_TYPE.h>\n\n");
TQ_FOR(ot, &(cs->targets[OT_INCLUDES]), next)
TQ_FOR(ot, &(cs->targets[OT_INCLUDES]), next) {
asn1c_activate_dependency(deps, 0, ot->buf);
fwrite(ot->buf, ot->len, 1, fp_h);
}
fprintf(fp_h, "\n");
TQ_FOR(ot, &(cs->targets[OT_DEPS]), next)
fwrite(ot->buf, ot->len, 1, fp_h);
@ -232,13 +231,16 @@ asn1c_copy_over(arg_t *arg, char *path) {
fprintf(stderr,
"File %s is already here as %s\n",
path, fname);
return 0;
return 1;
} else {
fprintf(stderr,
"Retaining local %s (%s suggested)\n",
fname, path);
return 0;
return 1;
}
} else if(errno == ENOENT) {
/* Ignore this */
return 0;
} else {
fprintf(stderr, "Symlink %s -> %s failed: %s\n",
path, fname, strerror(errno));
@ -248,6 +250,6 @@ asn1c_copy_over(arg_t *arg, char *path) {
fprintf(stderr, "Symlinked %s\t-> %s\n", path, fname);
return 0;
return 1;
}

View File

@ -1,6 +1,6 @@
#ifndef _ASN1_SAVE_H_
#define _ASN1_SAVE_H_
#ifndef _ASN1C_SAVE_H_
#define _ASN1C_SAVE_H_
int asn1c_save_compiled_output(arg_t *arg, const char *datadir);
#endif /* _ASN1_SAVE_H_ */
#endif /* _ASN1C_SAVE_H_ */