mirror of https://gerrit.osmocom.org/asn1c
-fknown-extern-type support
This commit is contained in:
parent
8aba2c1260
commit
97bdee2dd2
|
@ -27,4 +27,10 @@ int asn1f_process(asn1p_t *_asn,
|
|||
enum asn1f_flags,
|
||||
void (*error_log_callback)(int _severity, const char *fmt, ...));
|
||||
|
||||
|
||||
/*
|
||||
* Explicitly mark type as known.
|
||||
*/
|
||||
int asn1f_make_known_external_type(const char *);
|
||||
|
||||
#endif /* ASN1FIX_H */
|
||||
|
|
|
@ -28,9 +28,19 @@ asn1f_fix_dereference_types(arg_t *arg) {
|
|||
*/
|
||||
type_expr = asn1f_find_terminal_type(arg, expr, 0);
|
||||
if(type_expr == NULL) {
|
||||
const char *type_name;
|
||||
|
||||
if(errno == EEXIST) {
|
||||
/* Ignore missing type
|
||||
* if known to be defined externally:
|
||||
* -fknown-extern-type=<name>
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
type_name = asn1f_printable_reference(expr->reference);
|
||||
FATAL("Unknown type \"%s\" referenced by \"%s\" at line %d",
|
||||
asn1f_printable_reference(expr->reference),
|
||||
expr->Identifier, expr->_lineno);
|
||||
type_name, expr->Identifier, expr->_lineno);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
#ifndef _ASN1FIX_INTERNAL_H_
|
||||
#define _ASN1FIX_INTERNAL_H_
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* System headers required in various modules.
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "asn1fix_internal.h"
|
||||
|
||||
#include "asn1fix.h"
|
||||
|
||||
char const *
|
||||
asn1f_printable_reference(asn1p_ref_t *ref) {
|
||||
|
@ -274,3 +274,59 @@ asn1f_count_children(asn1p_expr_t *expr) {
|
|||
return count;
|
||||
}
|
||||
|
||||
|
||||
static char **known_types;
|
||||
static int known_types_count;
|
||||
static int known_types_size;
|
||||
|
||||
static int _known_types_cmp(const void *ap, const void *bp) {
|
||||
const char *a = *(const char * const *)ap;
|
||||
const char *b = *(const char * const *)bp;
|
||||
return strcmp(a, b);
|
||||
}
|
||||
|
||||
int
|
||||
asn1f_make_known_external_type(const char *type_name) {
|
||||
char *tname;
|
||||
|
||||
/* Check for duplicates */
|
||||
if(asn1f_check_known_external_type(type_name) == 0) {
|
||||
errno = EEXIST;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Ensure enough space */
|
||||
if(known_types_count <= known_types_size) {
|
||||
int n = known_types_size ? known_types_size << 1 : 4;
|
||||
void *p;
|
||||
p = realloc(known_types, n * sizeof(known_types[0]));
|
||||
if(!p) return -1;
|
||||
known_types = p;
|
||||
known_types_size = n;
|
||||
}
|
||||
|
||||
tname = strdup(type_name);
|
||||
if(!tname) return -1;
|
||||
|
||||
known_types[known_types_count++] = tname;
|
||||
|
||||
#ifdef HAVE_MERGESORT
|
||||
mergesort
|
||||
#else
|
||||
qsort
|
||||
#endif
|
||||
(known_types, known_types_count, sizeof(known_types[0]),
|
||||
_known_types_cmp);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
asn1f_check_known_external_type(const char *type_name) {
|
||||
void *p = bsearch(&type_name, known_types, known_types_count,
|
||||
sizeof(known_types[0]), _known_types_cmp);
|
||||
if(p) return 0;
|
||||
errno = ESRCH;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,4 +44,9 @@ int asn1f_check_unique_expr_child(arg_t *arg, asn1p_expr_t *child,
|
|||
*/
|
||||
int asn1f_count_children(asn1p_expr_t *parent);
|
||||
|
||||
/*
|
||||
* Check if type is explicitly known.
|
||||
*/
|
||||
int asn1f_check_known_external_type(const char *);
|
||||
|
||||
#endif /* _ASN1FIX_MISC_H_ */
|
||||
|
|
|
@ -228,12 +228,17 @@ asn1f_lookup_symbol(arg_t *arg, asn1p_ref_t *ref, asn1p_module_t **module_r) {
|
|||
}
|
||||
if(ref_tc == NULL) {
|
||||
DEBUG("Module \"%s\" does not contain \"%s\" "
|
||||
"mentioned at line %d",
|
||||
"mentioned at line %d: %s",
|
||||
src_mod->Identifier,
|
||||
identifier,
|
||||
ref->_lineno
|
||||
ref->_lineno,
|
||||
strerror(errno)
|
||||
);
|
||||
errno = ESRCH;
|
||||
if(asn1f_check_known_external_type(identifier) == 0) {
|
||||
errno = EEXIST; /* Exists somewhere */
|
||||
} else {
|
||||
errno = ESRCH;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -312,8 +317,9 @@ asn1f_find_terminal_thing(arg_t *arg, asn1p_expr_t *expr,
|
|||
*/
|
||||
tc = asn1f_lookup_symbol(arg, ref, &mod);
|
||||
if(tc == NULL) {
|
||||
DEBUG("\tSymbol \"%s\" not found",
|
||||
asn1f_printable_reference(ref));
|
||||
DEBUG("\tSymbol \"%s\" not found: %s",
|
||||
asn1f_printable_reference(ref),
|
||||
strerror(errno));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue