earlier detection of unknown -pdu=Type

This commit is contained in:
Lev Walkin 2017-11-11 14:52:11 -08:00
parent 9ce64c13c7
commit 5f4dbb751a
1 changed files with 117 additions and 76 deletions

View File

@ -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)) \
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 @@ asn1c__save_example_makefile(arg_t *arg, const asn1c_fdeps_t *deps,
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 @@ asn1c_copy_over(arg_t *arg, char *path) {
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 @@ asn1c__add_pdu_type(const char *ctypename) {
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 @@ asn1c__cleanup_pdu_type() {
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 @@ need_to_generate_pdu_collection(arg_t *arg) {
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;
}