make one-pass parsing for object identifier
diff --git a/skeletons/OBJECT_IDENTIFIER.c b/skeletons/OBJECT_IDENTIFIER.c
index 2939f25..066d562 100644
--- a/skeletons/OBJECT_IDENTIFIER.c
+++ b/skeletons/OBJECT_IDENTIFIER.c
@@ -648,12 +648,11 @@
 	long *arcs, unsigned int arcs_slots, const char **opt_oid_text_end) {
 	unsigned int arcs_count = 0;
 	const char *oid_end;
-	const char *value_start;
 	enum {
 		ST_LEADSPACE,
 		ST_TAILSPACE,
+		ST_AFTERVALUE,	/* Next character ought to be '.' or a space */
 		ST_WAITDIGITS,	/* Next character is expected to be a digit */
-		ST_DIGITS	/* INVARIANT: value_start != 0 in this state */
 	} state = ST_LEADSPACE;
 
 	if(!oid_text || oid_txt_length < -1 || (arcs_slots && !arcs)) {
@@ -665,13 +664,16 @@
 	if(oid_txt_length == -1)
 		oid_txt_length = strlen(oid_text);
 
-#define	_OID_CAPTURE_ARC(value_start, oid_text)		do {	\
+#define	_OID_CAPTURE_ARC(oid_text, oid_end)		do {	\
+	const char *endp = oid_end;				\
 	long value;						\
-	switch(asn_strtol(value_start, oid_text, &value)) {	\
+	switch(asn_strtol_lim(oid_text, &endp, &value)) {	\
+	case ASN_STRTOL_EXTRA_DATA:				\
 	case ASN_STRTOL_OK:					\
 		if(arcs_count < arcs_slots)			\
 			arcs[arcs_count] = value;		\
 		arcs_count++;					\
+		oid_text = endp - 1;				\
 		break;						\
 	case ASN_STRTOL_ERROR_RANGE:				\
 		if(opt_oid_text_end)				\
@@ -679,6 +681,7 @@
 		errno = ERANGE;					\
 		return -1;					\
 	case ASN_STRTOL_ERROR_INVAL:				\
+	case ASN_STRTOL_EXPECT_MORE:				\
 		if(opt_oid_text_end)				\
 			*opt_oid_text_end = oid_text;		\
 		errno = EINVAL;					\
@@ -693,23 +696,24 @@
 		case ST_LEADSPACE:
 		case ST_TAILSPACE:
 			continue;
-		case ST_DIGITS:
-			_OID_CAPTURE_ARC(value_start, oid_text);
+		case ST_AFTERVALUE:
 			state = ST_TAILSPACE;
 			continue;
 		case ST_WAITDIGITS:
-			break;
+			break;	/* Digits expected after ".", got whitespace */
 		}
+		break;
 	    case 0x2e:	/* '.' */
 		switch(state) {
 		case ST_LEADSPACE:
-		case ST_WAITDIGITS:
-			break;
 		case ST_TAILSPACE:
-			state = ST_WAITDIGITS;
+		case ST_WAITDIGITS:
+			if(opt_oid_text_end)
+				*opt_oid_text_end = oid_text;
+			errno = EINVAL;	/* Broken OID */
+			return -1;
 			break;
-		case ST_DIGITS:
-			_OID_CAPTURE_ARC(value_start, oid_text);
+		case ST_AFTERVALUE:
 			state = ST_WAITDIGITS;
 			continue;
 		}
@@ -718,14 +722,15 @@
 	    case 0x35: case 0x36: case 0x37: case 0x38: case 0x39:
 		switch(state) {
 		case ST_TAILSPACE:
-			state = ST_WAITDIGITS;
-			break;
+		case ST_AFTERVALUE:
+			if(opt_oid_text_end)
+				*opt_oid_text_end = oid_text;
+			errno = EINVAL;	/* "1. 1" => broken OID */
+			return -1;
 		case ST_LEADSPACE:
 		case ST_WAITDIGITS:
-			state = ST_DIGITS;
-			value_start = oid_text;
-			continue;
-		case ST_DIGITS:
+			_OID_CAPTURE_ARC(oid_text, oid_end);
+			state = ST_AFTERVALUE;
 			continue;
 		}
 		break;
@@ -744,12 +749,10 @@
 	switch(state) {
 	case ST_LEADSPACE:
 		return 0; /* No OID found in input data */
-	case ST_DIGITS:
-		_OID_CAPTURE_ARC(value_start, oid_text);
-		return arcs_count;
 	case ST_WAITDIGITS:
 		errno = EINVAL;	/* Broken OID */
 		return -1;
+	case ST_AFTERVALUE:
 	case ST_TAILSPACE:
 		return arcs_count;
 	}