-fknown-extern-type support

This commit is contained in:
Lev Walkin 2004-06-28 21:21:24 +00:00
parent 8aba2c1260
commit 97bdee2dd2
6 changed files with 95 additions and 8 deletions

View File

@ -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 */

View File

@ -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;
}

View File

@ -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.
*/

View File

@ -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;
}

View File

@ -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_ */

View File

@ -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;
}