Commit 5f4dbb75 authored by Lev Walkin's avatar Lev Walkin

earlier detection of unknown -pdu=Type

parent 9ce64c13
...@@ -32,18 +32,26 @@ static size_t safe_fwrite(const void *ptr, size_t size, size_t nitems, FILE *str ...@@ -32,18 +32,26 @@ static size_t safe_fwrite(const void *ptr, size_t size, size_t nitems, FILE *str
? safe_fprintf(fp_h, "#include \"%s\"\n", s) \ ? safe_fprintf(fp_h, "#include \"%s\"\n", s) \
: 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_dump_streams(arg_t *arg, asn1c_fdeps_t *, int, char **);
static int asn1c_print_streams(arg_t *arg); static int asn1c_print_streams(arg_t *arg);
static int asn1c_save_streams(arg_t *arg, asn1c_fdeps_t *, int, char **); 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 asn1c_copy_over(arg_t *arg, char *path);
static int identical_files(const char *fname1, const char *fname2); static int identical_files(const char *fname1, const char *fname2);
static int need_to_generate_pdu_collection(arg_t *arg); 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_pdu_collection_file(arg_t *arg);
static int generate_preamble(arg_t *, FILE *, int optc, char **argv); static int generate_preamble(arg_t *, FILE *, int optc, char **argv);
static int include_type_to_pdu_collection(arg_t *arg); static enum include_type_result include_type_to_pdu_collection(arg_t *arg);
static void pdu_collection_print_unused_types(arg_t *arg); static int pdu_collection_has_unused_types(arg_t *arg);
static const char *generate_pdu_C_definition(void); static const char *generate_pdu_C_definition(void);
static void asn1c__cleanup_pdu_type(void); static void asn1c__cleanup_pdu_type(void);
static int asn1c__pdu_type_lookup(const char *typename);
static int static int
asn1c__save_library_makefile(arg_t *arg, const asn1c_fdeps_t *deps, const char *datadir, const char *makefile_name) { asn1c__save_library_makefile(arg_t *arg, const asn1c_fdeps_t *deps, const char *datadir, const char *makefile_name) {
...@@ -211,12 +219,29 @@ asn1c__save_example_makefile(arg_t *arg, const asn1c_fdeps_t *deps, ...@@ -211,12 +219,29 @@ asn1c__save_example_makefile(arg_t *arg, const asn1c_fdeps_t *deps,
return 0; 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 int
asn1c_save_compiled_output(arg_t *arg, const char *datadir, asn1c_save_compiled_output(arg_t *arg, const char *datadir,
int argc, int optc, char **argv) { int argc, int optc, char **argv) {
asn1c_fdeps_t *deps = 0; asn1c_fdeps_t *deps = 0;
int ret = -1; int ret = -1;
/*
* Early check that we can properly generate PDU collection.
*/
if(can_generate_pdu_collection(arg) == -1) {
return -1;
}
do { do {
asn1p_module_t *mod; asn1p_module_t *mod;
...@@ -570,63 +595,79 @@ asn1c_copy_over(arg_t *arg, char *path) { ...@@ -570,63 +595,79 @@ asn1c_copy_over(arg_t *arg, char *path) {
static int static int
generate_pdu_collection_file(arg_t *arg) { generate_pdu_collection_file(arg_t *arg) {
asn1p_module_t *mod; abuf *buf = generate_pdu_collection(arg);
FILE *fp; assert(buf);
fp = asn1c_open_file("pdu_collection", ".c", 0); FILE *fp = asn1c_open_file("pdu_collection", ".c", 0);
if(fp == NULL) { if(fp == NULL) {
perror("pdu_collection.c"); perror("pdu_collection.c");
return -1; return -1;
} }
safe_fwrite(buf->buffer, buf->length, 1, fp);
fclose(fp);
safe_fprintf(fp, safe_fprintf(stderr, "Generated pdu_collection.c\n");
"/*\n" return 0;
" * 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"); static abuf *
safe_fprintf(fp, "struct asn_TYPE_descriptor_s *asn_pdu_collection[] = {\n"); generate_pdu_collection(arg_t *arg) {
TQ_FOR(mod, &(arg->asn->modules), mod_next) { asn1p_module_t *mod;
int mod_printed = 0; abuf *buf = abuf_new();
TQ_FOR(arg->expr, &(mod->members), next) {
if(!include_type_to_pdu_collection(arg)) abuf_printf(buf, "/*\n * Generated by asn1c-" VERSION
continue; " (http://lionet.info/asn1c)\n */\n\n");
if(!mod_printed++)
safe_fprintf(fp, "\t/* From module %s in %s */\n", TQ_FOR(mod, &(arg->asn->modules), mod_next) {
arg->expr->module->ModuleName, TQ_FOR(arg->expr, &(mod->members), next) {
arg->expr->module->source_file_name); if(include_type_to_pdu_collection(arg) == TI_NOT_INCLUDED) continue;
safe_fprintf(fp, "\t&asn_DEF_%s,\t\n", abuf_printf(buf,
asn1c_make_identifier(0, arg->expr, NULL)); "extern asn_TYPE_descriptor_t "
} "asn_DEF_%s;\n",
} asn1c_make_identifier(0, arg->expr, NULL));
}
}
safe_fprintf(fp, "\t0\n};\n\n"); 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));
}
}
pdu_collection_print_unused_types(arg); abuf_printf(buf, "\t0\n};\n\n");
fclose(fp); if(pdu_collection_has_unused_types(arg)) {
safe_fprintf(stderr, "Generated pdu_collection.c\n"); abuf_free(buf);
return NULL;
}
return 0; return buf;
} }
static struct PDUType { static struct PDUType {
char *typename; char *typename;
int used; int used;
} *pduType; } *pduType;
static int pduTypes; static size_t pduTypes;
static const char * static const char *
generate_pdu_C_definition(void) { generate_pdu_C_definition(void) {
...@@ -661,8 +702,7 @@ asn1c__add_pdu_type(const char *ctypename) { ...@@ -661,8 +702,7 @@ asn1c__add_pdu_type(const char *ctypename) {
static void static void
asn1c__cleanup_pdu_type() { asn1c__cleanup_pdu_type() {
int i; for(size_t i = 0; i < pduTypes; i++) {
for(i = 0; i < pduTypes; i++) {
free(pduType[i].typename); free(pduType[i].typename);
} }
free(pduType); free(pduType);
...@@ -672,15 +712,14 @@ asn1c__cleanup_pdu_type() { ...@@ -672,15 +712,14 @@ asn1c__cleanup_pdu_type() {
static int static int
asn1c__pdu_type_lookup(const char *typename) { asn1c__pdu_type_lookup(const char *typename) {
int i; for(size_t i = 0; i < pduTypes; i++) {
for(i = 0; i < pduTypes; i++) { struct PDUType *pt = &pduType[i];
struct PDUType *pt = &pduType[i]; if(strcmp(pt->typename, typename) == 0) {
if(strcmp(pt->typename, typename) == 0) { pt->used++;
pt->used++; return 1;
return 1; }
} }
} return 0;
return 0;
} }
static int static int
...@@ -692,34 +731,36 @@ need_to_generate_pdu_collection(arg_t *arg) { ...@@ -692,34 +731,36 @@ need_to_generate_pdu_collection(arg_t *arg) {
return 0; return 0;
} }
static void static int
pdu_collection_print_unused_types(arg_t *arg) { pdu_collection_has_unused_types(arg_t *arg) {
int i; int ret = 0;
for(i = 0; i < pduTypes; i++) {
struct PDUType *pt = &pduType[i]; for(size_t i = 0; i < pduTypes; i++) {
if(!pt->used) { struct PDUType *pt = &pduType[i];
WARNING("Missing type specified in -pdu=%s", if(!pt->used) {
pt->typename); 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) { include_type_to_pdu_collection(arg_t *arg) {
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) return 0;
return 0;
/* Parameterized types can't serve as PDU's without instantiation. */ /* Parameterized types can't serve as PDU's without instantiation. */
if(arg->expr->lhs_params) { if(arg->expr->lhs_params) {
return 0; return 0;
} }
if((arg->flags & A1C_PDU_ALL) if((arg->flags & A1C_PDU_ALL)
|| ((arg->flags & A1C_PDU_AUTO) && !arg->expr->_type_referenced) || ((arg->flags & A1C_PDU_AUTO) && !arg->expr->_type_referenced)
|| asn1c__pdu_type_lookup(arg->expr->Identifier)) { || asn1c__pdu_type_lookup(arg->expr->Identifier)) {
return 1; return 1;
} }
return 0; return 0;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment