Merge pull request #118 from gareins/master

Refreshing reserved keywords
diff --git a/.gitignore b/.gitignore
index da42ba2..2c69308 100644
--- a/.gitignore
+++ b/.gitignore
@@ -68,3 +68,6 @@
 # /skeletons/tests/
 /skeletons/tests/check-*
 
+#code coverage
+*.gcno
+*.gcda
diff --git a/.travis.yml b/.travis.yml
index 6e0f985..6bbea1a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,9 +2,14 @@
 compiler:
   - gcc
   - clang
+before_install:
+  - sudo apt-get install -y lcov
+  - gem install coveralls-lcov
 script:
     - autoreconf -iv
-    - ./configure --enable-Werror
+    - ./configure --enable-Werror --enable-code-coverage
     - make -j8
     - make check
     - make distcheck
+after_success:
+  - test "x$CC" = "xgcc" && make code-coverage-capture && coveralls-lcov asn1c-*-coverage.info
diff --git a/AUTHORS b/AUTHORS
index d510bcd..fcd16ad 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1 +1,15 @@
+Full list of copyright holders:
+
+Bartosz Marcinkiewicz <bma@megawatt.com.pl>
+Bent Nicolaisen <BN@JAI.com>
+Bi-Ruei, Chiu (brchiu @ github)
+Daniele Varrazzo <daniele.varrazzo@gmail.com>
+daa @ github
+Erika Thorsen (akire @ github)
+Max Khon (mkhon @ github)
 Lev Walkin <vlm@lionet.info>
+Simo Sorce <simo@redhat.com>
+theirix @ github
+Vasil Velichkov (velichkov @ github)
+Wim L <wiml@omnigroup.com>
+ymbirtt @ github
diff --git a/ChangeLog b/ChangeLog
index 78e26da..3c1a829 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 
 0.9.??:
+
+0.9.28: 2017-03-26
     * PER decoding: avoid memory leak on error. By github.com/simo5
     * Constness patch #46 by Wim L <wiml@omnigroup.com> (41bbf1c..78d604f).
     Build issues:
diff --git a/LICENSE b/LICENSE
index 8f08e96..306464b 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2003-2016  Lev Walkin <vlm@lionet.info>
+Copyright (c) 2003-2017  Lev Walkin <vlm@lionet.info> and contributors.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
diff --git a/Makefile.am b/Makefile.am
index 870ee8f..1f1f927 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,6 +1,9 @@
 
 ACLOCAL_AMFLAGS = -I m4
 
+@CODE_COVERAGE_RULES@
+CODE_COVERAGE_IGNORE_PATTERN="tests/*" "lex.yy.c" "y.tab.c" "asn1p_l.l" "asn1p_y.y"
+
 SUBDIRS = 				\
 	libasn1parser libasn1fix	\
 	libasn1print libasn1compiler	\
@@ -9,6 +12,6 @@
 
 docsdir = $(datadir)/doc/asn1c
 
-docs_DATA = README.md FAQ ChangeLog BUGS TODO
+docs_DATA = README.md INSTALL.md FAQ ChangeLog BUGS TODO
 
-EXTRA_DIST = README.md FAQ LICENSE BUGS
+EXTRA_DIST = README.md INSTALL.md FAQ LICENSE BUGS
diff --git a/asn1c/Makefile.am b/asn1c/Makefile.am
index d152722..81af76a 100644
--- a/asn1c/Makefile.am
+++ b/asn1c/Makefile.am
@@ -1,3 +1,4 @@
+@CODE_COVERAGE_RULES@
 
 SUBDIRS = . tests
 
diff --git a/asn1c/asn1c.c b/asn1c/asn1c.c
index 8a6f785..eb1eff7 100644
--- a/asn1c/asn1c.c
+++ b/asn1c/asn1c.c
@@ -326,7 +326,7 @@
      * of another language.
      */
     if(asn1_compile(asn, skeletons_dir, asn1_compiler_flags, ac + optind,
-                    optind - 1, av - optind)) {
+                    optind, av - optind)) {
         exit(EX_SOFTWARE);
     }
 
diff --git a/asn1c/tests/Makefile.am b/asn1c/tests/Makefile.am
index 15432fd..e6700c0 100644
--- a/asn1c/tests/Makefile.am
+++ b/asn1c/tests/Makefile.am
@@ -1,3 +1,4 @@
+@CODE_COVERAGE_RULES@
 
 SUBDIRS = check-src
 
diff --git a/asn1c/tests/check-assembly.sh b/asn1c/tests/check-assembly.sh
index d897f89..baa433f 100755
--- a/asn1c/tests/check-assembly.sh
+++ b/asn1c/tests/check-assembly.sh
@@ -17,7 +17,7 @@
 abs_top_builddir="${abs_top_builddir:-$(pwd)/../../}"
 
 if echo "$*" | grep -q -- -- ; then
-    TEST_DRIVER=$(echo "$*"  | sed -e 's/ -- .*/--/g')
+    TEST_DRIVER=$(echo "$*"  | sed -e 's/ -- .*/ -- /g')
     source_full=$(echo "$*"  | sed -e 's/.* //g')
 else
     TEST_DRIVER=""
@@ -54,7 +54,7 @@
 # This file is autogenerated by ../$0
 
 COMMON_FLAGS= -I.
-CFLAGS = \${COMMON_FLAGS} ${CFLAGS:-} -g -O0
+CFLAGS = \${COMMON_FLAGS} ${CFLAGS:-} -g -O0 -I ${abs_top_srcdir}/skeletons
 CPPFLAGS = -DSRCDIR=../${srcdir}
 CXXFLAGS = \${COMMON_FLAGS} ${CXXFLAGS}
 
@@ -63,12 +63,12 @@
 all: check-executable
 check-executable: compiled-module *.c*
 	@rm -f *.core
-	\$(CC) \$(CPPFLAGS) \$(CFLAGS) -o check-executable *.c* -lm
+	\$(CC) \$(CPPFLAGS) \$(CFLAGS) -o check-executable *.c* -L${abs_top_builddir}/skeletons/.libs -lasn1cskeletons -lm
 
 # Compile the corresponding .asn1 spec.
 compiled-module: ${asn_module} ${abs_top_builddir}/asn1c/asn1c
 	${abs_top_builddir}/asn1c/asn1c		\\
-		-S ${abs_top_srcdir}/skeletons	\\
+		-S /tmp/do/not/copy/skeletons	\\
 		-Wdebug-compiler		\\
 		${AFLAGS} ${asn_module}
 	rm -f converter-sample.c
diff --git a/configure.ac b/configure.ac
index 64a37a9..d124083 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,12 +1,10 @@
-AC_INIT([asn1c],[0.9.28],[vlm@lionet.info])
+AC_INIT([asn1c],[0.9.29],[vlm@lionet.info])
 
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_HEADER([config.h])
 AM_INIT_AUTOMAKE([foreign])
 AC_CONFIG_MACRO_DIR([m4])
 
-LT_INIT
-
 dnl Checks for programs.
 AC_PROG_CC
 AC_PROG_CPP
@@ -15,7 +13,12 @@
 AC_PROG_MAKE_SET
 AC_PROG_YACC
 AM_PROG_LEX
-AC_PATH_PROG(AR, ar, ar, $PATH:/usr/ucb:/usr/ccs/bin)	dnl for Solaris
+dnl locate ar using standard macro (old automake 1.11 does not know about AM_PROG_AR)
+m4_ifdef([AM_PROG_AR],
+         [AM_PROG_AR],
+         [AC_PATH_PROG(AR, ar, ar, $PATH:/usr/ucb:/usr/ccs/bin)])
+
+LT_INIT
 
 dnl If you need to see the details, just run make V=1.
 m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
@@ -75,6 +78,20 @@
       TESTSUITE_CFLAGS="-Werror -W -Wpointer-arith"
   ])
 
+AX_CODE_COVERAGE
+AS_IF([test x$enable_code_coverage != xno], [
+	CFLAGS="$CFLAGS $CODE_COVERAGE_CFLAGS"
+	# The CODE_COVERAGE_CPPFLAGS contains -DNDEBUG flag
+	# which removes assert(...) macros from code coverage and improves the
+	# branches score. But when it is defined it results in few
+	# unsed-but-set-variable warnings that are treated as errors in the travis-ci
+	# build because these variables are only used inside assert macros.
+	# error: variable ‘ret’ set but not used [-Werror=unused-but-set-variable]
+	#CPPFLAGS="$CPPFLAGS $CODE_COVERAGE_CPPFLAGS"
+	CXXFLAGS="$CXXFLAGS $CODE_COVERAGE_CXXFLAGS"
+	LDFLAGS="$LDFLAGS $CODE_COVERAGE_LDFLAGS"
+])
+
 AC_SUBST(ADD_CFLAGS)
 AC_SUBST(TESTSUITE_CFLAGS)
 
@@ -84,7 +101,14 @@
 AX_CHECK_COMPILE_FLAG([-std=c89],
     [SKELETONS_CFLAGS="$SKELETONS_CFLAGS -std=c89"])
 AX_CHECK_COMPILE_FLAG([-Wpedantic],
-    [SKELETONS_CFLAGS="$SKELETONS_CFLAGS -Wpedantic"])
+    [SKELETONS_CFLAGS="$SKELETONS_CFLAGS -Wpedantic"],
+    [
+        dnl When -Wpedantic is not supported try the -pedantic instead. (gcc-4.7)
+        dnl See https://gcc.gnu.org/gcc-4.8/changes.html
+        AX_CHECK_COMPILE_FLAG([-pedantic],
+            [SKELETONS_CFLAGS="$SKELETONS_CFLAGS -pedantic"], [], [-Werror])
+    ],
+    [-Werror]) #clang 3.0 prints warning when the flag is not supported
 AX_CHECK_COMPILE_FLAG([-Wno-duplicate-decl-specifier],
     [SKELETONS_CFLAGS="$SKELETONS_CFLAGS -Wno-duplicate-decl-specifier"])
 AC_SUBST(SKELETONS_CFLAGS)
diff --git a/doc/man/enber.1 b/doc/man/enber.1
index 827c211..6566398 100644
--- a/doc/man/enber.1
+++ b/doc/man/enber.1
@@ -39,7 +39,7 @@
 completely.
 Empty lines are ignored as well.
 .PP
-The following example \f[C]enber\f[](1) input demostrates the use of
+The following example \f[C]enber\f[](1) input demonstrates the use of
 comments:
 .PP
 <C O="0" T="[1]" TL="2" V="2">
diff --git a/doc/man/enber.man.md b/doc/man/enber.man.md
index 2bdb036..a6084ea 100644
--- a/doc/man/enber.man.md
+++ b/doc/man/enber.man.md
@@ -36,7 +36,7 @@
 A hash "**#**" or two dashes "**--**" following a whitespace is treated as a beginning of a comment line, which is ignored completely.
 Empty lines are ignored as well.
 
-The following example `enber`(1) input demostrates the use of comments:
+The following example `enber`(1) input demonstrates the use of comments:
 
 | \<C O="0" T="[1]" TL="2" V="2">
 |     \<I O="2" T="[1]" TL="2" V="Indefinite">
diff --git a/examples/sample.makefile.regen b/examples/sample.makefile.regen
index 50551b2..66bec0a 100755
--- a/examples/sample.makefile.regen
+++ b/examples/sample.makefile.regen
@@ -113,7 +113,7 @@
 	echo '	done; done; fi'
 	echo "	@if test -f sample-${ASN1PDU}-1.per ; then \\"
 	echo "	for f in sample-*-[1-9].per; do \\"
-	echo '	pdu=`echo $$f | sed -E -e "s/sample-([A-Za-z-]+)-[0-9].*/\1/"`; \'
+	echo '	pdu=`echo $$f | sed -E -e "s/sample-([A-Za-z-]+)-[0-9].*/\\1/"`; \'
 	echo '	for b in 1 17 33 980 8192; do \'
 	echo '	echo "Recoding $$f into DER into XER and back ($$b)..."; \'
 	echo '	./${TARGET} -b $$b -p $$pdu -iper -oder $$f > ./.tmp.1.$$$$ || exit 3; \'
diff --git a/examples/sample.source.PKIX1/Makefile b/examples/sample.source.PKIX1/Makefile
index ea68739..fdff822 100644
--- a/examples/sample.source.PKIX1/Makefile
+++ b/examples/sample.source.PKIX1/Makefile
@@ -375,7 +375,7 @@
 	make
 
 regen-makefile:
-	ASN1CMDOPTS="" \
+	ASN1CMDOPTS="-fwide-types" \
 	ASN1MODULES="../rfc3280-*.asn1" \
 	ASN1PDU=Certificate \
 	PROGNAME=x509dump \
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_misc.c b/libasn1compiler/asn1c_misc.c
index a60553b..9a6e4aa 100644
--- a/libasn1compiler/asn1c_misc.c
+++ b/libasn1compiler/asn1c_misc.c
@@ -267,7 +267,7 @@
 	switch(_format) {
 	case TNF_UNMODIFIED:
 		return asn1c_make_identifier(AMI_MASK_ONLY_SPACES,
-			0, exprid ? exprid->Identifier : typename, 0);
+			0, exprid ? exprid->Identifier : typename, (char*)0);
 	case TNF_INCLUDE:
 		return asn1c_make_identifier(
 			AMI_MASK_ONLY_SPACES | AMI_NODELIMITER,
@@ -275,15 +275,15 @@
 				? "\"" : "<"),
 			exprid ? exprid->Identifier : typename,
 			((!stdname || (arg->flags & A1C_INCLUDES_QUOTED))
-				? ".h\"" : ".h>"), 0);
+				? ".h\"" : ".h>"), (char*)0);
 	case TNF_SAFE:
-		return asn1c_make_identifier(0, exprid, typename, 0);
+		return asn1c_make_identifier(0, exprid, typename, (char*)0);
 	case TNF_CTYPE:	/* C type */
 		return asn1c_make_identifier(0, exprid,
-				exprid?"t":typename, exprid?0:"t", 0);
+				exprid?"t":typename, exprid?0:"t", (char*)0);
 	case TNF_RSAFE:	/* Recursion-safe type */
 		return asn1c_make_identifier(AMI_CHECK_RESERVED, 0,
-			"struct", " ", typename, 0);
+			"struct", " ", typename, (char*)0);
 	}
 
 	assert(!"unreachable");
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);
diff --git a/libasn1fix/Makefile.am b/libasn1fix/Makefile.am
index 71df46a..5e506cc 100644
--- a/libasn1fix/Makefile.am
+++ b/libasn1fix/Makefile.am
@@ -1,3 +1,4 @@
+@CODE_COVERAGE_RULES@
 
 AM_CFLAGS = @ADD_CFLAGS@
 AM_CPPFLAGS =				\
diff --git a/libasn1fix/asn1fix_crange.c b/libasn1fix/asn1fix_crange.c
index 311c727..4c1f321 100644
--- a/libasn1fix/asn1fix_crange.c
+++ b/libasn1fix/asn1fix_crange.c
@@ -673,10 +673,8 @@
 			range->right = tmp;
 		}
 
-		if(range->elements) {
-			free(range->elements);
-			range->elements = 0;
-		}
+		free(range->elements);
+		range->elements = 0;
 		range->el_size = 0;
 		return 0;
 	}
diff --git a/libasn1fix/asn1fix_tags.c b/libasn1fix/asn1fix_tags.c
index db4d4ed..d57e37e 100644
--- a/libasn1fix/asn1fix_tags.c
+++ b/libasn1fix/asn1fix_tags.c
@@ -166,7 +166,7 @@
 	arg.expr = expr;
 
 	count = asn1f_fetch_tags_impl(&arg, &tags, 0, 0, flags);
-	if(count <= 0 && tags) {
+	if (count <= 0) {
 		free(tags);
 		tags = 0;
 	}
diff --git a/libasn1parser/asn1p_constr.c b/libasn1parser/asn1p_constr.c
index 0b1e892..008ad40 100644
--- a/libasn1parser/asn1p_constr.c
+++ b/libasn1parser/asn1p_constr.c
@@ -23,14 +23,10 @@
 asn1p_constraint_free(asn1p_constraint_t *ct) {
 	if(ct) {
 
-		if(ct->containedSubtype)
-			asn1p_value_free(ct->containedSubtype);
-		if(ct->value)
-			asn1p_value_free(ct->value);
-		if(ct->range_start)
-			asn1p_value_free(ct->range_start);
-		if(ct->range_stop)
-			asn1p_value_free(ct->range_stop);
+		asn1p_value_free(ct->containedSubtype);
+		asn1p_value_free(ct->value);
+		asn1p_value_free(ct->range_start);
+		asn1p_value_free(ct->range_stop);
 
 		if(ct->elements) {
 			while(ct->el_count--) {
diff --git a/libasn1parser/asn1p_expr.c b/libasn1parser/asn1p_expr.c
index b7a03ec..46e54a3 100644
--- a/libasn1parser/asn1p_expr.c
+++ b/libasn1parser/asn1p_expr.c
@@ -246,20 +246,13 @@
 		}
 
 		free(expr->Identifier);
-		if(expr->reference)
-			asn1p_ref_free(expr->reference);
-		if(expr->constraints)
-			asn1p_constraint_free(expr->constraints);
-		if(expr->combined_constraints)
-			asn1p_constraint_free(expr->combined_constraints);
-		if(expr->lhs_params)
-			asn1p_paramlist_free(expr->lhs_params);
-		if(expr->value)
-			asn1p_value_free(expr->value);
-		if(expr->marker.default_value)
-			asn1p_value_free(expr->marker.default_value);
-		if(expr->with_syntax)
-			asn1p_wsyntx_free(expr->with_syntax);
+		asn1p_ref_free(expr->reference);
+		asn1p_constraint_free(expr->constraints);
+		asn1p_constraint_free(expr->combined_constraints);
+		asn1p_paramlist_free(expr->lhs_params);
+		asn1p_value_free(expr->value);
+		asn1p_value_free(expr->marker.default_value);
+		asn1p_wsyntx_free(expr->with_syntax);
 
 		if(expr->data && expr->data_free)
 			expr->data_free(expr->data);
diff --git a/libasn1parser/asn1p_param.c b/libasn1parser/asn1p_param.c
index 6fd7f21..df6054e 100644
--- a/libasn1parser/asn1p_param.c
+++ b/libasn1parser/asn1p_param.c
@@ -27,8 +27,7 @@
 		if(pl->params) {
 			int i = pl->params_count;
 			while(i--) {
-				if(pl->params[i].governor)
-					asn1p_ref_free(pl->params[i].governor);
+				asn1p_ref_free(pl->params[i].governor);
 				free(pl->params[i].argument);
 				pl->params[i].governor = 0;
 				pl->params[i].argument = 0;
@@ -82,8 +81,7 @@
 		pl->params_count++;
 		return 0;
 	} else {
-		if(pl->params[pl->params_count].governor)
-			asn1p_ref_free(pl->params[pl->params_count].governor);
+		asn1p_ref_free(pl->params[pl->params_count].governor);
 		return -1;
 	}
 }
diff --git a/libasn1parser/asn1p_y.c b/libasn1parser/asn1p_y.c
index e15fc02..9d355b7 100644
--- a/libasn1parser/asn1p_y.c
+++ b/libasn1parser/asn1p_y.c
@@ -430,7 +430,7 @@
 	} tv_nametag;
 }
 /* Line 193 of yacc.c.  */
-#line 434 "y.tab.c"
+#line 434 "asn1p_y.c"
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
@@ -443,7 +443,7 @@
 
 
 /* Line 216 of yacc.c.  */
-#line 447 "y.tab.c"
+#line 447 "asn1p_y.c"
 
 #ifdef short
 # undef short
@@ -2825,8 +2825,8 @@
 		checkmem((yyval.a_plist));
 		ret = asn1p_paramlist_add_param((yyval.a_plist), (yyvsp[(1) - (1)].a_parg).governor, (yyvsp[(1) - (1)].a_parg).argument);
 		checkmem(ret == 0);
-		if((yyvsp[(1) - (1)].a_parg).governor) asn1p_ref_free((yyvsp[(1) - (1)].a_parg).governor);
-		if((yyvsp[(1) - (1)].a_parg).argument) free((yyvsp[(1) - (1)].a_parg).argument);
+		asn1p_ref_free((yyvsp[(1) - (1)].a_parg).governor);
+		free((yyvsp[(1) - (1)].a_parg).argument);
 	}
     break;
 
@@ -2837,8 +2837,8 @@
 		(yyval.a_plist) = (yyvsp[(1) - (3)].a_plist);
 		ret = asn1p_paramlist_add_param((yyval.a_plist), (yyvsp[(3) - (3)].a_parg).governor, (yyvsp[(3) - (3)].a_parg).argument);
 		checkmem(ret == 0);
-		if((yyvsp[(3) - (3)].a_parg).governor) asn1p_ref_free((yyvsp[(3) - (3)].a_parg).governor);
-		if((yyvsp[(3) - (3)].a_parg).argument) free((yyvsp[(3) - (3)].a_parg).argument);
+		asn1p_ref_free((yyvsp[(3) - (3)].a_parg).governor);
+		free((yyvsp[(3) - (3)].a_parg).argument);
 	}
     break;
 
@@ -4795,7 +4795,7 @@
 
 
 /* Line 1267 of yacc.c.  */
-#line 4799 "y.tab.c"
+#line 4799 "asn1p_y.c"
       default: break;
     }
   YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
diff --git a/libasn1parser/asn1p_y.h b/libasn1parser/asn1p_y.h
index 9963cde..2cec4ee 100644
--- a/libasn1parser/asn1p_y.h
+++ b/libasn1parser/asn1p_y.h
@@ -294,7 +294,7 @@
 	} tv_nametag;
 }
 /* Line 1529 of yacc.c.  */
-#line 298 "y.tab.h"
+#line 298 "asn1p_y.h"
 	YYSTYPE;
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
diff --git a/libasn1parser/asn1p_y.y b/libasn1parser/asn1p_y.y
index aae339b..910989a 100644
--- a/libasn1parser/asn1p_y.y
+++ b/libasn1parser/asn1p_y.y
@@ -850,16 +850,16 @@
 		checkmem($$);
 		ret = asn1p_paramlist_add_param($$, $1.governor, $1.argument);
 		checkmem(ret == 0);
-		if($1.governor) asn1p_ref_free($1.governor);
-		if($1.argument) free($1.argument);
+		asn1p_ref_free($1.governor);
+		free($1.argument);
 	}
 	| ParameterArgumentList ',' ParameterArgumentName {
 		int ret;
 		$$ = $1;
 		ret = asn1p_paramlist_add_param($$, $3.governor, $3.argument);
 		checkmem(ret == 0);
-		if($3.governor) asn1p_ref_free($3.governor);
-		if($3.argument) free($3.argument);
+		asn1p_ref_free($3.governor);
+		free($3.argument);
 	}
 	;
 	
diff --git a/m4/ax_code_coverage.m4 b/m4/ax_code_coverage.m4
new file mode 100644
index 0000000..93dfce3
--- /dev/null
+++ b/m4/ax_code_coverage.m4
@@ -0,0 +1,274 @@
+# ===========================================================================
+#     http://www.gnu.org/software/autoconf-archive/ax_code_coverage.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_CODE_COVERAGE()
+#
+# DESCRIPTION
+#
+#   Defines CODE_COVERAGE_CPPFLAGS, CODE_COVERAGE_CFLAGS,
+#   CODE_COVERAGE_CXXFLAGS and CODE_COVERAGE_LDFLAGS which should be
+#   included in the CPPFLAGS, CFLAGS CXXFLAGS and LIBS/LDFLAGS variables of
+#   every build target (program or library) which should be built with code
+#   coverage support. Also defines CODE_COVERAGE_RULES which should be
+#   substituted in your Makefile; and $enable_code_coverage which can be
+#   used in subsequent configure output. CODE_COVERAGE_ENABLED is defined
+#   and substituted, and corresponds to the value of the
+#   --enable-code-coverage option, which defaults to being disabled.
+#
+#   Test also for gcov program and create GCOV variable that could be
+#   substituted.
+#
+#   Note that all optimisation flags in CFLAGS must be disabled when code
+#   coverage is enabled.
+#
+#   Usage example:
+#
+#   configure.ac:
+#
+#     AX_CODE_COVERAGE
+#
+#   Makefile.am:
+#
+#     @CODE_COVERAGE_RULES@
+#     my_program_LIBS = ... $(CODE_COVERAGE_LDFLAGS) ...
+#     my_program_CPPFLAGS = ... $(CODE_COVERAGE_CPPFLAGS) ...
+#     my_program_CFLAGS = ... $(CODE_COVERAGE_CFLAGS) ...
+#     my_program_CXXFLAGS = ... $(CODE_COVERAGE_CXXFLAGS) ...
+#
+#   This results in a "check-code-coverage" rule being added to any
+#   Makefile.am which includes "@CODE_COVERAGE_RULES@" (assuming the module
+#   has been configured with --enable-code-coverage). Running `make
+#   check-code-coverage` in that directory will run the module's test suite
+#   (`make check`) and build a code coverage report detailing the code which
+#   was touched, then print the URI for the report.
+#
+#   This code was derived from Makefile.decl in GLib, originally licenced
+#   under LGPLv2.1+.
+#
+# LICENSE
+#
+#   Copyright (c) 2012, 2016 Philip Withnall
+#   Copyright (c) 2012 Xan Lopez
+#   Copyright (c) 2012 Christian Persch
+#   Copyright (c) 2012 Paolo Borelli
+#   Copyright (c) 2012 Dan Winship
+#   Copyright (c) 2015 Bastien ROUCARIES
+#
+#   This library is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU Lesser General Public License as published by
+#   the Free Software Foundation; either version 2.1 of the License, or (at
+#   your option) any later version.
+#
+#   This library is distributed in the hope that it will be useful, but
+#   WITHOUT ANY WARRANTY; without even the implied warranty of
+#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
+#   General Public License for more details.
+#
+#   You should have received a copy of the GNU Lesser General Public License
+#   along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+#serial 16
+
+AC_DEFUN([AX_CODE_COVERAGE],[
+	dnl Check for --enable-code-coverage
+	AC_REQUIRE([AC_PROG_SED])
+
+	# allow to override gcov location
+	AC_ARG_WITH([gcov],
+	  [AS_HELP_STRING([--with-gcov[=GCOV]], [use given GCOV for coverage (GCOV=gcov).])],
+	  [_AX_CODE_COVERAGE_GCOV_PROG_WITH=$with_gcov],
+	  [_AX_CODE_COVERAGE_GCOV_PROG_WITH=gcov])
+
+	AC_MSG_CHECKING([whether to build with code coverage support])
+	AC_ARG_ENABLE([code-coverage],
+	  AS_HELP_STRING([--enable-code-coverage],
+	  [Whether to enable code coverage support]),,
+	  enable_code_coverage=no)
+
+	AM_CONDITIONAL([CODE_COVERAGE_ENABLED], [test x$enable_code_coverage = xyes])
+	AC_SUBST([CODE_COVERAGE_ENABLED], [$enable_code_coverage])
+	AC_MSG_RESULT($enable_code_coverage)
+
+	AS_IF([ test "$enable_code_coverage" = "yes" ], [
+		# check for gcov
+		AC_CHECK_TOOL([GCOV],
+		  [$_AX_CODE_COVERAGE_GCOV_PROG_WITH],
+		  [:])
+		AS_IF([test "X$GCOV" = "X:"],
+		  [AC_MSG_ERROR([gcov is needed to do coverage])])
+		AC_SUBST([GCOV])
+
+		dnl Check if gcc is being used
+		AS_IF([ test "$GCC" = "no" ], [
+			AC_MSG_ERROR([not compiling with gcc, which is required for gcov code coverage])
+		])
+
+		# List of supported lcov versions.
+		lcov_version_list="1.6 1.7 1.8 1.9 1.10 1.11 1.12"
+
+		AC_CHECK_PROG([LCOV], [lcov], [lcov])
+		AC_CHECK_PROG([GENHTML], [genhtml], [genhtml])
+
+		AS_IF([ test "$LCOV" ], [
+			AC_CACHE_CHECK([for lcov version], ax_cv_lcov_version, [
+				ax_cv_lcov_version=invalid
+				lcov_version=`$LCOV -v 2>/dev/null | $SED -e 's/^.* //'`
+				for lcov_check_version in $lcov_version_list; do
+					if test "$lcov_version" = "$lcov_check_version"; then
+						ax_cv_lcov_version="$lcov_check_version (ok)"
+					fi
+				done
+			])
+		], [
+			lcov_msg="To enable code coverage reporting you must have one of the following lcov versions installed: $lcov_version_list"
+			AC_MSG_ERROR([$lcov_msg])
+		])
+
+		case $ax_cv_lcov_version in
+			""|invalid[)]
+				lcov_msg="You must have one of the following versions of lcov: $lcov_version_list (found: $lcov_version)."
+				AC_MSG_ERROR([$lcov_msg])
+				LCOV="exit 0;"
+			;;
+		esac
+
+		AS_IF([ test -z "$GENHTML" ], [
+			AC_MSG_ERROR([Could not find genhtml from the lcov package])
+		])
+
+		dnl Build the code coverage flags
+		CODE_COVERAGE_CPPFLAGS="-DNDEBUG"
+		CODE_COVERAGE_CFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
+		CODE_COVERAGE_CXXFLAGS="-O0 -g -fprofile-arcs -ftest-coverage"
+		CODE_COVERAGE_LDFLAGS="-lgcov"
+
+		AC_SUBST([CODE_COVERAGE_CPPFLAGS])
+		AC_SUBST([CODE_COVERAGE_CFLAGS])
+		AC_SUBST([CODE_COVERAGE_CXXFLAGS])
+		AC_SUBST([CODE_COVERAGE_LDFLAGS])
+	])
+
+[CODE_COVERAGE_RULES='
+# Code coverage
+#
+# Optional:
+#  - CODE_COVERAGE_DIRECTORY: Top-level directory for code coverage reporting.
+#    Multiple directories may be specified, separated by whitespace.
+#    (Default: $(top_builddir))
+#  - CODE_COVERAGE_OUTPUT_FILE: Filename and path for the .info file generated
+#    by lcov for code coverage. (Default:
+#    $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info)
+#  - CODE_COVERAGE_OUTPUT_DIRECTORY: Directory for generated code coverage
+#    reports to be created. (Default:
+#    $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage)
+#  - CODE_COVERAGE_BRANCH_COVERAGE: Set to 1 to enforce branch coverage,
+#    set to 0 to disable it and leave empty to stay with the default.
+#    (Default: empty)
+#  - CODE_COVERAGE_LCOV_SHOPTS_DEFAULT: Extra options shared between both lcov
+#    instances. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
+#  - CODE_COVERAGE_LCOV_SHOPTS: Extra options to shared between both lcov
+#    instances. (Default: $CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
+#  - CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH: --gcov-tool pathtogcov
+#  - CODE_COVERAGE_LCOV_OPTIONS_DEFAULT: Extra options to pass to the
+#    collecting lcov instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
+#  - CODE_COVERAGE_LCOV_OPTIONS: Extra options to pass to the collecting lcov
+#    instance. (Default: $CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
+#  - CODE_COVERAGE_LCOV_RMOPTS_DEFAULT: Extra options to pass to the filtering
+#    lcov instance. (Default: empty)
+#  - CODE_COVERAGE_LCOV_RMOPTS: Extra options to pass to the filtering lcov
+#    instance. (Default: $CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
+#  - CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT: Extra options to pass to the
+#    genhtml instance. (Default: based on $CODE_COVERAGE_BRANCH_COVERAGE)
+#  - CODE_COVERAGE_GENHTML_OPTIONS: Extra options to pass to the genhtml
+#    instance. (Default: $CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT)
+#  - CODE_COVERAGE_IGNORE_PATTERN: Extra glob pattern of files to ignore
+#
+# The generated report will be titled using the $(PACKAGE_NAME) and
+# $(PACKAGE_VERSION). In order to add the current git hash to the title,
+# use the git-version-gen script, available online.
+
+# Optional variables
+CODE_COVERAGE_DIRECTORY ?= $(top_builddir)
+CODE_COVERAGE_OUTPUT_FILE ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage.info
+CODE_COVERAGE_OUTPUT_DIRECTORY ?= $(PACKAGE_NAME)-$(PACKAGE_VERSION)-coverage
+CODE_COVERAGE_BRANCH_COVERAGE ?=
+CODE_COVERAGE_LCOV_SHOPTS_DEFAULT ?= $(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
+--rc lcov_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
+CODE_COVERAGE_LCOV_SHOPTS ?= $(CODE_COVERAGE_LCOV_SHOPTS_DEFAULT)
+CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH ?= --gcov-tool "$(GCOV)"
+CODE_COVERAGE_LCOV_OPTIONS_DEFAULT ?= $(CODE_COVERAGE_LCOV_OPTIONS_GCOVPATH)
+CODE_COVERAGE_LCOV_OPTIONS ?= $(CODE_COVERAGE_LCOV_OPTIONS_DEFAULT)
+CODE_COVERAGE_LCOV_RMOPTS_DEFAULT ?=
+CODE_COVERAGE_LCOV_RMOPTS ?= $(CODE_COVERAGE_LCOV_RMOPTS_DEFAULT)
+CODE_COVERAGE_GENHTML_OPTIONS_DEFAULT ?=\
+$(if $(CODE_COVERAGE_BRANCH_COVERAGE),\
+--rc genhtml_branch_coverage=$(CODE_COVERAGE_BRANCH_COVERAGE))
+CODE_COVERAGE_GENHTML_OPTIONS ?= $(CODE_COVERAGE_GENHTML_OPTIONS_DEFAULTS)
+CODE_COVERAGE_IGNORE_PATTERN ?=
+
+code_coverage_v_lcov_cap = $(code_coverage_v_lcov_cap_$(V))
+code_coverage_v_lcov_cap_ = $(code_coverage_v_lcov_cap_$(AM_DEFAULT_VERBOSITY))
+code_coverage_v_lcov_cap_0 = @echo "  LCOV   --capture"\
+ $(CODE_COVERAGE_OUTPUT_FILE);
+code_coverage_v_lcov_ign = $(code_coverage_v_lcov_ign_$(V))
+code_coverage_v_lcov_ign_ = $(code_coverage_v_lcov_ign_$(AM_DEFAULT_VERBOSITY))
+code_coverage_v_lcov_ign_0 = @echo "  LCOV   --remove /tmp/*"\
+ $(CODE_COVERAGE_IGNORE_PATTERN);
+code_coverage_v_genhtml = $(code_coverage_v_genhtml_$(V))
+code_coverage_v_genhtml_ = $(code_coverage_v_genhtml_$(AM_DEFAULT_VERBOSITY))
+code_coverage_v_genhtml_0 = @echo "  GEN   " $(CODE_COVERAGE_OUTPUT_DIRECTORY);
+code_coverage_quiet = $(code_coverage_quiet_$(V))
+code_coverage_quiet_ = $(code_coverage_quiet_$(AM_DEFAULT_VERBOSITY))
+code_coverage_quiet_0 = --quiet
+
+# sanitizes the test-name: replaces with underscores: dashes and dots
+code_coverage_sanitize = $(subst -,_,$(subst .,_,$(1)))
+
+# Use recursive makes in order to ignore errors during check
+check-code-coverage:
+ifeq ($(CODE_COVERAGE_ENABLED),yes)
+	-$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) -k check
+	$(A''M_V_at)$(MAKE) $(AM_MAKEFLAGS) code-coverage-capture
+else
+	@echo "Need to reconfigure with --enable-code-coverage"
+endif
+
+# Capture code coverage data
+code-coverage-capture: code-coverage-capture-hook
+ifeq ($(CODE_COVERAGE_ENABLED),yes)
+	$(code_coverage_v_lcov_cap)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --capture --output-file "$(CODE_COVERAGE_OUTPUT_FILE).tmp" --test-name "$(call code_coverage_sanitize,$(PACKAGE_NAME)-$(PACKAGE_VERSION))" --no-checksum --compat-libtool $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_OPTIONS)
+	$(code_coverage_v_lcov_ign)$(LCOV) $(code_coverage_quiet) $(addprefix --directory ,$(CODE_COVERAGE_DIRECTORY)) --remove "$(CODE_COVERAGE_OUTPUT_FILE).tmp" "/tmp/*" $(CODE_COVERAGE_IGNORE_PATTERN) --output-file "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_LCOV_SHOPTS) $(CODE_COVERAGE_LCOV_RMOPTS)
+	-@rm -f $(CODE_COVERAGE_OUTPUT_FILE).tmp
+	$(code_coverage_v_genhtml)LANG=C $(GENHTML) $(code_coverage_quiet) $(addprefix --prefix ,$(CODE_COVERAGE_DIRECTORY)) --output-directory "$(CODE_COVERAGE_OUTPUT_DIRECTORY)" --title "$(PACKAGE_NAME)-$(PACKAGE_VERSION) Code Coverage" --legend --show-details "$(CODE_COVERAGE_OUTPUT_FILE)" $(CODE_COVERAGE_GENHTML_OPTIONS)
+	@echo "file://$(abs_builddir)/$(CODE_COVERAGE_OUTPUT_DIRECTORY)/index.html"
+else
+	@echo "Need to reconfigure with --enable-code-coverage"
+endif
+
+# Hook rule executed before code-coverage-capture, overridable by the user
+code-coverage-capture-hook:
+
+ifeq ($(CODE_COVERAGE_ENABLED),yes)
+clean: code-coverage-clean
+distclean: code-coverage-clean
+code-coverage-clean:
+	-$(LCOV) --directory $(top_builddir) -z
+	-rm -rf $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_FILE).tmp $(CODE_COVERAGE_OUTPUT_DIRECTORY)
+	-find . \( -name "*.gcda" -o -name "*.gcno" -o -name "*.gcov" \) -delete
+endif
+
+GITIGNOREFILES ?=
+GITIGNOREFILES += $(CODE_COVERAGE_OUTPUT_FILE) $(CODE_COVERAGE_OUTPUT_DIRECTORY)
+
+A''M_DISTCHECK_CONFIGURE_FLAGS ?=
+A''M_DISTCHECK_CONFIGURE_FLAGS += --disable-code-coverage
+
+.PHONY: check-code-coverage code-coverage-capture code-coverage-capture-hook code-coverage-clean
+']
+
+	AC_SUBST([CODE_COVERAGE_RULES])
+	m4_ifdef([_AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE([CODE_COVERAGE_RULES])])
+])
diff --git a/skeletons/ANY.c b/skeletons/ANY.c
index 77024bd..055138d 100644
--- a/skeletons/ANY.c
+++ b/skeletons/ANY.c
@@ -6,7 +6,7 @@
 #include <ANY.h>
 #include <errno.h>
 
-static asn_OCTET_STRING_specifics_t asn_DEF_ANY_specs = {
+static asn_OCTET_STRING_specifics_t asn_SPC_ANY_specs = {
 	sizeof(ANY_t),
 	offsetof(ANY_t, _asn_ctx),
 	ASN_OSUBV_ANY
@@ -26,7 +26,7 @@
 	0, 0, 0, 0,
 	0,	/* No PER visible constraints */
 	0, 0,	/* No members */
-	&asn_DEF_ANY_specs,
+	&asn_SPC_ANY_specs,
 };
 
 
diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c
index 997ff41..7b8e975 100644
--- a/skeletons/BIT_STRING.c
+++ b/skeletons/BIT_STRING.c
@@ -12,7 +12,7 @@
 static const ber_tlv_tag_t asn_DEF_BIT_STRING_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (3 << 2))
 };
-static asn_OCTET_STRING_specifics_t asn_DEF_BIT_STRING_specs = {
+static asn_OCTET_STRING_specifics_t asn_SPC_BIT_STRING_specs = {
 	sizeof(BIT_STRING_t),
 	offsetof(BIT_STRING_t, _asn_ctx),
 	ASN_OSUBV_BIT
@@ -38,7 +38,7 @@
 	  / sizeof(asn_DEF_BIT_STRING_tags[0]),
 	0,	/* No PER visible constraints */
 	0, 0,	/* No members */
-	&asn_DEF_BIT_STRING_specs
+	&asn_SPC_BIT_STRING_specs
 };
 
 /*
diff --git a/skeletons/BMPString.c b/skeletons/BMPString.c
index 8beaabd..b6348c1 100644
--- a/skeletons/BMPString.c
+++ b/skeletons/BMPString.c
@@ -13,7 +13,7 @@
 	(ASN_TAG_CLASS_UNIVERSAL | (30 << 2)),	/* [UNIVERSAL 30] IMPLICIT ...*/
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
-static asn_OCTET_STRING_specifics_t asn_DEF_BMPString_specs = {
+static asn_OCTET_STRING_specifics_t asn_SPC_BMPString_specs = {
 	sizeof(BMPString_t),
 	offsetof(BMPString_t, _asn_ctx),
 	ASN_OSUBV_U16	/* 16-bits character */
@@ -44,7 +44,7 @@
 	  / sizeof(asn_DEF_BMPString_tags[0]),
 	&asn_DEF_BMPString_constraints,
 	0, 0,	/* No members */
-	&asn_DEF_BMPString_specs
+	&asn_SPC_BMPString_specs
 };
 
 /*
diff --git a/skeletons/GeneralizedTime.c b/skeletons/GeneralizedTime.c
index 7e14477..07297db 100644
--- a/skeletons/GeneralizedTime.c
+++ b/skeletons/GeneralizedTime.c
@@ -4,7 +4,9 @@
  */
 #define	_POSIX_PTHREAD_SEMANTICS	/* for Sun */
 #define	_REENTRANT			/* for Sun */
+#ifndef _BSD_SOURCE
 #define _BSD_SOURCE     /* for timegm(3) */
+#endif
 #include <asn_internal.h>
 #include <GeneralizedTime.h>
 
diff --git a/skeletons/Makefile.am b/skeletons/Makefile.am
index f15a695..9978946 100644
--- a/skeletons/Makefile.am
+++ b/skeletons/Makefile.am
@@ -6,7 +6,7 @@
 		${srcdir}/*.[ch]		\
 		${srcdir}/file-dependencies
 
-smodsdir=$(pkgdata)
+smodsdir=$(pkgdatadir)
 
 nobase_dist_smods_DATA =     \
 	standard-modules/README  \
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index 5420ded..3e0f115 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -14,12 +14,12 @@
 static const ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[] = {
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
 };
-static const asn_OCTET_STRING_specifics_t asn_DEF_OCTET_STRING_specs = {
+static asn_OCTET_STRING_specifics_t asn_SPC_OCTET_STRING_specs = {
 	sizeof(OCTET_STRING_t),
 	offsetof(OCTET_STRING_t, _asn_ctx),
 	ASN_OSUBV_STR
 };
-static const asn_per_constraints_t asn_DEF_OCTET_STRING_constraints = {
+static asn_per_constraints_t asn_DEF_OCTET_STRING_constraints = {
 	{ APC_CONSTRAINED, 8, 8, 0, 255 },
 	{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 },
 	0, 0
@@ -45,7 +45,7 @@
 	  / sizeof(asn_DEF_OCTET_STRING_tags[0]),
 	0,	/* No PER visible constraints */
 	0, 0,	/* No members */
-	&asn_DEF_OCTET_STRING_specs
+	&asn_SPC_OCTET_STRING_specs
 };
 
 #undef	_CH_PHASE
@@ -170,7 +170,7 @@
 	void **sptr, const void *buf_ptr, size_t size, int tag_mode) {
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
 				? (asn_OCTET_STRING_specifics_t *)td->specifics
-				: &asn_DEF_OCTET_STRING_specs;
+				: &asn_SPC_OCTET_STRING_specs;
 	BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
 	asn_dec_rval_t rval;
 	asn_struct_ctx_t *ctx;
@@ -244,8 +244,8 @@
 		ber_tlv_tag_t expected_tag;
 		ssize_t tl, ll, tlvl;
 				/* This one works even if (sel->left == -1) */
-		ssize_t Left = ((!sel||(size_t)sel->left >= size)
-					?(ssize_t)size:sel->left);
+		size_t Left = ((!sel||(size_t)sel->left >= size)
+					?size:(size_t)sel->left);
 
 
 		ASN_DEBUG("%p, s->l=%ld, s->wn=%ld, s->g=%ld\n", sel,
@@ -519,7 +519,7 @@
 	asn_enc_rval_t er;
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
 				? (asn_OCTET_STRING_specifics_t *)td->specifics
-				: &asn_DEF_OCTET_STRING_specs;
+				: &asn_SPC_OCTET_STRING_specs;
 	BIT_STRING_t *st = (BIT_STRING_t *)sptr;
 	enum asn_OS_Subvariant type_variant = specs->subvariant;
 	int fix_last_byte = 0;
@@ -1112,7 +1112,7 @@
 	OCTET_STRING_t *st = (OCTET_STRING_t *)*sptr;
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
 				? (asn_OCTET_STRING_specifics_t *)td->specifics
-				: &asn_DEF_OCTET_STRING_specs;
+				: &asn_SPC_OCTET_STRING_specs;
 	const char *xml_tag = opt_mname ? opt_mname : td->xml_tag;
 	asn_struct_ctx_t *ctx;		/* Per-structure parser context */
 	asn_dec_rval_t rval;		/* Return value from the decoder */
@@ -1327,7 +1327,7 @@
 
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
 		? (asn_OCTET_STRING_specifics_t *)td->specifics
-		: &asn_DEF_OCTET_STRING_specs;
+		: &asn_SPC_OCTET_STRING_specs;
 	asn_per_constraints_t *pc = constraints ? constraints
 				: td->per_constraints;
 	asn_per_constraint_t *cval;
@@ -1498,7 +1498,7 @@
 
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
 		? (asn_OCTET_STRING_specifics_t *)td->specifics
-		: &asn_DEF_OCTET_STRING_specs;
+		: &asn_SPC_OCTET_STRING_specs;
 	asn_per_constraints_t *pc = constraints ? constraints
 				: td->per_constraints;
 	asn_per_constraint_t *cval;
@@ -1721,7 +1721,7 @@
 
 	specs = td->specifics
 		    ? (asn_OCTET_STRING_specifics_t *)td->specifics
-		    : &asn_DEF_OCTET_STRING_specs;
+		    : &asn_SPC_OCTET_STRING_specs;
 	ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
 
 	ASN_DEBUG("Freeing %s as OCTET STRING", td->name);
@@ -1793,7 +1793,7 @@
 OCTET_STRING_new_fromBuf(asn_TYPE_descriptor_t *td, const char *str, int len) {
 	asn_OCTET_STRING_specifics_t *specs = td->specifics
 				? (asn_OCTET_STRING_specifics_t *)td->specifics
-				: &asn_DEF_OCTET_STRING_specs;
+				: &asn_SPC_OCTET_STRING_specs;
 	OCTET_STRING_t *st;
 
 	st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
diff --git a/skeletons/PrintableString.c b/skeletons/PrintableString.c
index 7b6828d..9a14938 100644
--- a/skeletons/PrintableString.c
+++ b/skeletons/PrintableString.c
@@ -41,7 +41,7 @@
 		return _PrintableString_code2value[code];
 	return -1;
 }
-static const asn_per_constraints_t asn_DEF_PrintableString_constraints = {
+static asn_per_constraints_t asn_DEF_PrintableString_constraints = {
 	{ APC_CONSTRAINED, 4, 4, 0x20, 0x39 },	/* Value */
 	{ APC_SEMI_CONSTRAINED, -1, -1, 0, 0 },	/* Size */
 	asn_DEF_PrintableString_v2c,
diff --git a/skeletons/REAL.c b/skeletons/REAL.c
index 0a25062..12c1e3e 100644
--- a/skeletons/REAL.c
+++ b/skeletons/REAL.c
@@ -3,7 +3,9 @@
  * Redistribution and modifications are permitted subject to BSD license.
  */
 #define	_ISOC99_SOURCE		/* For ilogb() and quiet NAN */
+#ifndef _BSD_SOURCE
 #define	_BSD_SOURCE		/* To reintroduce finite(3) */
+#endif
 #if	defined(__alpha)
 #include <sys/resource.h>	/* For INFINITY */
 #endif
diff --git a/skeletons/UniversalString.c b/skeletons/UniversalString.c
index 21753eb..6e9d0c3 100644
--- a/skeletons/UniversalString.c
+++ b/skeletons/UniversalString.c
@@ -13,7 +13,7 @@
 	(ASN_TAG_CLASS_UNIVERSAL | (28 << 2)),	/* [UNIVERSAL 28] IMPLICIT ...*/
 	(ASN_TAG_CLASS_UNIVERSAL | (4 << 2))	/* ... OCTET STRING */
 };
-static asn_OCTET_STRING_specifics_t asn_DEF_UniversalString_specs = {
+static asn_OCTET_STRING_specifics_t asn_SPC_UniversalString_specs = {
 	sizeof(UniversalString_t),
 	offsetof(UniversalString_t, _asn_ctx),
 	ASN_OSUBV_U32	/* 32-bits character */
@@ -44,7 +44,7 @@
 	  / sizeof(asn_DEF_UniversalString_tags[0]),
 	&asn_DEF_UniversalString_constraints,
 	0, 0,	/* No members */
-	&asn_DEF_UniversalString_specs
+	&asn_SPC_UniversalString_specs
 };
 
 
diff --git a/skeletons/asn_internal.h b/skeletons/asn_internal.h
index 9c94ca6..7c9325c 100644
--- a/skeletons/asn_internal.h
+++ b/skeletons/asn_internal.h
@@ -103,7 +103,7 @@
  * Check stack against overflow, if limit is set.
  */
 #define	ASN__DEFAULT_STACK_MAX	(30000)
-static int __attribute__((unused))
+static int GCC_NOTUSED
 ASN__STACK_OVERFLOW_CHECK(asn_codec_ctx_t *ctx) {
 	if(ctx && ctx->max_stack_size) {
 
diff --git a/skeletons/asn_system.h b/skeletons/asn_system.h
index d19837e..5bf02c2 100644
--- a/skeletons/asn_system.h
+++ b/skeletons/asn_system.h
@@ -47,12 +47,16 @@
 #endif
 #ifndef	ASSUMESTDTYPES	/* Standard types have been defined elsewhere */
 #define	ssize_t		SSIZE_T
+#if _MSC_VER < 1600
 typedef	char		int8_t;
 typedef	short		int16_t;
 typedef	int		int32_t;
 typedef	unsigned char	uint8_t;
 typedef	unsigned short	uint16_t;
 typedef	unsigned int	uint32_t;
+#else /* _MSC_VER >= 1600 */
+#include <stdint.h>
+#endif /* _MSC_VER < 1600 */
 #endif	/* ASSUMESTDTYPES */
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index 6116e6a..158101b 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -671,7 +671,6 @@
 			case -1:
 				ctx->phase = 5;
 				RETURN(RC_FAIL);
-				continue;
 			case 1:
 				ctx->phase = 3;
 				/* Fall through */
diff --git a/skeletons/der_encoder.c b/skeletons/der_encoder.c
index 1c01480..1e2668e 100644
--- a/skeletons/der_encoder.c
+++ b/skeletons/der_encoder.c
@@ -146,8 +146,8 @@
 
 	if(!cb) return overall_length - struct_length;
 
-	ASN_DEBUG("%s %s TL sequence (%d elements)",
-		cb?"Encoding":"Estimating", sd->name, tags_count);
+	ASN_DEBUG("Encoding %s TL sequence (%d elements)", sd->name,
+                  tags_count);
 
 	/*
 	 * Encode the TL sequence for real.
diff --git a/skeletons/per_support.c b/skeletons/per_support.c
index 5ecdc2e..635db40 100644
--- a/skeletons/per_support.c
+++ b/skeletons/per_support.c
@@ -109,7 +109,7 @@
 		(int)pd->moved,
 		(((long)pd->buffer) & 0xf),
 		(int)pd->nboff, (int)pd->nbits,
-		pd->buffer[0],
+		((pd->buffer != NULL)?pd->buffer[0]:0),
 		(int)(pd->nbits - pd->nboff),
 		(int)accum);
 
@@ -394,8 +394,8 @@
 		buf[2] = bits >> 8,
 		buf[3] = bits;
 	else {
-		per_put_few_bits(po, bits >> (obits - 24), 24);
-		per_put_few_bits(po, bits, obits - 24);
+		if(per_put_few_bits(po, bits >> (obits - 24), 24)) return -1;
+		if(per_put_few_bits(po, bits, obits - 24)) return -1;
 	}
 
 	ASN_DEBUG("[PER out %u/%x => %02x buf+%ld]",
diff --git a/skeletons/tests/Makefile.am b/skeletons/tests/Makefile.am
index 546bb67..26db11b 100644
--- a/skeletons/tests/Makefile.am
+++ b/skeletons/tests/Makefile.am
@@ -1,3 +1,5 @@
+@CODE_COVERAGE_RULES@
+
 check_PROGRAMS = \
 	check-ber_tlv_tag	\
 	check-length		\
diff --git a/tests/125-bitstring-constraint-OK.asn1.-X b/tests/125-bitstring-constraint-OK.asn1.-X
index b33fecc..534182a 100644
--- a/tests/125-bitstring-constraint-OK.asn1.-X
+++ b/tests/125-bitstring-constraint-OK.asn1.-X
@@ -1,4 +1,4 @@
-<!-- XML DTD generated by asn1c-0.9.28 -->
+<!-- XML DTD generated by asn1c-0.9.29 -->
 
 <!-- ASN.1 module
 ModuleBitStringConstraint { iso org(3) dod(6) internet(1) private(4)
diff --git a/tests/31-set-of-OK.asn1.-Pfwide-types b/tests/31-set-of-OK.asn1.-Pfwide-types
index 59bc7f9..a093940 100644
--- a/tests/31-set-of-OK.asn1.-Pfwide-types
+++ b/tests/31-set-of-OK.asn1.-Pfwide-types
@@ -184,6 +184,19 @@
 
 struct Forest;
 
+/*** <<< FWD-DEFS [Stuff] >>> ***/
+
+typedef struct Member {
+	BIT_STRING_t	 cup_of_coffee;
+	/*
+	 * This type is extensible,
+	 * possible extensions are below.
+	 */
+	
+	/* Context for parsing across buffer boundaries */
+	asn_struct_ctx_t _asn_ctx;
+} Member;
+
 /*** <<< TYPE-DECLS [Stuff] >>> ***/
 
 typedef struct Stuff {
@@ -194,16 +207,7 @@
 		asn_struct_ctx_t _asn_ctx;
 	} *trees;
 	struct anything {
-		A_SET_OF(struct Member {
-			BIT_STRING_t	 cup_of_coffee;
-			/*
-			 * This type is extensible,
-			 * possible extensions are below.
-			 */
-			
-			/* Context for parsing across buffer boundaries */
-			asn_struct_ctx_t _asn_ctx;
-		} ) list;
+		A_SET_OF(Member) list;
 		
 		/* Context for parsing across buffer boundaries */
 		asn_struct_ctx_t _asn_ctx;
diff --git a/tests/72-same-names-OK.asn1.-Pfwide-types b/tests/72-same-names-OK.asn1.-Pfwide-types
index 7560c6a..ec6c12e 100644
--- a/tests/72-same-names-OK.asn1.-Pfwide-types
+++ b/tests/72-same-names-OK.asn1.-Pfwide-types
@@ -7,16 +7,20 @@
 #include <constr_SEQUENCE.h>
 #include <constr_SET_OF.h>
 
+/*** <<< FWD-DEFS [Type] >>> ***/
+
+typedef struct Member {
+	Type1_t	 t1;
+	Type2_t	 t2;
+	
+	/* Context for parsing across buffer boundaries */
+	asn_struct_ctx_t _asn_ctx;
+} Member;
+
 /*** <<< TYPE-DECLS [Type] >>> ***/
 
 typedef struct Type {
-	A_SET_OF(struct Member {
-		Type1_t	 t1;
-		Type2_t	 t2;
-		
-		/* Context for parsing across buffer boundaries */
-		asn_struct_ctx_t _asn_ctx;
-	} ) list;
+	A_SET_OF(Member) list;
 	
 	/* Context for parsing across buffer boundaries */
 	asn_struct_ctx_t _asn_ctx;
diff --git a/tests/92-circular-loops-OK.asn1.-Pfindirect-choice b/tests/92-circular-loops-OK.asn1.-Pfindirect-choice
index 6695a41..4faa747 100644
--- a/tests/92-circular-loops-OK.asn1.-Pfindirect-choice
+++ b/tests/92-circular-loops-OK.asn1.-Pfindirect-choice
@@ -623,23 +623,27 @@
 struct Set;
 struct Sequence;
 
+/*** <<< FWD-DEFS [Set] >>> ***/
+
+typedef struct Member {
+	long	 Int;
+	struct Set	*set;
+	struct Sequence	*seq;
+	struct Set	*set2	/* OPTIONAL */;
+	/*
+	 * This type is extensible,
+	 * possible extensions are below.
+	 */
+	struct Set	*set3;
+	
+	/* Context for parsing across buffer boundaries */
+	asn_struct_ctx_t _asn_ctx;
+} Member;
+
 /*** <<< TYPE-DECLS [Set] >>> ***/
 
 typedef struct Set {
-	A_SET_OF(struct Member {
-		long	 Int;
-		struct Set	*set;
-		struct Sequence	*seq;
-		struct Set	*set2	/* OPTIONAL */;
-		/*
-		 * This type is extensible,
-		 * possible extensions are below.
-		 */
-		struct Set	*set3;
-		
-		/* Context for parsing across buffer boundaries */
-		asn_struct_ctx_t _asn_ctx;
-	} ) list;
+	A_SET_OF(Member) list;
 	
 	/* Context for parsing across buffer boundaries */
 	asn_struct_ctx_t _asn_ctx;
diff --git a/tests/92-circular-loops-OK.asn1.-Pfwide-types b/tests/92-circular-loops-OK.asn1.-Pfwide-types
index 21918d9..8ba7f73 100644
--- a/tests/92-circular-loops-OK.asn1.-Pfwide-types
+++ b/tests/92-circular-loops-OK.asn1.-Pfwide-types
@@ -622,23 +622,27 @@
 struct Set;
 struct Sequence;
 
+/*** <<< FWD-DEFS [Set] >>> ***/
+
+typedef struct Member {
+	INTEGER_t	 Int;
+	struct Set	*set;
+	struct Sequence	*seq;
+	struct Set	*set2	/* OPTIONAL */;
+	/*
+	 * This type is extensible,
+	 * possible extensions are below.
+	 */
+	struct Set	*set3;
+	
+	/* Context for parsing across buffer boundaries */
+	asn_struct_ctx_t _asn_ctx;
+} Member;
+
 /*** <<< TYPE-DECLS [Set] >>> ***/
 
 typedef struct Set {
-	A_SET_OF(struct Member {
-		INTEGER_t	 Int;
-		struct Set	*set;
-		struct Sequence	*seq;
-		struct Set	*set2	/* OPTIONAL */;
-		/*
-		 * This type is extensible,
-		 * possible extensions are below.
-		 */
-		struct Set	*set3;
-		
-		/* Context for parsing across buffer boundaries */
-		asn_struct_ctx_t _asn_ctx;
-	} ) list;
+	A_SET_OF(Member) list;
 	
 	/* Context for parsing across buffer boundaries */
 	asn_struct_ctx_t _asn_ctx;