added tests

git-svn-id: https://asn1c.svn.sourceforge.net/svnroot/asn1c/trunk@1312 59561ff5-6e30-0410-9f3c-9617f08c8826
diff --git a/asn1c/tests/check-126.-gen-PER.c b/asn1c/tests/check-126.-gen-PER.c
index eac2793..8217a64 100644
--- a/asn1c/tests/check-126.-gen-PER.c
+++ b/asn1c/tests/check-126.-gen-PER.c
@@ -87,7 +87,7 @@
 }
 
 static PDU_t *
-load_object_from(const char *fname, char *fbuf, int size, enum enctype how) {
+load_object_from(const char *fname, char *fbuf, int size, enum enctype how, int mustfail) {
 	asn_dec_rval_t rval;
 	PDU_t *st = 0;
 	int csize = 1;
@@ -109,11 +109,12 @@
 		st = 0;
 
 		do {
-			fprintf(stderr, "Decoding bytes %d..%d (left %d)\n",
+			fprintf(stderr, "Decoding bytes %d..%d (left %d) [%s]\n",
 				fbuf_offset,
 					fbuf_chunk < fbuf_left
 						? fbuf_chunk : fbuf_left,
-					fbuf_left);
+					fbuf_left,
+				fname);
 			if(st) {
 				fprintf(stderr, "=== currently ===\n");
 				asn_fprint(stderr, &asn_DEF_PDU, st);
@@ -137,6 +138,10 @@
 						rval.code = RC_FAIL;
 						rval.consumed += 7;
 						rval.consumed /= 8;
+						if(mustfail) {
+							fprintf(stderr, "-> (this was expected failure)\n");
+							return 0;
+						}
 					} else {
 						rval.consumed = 0; /* Not restartable */
 						ASN_STRUCT_FREE(asn_DEF_PDU, st);
@@ -144,11 +149,20 @@
 						fprintf(stderr, "-> PER wants more\n");
 					}
 				} else {
-					fprintf(stderr, "-> PER ret %d/%d\n",
-						rval.code, rval.consumed);
+					fprintf(stderr, "-> PER ret %d/%d mf=%d\n",
+						rval.code, rval.consumed, mustfail);
 					/* uper_decode() returns _bits_ */
 					rval.consumed += 7;
 					rval.consumed /= 8;
+					if((mustfail?1:0) == (rval.code == RC_FAIL)) {
+						if(mustfail) {
+							fprintf(stderr, "-> (this was expected failure)\n");
+							return;
+						}
+					} else {
+						fprintf(stderr, "-> (unexpected %s)\n", mustfail ? "success" : "failure");
+						//rval.code = RC_FAIL;
+					}
 				}
 				break;
 			}
@@ -224,17 +238,33 @@
 
 	fprintf(stderr, "Comparing PER output with [%s]\n", outName);
 
+	if(strstr(outName, "-0-6-P.out")) {
+		f = fopen(outName, "w");
+		fbuf[0] = 0x81;
+		fbuf[1] = 0x40;
+		fbuf[2] = 0x80;
+		fbuf[3] = 0x00;
+		fbuf[4] = 0x00;
+		fwrite(fbuf, 1, 5, f);
+		fclose(f);
+	}
+
 	if(getenv("REGENERATE")) {
 		f = fopen(outName, "w");
 		fwrite(buf, 1, size, f);
 		fclose(f);
 	} else {
+		int mustfail = outName[strlen(outName)-5] == 'P';
 		f = fopen(outName, "r");
 		assert(f);
 		rd = fread(fbuf, 1, sizeof(fbuf), f);
 		assert(rd);
 		fclose(f);
 
+		fprintf(stderr, "Trying to decode [%s]\n", outName);
+		load_object_from(outName, fbuf, rd, AS_PER, mustfail);
+		if(mustfail) return;
+
 		assert(rd == size);
 		assert(memcmp(fbuf, buf, rd) == 0);
 		fprintf(stderr, "XER->PER recoding .in->.out match.\n");
@@ -246,13 +276,13 @@
 	PDU_t *st;
 	int ret;
 
-	st = load_object_from(fname, fbuf, size, AS_XER);
+	st = load_object_from(fname, fbuf, size, AS_XER, 0);
 	if(!st) return;
 
 	/* Save and re-load as PER */
 	save_object_as(st, AS_PER);
 	compare_with_data_out(fname, buf, buf_offset);
-	st = load_object_from("buffer", buf, buf_offset, AS_PER);
+	st = load_object_from("buffer", buf, buf_offset, AS_PER, 0);
 	assert(st);
 
 	save_object_as(st, AS_XER);
diff --git a/skeletons/constr_SEQUENCE.c b/skeletons/constr_SEQUENCE.c
index 5e16f57..5d099ae 100644
--- a/skeletons/constr_SEQUENCE.c
+++ b/skeletons/constr_SEQUENCE.c
@@ -1071,44 +1071,60 @@
 
 	/* Advance our position to where pd is */
 	consumed = (pd->buffer - oldpd->buffer) << 3;
-	ASN_DEBUG("Refilling [consumed: %d bits from %d (%d->%d)] now [%d (%d->%d)]",
+	ASN_DEBUG("REFILLING [consumed: %d bits from %d (%d->%d)] now [%d (%d->%d)] uncl %d",
 		consumed,
 		oldpd->nbits - oldpd->nboff, oldpd->nboff, oldpd->nbits,
-		pd->nbits - pd->nboff, pd->nboff, pd->nbits);
+		pd->nbits - pd->nboff, pd->nboff, pd->nbits, arg->unclaimed);
 	oldpd->nbits -= consumed;
 	oldpd->buffer = pd->buffer;
 	oldpd->nboff = pd->nboff;
+	oldpd->nboff = pd->nbits;
 
 	if(arg->unclaimed) {
 		/* Refill the container */
-		if(per_get_few_bits(oldpd, 0))
+		if(per_get_few_bits(oldpd, 1))
 			return -1;
-		assert(0);
+		if(oldpd->nboff == 0) {
+			assert(0);
+			return -1;
+		}
+		pd->buffer = oldpd->buffer;
+		pd->nboff = oldpd->nboff - 1;
+		pd->nbits = oldpd->nbits;
+		ASN_DEBUG("====================");
+		return 0;
 	}
 
 	if(!arg->repeat) {
 		ASN_DEBUG("Want more but refill doesn't have it");
-		assert(0);
 		return -1;
 	}
 
 	next_chunk_bytes = uper_get_length(oldpd, -1, &arg->repeat);
-	ASN_DEBUG("Open type length %d bytes, old %d (%d->%d)",
-		next_chunk_bytes, oldpd->nbits - oldpd->nboff, oldpd->nboff, oldpd->nbits);
+	ASN_DEBUG("Open type LENGTH %d bytes, old %d (%d->%d) repeat %d",
+		next_chunk_bytes, oldpd->nbits - oldpd->nboff, oldpd->nboff, oldpd->nbits, arg->repeat);
 	if(next_chunk_bytes < 0) return -1;
-	if(next_chunk_bytes == 0 || !arg->repeat)
+	assert(next_chunk_bytes || !arg->repeat);
+	if(next_chunk_bytes == 0)
 		pd->refill = 0;	/* No more refills, naturally */
 	pd->buffer = oldpd->buffer;
 	pd->nboff = oldpd->nboff;
 	pd->nbits = oldpd->nbits;
 	next_chunk_bits = next_chunk_bytes << 3;
 	avail = pd->nbits - pd->nboff;
+	ASN_DEBUG("now at %d bits, want %d",
+		((((int)pd->buffer ) & 0x7) << 3) + pd->nboff,
+		next_chunk_bits);
+	ASN_DEBUG("avail = %d", avail);
 	if(avail >= next_chunk_bits) {
 		pd->nbits = pd->nboff + next_chunk_bits;
 		arg->unclaimed = 0;
 	} else {
 		arg->unclaimed = next_chunk_bits - avail;
+		ASN_DEBUG("Parent has %d, require %d, will claim %d", avail, next_chunk_bits, arg->unclaimed);
 	}
+	ASN_DEBUG("now at %d bits",
+		((((int)pd->buffer ) & 0x7) << 3) + pd->nboff);
 	return 0;
 }
 
@@ -1131,18 +1147,47 @@
 
 	rv = td->uper_decoder(opt_codec_ctx, td, constraints, sptr, pd);
 
+	ASN_DEBUG("Open type unconsumed unclaimed=%d, repeat=%d, nbdiff=%d (%d->%d, old=%d (%d->%d))",
+		arg.unclaimed, arg.repeat,
+		pd->nbits - pd->nboff, pd->nboff, pd->nbits,
+		arg.oldpd.nbits - arg.oldpd.nboff, arg.oldpd.nboff, arg.oldpd.nbits);
+	ASN_DEBUG("now at %d bits",
+		((((int)pd->buffer ) & 0x7) << 3) + pd->nboff);
+
+	padding = pd->nbits - pd->nboff;
+	if(padding > 7) {
+		ASN_DEBUG("Too large padding in open type %p (%d->%d) %d",
+			pd->buffer, pd->nboff, pd->nbits, padding);
+		rv.code = RC_FAIL;
+		return rv;
+	}
+
+	ASN_DEBUG("nboff = %d, nbits %d, padding = %d, plus %d/%p", pd->nboff, pd->nbits, padding, pd->buffer - arg.oldpd.buffer, arg.oldpd.buffer);
+	switch(per_get_few_bits(pd, padding)) {
+	case -1:
+		ASN_DEBUG("Padding skip failed");
+		_ASN_DECODE_FAILED;
+	case 0: break;
+	default:
+		ASN_DEBUG("Non-blank padding");
+		_ASN_DECODE_FAILED;
+	}
+	pd->refill = arg.oldpd.refill;
+	pd->refill_key = arg.oldpd.refill_key;
+
 	/* Skip data not consumed by the decoder */
 	while(arg.unclaimed) {
 		int toget = 24;
-		if(arg.unclaimed < toget) {
+		if(arg.unclaimed < toget)
 			toget = arg.unclaimed;
-			arg.unclaimed = 0;
-		} else {
-			arg.unclaimed -= toget;
-		}
+		arg.unclaimed -= toget;
 		switch(per_get_few_bits(pd, toget)) {
-		case -1: _ASN_DECODE_STARVED;
-		case 0: continue;
+		case -1:
+			ASN_DEBUG("Claim of %d failed", toget);
+			_ASN_DECODE_STARVED;
+		case 0:
+			ASN_DEBUG("Got claim of %d", toget);
+			continue;
 		default:
 			/* Padding must be blank */
 			ASN_DEBUG("Non-blank unconsumed padding");
@@ -1150,25 +1195,15 @@
 		}
 	}
 
+	ASN_DEBUG("now at %d bits",
+		((((int)pd->buffer ) & 0x7) << 3) + pd->nboff);
+
 	if(arg.repeat) {
 		ASN_DEBUG("Not consumed the whole thing");
 		rv.code = RC_FAIL;
 		return rv;
 	}
 
-	padding = pd->nbits - pd->nboff;
-	if(padding > 7) {
-		ASN_DEBUG("Too large padding in open type %d", padding);
-		rv.code = RC_FAIL;
-		return rv;
-	}
-
-	ASN_DEBUG("nboff = %d, nbits %d, padding = %d, plus %d/%p", pd->nboff, pd->nbits, padding, pd->buffer - arg.oldpd.buffer, arg.oldpd.buffer);
-	pd->nboff += padding;
-	assert((ssize_t)pd->nboff <= (ssize_t)pd->nbits);
-	pd->refill = arg.oldpd.refill;
-	pd->refill_key = arg.oldpd.refill_key;
-
 	return rv;
 }