allow local cleanup

diff --git a/skeletons/BIT_STRING.c b/skeletons/BIT_STRING.c
index b3b77d1..19c81e7 100644
--- a/skeletons/BIT_STRING.c
+++ b/skeletons/BIT_STRING.c
@@ -126,6 +126,8 @@
 	if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
 
 	return er;
+cb_failed:
+	_ASN_ENCODE_FAILED;
 }
 
 
diff --git a/skeletons/BOOLEAN.c b/skeletons/BOOLEAN.c
index 992b9a8..43b890f 100644
--- a/skeletons/BOOLEAN.c
+++ b/skeletons/BOOLEAN.c
@@ -148,6 +148,8 @@
 	}
 
 	return er;
+cb_failed:
+	_ASN_ENCODE_FAILED;
 }
 
 int
diff --git a/skeletons/OCTET_STRING.c b/skeletons/OCTET_STRING.c
index 2730fc4..e3b7a0a 100644
--- a/skeletons/OCTET_STRING.c
+++ b/skeletons/OCTET_STRING.c
@@ -571,12 +571,8 @@
 	uint8_t *end;
 	size_t i;
 
-	if(!st || !st->buf) {
-		er.encoded = -1;
-		er.failed_type = td;
-		er.structure_ptr = sptr;
-		return er;
-	}
+	if(!st || !st->buf)
+		_ASN_ENCODE_FAILED;
 
 	er.encoded = 0;
 
@@ -621,6 +617,8 @@
 	}
 
 	return er;
+cb_failed:
+	_ASN_ENCODE_FAILED;
 }
 
 asn_enc_rval_t
@@ -636,7 +634,8 @@
 	if(!st || !st->buf)
 		_ASN_ENCODE_FAILED;
 
-	_ASN_CALLBACK(st->buf, st->size);
+	if(cb(st->buf, st->size, app_key) < 0)
+		_ASN_ENCODE_FAILED;
 	er.encoded = st->size;
 
 	return er;
diff --git a/skeletons/REAL.c b/skeletons/REAL.c
index c6d90f3..6d3e55e 100644
--- a/skeletons/REAL.c
+++ b/skeletons/REAL.c
@@ -12,7 +12,7 @@
 #undef	INT_MAX
 #define	INT_MAX	((int)(((unsigned int)-1) >> 1))
 
-static const double real_zero;
+static volatile double real_zero = 0.0;
 #ifndef	NAN
 #define	NAN	(real_zero/real_zero)
 #endif
diff --git a/skeletons/asn_internal.h b/skeletons/asn_internal.h
index e8a6993..a7690eb 100644
--- a/skeletons/asn_internal.h
+++ b/skeletons/asn_internal.h
@@ -46,9 +46,9 @@
 /*
  * Invoke the application-supplied callback and fail, if something is wrong.
  */
-#define	__ASN_E_cbc(buf, size)	(cb((buf), (size), app_key) == -1)
+#define	__ASN_E_cbc(buf, size)	(cb((buf), (size), app_key) < 0)
 #define	_ASN_E_CALLBACK(foo)	do {					\
-		if(foo)	_ASN_ENCODE_FAILED;				\
+		if(foo)	goto cb_failed;					\
 	} while(0)
 #define	_ASN_CALLBACK(buf, size)					\
 	_ASN_E_CALLBACK(__ASN_E_cbc(buf, size))
diff --git a/skeletons/constr_CHOICE.c b/skeletons/constr_CHOICE.c
index 4db6d7b..46fd521 100644
--- a/skeletons/constr_CHOICE.c
+++ b/skeletons/constr_CHOICE.c
@@ -588,6 +588,8 @@
 	if(!(flags & XER_F_CANONICAL)) _i_ASN_TEXT_INDENT(1, ilevel - 1);
 
 	return er;
+cb_failed:
+	_ASN_ENCODE_FAILED;
 }
 
 int
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index 07c7772..83da765 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -623,6 +623,8 @@
 	if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
 
 	return er;
+cb_failed:
+	_ASN_ENCODE_FAILED;
 }
 
 int
diff --git a/skeletons/constr_SEQUENCE_OF.c b/skeletons/constr_SEQUENCE_OF.c
index b99831f..3d526d0 100644
--- a/skeletons/constr_SEQUENCE_OF.c
+++ b/skeletons/constr_SEQUENCE_OF.c
@@ -128,5 +128,7 @@
 	if(!xcan) _i_ASN_TEXT_INDENT(1, ilevel - 1);
 
 	return er;
+cb_failed:
+	_ASN_ENCODE_FAILED;
 }
 
diff --git a/skeletons/xer_encoder.c b/skeletons/xer_encoder.c
index 3c97a8f..d3f04d6 100644
--- a/skeletons/xer_encoder.c
+++ b/skeletons/xer_encoder.c
@@ -19,12 +19,7 @@
 	size_t mlen;
 	int xcan = (xer_flags & XER_F_CANONICAL) ? 1 : 2;
 
-	if(!td || !sptr) {
-		er.encoded = -1;
-		er.failed_type = td;
-		er.structure_ptr = sptr;
-		return er;
-	}
+	if(!td || !sptr) goto cb_failed;
 
 	mname = td->name;
 	mlen = strlen(mname);
@@ -34,11 +29,13 @@
 	tmper = td->xer_encoder(td, sptr, 1, xer_flags, cb, app_key);
 	if(tmper.encoded == -1) return tmper;
 
-	_ASN_CALLBACK3("</", xcan, mname, mlen, ">\n",xcan);
+	_ASN_CALLBACK3("</", 2, mname, mlen, ">\n", xcan);
 
-	er.encoded = 2 + (2 * xcan) + (2 * mlen) + tmper.encoded;
+	er.encoded = 4 + xcan + (2 * mlen) + tmper.encoded;
 
 	return er;
+cb_failed:
+	_ASN_ENCODE_FAILED;
 }
 
 /*