upgrade: PER related changes


git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@1011 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/libasn1compiler/asn1c_save.c b/libasn1compiler/asn1c_save.c
index d35db94..dca0cf1 100644
--- a/libasn1compiler/asn1c_save.c
+++ b/libasn1compiler/asn1c_save.c
@@ -11,6 +11,7 @@
 static int asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *);
 static int asn1c_copy_over(arg_t *arg, char *path);
 static int identical_files(const char *fname1, const char *fname2);
+static int generate_pdu_collection_file(arg_t *arg);
 
 int
 asn1c_save_compiled_output(arg_t *arg, const char *datadir,
@@ -18,7 +19,7 @@
 	asn1c_fdeps_t *deps = 0;
 	asn1c_fdeps_t *dlist;
 	asn1p_module_t *mod;
-	FILE *mkf;
+	FILE *mkf;	/* Makefile.am.sample */
 	int i;
 
 	deps = asn1c_read_file_dependencies(arg, datadir);
@@ -108,6 +109,12 @@
 		}
 	}
 
+	if(arg->flags & A1C_PDU_AUTO) {
+		fprintf(mkf, "ASN_MODULE_SOURCES+=pdu_collection.c\n");
+		if(generate_pdu_collection_file(arg))
+			return -1;
+	}
+
 	fprintf(mkf, "\n\n"
 		"lib_LTLIBRARIES=libsomething.la\n"
 		"libsomething_la_SOURCES="
@@ -438,3 +445,62 @@
 	return 1;
 }
 
+
+static int
+generate_pdu_collection_file(arg_t *arg) {
+	asn1p_module_t *mod;
+	FILE *fp;
+
+	fp = asn1c_open_file("pdu_collection", ".c", 0);
+	if(fp == NULL) {
+		perror("pdu_collection.c");
+		return -1;
+	}
+
+	fprintf(fp,
+		"/*\n"
+		" * Generated by asn1c-" VERSION " (http://lionet.info/asn1c)\n"
+		" */\n\n");
+	fprintf(fp, "struct asn_TYPE_descriptor_s;\t"
+			"/* Forward declaration */\n\n");
+
+	TQ_FOR(mod, &(arg->asn->modules), mod_next) {
+		TQ_FOR(arg->expr, &(mod->members), next) {
+			if(arg->expr->_type_referenced
+			|| !asn1_lang_map[arg->expr->meta_type]
+				[arg->expr->expr_type].type_cb)
+				continue;
+			fprintf(fp, "extern struct asn_TYPE_descriptor_s "
+				"asn_DEF_%s;\n",
+				asn1c_make_identifier(0, arg->expr->Identifier,
+					NULL));
+		}
+	}
+
+	fprintf(fp, "\n\n");
+	fprintf(fp, "struct asn_TYPE_descriptor_s *asn_pdu_collection[] = {\n");
+	TQ_FOR(mod, &(arg->asn->modules), mod_next) {
+		int mod_printed = 0;
+		TQ_FOR(arg->expr, &(mod->members), next) {
+			if(arg->expr->_type_referenced
+			|| !asn1_lang_map[arg->expr->meta_type]
+				[arg->expr->expr_type].type_cb)
+				continue;
+			if(!mod_printed++)
+			fprintf(fp, "\t/* From module %s in %s */\n",
+				arg->expr->module->ModuleName,
+				arg->expr->module->source_file_name);
+			fprintf(fp, "\t&asn_DEF_%s,\t\n",
+				asn1c_make_identifier(0, arg->expr->Identifier,
+					NULL));
+		}
+	}
+
+	fprintf(fp, "\t0\n};\n\n");
+
+	fclose(fp);
+	fprintf(stderr, "Generated pdu_collection.c\n");
+
+	return 0;
+}
+