early suggestion of -fcompound-names
diff --git a/examples/sample.source.LDAP3/Makefile b/examples/sample.source.LDAP3/Makefile
index 237d3be..206fdbd 100644
--- a/examples/sample.source.LDAP3/Makefile
+++ b/examples/sample.source.LDAP3/Makefile
@@ -206,66 +206,84 @@
CPPFLAGS="" \
../sample.makefile.regen
-check: ${TARGET} check-ber check-xer check-per
+check: ${TARGET} check-ber check-xer check-oer check-per
@echo ================
@echo All tests passed
@echo ================
check-ber:
@if test -f sample-LDAPMessage-1.[db]er ; then \
- for f in sample-LDAPMessage-*.[db]er; do \
+ for f in sample-*-*.[db]er; do \
+ pdu=`echo $$f | sed -E -e "s/sample-([A-Za-z0-9-]+)-[0-9].*/\1/"`; \
for b in 1 17 33 980 8192; do \
- echo "Recoding $$f into XER and back ($$b)..."; \
- ./${TARGET} -b $$b -iber -oxer $$f > ./.tmp.1.$$$$ || exit 2; \
- ./${TARGET} -b $$b -ixer -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 3; \
+ echo "Recoding $$f ($$pdu) into XER and back ($$b)..."; \
+ ./${TARGET} -p $$pdu -b $$b -iber -oxer $$f > ./.tmp.1.$$$$ || exit 2; \
+ ./${TARGET} -p $$pdu -b $$b -ixer -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 3; \
diff ./.tmp.1.$$$$ ./.tmp.2.$$$$ || exit 4; \
rm -f ./.tmp.[12].$$$$; \
echo "Test junking $$f (please wait)..."; \
- ./${TARGET} -J0.0001 -n 1000 -b $$b -iber -onull $$f || exit 5; \
- ./${TARGET} -J0.001 -n 1000 -b $$b -iber -onull $$f || exit 6; \
+ ./${TARGET} -J0.0001 -n 1000 -p $$pdu -b $$b -iber -onull $$f || exit 5; \
+ ./${TARGET} -J0.001 -n 1000 -p $$pdu -b $$b -iber -onull $$f || exit 6; \
done; done; fi
check-xer:
@if test -f sample-LDAPMessage-1.xer ; then \
- for f in sample-LDAPMessage-*.xer; do \
+ for f in sample-*-*.xer; do \
+ pdu=`echo $$f | sed -E -e "s/sample-([A-Za-z0-9-]+)-[0-9].*/\1/"`; \
for b in 1 17 33 980 8192; do \
- echo "Recoding $$f into DER and back ($$b)..."; \
- ./${TARGET} -b $$b -ixer -oder $$f > ./.tmp.1.$$$$ || exit 2; \
- ./${TARGET} -b $$b -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 3; \
+ echo "Recoding $$f ($$pdu) into DER and back ($$b)..."; \
+ ./${TARGET} -p $$pdu -b $$b -ixer -oder $$f > ./.tmp.1.$$$$ || exit 2; \
+ ./${TARGET} -p $$pdu -b $$b -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 3; \
diff $$f ./.tmp.2.$$$$ || exit 4; \
rm -f ./.tmp.[12].$$$$; \
echo "Test junking $$f (please wait)..."; \
- ./${TARGET} -J0.0001 -n 1000 -b $$b -ixer -onull $$f || exit 5; \
- ./${TARGET} -J0.001 -n 1000 -b $$b -ixer -onull $$f || exit 6; \
+ ./${TARGET} -J0.0001 -n 1000 -p $$pdu -b $$b -ixer -onull $$f || exit 5; \
+ ./${TARGET} -J0.001 -n 1000 -p $$pdu -b $$b -ixer -onull $$f || exit 6; \
+ done; done; fi
+
+check-oer:
+ @if test -f sample-LDAPMessage-1.*oer ; then \
+ for f in sample-*-*.*oer; do \
+ pdu=`echo $$f | sed -E -e "s/sample-([A-Za-z0-9-]+)-[0-9].*/\1/"`; \
+ for b in 1 17 33 980 8192; do \
+ echo "Recoding $$f ($$pdu) into XER and back ($$b)..."; \
+ ./${TARGET} -p $$pdu -b $$b -ioer -oxer $$f > ./.tmp.1.$$$$ || exit 2; \
+ ./${TARGET} -p $$pdu -b $$b -ixer -ooer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 3; \
+ diff $$f ./.tmp.2.$$$$ || exit 4; \
+ rm -f ./.tmp.[12].$$$$; \
+ echo "Test junking $$f (please wait) ($$b) ..."; \
+ ./${TARGET} -J0.0001 -n 1000 -p $$pdu -b $$b -ioer -onull $$f || exit 5; \
+ ./${TARGET} -J0.001 -n 1000 -p $$pdu -b $$b -ioer -onull $$f || exit 6; \
done; done; fi
check-per:
@if test -f sample-LDAPMessage-1-nopad.per ; then \
- for f in sample-LDAPMessage-[1-9]-nopad.per; do \
+ for f in sample-*-[1-9]-nopad.per; do \
+ pdu=`echo $$f | sed -E -e "s/sample-([A-Za-z0-9-]+)-[0-9].*/\1/"`; \
for b in 1 17 33 980 8192; do \
- echo "Recoding non-padded $$f into DER into XER and back ($$b)..."; \
- ./${TARGET} -b $$b -per-nopad -iper -oder $$f > ./.tmp.1.$$$$ || exit 2; \
- ./${TARGET} -b $$b -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 3; \
- ./${TARGET} -b $$b -ixer -oder ./.tmp.2.$$$$ > ./.tmp.3.$$$$ || exit 4; \
+ echo "Recoding non-padded $$f ($$pdu) into DER into XER and back ($$b)..."; \
+ ./${TARGET} -p $$pdu -b $$b -per-nopad -iper -oder $$f > ./.tmp.1.$$$$ || exit 2; \
+ ./${TARGET} -p $$pdu -b $$b -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 3; \
+ ./${TARGET} -p $$pdu -b $$b -ixer -oder ./.tmp.2.$$$$ > ./.tmp.3.$$$$ || exit 4; \
diff ./.tmp.1.$$$$ ./.tmp.3.$$$$ || exit 5; \
rm -f ./.tmp.[123].$$$$; \
echo "Test junking $$f (please wait)..."; \
- ./${TARGET} -J0.0001 -n 1000 -b $$b -per-nopad -iper -onull $$f || exit 6; \
- ./${TARGET} -J0.001 -n 1000 -b $$b -per-nopad -iper -onull $$f || exit 7; \
+ ./${TARGET} -J0.0001 -n 1000 -p $$pdu -b $$b -per-nopad -iper -onull $$f || exit 6; \
+ ./${TARGET} -J0.001 -n 1000 -p $$pdu -b $$b -per-nopad -iper -onull $$f || exit 7; \
done; done; fi
@if test -f sample-LDAPMessage-1.per ; then \
for f in sample-*-[1-9].per; do \
- pdu=`echo $$f | sed -E -e "s/sample-([A-Za-z-]+)-[0-9].*/\1/"`; \
+ pdu=`echo $$f | sed -E -e "s/sample-([A-Za-z0-9-]+)-[0-9].*/\1/"`; \
for b in 1 17 33 980 8192; do \
- echo "Recoding $$f into DER into XER and back ($$b)..."; \
- ./${TARGET} -b $$b -p $$pdu -iper -oder $$f > ./.tmp.1.$$$$ || exit 3; \
- ./${TARGET} -b $$b -p $$pdu -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 4; \
- ./${TARGET} -b $$b -p $$pdu -ixer -oper ./.tmp.2.$$$$ > ./.tmp.1.$$$$ || exit 5; \
+ echo "Recoding $$f ($$pdu) into DER into XER and back ($$b)..."; \
+ ./${TARGET} -p $$pdu -b $$b -iper -oder $$f > ./.tmp.1.$$$$ || exit 3; \
+ ./${TARGET} -p $$pdu -b $$b -iber -oxer ./.tmp.1.$$$$ > ./.tmp.2.$$$$ || exit 4; \
+ ./${TARGET} -p $$pdu -b $$b -ixer -oper ./.tmp.2.$$$$ > ./.tmp.1.$$$$ || exit 5; \
diff $$f ./.tmp.1.$$$$ || exit 6; \
rm -f ./.tmp.[12].$$$$; \
echo "Test junking $$f (please wait)..."; \
- ./${TARGET} -J0.0001 -n 1000 -b $$b -iper -onull $$f || exit 7; \
- ./${TARGET} -J0.001 -n 1000 -b $$b -iper -onull $$f || exit 8; \
+ ./${TARGET} -J0.0001 -n 1000 -p $$pdu -b $$b -iper -onull $$f || exit 7; \
+ ./${TARGET} -J0.001 -n 1000 -p $$pdu -b $$b -iper -onull $$f || exit 8; \
done; done; fi
maybe-wip-pause:
diff --git a/libasn1compiler/asn1c_naming.c b/libasn1compiler/asn1c_naming.c
index 6ab3c4a..e408e55 100644
--- a/libasn1compiler/asn1c_naming.c
+++ b/libasn1compiler/asn1c_naming.c
@@ -4,6 +4,68 @@
#include "asn1c_misc.h"
#include <asn1_buffer.h>
+struct intl_name {
+ asn1p_expr_t *expr;
+ asn1p_expr_t *clashes_with;
+ const char *name;
+ TQ_ENTRY(struct intl_name) next;
+};
+static TQ_HEAD(struct intl_name) used_names;
+
+void
+c_name_clash_finder_init() {
+ TQ_INIT(&used_names);
+}
+
+static void
+register_global_name(arg_t *arg, const char *name) {
+ struct intl_name *n;
+
+ TQ_FOR(n, &used_names, next) {
+ if(strcmp(n->name, name) == 0) {
+ if(!(arg->expr->_mark & TM_NAMEGIVEN) && arg->expr != n->expr) {
+ n->clashes_with = arg->expr;
+ return;
+ }
+ }
+ }
+
+ n = calloc(1, sizeof(*n));
+ assert(n);
+ n->expr = arg->expr;
+ n->name = strdup(name);
+ TQ_ADD(&used_names, n, next);
+}
+
+int
+c_name_clash(arg_t *arg) {
+ struct intl_name *n;
+ size_t n_clashes = 0;
+ const size_t max_clashes = 5;
+
+ TQ_FOR(n, &used_names, next) {
+ if(n->clashes_with) {
+ if(n_clashes++ > max_clashes) continue;
+ FATAL(
+ "Name \"%s\" is generated by %s.%s at line %s:%d and "
+ "%s.%s at line %s:%d",
+ n->name, n->expr->module->ModuleName, n->expr->Identifier,
+ n->expr->module->source_file_name, n->expr->_lineno,
+ n->clashes_with->module->ModuleName,
+ n->clashes_with->Identifier,
+ n->clashes_with->module->source_file_name,
+ n->clashes_with->_lineno);
+ }
+ }
+
+ if(n_clashes > max_clashes) {
+ FATAL("... %zu more name clashes not shown", n_clashes - max_clashes);
+ }
+
+ return n_clashes > 0;
+}
+
+
static abuf *
construct_base_name(abuf *buf, arg_t *arg, int compound_names,
int avoid_keywords) {
@@ -97,6 +159,16 @@
abuf_free(part_name);
abuf_free(member_name);
+ /* A _subset_ of names is checked against being globally unique */
+ register_global_name(arg, names.base_name);
+ register_global_name(arg, names.full_name);
+ register_global_name(arg, names.presence_enum);
+ register_global_name(arg, names.presence_name);
+ register_global_name(arg, names.members_enum);
+ register_global_name(arg, names.members_name);
+
+ arg->expr->_mark |= TM_NAMEGIVEN;
+
return names;
}
@@ -133,5 +205,3 @@
return ab.buffer;
}
-
-
diff --git a/libasn1compiler/asn1c_naming.h b/libasn1compiler/asn1c_naming.h
index 2e0e88d..737f133 100644
--- a/libasn1compiler/asn1c_naming.h
+++ b/libasn1compiler/asn1c_naming.h
@@ -16,4 +16,13 @@
const char *c_member_name(arg_t *, asn1p_expr_t *); /* %s_%s */
const char *c_presence_name(arg_t *, asn1p_expr_t *); /* %s_PR_%s */
+/*
+ * Returns 0 if no C name clashes have been encountered.
+ * Returns 1 if C name clashes have been encountered.
+ * Prints out the clashing items and suggests -fcompound-names.
+ */
+int c_name_clash(arg_t *arg);
+
+void c_name_clash_finder_init(void);
+
#endif /* ASN1_COMPILER_NAMING_H */
diff --git a/libasn1compiler/asn1compiler.c b/libasn1compiler/asn1compiler.c
index de09cfb..8d963ef 100644
--- a/libasn1compiler/asn1compiler.c
+++ b/libasn1compiler/asn1compiler.c
@@ -3,6 +3,7 @@
#include "asn1c_out.h"
#include "asn1c_save.h"
#include "asn1c_ioc.h"
+#include "asn1c_naming.h"
static void default_logger_cb(int, const char *fmt, ...);
static int asn1c_compile_expr(arg_t *arg, const asn1c_ioc_table_and_objset_t *);
@@ -17,6 +18,8 @@
asn1p_module_t *mod;
int ret;
+ c_name_clash_finder_init();
+
/*
* Initialize target language.
*/
@@ -60,6 +63,20 @@
}
}
+ if(c_name_clash(arg)) {
+ if(arg->flags & A1C_COMPOUND_NAMES) {
+ FATAL("Name clashes encountered even with -fcompound-names flag");
+ /* Proceed further for better debugging. */
+ } else {
+ FATAL("Use \"-fcompound-names\" flag to asn1c to resolve name clashes");
+ if(arg->flags & A1C_PRINT_COMPILED) {
+ /* Proceed further for better debugging. */
+ } else {
+ return -1;
+ }
+ }
+ }
+
DEBUG("Saving compiled data");
/*
diff --git a/libasn1parser/asn1p_expr.h b/libasn1parser/asn1p_expr.h
index 2d72586..4def1fe 100644
--- a/libasn1parser/asn1p_expr.h
+++ b/libasn1parser/asn1p_expr.h
@@ -250,7 +250,8 @@
TM_RECURSION = (1<<0), /* Used to break recursion */
TM_BROKEN = (1<<1), /* A warning was already issued */
TM_PERFROMCT = (1<<2), /* PER FROM() constraint tables emitted */
- TM_NAMECLASH = (1<<3) /* Name clash found, need to add module name to resolve */
+ TM_NAMECLASH = (1<<3), /* Name clash found, need to add module name to resolve */
+ TM_NAMEGIVEN = (1<<4) /* The expression has already yielded a name */
} _mark;
/*
diff --git a/tests/tests-asn1c-compiler/110-param-3-OK.asn1.-Pfwide-types b/tests/tests-asn1c-compiler/110-param-3-OK.asn1.-Pfcompound-names
similarity index 92%
rename from tests/tests-asn1c-compiler/110-param-3-OK.asn1.-Pfwide-types
rename to tests/tests-asn1c-compiler/110-param-3-OK.asn1.-Pfcompound-names
index 5c3c98c..ccf82a8 100644
--- a/tests/tests-asn1c-compiler/110-param-3-OK.asn1.-Pfwide-types
+++ b/tests/tests-asn1c-compiler/110-param-3-OK.asn1.-Pfcompound-names
@@ -1,33 +1,33 @@
/*** <<< INCLUDES [Flag] >>> ***/
-#include <INTEGER.h>
+#include <NativeInteger.h>
#include <constr_SEQUENCE.h>
-#include <ENUMERATED.h>
+#include <NativeEnumerated.h>
/*** <<< DEPS [Flag] >>> ***/
-typedef enum field {
- field_red = 0,
- field_green = 1,
- field_blue = 5
-} e_field;
-typedef enum field {
- field_red = 3,
- field_green = 4,
- field_blue = 5
-} e_field;
+typedef enum Flag_16P0__field {
+ Flag_16P0__field_red = 0,
+ Flag_16P0__field_green = 1,
+ Flag_16P0__field_blue = 5
+} e_Flag_16P0__field;
+typedef enum Flag_16P1__field {
+ Flag_16P1__field_red = 3,
+ Flag_16P1__field_green = 4,
+ Flag_16P1__field_blue = 5
+} e_Flag_16P1__field;
/*** <<< TYPE-DECLS [Flag] >>> ***/
typedef struct Flag_16P0 {
- INTEGER_t *field /* DEFAULT 5 */;
+ long *field /* DEFAULT 5 */;
/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
} Flag_16P0_t;
typedef struct Flag_16P1 {
- ENUMERATED_t *field /* DEFAULT 5 */;
+ long *field /* DEFAULT 5 */;
/* Context for parsing across buffer boundaries */
asn_struct_ctx_t _asn_ctx;
@@ -46,14 +46,14 @@
/*** <<< CODE [Flag] >>> ***/
/*
- * This type is implemented using ENUMERATED,
+ * This type is implemented using NativeEnumerated,
* so here we adjust the DEF accordingly.
*/
/*** <<< STAT-DEFS [Flag] >>> ***/
static int asn_DFL_2_set_5(int set_value, void **sptr) {
- INTEGER_t *st = *sptr;
+ long *st = *sptr;
if(!st) {
if(!set_value) return -1; /* Not a default value */
@@ -63,20 +63,18 @@
if(set_value) {
/* Install default value 5 */
- return asn_long2INTEGER(st, 5);
+ *st = 5;
+ return 0;
} else {
/* Test default value 5 */
- long value;
- if(asn_INTEGER2long(st, &value))
- return -1;
- return (value == 5);
+ return (*st == 5);
}
}
asn_TYPE_member_t asn_MBR_Flag_16P0_1[] = {
{ ATF_POINTER, 1, offsetof(struct Flag_16P0, field),
.tag = (ASN_TAG_CLASS_UNIVERSAL | (2 << 2)),
.tag_mode = 0,
- .type = &asn_DEF_INTEGER,
+ .type = &asn_DEF_NativeInteger,
.type_selector = 0,
.memb_constraints = 0, /* Defer constraints checking to the member type */
.oer_constraints = 0, /* OER is not compiled, use -gen-OER */
@@ -119,7 +117,7 @@
};
static int asn_DFL_7_set_5(int set_value, void **sptr) {
- ENUMERATED_t *st = *sptr;
+ long *st = *sptr;
if(!st) {
if(!set_value) return -1; /* Not a default value */
@@ -129,13 +127,11 @@
if(set_value) {
/* Install default value 5 */
- return asn_long2INTEGER(st, 5);
+ *st = 5;
+ return 0;
} else {
/* Test default value 5 */
- long value;
- if(asn_INTEGER2long(st, &value))
- return -1;
- return (value == 5);
+ return (*st == 5);
}
}
static const asn_INTEGER_enum_map_t asn_MAP_field_value2enum_7[] = {
@@ -164,8 +160,8 @@
asn_TYPE_descriptor_t asn_DEF_field_7 = {
"field",
"field",
- &asn_OP_ENUMERATED,
- ENUMERATED_constraint,
+ &asn_OP_NativeEnumerated,
+ NativeEnumerated_constraint,
asn_DEF_field_tags_7,
sizeof(asn_DEF_field_tags_7)
/sizeof(asn_DEF_field_tags_7[0]), /* 1 */
diff --git a/tests/tests-asn1c-compiler/142-anonymous-types-deco-OK.asn1.-P b/tests/tests-asn1c-compiler/142-anonymous-types-deco-OK.asn1.-Pfcompound-names
similarity index 96%
rename from tests/tests-asn1c-compiler/142-anonymous-types-deco-OK.asn1.-P
rename to tests/tests-asn1c-compiler/142-anonymous-types-deco-OK.asn1.-Pfcompound-names
index 649ddb2..12db782 100644
--- a/tests/tests-asn1c-compiler/142-anonymous-types-deco-OK.asn1.-P
+++ b/tests/tests-asn1c-compiler/142-anonymous-types-deco-OK.asn1.-Pfcompound-names
@@ -105,7 +105,7 @@
typedef struct Type1 {
Type1_PR present;
union Type1_u {
- struct anonType {
+ struct Type1__anonType {
OCTET_STRING_t x;
OCTET_STRING_t y;
@@ -182,7 +182,7 @@
/*** <<< STAT-DEFS [Type1] >>> ***/
static asn_TYPE_member_t asn_MBR_anonType_2[] = {
- { ATF_NOFLAGS, 0, offsetof(struct anonType, x),
+ { ATF_NOFLAGS, 0, offsetof(struct Type1__anonType, x),
.tag = (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = &asn_DEF_OCTET_STRING,
@@ -193,7 +193,7 @@
.default_value = 0,
.name = "x"
},
- { ATF_NOFLAGS, 0, offsetof(struct anonType, y),
+ { ATF_NOFLAGS, 0, offsetof(struct Type1__anonType, y),
.tag = (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = &asn_DEF_OCTET_STRING,
@@ -214,8 +214,8 @@
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* y */
};
static asn_SEQUENCE_specifics_t asn_SPC_anonType_specs_2 = {
- sizeof(struct anonType),
- offsetof(struct anonType, _asn_ctx),
+ sizeof(struct Type1__anonType),
+ offsetof(struct Type1__anonType, _asn_ctx),
.tag2el = asn_MAP_anonType_tag2el_2,
.tag2el_count = 2, /* Count of tags in the map */
0, 0, 0, /* Optional elements (not needed) */
@@ -302,7 +302,7 @@
typedef struct Type2 {
Type2_PR present;
union Type2_u {
- struct anonType {
+ struct Type2__anonType {
OCTET_STRING_t x;
OCTET_STRING_t y;
@@ -379,7 +379,7 @@
/*** <<< STAT-DEFS [Type2] >>> ***/
static asn_TYPE_member_t asn_MBR_anonType_2[] = {
- { ATF_NOFLAGS, 0, offsetof(struct anonType, x),
+ { ATF_NOFLAGS, 0, offsetof(struct Type2__anonType, x),
.tag = (ASN_TAG_CLASS_CONTEXT | (0 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = &asn_DEF_OCTET_STRING,
@@ -390,7 +390,7 @@
.default_value = 0,
.name = "x"
},
- { ATF_NOFLAGS, 0, offsetof(struct anonType, y),
+ { ATF_NOFLAGS, 0, offsetof(struct Type2__anonType, y),
.tag = (ASN_TAG_CLASS_CONTEXT | (1 << 2)),
.tag_mode = -1, /* IMPLICIT tag at current level */
.type = &asn_DEF_OCTET_STRING,
@@ -411,8 +411,8 @@
{ (ASN_TAG_CLASS_CONTEXT | (1 << 2)), 1, 0, 0 } /* y */
};
static asn_SEQUENCE_specifics_t asn_SPC_anonType_specs_2 = {
- sizeof(struct anonType),
- offsetof(struct anonType, _asn_ctx),
+ sizeof(struct Type2__anonType),
+ offsetof(struct Type2__anonType, _asn_ctx),
.tag2el = asn_MAP_anonType_tag2el_2,
.tag2el_count = 2, /* Count of tags in the map */
0, 0, 0, /* Optional elements (not needed) */