checking reserved keywords and double identifiers

git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@618 59561ff5-6e30-0410-9f3c-9617f08c8826
This commit is contained in:
vlm 2005-01-28 12:18:50 +00:00
parent 37bc03dca3
commit af8419717f
5 changed files with 151 additions and 66 deletions

View File

@ -35,6 +35,7 @@ static int expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr);
static int expr_elements_count(arg_t *arg, asn1p_expr_t *expr);
static int emit_member_table(arg_t *arg, asn1p_expr_t *expr);
static int emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *opt_modifier);
static int out_identifiers_chain(arg_t *arg, int check_reserved_keywords);
enum tvm_compat {
_TVM_SAME = 0, /* tags and all_tags are same */
@ -65,7 +66,7 @@ static int emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode
&& __m->expr_type > ASN_CONSTR_MASK) \
|| __m->meta_type == AMT_TYPEREF) { \
GEN_INCLUDE(asn1c_type_name(arg, \
__m, TNF_INCLUDE)); \
__m, TNF_INCLUDE)); \
} \
} \
if(expr->expr_type == ASN_CONSTR_SET_OF) \
@ -74,7 +75,9 @@ static int emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode
GEN_INCLUDE("asn_SEQUENCE_OF"); \
} while(0)
#define MKID(id) asn1c_make_identifier(0, (id), 0)
/* MKID() without checking for reserved keywords */
#define MKID_nr(id) asn1c_make_identifier(0, (id), 0)
#define MKID(id) asn1c_make_identifier(AMI_CHECK_RESERVED, (id), 0)
int
asn1c_lang_C_type_REAL(arg_t *arg) {
@ -126,7 +129,7 @@ asn1c_lang_C_type_SEQUENCE(arg_t *arg) {
DEPENDENCIES;
if(arg->embed) {
OUT("struct %s {\n", MKID(expr->Identifier));
OUT("struct "); out_identifiers_chain(arg, 1); OUT(" {\n");
} else {
OUT("typedef struct %s {\n",
MKID(expr->Identifier));
@ -184,7 +187,7 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
if(expr_elements_count(arg, expr)) {
int comp_mode = 0; /* {root,ext=1,root,root,...} */
p = MKID(expr->Identifier);
p = MKID_nr(expr->Identifier);
OUT("static asn_TYPE_member_t asn_MBR_%s[] = {\n", p);
elements = 0;
@ -214,12 +217,13 @@ asn1c_lang_C_type_SEQUENCE_def(arg_t *arg) {
*/
emit_tag2member_map(arg, tag2el, tag2el_count, 0);
OUT("static asn_SEQUENCE_specifics_t asn_DEF_%s_specs = {\n",
MKID_nr(expr->Identifier));
p = MKID(expr->Identifier);
OUT("static asn_SEQUENCE_specifics_t asn_DEF_%s_specs = {\n", p);
INDENTED(
OUT("sizeof(struct %s),\n", p);
OUT("offsetof(struct %s, _asn_ctx),\n", p);
OUT("asn_DEF_%s_tag2el,\n", p);
OUT("asn_DEF_%s_tag2el,\n", MKID_nr(expr->Identifier));
OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
OUT("%d,\t/* Start extensions */\n",
ext_start);
@ -256,26 +260,26 @@ asn1c_lang_C_type_SET(arg_t *arg) {
OUT(" * Method of determining the components presence\n");
OUT(" */\n");
mcount = 0;
OUT("typedef enum %s_PR {\n", MKID(expr->Identifier));
OUT("typedef enum "); out_identifiers_chain(arg, 0); OUT("_PR {\n");
TQ_FOR(v, &(expr->members), next) {
if(v->expr_type == A1TC_EXTENSIBLE) continue;
INDENTED(
id = MKID(expr->Identifier);
OUT("%s_PR_", id);
id = MKID(v->Identifier);
out_identifiers_chain(arg, 0);
OUT("_PR_");
id = MKID_nr(v->Identifier);
OUT("%s,\t/* Member %s is present */\n",
id, id)
);
mcount++;
}
id = MKID(expr->Identifier);
OUT("} %s_PR;\n", id);
OUT("} "); out_identifiers_chain(arg, 0); OUT("_PR;\n");
REDIR(OT_TYPE_DECLS);
if(arg->embed) {
OUT("struct %s {\n", id);
OUT("struct "); out_identifiers_chain(arg, 1); OUT(" {\n");
} else {
id = MKID(expr->Identifier);
OUT("typedef struct %s {\n", id);
}
@ -290,7 +294,7 @@ asn1c_lang_C_type_SET(arg_t *arg) {
}
INDENTED(
id = MKID(expr->Identifier);
id = MKID_nr(expr->Identifier);
OUT("\n");
OUT("/* Presence bitmask: ASN_SET_ISPRESENT(p%s, %s_PR_x) */\n",
id, id);
@ -350,8 +354,8 @@ asn1c_lang_C_type_SET_def(arg_t *arg) {
if(expr_elements_count(arg, expr)) {
int comp_mode = 0; /* {root,ext=1,root,root,...} */
p = MKID(expr->Identifier);
OUT("static asn_TYPE_member_t asn_MBR_%s[] = {\n", p);
OUT("static asn_TYPE_member_t asn_MBR_%s[] = {\n",
MKID_nr(expr->Identifier));
elements = 0;
INDENTED(TQ_FOR(v, &(expr->members), next) {
@ -385,8 +389,9 @@ asn1c_lang_C_type_SET_def(arg_t *arg) {
/*
* Emit a map of mandatory elements.
*/
OUT("static uint8_t asn_DEF_%s_mmap",
MKID_nr(expr->Identifier));
p = MKID(expr->Identifier);
OUT("static uint8_t asn_DEF_%s_mmap", p);
OUT("[(%d + (8 * sizeof(unsigned int)) - 1) / 8]", elements);
OUT(" = {\n", p);
INDENTED(
@ -415,11 +420,14 @@ asn1c_lang_C_type_SET_def(arg_t *arg) {
OUT("\n");
OUT("};\n");
OUT("static asn_SET_specifics_t asn_DEF_%s_specs = {\n", p);
OUT("static asn_SET_specifics_t asn_DEF_%s_specs = {\n",
MKID_nr(expr->Identifier));
p = MKID(expr->Identifier);
INDENTED(
OUT("sizeof(struct %s),\n", p);
OUT("offsetof(struct %s, _asn_ctx),\n", p);
OUT("offsetof(struct %s, _presence_map),\n", p);
p = MKID_nr(expr->Identifier);
OUT("asn_DEF_%s_tag2el,\n", p);
OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
if(tag2el_cxer)
@ -452,7 +460,7 @@ asn1c_lang_C_type_SEx_OF(arg_t *arg) {
DEPENDENCIES;
if(arg->embed) {
OUT("struct %s {\n", MKID(expr->Identifier));
OUT("struct "); out_identifiers_chain(arg, 1); OUT(" {\n");
} else {
OUT("typedef struct %s {\n", MKID(expr->Identifier));
}
@ -483,7 +491,7 @@ asn1c_lang_C_type_SEx_OF(arg_t *arg) {
arg->embed--;
assert(arg->target->target == OT_TYPE_DECLS);
} else {
OUT("%s", asn1c_type_name(arg, memb, TNF_CTYPE));
OUT("%s", asn1c_type_name(arg, memb, TNF_CTYPE | TNF_CHECK));
}
OUT(") list;\n");
INDENT(-1);
@ -545,8 +553,9 @@ asn1c_lang_C_type_SEx_OF_def(arg_t *arg, int seq_of) {
*/
tv_mode = emit_tags_vectors(arg, expr, &tags_count, &all_tags_count);
OUT("static asn_SET_OF_specifics_t asn_DEF_%s_specs = {\n",
MKID_nr(expr->Identifier));
p = MKID(expr->Identifier);
OUT("static asn_SET_OF_specifics_t asn_DEF_%s_specs = {\n", p);
INDENTED(
OUT("sizeof(struct %s),\n", p);
OUT("offsetof(struct %s, _asn_ctx),\n", p);
@ -578,36 +587,36 @@ asn1c_lang_C_type_CHOICE(arg_t *arg) {
REDIR(OT_DEPS);
id = MKID(expr->Identifier);
OUT("typedef enum %s_PR {\n", id);
OUT("typedef enum "); out_identifiers_chain(arg, 0); OUT("_PR {\n");
INDENTED(
OUT("%s_PR_NOTHING,\t"
"/* No components present */\n", id);
out_identifiers_chain(arg, 0);
OUT("_PR_NOTHING,\t/* No components present */\n");
TQ_FOR(v, &(expr->members), next) {
if(v->expr_type == A1TC_EXTENSIBLE) {
OUT("/* Extensions may appear below */\n");
continue;
}
id = MKID(expr->Identifier);
OUT("%s_PR_", id);
id = MKID(v->Identifier);
out_identifiers_chain(arg, 0);
OUT("_PR_");
id = MKID_nr(v->Identifier);
OUT("%s,\n", id, id);
}
);
id = MKID(expr->Identifier);
OUT("} %s_PR;\n", id);
OUT("} "); out_identifiers_chain(arg, 0); OUT("_PR;\n");
REDIR(OT_TYPE_DECLS);
if(arg->embed) {
OUT("struct %s {\n", id);
OUT("struct "); out_identifiers_chain(arg, 1); OUT(" {\n");
} else {
id = MKID(expr->Identifier);
OUT("typedef struct %s {\n", id);
}
INDENTED(
OUT("%s_PR present;\n", id);
OUT("union {\n", id);
out_identifiers_chain(arg, 0);
OUT("_PR present;\n");
OUT("union {\n");
TQ_FOR(v, &(expr->members), next) {
if(expr_better_indirect(arg, v))
v->marker.flags |= EM_INDIRECT;
@ -690,14 +699,15 @@ asn1c_lang_C_type_CHOICE_def(arg_t *arg) {
*/
emit_tag2member_map(arg, tag2el, tag2el_count, 0);
OUT("static asn_CHOICE_specifics_t asn_DEF_%s_specs = {\n",
MKID_nr(expr->Identifier));
p = MKID(expr->Identifier);
OUT("static asn_CHOICE_specifics_t asn_DEF_%s_specs = {\n", p);
INDENTED(
OUT("sizeof(struct %s),\n", p);
OUT("offsetof(struct %s, _asn_ctx),\n", p);
OUT("offsetof(struct %s, present),\n", p);
OUT("sizeof(((struct %s *)0)->present),\n", p);
OUT("asn_DEF_%s_tag2el,\n", p);
OUT("asn_DEF_%s_tag2el,\n", MKID_nr(expr->Identifier));
OUT("%d,\t/* Count of tags in the map */\n", tag2el_count);
OUT("%d\t/* Whether extensible */\n",
check_if_extensible(expr));
@ -784,13 +794,13 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
tnfmt = TNF_RSAFE;
OUT("\n");
OUT("%s;\t/* Forward declaration */\n",
asn1c_type_name(arg, arg->expr, tnfmt));
asn1c_type_name(arg, arg->expr, tnfmt | TNF_CHECK));
}
}
REDIR(OT_TYPE_DECLS);
OUT("%s\t", asn1c_type_name(arg, arg->expr, tnfmt));
OUT("%s\t", asn1c_type_name(arg, arg->expr, tnfmt | TNF_CHECK));
OUT("%s", expr->marker.flags?"*":" ");
OUT("%s", MKID(expr->Identifier));
if((expr->marker.flags & EM_DEFAULT) == EM_DEFAULT)
@ -808,7 +818,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
REDIR(OT_TYPE_DECLS);
OUT("typedef %s\t", asn1c_type_name(arg, arg->expr, TNF_CTYPE));
OUT("typedef %s\t", asn1c_type_name(arg, arg->expr, TNF_CTYPE | TNF_CHECK));
OUT("%s", expr->marker.flags?"*":" ");
OUT("%s_t", MKID(expr->Identifier));
@ -824,9 +834,8 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
REDIR(OT_FUNC_DECLS);
type_name = asn1c_type_name(arg, expr, TNF_SAFE);
OUT("/* This type is equivalent to %s */\n", type_name);
p = MKID(expr->Identifier);
if(HIDE_INNER_DEFS) OUT("/* ");
OUT("#define\tasn_DEF_%s\t", p);
OUT("#define\tasn_DEF_%s\t", MKID_nr(expr->Identifier));
type_name = asn1c_type_name(arg, expr, TNF_SAFE);
OUT("asn_DEF_%s\n", type_name);
if(HIDE_INNER_DEFS)
@ -987,7 +996,7 @@ asn1c_lang_C_type_SIMPLE_TYPE(arg_t *arg) {
REDIR(OT_FUNC_DECLS);
p = MKID(expr->Identifier);
p = MKID_nr(expr->Identifier);
if(HIDE_INNER_DEFS) OUT("/* ");
OUT("extern asn_TYPE_descriptor_t asn_DEF_%s;", p);
if(HIDE_INNER_DEFS) OUT(" // (Use -fall-defs-global to expose) */");
@ -1237,7 +1246,7 @@ emit_tag2member_map(arg_t *arg, tag2el_t *tag2el, int tag2el_count, const char *
asn1p_expr_t *expr = arg->expr;
OUT("static asn_TYPE_tag2member_t asn_DEF_%s_tag2el%s[] = {\n",
MKID(expr->Identifier), opt_modifier?opt_modifier:"");
MKID_nr(expr->Identifier), opt_modifier?opt_modifier:"");
if(tag2el_count) {
int i;
for(i = 0; i < tag2el_count; i++) {
@ -1303,7 +1312,7 @@ emit_tags_vectors(arg_t *arg, asn1p_expr_t *expr, int *tags_count_r, int *all_ta
#define EMIT_TAGS_TABLE(name, tags, tags_count) do { \
OUT("static ber_tlv_tag_t asn_DEF_%s%s_tags[] = {\n", \
MKID(expr->Identifier), name); \
MKID_nr(expr->Identifier), name); \
INDENT(+1); \
/* Print the array of collected tags */ \
for(i = 0; i < tags_count; i++) { \
@ -1423,10 +1432,10 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
if(C99_MODE) OUT(".type = ");
if(expr->_anonymous_type && (expr->expr_type & ASN_CONSTR_MASK)) {
OUT("(void *)&asn_DEF_%s_member,\n",
MKID(arg->expr->Identifier));
MKID_nr(arg->expr->Identifier));
} else if(expr->expr_type & ASN_CONSTR_MASK) {
OUT("(void *)&asn_DEF_%s,\n",
MKID(expr->Identifier));
MKID_nr(expr->Identifier));
} else {
OUT("(void *)&asn_DEF_%s,\n",
asn1c_type_name(arg, expr, TNF_SAFE));
@ -1436,7 +1445,7 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
if(arg->flags & A1C_NO_CONSTRAINTS) {
OUT("0,\t/* No check because of -fno-constraints */\n");
} else {
char *id = MKID(expr->Identifier);
char *id = MKID_nr(expr->Identifier);
if(expr->_anonymous_type
&& !strcmp(expr->Identifier, "member"))
id = asn1c_type_name(arg, expr, TNF_SAFE);
@ -1460,7 +1469,7 @@ emit_member_table(arg_t *arg, asn1p_expr_t *expr) {
if(expr->_anonymous_type && !strcmp(expr->Identifier, "member"))
p = asn1c_type_name(arg, expr, TNF_SAFE);
else
p = MKID(expr->Identifier);
p = MKID_nr(expr->Identifier);
OUT("static int\n");
OUT("memb_%s_%d_constraint(asn_TYPE_descriptor_t *td, const void *sptr,\n", p, global_memb_unique);
INDENT(+1);
@ -1487,10 +1496,11 @@ static int
emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_count, int all_tags_count, int elements_count, enum etd_spec spec) {
char *p;
p = MKID(expr->Identifier);
if(HIDE_INNER_DEFS)
OUT("static /* Use -fall-defs-global to expose */\n");
OUT("asn_TYPE_descriptor_t asn_DEF_%s = {\n", p);
OUT("asn_TYPE_descriptor_t asn_DEF_%s = {\n",
MKID_nr(expr->Identifier));
p = MKID(expr->Identifier);
INDENT(+1);
OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
OUT("\"%s\",\n", expr->_anonymous_type?"":expr->Identifier);
@ -1515,14 +1525,13 @@ emit_type_DEF(arg_t *arg, asn1p_expr_t *expr, enum tvm_compat tv_mode, int tags_
}
OUT("%s_encode_xer,\n", p);
p = MKID(expr->Identifier);
if(expr->expr_type == ASN_CONSTR_CHOICE) {
OUT("CHOICE_outmost_tag,\n");
} else {
OUT("0,\t/* Use generic outmost tag fetcher */\n");
}
p = MKID_nr(expr->Identifier);
if(tags_count) {
OUT("asn_DEF_%s_tags,\n", p);
OUT("sizeof(asn_DEF_%s_tags)\n", p);
@ -1627,3 +1636,32 @@ expr_as_xmlvaluelist(arg_t *arg, asn1p_expr_t *expr) {
return 0;
}
}
static int
out_identifiers_chain(arg_t *arg, int check_reserved_keywords) {
asn1p_expr_t *expr = arg->expr;
char *id;
assert(expr->Identifier);
if(arg->flags & A1C_DOUBLE_IDENTIFIERS
&& expr->parent_expr
&& expr->parent_expr->Identifier) {
arg_t tmparg = *arg;
tmparg.expr = expr->parent_expr;
tmparg.flags &= ~A1C_DOUBLE_IDENTIFIERS;
out_identifiers_chain(&tmparg, 0);
OUT("_"); /* a separator between id components */
/* Fall through */
}
if(check_reserved_keywords)
id = MKID(expr->Identifier);
else
id = MKID_nr(expr->Identifier);
OUT("%s", id);
return 0;
}

View File

@ -13,8 +13,6 @@ static int emit_size_determination_code(arg_t *arg, asn1p_expr_type_e etype);
static asn1p_expr_type_e _find_terminal_type(arg_t *arg);
static int emit_range_comparison_code(arg_t *arg, asn1cnst_range_t *range, const char *varname, asn1c_integer_t natural_start, asn1c_integer_t natural_stop);
#define MKID(id) asn1c_make_identifier(0, (id), 0)
static int global_compile_mark;
int

View File

@ -3,17 +3,35 @@
#include <asn1fix_export.h>
/*
* Checks that the given string is not a reserved C/C++ keyword.
*/
static char *res_kwd[] = {
"char", "int", "long",
"float", "double",
"struct", "typedef", "class" };
static int
reserved_keyword(const char *str) {
int i;
for(i = 0 ; i < sizeof(res_kwd)/sizeof(res_kwd[0]); i++) {
if(strcmp(str, res_kwd[i]) == 0)
return 1;
}
return 0;
}
/*
* Construct identifier from multiple parts.
* Convert unsafe characters to underscores.
*/
char *
asn1c_make_identifier(int unsafe_only_spaces, char *arg1, ...) {
asn1c_make_identifier(enum ami_flags_e flags, char *arg1, ...) {
static char *storage;
static int storage_size;
int nodelimiter = 0;
va_list ap;
char *str;
char *nextstr;
int size;
char *p;
@ -49,8 +67,9 @@ asn1c_make_identifier(int unsafe_only_spaces, char *arg1, ...) {
va_start(ap, arg1);
str = arg1;
p = storage;
for(str = arg1; str; str = va_arg(ap, char *)) {
for(str = arg1; str; str = nextstr) {
int subst_made = 0;
nextstr = va_arg(ap, char *);
if(str[0] == ' ' && str[1] == '\0') {
*p++ = ' ';
@ -62,12 +81,23 @@ asn1c_make_identifier(int unsafe_only_spaces, char *arg1, ...) {
*p++ = '_'; /* Delimiter between tokens */
nodelimiter = 0;
/*
* If it is a single argument, check that it does not clash
* with C/C++ language keywords.
*/
if((flags & AMI_CHECK_RESERVED)
&& str == arg1 && !nextstr && reserved_keyword(str)) {
*p++ = toupper(*str++);
/* Fall through */
}
for(; *str; str++) {
if(isalnum(*str)) {
*p++ = *str;
subst_made = 0;
} else if(!subst_made++) {
if(unsafe_only_spaces && !isspace(*str)) {
if((flags & AMI_MASK_ONLY_SPACES)
&& !isspace(*str)) {
*p ++ = *str;
} else {
*p++ = '_';
@ -87,6 +117,9 @@ char *
asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
asn1p_expr_t *top_parent;
char *typename;
enum ami_flags_e ami_flags = (_format & TNF_CHECK)
? AMI_CHECK_RESERVED : 0;
_format &= ~TNF_CHECK;
/* Rewind to the topmost parent expression */
if((top_parent = expr->parent_expr))
@ -180,13 +213,19 @@ asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format) {
switch(_format) {
case TNF_UNMODIFIED:
case TNF_INCLUDE:
return asn1c_make_identifier(1, typename, 0);
assert(ami_flags == 0); /* (TNF_INCLUDE | TNF_CHECK)?! */
ami_flags |= AMI_MASK_ONLY_SPACES;
return asn1c_make_identifier(ami_flags, typename, 0);
case TNF_SAFE:
return asn1c_make_identifier(0, typename, 0);
return asn1c_make_identifier(ami_flags, typename, 0);
case TNF_CTYPE:
return asn1c_make_identifier(0, typename, "t", 0);
return asn1c_make_identifier(ami_flags, typename, "t", 0);
case TNF_RSAFE:
return asn1c_make_identifier(0, "struct", " ", typename, 0);
return asn1c_make_identifier(ami_flags, "struct", " ", typename, 0);
case TNF_NORCHECK:
case TNF_CHECK:
assert(_format != TNF_NORCHECK);
assert(_format != TNF_CHECK);
}
assert(!"unreachable");

View File

@ -6,17 +6,23 @@
* The function will concatenate the names and replace unsafe characters
* with safe ones.
*/
char *asn1c_make_identifier(int unsafe_only_spaces, char *arg1, ...);
enum ami_flags_e {
AMI_MASK_ONLY_SPACES = 1, /* Mask only spaces, everything else's safe */
AMI_CHECK_RESERVED = 2, /* Check against reserved keywords */
};
char *asn1c_make_identifier(enum ami_flags_e, char *arg1, ...);
/*
* Return the type name of the specified expression.
*/
enum tnfmt {
TNF_UNMODIFIED, /* Return unmodified type name */
TNF_INCLUDE, /* Format for #include <> */
TNF_CTYPE, /* Format as normal C-ish type (append "_t") */
TNF_SAFE, /* Replace unsafe characters with _ */
TNF_RSAFE, /* Recursion-safe C type format */
TNF_NORCHECK = 0x00,
TNF_CHECK = 0x01,
TNF_UNMODIFIED = 0x10, /* Return unmodified type name */
TNF_INCLUDE = 0x20, /* Format for #include <> */
TNF_CTYPE = 0x30, /* Format as normal C-ish type (append "_t") */
TNF_SAFE = 0x40, /* Replace unsafe characters with _ */
TNF_RSAFE = 0x50, /* Recursion-safe C type format */
};
char *asn1c_type_name(arg_t *arg, asn1p_expr_t *expr, enum tnfmt _format);

View File

@ -39,6 +39,10 @@ enum asn1c_flags {
* Do not generate constraint checking code.
*/
A1C_NO_CONSTRAINTS = 0x0080,
/*
* Generate type_id_PR_member things identifiers of id_PR_member.
*/
A1C_DOUBLE_IDENTIFIERS = 0x0100,
};
/*