mirror of https://gerrit.osmocom.org/asn1c
file dependencies
This commit is contained in:
parent
cb636964c6
commit
acd9f8b366
|
@ -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;
|
||||
}
|
||||
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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_ */
|
||||
|
|
Loading…
Reference in New Issue