file dependencies

diff --git a/libasn1compiler/asn1c_save.c b/libasn1compiler/asn1c_save.c
index 15d1b67..3c63053 100644
--- a/libasn1compiler/asn1c_save.c
+++ b/libasn1compiler/asn1c_save.c
@@ -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 @@
 	/*
 	 * 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 @@
  * 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 @@
 }
 
 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 @@
 		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 @@
 		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 @@
 
 	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 @@
 				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 @@
 
 	fprintf(stderr, "Symlinked %s\t-> %s\n", path, fname);
 
-	return 0;
+	return 1;
 }