Fix 'declaration inside parameter list' warning
1. Add forward definition section.
2. Move type definition inside A_SEQUENCE_OF() to forward definition section.
3. Modify asn1c_lang_C_type_CHOICE() ...etc functions to achieve it.
4. Modify test cases used during 'make check'.
diff --git a/libasn1compiler/asn1c_C.c b/libasn1compiler/asn1c_C.c
index b4cd736..d1fc1ab 100644
--- a/libasn1compiler/asn1c_C.c
+++ b/libasn1compiler/asn1c_C.c
@@ -120,6 +120,7 @@
struct value2enum *v2e;
int map_extensions = (expr->expr_type == ASN_BASIC_INTEGER);
int eidx;
+ int saved_target = arg->target->target;
v2e = alloca((el_count + 1) * sizeof(*v2e));
@@ -248,6 +249,8 @@
OUT("};\n");
}
+ REDIR(saved_target);
+
return asn1c_lang_C_type_SIMPLE_TYPE(arg);
}
@@ -256,6 +259,7 @@
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
int el_count = expr_elements_count(arg, expr);
+ int saved_target = arg->target->target;
if(el_count) {
int eidx = 0;
@@ -283,6 +287,8 @@
assert(eidx == el_count);
}
+ REDIR(saved_target);
+
return asn1c_lang_C_type_SIMPLE_TYPE(arg);
}
@@ -291,14 +297,23 @@
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
int comp_mode = 0; /* {root,ext=1,root,root,...} */
+ int saved_target = arg->target->target;
DEPENDENCIES;
if(arg->embed) {
+
+ /* Use _anonymous_type field to indicate it's called from
+ * asn1c_lang_C_type_SEx_OF() */
+ if (expr->_anonymous_type) {
+ REDIR(OT_FWD_DEFS);
+ OUT("typedef ");
+ }
OUT("struct ");
out_name_chain(arg, ONC_avoid_keywords);
OUT(" {\n");
} else {
+ REDIR(OT_TYPE_DECLS);
OUT("typedef struct %s {\n",
MKID_safe(expr));
}
@@ -313,12 +328,24 @@
}
PCTX_DEF;
- OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+
+ if (arg->embed && expr->_anonymous_type) {
+ OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
+ out_name_chain(arg, ONC_avoid_keywords);
+ OUT("%s;\n", arg->embed ? "" : "_t");
+
+ REDIR(saved_target);
+
+ OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
+ out_name_chain(arg, ONC_avoid_keywords);
+ } else {
+ OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
expr->_anonymous_type ? "" :
arg->embed
? MKID_safe(expr)
: MKID(expr),
arg->embed ? "" : "_t");
+ }
return asn1c_lang_C_type_SEQUENCE_def(arg);
}
@@ -337,6 +364,7 @@
enum tvm_compat tv_mode;
int roms_count; /* Root optional members */
int aoms_count; /* Additions optional members */
+ int saved_target = arg->target->target;
/*
* Fetch every inner tag from the tag to elements map.
@@ -477,7 +505,7 @@
emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, elements,
ETD_HAS_SPECIFICS);
- REDIR(OT_TYPE_DECLS);
+ REDIR(saved_target);
return 0;
} /* _SEQUENCE_def() */
@@ -489,6 +517,7 @@
long mcount;
char *id;
int comp_mode = 0; /* {root,ext=1,root,root,...} */
+ int saved_target = arg->target->target;
DEPENDENCIES;
@@ -515,13 +544,18 @@
}
OUT("} "); out_name_chain(arg, ONC_noflags); OUT("_PR;\n");
- REDIR(OT_TYPE_DECLS);
+ REDIR(saved_target);
if(arg->embed) {
+ if (expr->_anonymous_type) {
+ REDIR(OT_FWD_DEFS);
+ OUT("typedef ");
+ }
OUT("struct ");
out_name_chain(arg, ONC_avoid_keywords);
OUT(" {\n");
} else {
+ REDIR(OT_TYPE_DECLS);
OUT("typedef struct %s {\n",
MKID_safe(expr));
}
@@ -545,9 +579,21 @@
);
PCTX_DEF;
- OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
- expr->_anonymous_type ? "" : MKID_safe(expr),
- arg->embed ? "" : "_t");
+
+ if (arg->embed && expr->_anonymous_type) {
+ OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
+ out_name_chain(arg, ONC_avoid_keywords);
+ OUT("%s;\n", arg->embed ? "" : "_t");
+
+ REDIR(saved_target);
+
+ OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
+ out_name_chain(arg, ONC_avoid_keywords);
+ } else {
+ OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ expr->_anonymous_type ? "" : MKID_safe(expr),
+ arg->embed ? "" : "_t");
+ }
return asn1c_lang_C_type_SET_def(arg);
}
@@ -565,6 +611,7 @@
int all_tags_count;
enum tvm_compat tv_mode;
char *p;
+ int saved_target = arg->target->target;
/*
* Fetch every inner tag from the tag to elements map.
@@ -598,7 +645,7 @@
OUT("static asn_TYPE_member_t asn_MBR_%s_%d[] = {\n",
MKID(expr), expr->_type_unique_index);
-
+
elements = 0;
INDENTED(TQ_FOR(v, &(expr->members), next) {
if(v->expr_type == A1TC_EXTENSIBLE) {
@@ -692,7 +739,7 @@
emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, elements,
ETD_HAS_SPECIFICS);
- REDIR(OT_TYPE_DECLS);
+ REDIR(saved_target);
return 0;
} /* _SET_def() */
@@ -701,10 +748,15 @@
asn1c_lang_C_type_SEx_OF(arg_t *arg) {
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *memb = TQ_FIRST(&expr->members);
+ int saved_target = arg->target->target;
DEPENDENCIES;
if(arg->embed) {
+ if (expr->_anonymous_type) {
+ REDIR(OT_FWD_DEFS);
+ OUT("typedef ");
+ }
OUT("struct ");
out_name_chain(arg, ONC_avoid_keywords);
OUT(" {\n");
@@ -748,7 +800,8 @@
if(tmp_memb.Identifier != memb->Identifier)
if(0) free(tmp_memb.Identifier);
arg->embed--;
- assert(arg->target->target == OT_TYPE_DECLS);
+ assert(arg->target->target == OT_TYPE_DECLS ||
+ arg->target->target == OT_FWD_DEFS);
} else {
OUT("%s", asn1c_type_name(arg, memb,
(memb->marker.flags & EM_UNRECURSE)
@@ -761,9 +814,21 @@
INDENT(-1);
PCTX_DEF;
- OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
- expr->_anonymous_type ? "" : MKID_safe(expr),
- arg->embed ? "" : "_t");
+
+ if (arg->embed && expr->_anonymous_type) {
+ OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
+ out_name_chain(arg, ONC_avoid_keywords);
+ OUT("%s;\n", arg->embed ? "" : "_t");
+
+ REDIR(saved_target);
+
+ OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
+ out_name_chain(arg, ONC_avoid_keywords);
+ } else {
+ OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ expr->_anonymous_type ? "" : MKID_safe(expr),
+ arg->embed ? "" : "_t");
+ }
/*
* SET OF/SEQUENCE OF definition
@@ -779,6 +844,7 @@
int tags_count;
int all_tags_count;
enum tvm_compat tv_mode;
+ int saved_target = arg->target->target;
/*
* Print out the table according to which parsing is performed.
@@ -840,7 +906,7 @@
emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, 1,
ETD_HAS_SPECIFICS);
- REDIR(OT_TYPE_DECLS);
+ REDIR(saved_target);
return 0;
} /* _SEx_OF_def() */
@@ -850,6 +916,7 @@
asn1p_expr_t *expr = arg->expr;
asn1p_expr_t *v;
char *id;
+ int saved_target = arg->target->target;
DEPENDENCIES;
@@ -878,11 +945,16 @@
);
OUT("} "); out_name_chain(arg, ONC_noflags); OUT("_PR;\n");
- REDIR(OT_TYPE_DECLS);
+ REDIR(saved_target);
if(arg->embed) {
+ if (expr->_anonymous_type) {
+ REDIR(OT_FWD_DEFS);
+ OUT("typedef ");
+ }
OUT("struct "); out_name_chain(arg, ONC_avoid_keywords); OUT(" {\n");
} else {
+ REDIR(OT_TYPE_DECLS);
OUT("typedef struct %s {\n", MKID_safe(expr));
}
@@ -903,12 +975,24 @@
);
PCTX_DEF;
- OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
- expr->_anonymous_type ? "" :
- arg->embed
- ? MKID_safe(expr)
- : MKID(expr),
- arg->embed ? "" : "_t");
+
+ if (arg->embed && expr->_anonymous_type) {
+ OUT("} %s", (expr->marker.flags & EM_INDIRECT)?"*":"");
+ out_name_chain(arg, ONC_avoid_keywords);
+ OUT("%s;\n", arg->embed ? "" : "_t");
+
+ REDIR(saved_target);
+
+ OUT("%s", (expr->marker.flags & EM_INDIRECT)?"*":"");
+ out_name_chain(arg, ONC_avoid_keywords);
+ } else {
+ OUT("} %s%s%s", (expr->marker.flags & EM_INDIRECT)?"*":"",
+ expr->_anonymous_type ? "" :
+ arg->embed
+ ? MKID_safe(expr)
+ : MKID(expr),
+ arg->embed ? "" : "_t");
+ }
return asn1c_lang_C_type_CHOICE_def(arg);
}
@@ -924,6 +1008,7 @@
int all_tags_count;
enum tvm_compat tv_mode;
int *cmap = 0;
+ int saved_target = arg->target->target;
/*
* Fetch every inner tag from the tag to elements map.
@@ -1026,7 +1111,7 @@
emit_type_DEF(arg, expr, tv_mode, tags_count, all_tags_count, elements,
ETD_HAS_SPECIFICS);
- REDIR(OT_TYPE_DECLS);
+ REDIR(saved_target);
return 0;
} /* _CHOICE_def() */
@@ -1081,6 +1166,7 @@
enum tvm_compat tv_mode;
enum etd_spec etd_spec;
char *p;
+ int saved_target = arg->target->target;
if(arg->embed) {
enum tnfmt tnfmt = TNF_CTYPE;
@@ -1093,13 +1179,15 @@
if(expr->marker.flags & (EM_INDIRECT | EM_UNRECURSE)) {
if(terminal_structable(arg, expr)) {
tnfmt = TNF_RSAFE;
- REDIR(OT_FWD_DECLS);
- OUT("%s;\n",
- asn1c_type_name(arg, arg->expr, tnfmt));
+ if(saved_target != OT_FWD_DECLS) {
+ REDIR(OT_FWD_DECLS);
+ OUT("%s;\n",
+ asn1c_type_name(arg, arg->expr, tnfmt));
+ }
+ REDIR(saved_target);
}
}
- REDIR(OT_TYPE_DECLS);
OUT("%s", asn1c_type_name(arg, arg->expr, tnfmt));
if(!expr->_anonymous_type) {
@@ -1143,7 +1231,7 @@
* Type1 ::= Type2
*/
if(arg->embed && etd_spec == ETD_NO_SPECIFICS) {
- REDIR(OT_TYPE_DECLS);
+ REDIR(saved_target);
return 0;
}
if((!expr->constraints || (arg->flags & A1C_NO_CONSTRAINTS))
@@ -1165,7 +1253,7 @@
REDIR(OT_CODE);
OUT("/* This type is equivalent to %s */\n", type_name);
OUT("\n");
- REDIR(OT_TYPE_DECLS);
+ REDIR(saved_target);
return 0;
}
@@ -1418,7 +1506,7 @@
}
}
- REDIR(OT_TYPE_DECLS);
+ REDIR(saved_target);
return 0;
}
@@ -2620,9 +2708,11 @@
if(memb->marker.flags & (EM_INDIRECT | EM_UNRECURSE)) {
if(terminal_structable(arg, memb)) {
int saved_target = arg->target->target;
- REDIR(OT_FWD_DECLS);
- OUT("%s;\n",
- asn1c_type_name(arg, memb, TNF_RSAFE));
+ if(saved_target != OT_FWD_DECLS) {
+ REDIR(OT_FWD_DECLS);
+ OUT("%s;\n",
+ asn1c_type_name(arg, memb, TNF_RSAFE));
+ }
REDIR(saved_target);
}
}
diff --git a/libasn1compiler/asn1c_out.c b/libasn1compiler/asn1c_out.c
index 46029f7..8314bb5 100644
--- a/libasn1compiler/asn1c_out.c
+++ b/libasn1compiler/asn1c_out.c
@@ -38,6 +38,11 @@
*/
if(dst->indented == 0) {
int i = dst->indent_level;
+ if (i < 0) {
+ /* fatal error */
+ fprintf(stderr, "target %d : Indent level %d ?!\n", arg->target->target, i);
+ exit(1);
+ }
dst->indented = 1;
while(i--) {
ret = asn1c_compiled_output(arg, "\t");
diff --git a/libasn1compiler/asn1c_out.h b/libasn1compiler/asn1c_out.h
index e21827e..3abe701 100644
--- a/libasn1compiler/asn1c_out.h
+++ b/libasn1compiler/asn1c_out.h
@@ -17,6 +17,7 @@
OT_INCLUDES, /* #include files */
OT_DEPS, /* Dependencies (other than #includes) */
OT_FWD_DECLS, /* Forward declarations */
+ OT_FWD_DEFS, /* Forward definitions */
OT_TYPE_DECLS, /* Type declarations */
OT_FUNC_DECLS, /* Function declarations */
OT_POST_INCLUDE,/* #include after type definition */
@@ -35,7 +36,7 @@
} compiler_streams_t;
static char *_compiler_stream2str[] __attribute__ ((unused))
- = { "IGNORE", "INCLUDES", "DEPS", "FWD-DECLS", "TYPE-DECLS", "FUNC-DECLS", "POST-INCLUDE", "CTABLES", "CODE", "CTDEFS", "STAT-DEFS" };
+ = { "IGNORE", "INCLUDES", "DEPS", "FWD-DECLS", "FWD-DEFS", "TYPE-DECLS", "FUNC-DECLS", "POST-INCLUDE", "CTABLES", "CODE", "CTDEFS", "STAT-DEFS" };
int asn1c_compiled_output(arg_t *arg, const char *fmt, ...);
@@ -56,8 +57,6 @@
} while(0)
#define EMBED(ev) do { \
- int saved_target = arg->target->target; \
- REDIR(OT_TYPE_DECLS); \
arg->embed++; \
INDENTED(arg_t _tmp = *arg; \
_tmp.expr = ev; \
@@ -66,8 +65,8 @@
arg->embed--; \
if(ev->expr_type != A1TC_EXTENSIBLE) \
OUT(";\n"); \
- assert(arg->target->target == OT_TYPE_DECLS); \
- REDIR(saved_target); \
+ assert(arg->target->target == OT_TYPE_DECLS || \
+ arg->target->target == OT_FWD_DEFS); \
} while(0)
/* Output a piece of text into a default stream */
diff --git a/libasn1compiler/asn1c_save.c b/libasn1compiler/asn1c_save.c
index f8348cc..5b945b7 100644
--- a/libasn1compiler/asn1c_save.c
+++ b/libasn1compiler/asn1c_save.c
@@ -283,6 +283,7 @@
safe_fprintf(fp_h, "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n");
SAVE_STREAM(fp_h, OT_DEPS, "Dependencies", 0);
SAVE_STREAM(fp_h, OT_FWD_DECLS, "Forward declarations", 0);
+ SAVE_STREAM(fp_h, OT_FWD_DEFS, "Forward definitions", 0);
SAVE_STREAM(fp_h, OT_TYPE_DECLS, expr->Identifier, 0);
SAVE_STREAM(fp_h, OT_FUNC_DECLS,"Implementation", 0);
safe_fprintf(fp_h, "\n#ifdef __cplusplus\n}\n#endif\n");
@@ -305,7 +306,7 @@
TQ_FOR(ot, &(cs->destination[OT_STAT_DEFS].chunks), next)
safe_fwrite(ot->buf, ot->len, 1, fp_c);
- assert(OT_MAX == 11); /* Protection from reckless changes */
+ assert(OT_MAX == 12); /* Protection from reckless changes */
fclose(fp_c);
fclose(fp_h);