--- generic/tclCmdAH.c	Mon Dec 16 16:47:39 2002
+++ generic/tclCmdAH-nformat.c	Mon Dec 16 18:29:37 2002
@@ -1951,6 +1951,7 @@
 #   define DOUBLE_VALUE 3
 #   define STRING_VALUE 4
 #   define WIDE_VALUE 5
+#   define NO_VALUE -1
 #   define MAX_FLOAT_SIZE 320
 
     Tcl_Obj *resultPtr;  	/* Where result is stored finally. */
@@ -2232,6 +2233,39 @@
 		    size += (width - stringLen);
 		}
 		break;
+	    case 'N': {
+		/*
+		 * Get the current byte count of the result string.
+		 */
+		int objlen = -1;
+
+		whichValue = NO_VALUE;
+		Tcl_GetStringFromObj(resultPtr, &objlen);
+		if (Tcl_ObjSetVar2(interp, objv[objIndex], NULL,
+			Tcl_NewIntObj(objlen), TCL_LEAVE_ERR_MSG) == NULL) {
+			goto fmtError;
+		}
+
+		break;
+	    }
+	    case 'n': {
+		/*
+		 * Get the current character count of the result string.
+		 * Very similar to %N.
+		 */
+		int objlen = -1;
+		char * resultStr = NULL;
+
+		whichValue = NO_VALUE;
+		resultStr = Tcl_GetStringFromObj(resultPtr, &objlen);
+		if (Tcl_ObjSetVar2(interp, objv[objIndex], NULL,
+			Tcl_NewIntObj(Tcl_NumUtfChars(resultStr, objlen)),
+			TCL_LEAVE_ERR_MSG) == NULL) {
+			goto fmtError;
+		}
+
+		break;
+	    }
 	    case 'c':
 		if (Tcl_GetLongFromObj(interp,	/* INTL: Tcl source. */
 			objv[objIndex], &intValue) != TCL_OK) {
@@ -2281,7 +2315,7 @@
 	}
 	if (noPercent) {
 	    Tcl_AppendToObj(resultPtr, ptrValue, size);
-	} else {
+	} else if (whichValue != NO_VALUE) {
 	    if (size > dstSize) {
 	        if (dst != staticBuf) {
 		    ckfree(dst);
