Skip to content
Snippets Groups Projects
Commit acd9f8b3 authored by Lev Walkin's avatar Lev Walkin
Browse files

file dependencies

parent cb636964
No related branches found
No related tags found
No related merge requests found
#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;
}
#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_ */
#include "asn1c_internal.h" #include "asn1c_internal.h"
#include "asn1c_compat.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_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); static int asn1c_copy_over(arg_t *arg, char *path);
int int
asn1c_save_compiled_output(arg_t *arg, const char *datadir) { asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
asn1c_fdeps_t *deps = 0;
(void)datadir; FILE *mkf;
asn1c_fdeps_t *dlist;
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->mod, &(arg->asn->modules), mod_next) {
TQ_FOR(arg->expr, &(arg->mod->members), next) { TQ_FOR(arg->expr, &(arg->mod->members), next) {
if(asn1_lang_map[arg->expr->meta_type] if(asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb) { [arg->expr->expr_type].type_cb) {
if(asn1c_dump_streams(arg)) if(asn1c_dump_streams(arg, deps))
return -1; return -1;
} }
} }
...@@ -24,68 +32,65 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir) { ...@@ -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. * Dump out the Makefile template and the rest of the support code.
*/ */
if((arg->flags & A1C_PRINT_COMPILED) == 0 if((arg->flags & A1C_PRINT_COMPILED)
&& (arg->flags & A1C_OMIT_SUPPORT_CODE) == 0) { || (arg->flags & A1C_OMIT_SUPPORT_CODE)) {
glob_t pg; return 0; /* Finished */
FILE *mkf; }
char *p;
int i;
i = strlen(datadir) + sizeof("/*.[ch]");
p = alloca(i);
snprintf(p, i, "%s/*.[ch]", datadir);
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"); mkf = asn1c_open_file("Makefile.am", ".sample");
if(mkf == NULL) { if(mkf == NULL) {
globfree(&pg); perror("Makefile.am.sample");
perror("Makefile.am.sample"); return -1;
return -1; }
}
fprintf(mkf, "ASN_SRCS="); fprintf(mkf, "ASN_MODULE_SOURCES=");
TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) { TQ_FOR(arg->mod, &(arg->asn->modules), mod_next) {
TQ_FOR(arg->expr, &(arg->mod->members), next) { TQ_FOR(arg->expr, &(arg->mod->members), next) {
if(asn1_lang_map[arg->expr->meta_type] if(asn1_lang_map[arg->expr->meta_type]
[arg->expr->expr_type].type_cb) { [arg->expr->expr_type].type_cb) {
fprintf(mkf, "\t\\\n\t%s.c %s.h", fprintf(mkf, "\t\\\n\t%s.c %s.h",
arg->expr->Identifier, arg->expr->Identifier,
arg->expr->Identifier); arg->expr->Identifier);
}
} }
} }
}
/*
* 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);
for(i = 0; i < pg.gl_pathc; i++) { if(asn1c_copy_over(arg, buf) == -1) {
if(asn1c_copy_over(arg, pg.gl_pathv[i])) {
fprintf(mkf, ">>>ABORTED<<<"); fprintf(mkf, ">>>ABORTED<<<");
fclose(mkf); fclose(mkf);
globfree(&pg);
return -1; return -1;
} else { } else {
fprintf(mkf, "\t\\\n\t%s", fprintf(mkf, "\t\\\n\t%s", fname);
a1c_basename(pg.gl_pathv[i]));
} }
} }
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; return 0;
} }
...@@ -93,11 +98,11 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir) { ...@@ -93,11 +98,11 @@ asn1c_save_compiled_output(arg_t *arg, const char *datadir) {
* Dump the streams. * Dump the streams.
*/ */
static int static int
asn1c_dump_streams(arg_t *arg) { asn1c_dump_streams(arg_t *arg, asn1c_fdeps_t *deps) {
if(arg->flags & A1C_PRINT_COMPILED) { if(arg->flags & A1C_PRINT_COMPILED) {
return asn1c_print_streams(arg); return asn1c_print_streams(arg);
} else { } else {
return asn1c_save_streams(arg); return asn1c_save_streams(arg, deps);
} }
} }
...@@ -125,7 +130,7 @@ asn1c_print_streams(arg_t *arg) { ...@@ -125,7 +130,7 @@ asn1c_print_streams(arg_t *arg) {
} }
static int static int
asn1c_save_streams(arg_t *arg) { asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *deps) {
asn1p_expr_t *expr = arg->expr; asn1p_expr_t *expr = arg->expr;
compiler_streams_t *cs = expr->data; compiler_streams_t *cs = expr->data;
out_chunk_t *ot; out_chunk_t *ot;
...@@ -138,8 +143,8 @@ asn1c_save_streams(arg_t *arg) { ...@@ -138,8 +143,8 @@ asn1c_save_streams(arg_t *arg) {
return -1; return -1;
} }
fp_c = asn1c_open_file(arg, expr->Identifier, ".c"); fp_c = asn1c_open_file(expr->Identifier, ".c");
fp_h = asn1c_open_file(arg, expr->Identifier, ".h"); fp_h = asn1c_open_file(expr->Identifier, ".h");
if(fp_c == NULL || fp_h == NULL) { if(fp_c == NULL || fp_h == NULL) {
if(fp_c) fclose(fp_c); /* lacks unlink() */ if(fp_c) fclose(fp_c); /* lacks unlink() */
if(fp_h) fclose(fp_h); /* lacks unlink() */ if(fp_h) fclose(fp_h); /* lacks unlink() */
...@@ -163,15 +168,7 @@ asn1c_save_streams(arg_t *arg) { ...@@ -163,15 +168,7 @@ asn1c_save_streams(arg_t *arg) {
arg->mod->source_file_name arg->mod->source_file_name
); );
header_id = alloca(strlen(expr->Identifier) + 1); header_id = asn1c_make_identifier(0, expr->Identifier, NULL);
if(1) {
char *src, *dst;
for(src = expr->Identifier, dst = header_id;
(*dst=*src); src++, dst++)
if(!isalnum(*src)) *dst = '_';
*dst = '\0';
}
fprintf(fp_h, fprintf(fp_h,
"#ifndef\t_%s_H_\n" "#ifndef\t_%s_H_\n"
"#define\t_%s_H_\n" "#define\t_%s_H_\n"
...@@ -181,8 +178,10 @@ asn1c_save_streams(arg_t *arg) { ...@@ -181,8 +178,10 @@ asn1c_save_streams(arg_t *arg) {
fprintf(fp_h, "#include <constr_TYPE.h>\n\n"); 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); fwrite(ot->buf, ot->len, 1, fp_h);
}
fprintf(fp_h, "\n"); fprintf(fp_h, "\n");
TQ_FOR(ot, &(cs->targets[OT_DEPS]), next) TQ_FOR(ot, &(cs->targets[OT_DEPS]), next)
fwrite(ot->buf, ot->len, 1, fp_h); fwrite(ot->buf, ot->len, 1, fp_h);
...@@ -232,13 +231,16 @@ asn1c_copy_over(arg_t *arg, char *path) { ...@@ -232,13 +231,16 @@ asn1c_copy_over(arg_t *arg, char *path) {
fprintf(stderr, fprintf(stderr,
"File %s is already here as %s\n", "File %s is already here as %s\n",
path, fname); path, fname);
return 0; return 1;
} else { } else {
fprintf(stderr, fprintf(stderr,
"Retaining local %s (%s suggested)\n", "Retaining local %s (%s suggested)\n",
fname, path); fname, path);
return 0; return 1;
} }
} else if(errno == ENOENT) {
/* Ignore this */
return 0;
} else { } else {
fprintf(stderr, "Symlink %s -> %s failed: %s\n", fprintf(stderr, "Symlink %s -> %s failed: %s\n",
path, fname, strerror(errno)); path, fname, strerror(errno));
...@@ -248,6 +250,6 @@ asn1c_copy_over(arg_t *arg, char *path) { ...@@ -248,6 +250,6 @@ asn1c_copy_over(arg_t *arg, char *path) {
fprintf(stderr, "Symlinked %s\t-> %s\n", path, fname); fprintf(stderr, "Symlinked %s\t-> %s\n", path, fname);
return 0; return 1;
} }
#ifndef _ASN1_SAVE_H_ #ifndef _ASN1C_SAVE_H_
#define _ASN1_SAVE_H_ #define _ASN1C_SAVE_H_
int asn1c_save_compiled_output(arg_t *arg, const char *datadir); int asn1c_save_compiled_output(arg_t *arg, const char *datadir);
#endif /* _ASN1_SAVE_H_ */ #endif /* _ASN1C_SAVE_H_ */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment