earlier detection of unknown -pdu=Type
diff --git a/libasn1compiler/asn1c_save.c b/libasn1compiler/asn1c_save.c
index 5fe1b37..f302ceb 100644
--- a/libasn1compiler/asn1c_save.c
+++ b/libasn1compiler/asn1c_save.c
@@ -32,18 +32,26 @@
? safe_fprintf(fp_h, "#include \"%s\"\n", s) \
: safe_fprintf(fp_h, "#include <%s>\n", s)) \
+enum include_type_result {
+ TI_NOT_INCLUDED,
+ TI_INCLUDED_FROM_BULK,
+ TI_INCLUDED_FROM_CMDLINE
+};
+
static int asn1c_dump_streams(arg_t *arg, asn1c_fdeps_t *, int, char **);
static int asn1c_print_streams(arg_t *arg);
static int asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *, int, char **);
static int asn1c_copy_over(arg_t *arg, char *path);
static int identical_files(const char *fname1, const char *fname2);
static int need_to_generate_pdu_collection(arg_t *arg);
+static abuf *generate_pdu_collection(arg_t *arg);
static int generate_pdu_collection_file(arg_t *arg);
static int generate_preamble(arg_t *, FILE *, int optc, char **argv);
-static int include_type_to_pdu_collection(arg_t *arg);
-static void pdu_collection_print_unused_types(arg_t *arg);
+static enum include_type_result include_type_to_pdu_collection(arg_t *arg);
+static int pdu_collection_has_unused_types(arg_t *arg);
static const char *generate_pdu_C_definition(void);
static void asn1c__cleanup_pdu_type(void);
+static int asn1c__pdu_type_lookup(const char *typename);
static int
asn1c__save_library_makefile(arg_t *arg, const asn1c_fdeps_t *deps, const char *datadir, const char *makefile_name) {
@@ -211,12 +219,29 @@
return 0;
}
+static int
+can_generate_pdu_collection(arg_t *arg) {
+ abuf *buf = generate_pdu_collection(arg);
+ if(!buf) {
+ return -1;
+ }
+ abuf_free(buf);
+ return 0;
+}
+
int
asn1c_save_compiled_output(arg_t *arg, const char *datadir,
int argc, int optc, char **argv) {
asn1c_fdeps_t *deps = 0;
int ret = -1;
+ /*
+ * Early check that we can properly generate PDU collection.
+ */
+ if(can_generate_pdu_collection(arg) == -1) {
+ return -1;
+ }
+
do {
asn1p_module_t *mod;
@@ -570,63 +595,79 @@
static int
generate_pdu_collection_file(arg_t *arg) {
- asn1p_module_t *mod;
- FILE *fp;
+ abuf *buf = generate_pdu_collection(arg);
+ assert(buf);
- fp = asn1c_open_file("pdu_collection", ".c", 0);
+ FILE *fp = asn1c_open_file("pdu_collection", ".c", 0);
if(fp == NULL) {
perror("pdu_collection.c");
return -1;
}
+ safe_fwrite(buf->buffer, buf->length, 1, fp);
+ fclose(fp);
- safe_fprintf(fp,
- "/*\n"
- " * Generated by asn1c-" VERSION " (http://lionet.info/asn1c)\n"
- " */\n\n");
- safe_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(!include_type_to_pdu_collection(arg))
- continue;
- safe_fprintf(fp, "extern struct asn_TYPE_descriptor_s "
- "asn_DEF_%s;\n",
- asn1c_make_identifier(0, arg->expr, NULL));
- }
- }
-
- safe_fprintf(fp, "\n\n");
- safe_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(!include_type_to_pdu_collection(arg))
- continue;
- if(!mod_printed++)
- safe_fprintf(fp, "\t/* From module %s in %s */\n",
- arg->expr->module->ModuleName,
- arg->expr->module->source_file_name);
- safe_fprintf(fp, "\t&asn_DEF_%s,\t\n",
- asn1c_make_identifier(0, arg->expr, NULL));
- }
- }
-
- safe_fprintf(fp, "\t0\n};\n\n");
-
- pdu_collection_print_unused_types(arg);
-
- fclose(fp);
safe_fprintf(stderr, "Generated pdu_collection.c\n");
+ return 0;
+}
- return 0;
+static abuf *
+generate_pdu_collection(arg_t *arg) {
+ asn1p_module_t *mod;
+ abuf *buf = abuf_new();
+
+ abuf_printf(buf, "/*\n * Generated by asn1c-" VERSION
+ " (http://lionet.info/asn1c)\n */\n\n");
+
+ TQ_FOR(mod, &(arg->asn->modules), mod_next) {
+ TQ_FOR(arg->expr, &(mod->members), next) {
+ if(include_type_to_pdu_collection(arg) == TI_NOT_INCLUDED) continue;
+ abuf_printf(buf,
+ "extern asn_TYPE_descriptor_t "
+ "asn_DEF_%s;\n",
+ asn1c_make_identifier(0, arg->expr, NULL));
+ }
+ }
+
+ abuf_printf(buf, "\n\n");
+ abuf_printf(buf, "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) {
+ switch(include_type_to_pdu_collection(arg)) {
+ case TI_NOT_INCLUDED:
+ continue;
+ case TI_INCLUDED_FROM_BULK:
+ /* Increment */
+ asn1c__pdu_type_lookup(arg->expr->Identifier);
+ break;
+ case TI_INCLUDED_FROM_CMDLINE:
+ break;
+ }
+ if(!mod_printed++) {
+ abuf_printf(buf, "\t/* From module %s in %s */\n",
+ arg->expr->module->ModuleName,
+ arg->expr->module->source_file_name);
+ }
+ abuf_printf(buf, "\t&asn_DEF_%s,\t\n",
+ asn1c_make_identifier(0, arg->expr, NULL));
+ }
+ }
+
+ abuf_printf(buf, "\t0\n};\n\n");
+
+ if(pdu_collection_has_unused_types(arg)) {
+ abuf_free(buf);
+ return NULL;
+ }
+
+ return buf;
}
static struct PDUType {
char *typename;
int used;
} *pduType;
-static int pduTypes;
+static size_t pduTypes;
static const char *
generate_pdu_C_definition(void) {
@@ -661,8 +702,7 @@
static void
asn1c__cleanup_pdu_type() {
- int i;
- for(i = 0; i < pduTypes; i++) {
+ for(size_t i = 0; i < pduTypes; i++) {
free(pduType[i].typename);
}
free(pduType);
@@ -672,15 +712,14 @@
static int
asn1c__pdu_type_lookup(const char *typename) {
- int i;
- for(i = 0; i < pduTypes; i++) {
- struct PDUType *pt = &pduType[i];
- if(strcmp(pt->typename, typename) == 0) {
- pt->used++;
- return 1;
- }
- }
- return 0;
+ for(size_t i = 0; i < pduTypes; i++) {
+ struct PDUType *pt = &pduType[i];
+ if(strcmp(pt->typename, typename) == 0) {
+ pt->used++;
+ return 1;
+ }
+ }
+ return 0;
}
static int
@@ -692,34 +731,36 @@
return 0;
}
-static void
-pdu_collection_print_unused_types(arg_t *arg) {
- int i;
- for(i = 0; i < pduTypes; i++) {
- struct PDUType *pt = &pduType[i];
- if(!pt->used) {
- WARNING("Missing type specified in -pdu=%s",
- pt->typename);
- }
- }
+static int
+pdu_collection_has_unused_types(arg_t *arg) {
+ int ret = 0;
+
+ for(size_t i = 0; i < pduTypes; i++) {
+ struct PDUType *pt = &pduType[i];
+ if(!pt->used) {
+ FATAL("Unknown ASN.1 type specified in -pdu=%s", pt->typename);
+ ret = -1;
+ }
+ }
+
+ return ret;
}
-static int
+static enum include_type_result
include_type_to_pdu_collection(arg_t *arg) {
- if(!asn1_lang_map[arg->expr->meta_type]
- [arg->expr->expr_type].type_cb)
- return 0;
+ if(!asn1_lang_map[arg->expr->meta_type][arg->expr->expr_type].type_cb)
+ return 0;
/* Parameterized types can't serve as PDU's without instantiation. */
if(arg->expr->lhs_params) {
return 0;
}
- if((arg->flags & A1C_PDU_ALL)
- || ((arg->flags & A1C_PDU_AUTO) && !arg->expr->_type_referenced)
- || asn1c__pdu_type_lookup(arg->expr->Identifier)) {
- return 1;
- }
+ if((arg->flags & A1C_PDU_ALL)
+ || ((arg->flags & A1C_PDU_AUTO) && !arg->expr->_type_referenced)
+ || asn1c__pdu_type_lookup(arg->expr->Identifier)) {
+ return 1;
+ }
- return 0;
+ return 0;
}