updated for version 7.0109
diff --git a/src/gui_mac.c b/src/gui_mac.c
index 70393be..8f54249 100644
--- a/src/gui_mac.c
+++ b/src/gui_mac.c
@@ -3865,8 +3865,7 @@
     else
     {
 	font = gui_mac_find_font(font_name);
-	STRNCPY(used_font_name, font_name, sizeof(used_font_name));
-	used_font_name[sizeof(used_font_name) - 1] = NUL;
+	vim_strncpy(used_font_name, font_name, sizeof(used_font_name) - 1);
 
 	if (font == NOFONT)
 	    return FAIL;
@@ -6201,8 +6200,7 @@
 	if (name[0] > IOSIZE)
 	    name[0] = IOSIZE - 1;
 #endif
-	STRNCPY(textfield, &name[1], name[0]);
-	textfield[name[0]] = NUL;
+	vim_strncpy(textfield, &name[1], name[0]);
     }
 
     /* Restore the original graphical port */
@@ -6522,8 +6520,7 @@
 #endif
 
     /* Start filling fname with file.name  */
-    STRNCPY(filenamePtr, &file.name[1], file.name[0]);
-    filenamePtr[file.name[0]] = 0; /* NULL terminate the string */
+    vim_strncpy(filenamePtr, &file.name[1], file.name[0]);
 
     /* Get the info about the file specified in FSSpec */
     theCPB.dirInfo.ioFDirIndex = 0;
@@ -6625,8 +6622,7 @@
 
 	/* Put the new directoryName in front of the current fname */
 	STRCPY(temporaryPtr, filenamePtr);
-	STRNCPY(filenamePtr, &directoryName[1], directoryName[0]);
-	filenamePtr[directoryName[0]] = 0; /* NULL terminate the string */
+	vim_strncpy(filenamePtr, &directoryName[1], directoryName[0]);
 	STRCAT(filenamePtr, ":");
 	STRCAT(filenamePtr, temporaryPtr);
     }
@@ -6660,8 +6656,7 @@
     {
 	/* Add the volume name */
 	STRCPY(temporaryPtr, filenamePtr);
-	STRNCPY(filenamePtr, &directoryName[1], directoryName[0]);
-	filenamePtr[directoryName[0]] = 0; /* NULL terminate the string */
+	vim_strncpy(filenamePtr, &directoryName[1], directoryName[0]);
 	STRCAT(filenamePtr, ":");
 	STRCAT(filenamePtr, temporaryPtr);
 
diff --git a/src/gui_motif.c b/src/gui_motif.c
index 408b588..14f65ca 100644
--- a/src/gui_motif.c
+++ b/src/gui_motif.c
@@ -2620,10 +2620,7 @@
 	if (p == NULL || dialogStatus < 0)
 	    *textfield = NUL;
 	else
-	{
-	    STRNCPY(textfield, p, IOSIZE);
-	    textfield[IOSIZE - 1] = NUL;
-	}
+	    vim_strncpy(textfield, p, IOSIZE - 1);
     }
 
     suppress_dialog_mnemonics(dialogform);
diff --git a/src/mbyte.c b/src/mbyte.c
index ff165fa..a006312 100644
--- a/src/mbyte.c
+++ b/src/mbyte.c
@@ -701,6 +701,7 @@
 		     * where mblen() returns 0 for invalid character.
 		     * Therefore, following condition includes 0.
 		     */
+		    (void)mblen(NULL, 0);	/* First reset the state. */
 		    if (mblen(buf, (size_t)1) <= 0)
 			n = 2;
 		    else
diff --git a/src/misc2.c b/src/misc2.c
index 75d8a4d..8434ec6 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1372,7 +1372,7 @@
 vim_strncpy(to, from, len)
     char_u	*to;
     char_u	*from;
-    int		len;
+    size_t	len;
 {
     STRNCPY(to, from, len);
     to[len] = NUL;
@@ -2957,8 +2957,7 @@
 {
     char_u	dir[MAXPATHL];
 
-    STRNCPY(dir, fname, MAXPATHL);
-    dir[MAXPATHL - 1] = NUL;
+    vim_strncpy(dir, fname, MAXPATHL - 1);
     *gettail_sep(dir) = NUL;
     return mch_chdir((char *)dir) == 0 ? OK : FAIL;
 }
@@ -3907,8 +3906,7 @@
 	if (!vim_isAbsName(rel_fname) && len + 1 < MAXPATHL)
 	{
 	    /* Make the start dir an absolute path name. */
-	    STRNCPY(ff_expand_buffer, rel_fname, len);
-	    ff_expand_buffer[len] = NUL;
+	    vim_strncpy(ff_expand_buffer, rel_fname, len);
 	    ff_search_ctx->ffsc_start_dir = FullName_save(ff_expand_buffer,
 								       FALSE);
 	}
@@ -4810,7 +4808,7 @@
      * device/inode (unix) or the full path name (not Unix). */
     if (path_with_url(fname))
     {
-	STRNCPY(ff_expand_buffer, fname, MAXPATHL);
+	vim_strncpy(ff_expand_buffer, fname, MAXPATHL - 1);
 #ifdef UNIX
 	url = TRUE;
 #endif
@@ -5393,9 +5391,10 @@
 }
 
 /*
- * Get user name from machine-specific function and cache it.
+ * Get user name from machine-specific function.
  * Returns the user name in "buf[len]".
- * Some systems are quite slow in obtaining the user name (Windows NT).
+ * Some systems are quite slow in obtaining the user name (Windows NT), thus
+ * cache the result.
  * Returns OK or FAIL.
  */
     int
@@ -5410,7 +5409,7 @@
 	username = vim_strsave(buf);
     }
     else
-	STRNCPY(buf, username, len);
+	vim_strncpy(buf, username, len - 1);
     return OK;
 }
 
diff --git a/src/os_msdos.c b/src/os_msdos.c
index a70d58e..36304cc 100644
--- a/src/os_msdos.c
+++ b/src/os_msdos.c
@@ -1515,8 +1515,7 @@
 {
     if (!force && mch_isFullName(fname))	/* already expanded */
     {
-	STRNCPY(buf, fname, len);
-	buf[len - 1] = NUL;
+	vim_strncpy(buf, fname, len - 1);
 	slash_adjust(buf);
 	return OK;
     }
@@ -1533,8 +1532,7 @@
 	if (!_truename(fname, fullpath))
 	    return FAIL;
 	slash_adjust(fullpath);	    /* Only needed when 'shellslash' set */
-	STRNCPY(buf, fullpath, len);
-	buf[len - 1] = NUL;
+	vim_strncpy(buf, fullpath, len - 1);
 	return OK;
 
 # else  /* Old code, to be deleted... */
@@ -3074,9 +3072,8 @@
     int		len)
 {
 #ifdef DJGPP
-    STRNCPY(s, "PC (32 bits Vim)", len);
+    vim_strncpy(s, "PC (32 bits Vim)", len - 1);
 #else
-    STRNCPY(s, "PC (16 bits Vim)", len);
+    vim_strncpy(s, "PC (16 bits Vim)", len - 1);
 #endif
-    s[len - 1] = NUL;	/* make sure it's terminated */
 }
diff --git a/src/os_unix.c b/src/os_unix.c
index e22f622..9952266 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -2072,7 +2072,7 @@
     int	    len;
 {
 #ifdef VMS
-    STRNCPY((char *)s, cuserid(NULL), len);
+    vim_strncpy((char *)s, cuserid(NULL), len - 1);
     return OK;
 #else
     return mch_get_uname(getuid(), s, len);
@@ -2095,8 +2095,7 @@
     if ((pw = getpwuid(uid)) != NULL
 	    && pw->pw_name != NULL && *(pw->pw_name) != NUL)
     {
-	STRNCPY(s, pw->pw_name, len);
-	s[len - 1] = NUL;
+	vim_strncpy(s, (char_u *)pw->pw_name, len - 1);
 	return OK;
     }
 #endif
@@ -2119,8 +2118,7 @@
     if (uname(&vutsname) < 0)
 	*s = NUL;
     else
-	STRNCPY(s, vutsname.nodename, len);
-    s[len - 1] = NUL;	/* make sure it's terminated */
+	vim_strncpy(s, (char_u *)vutsname.nodename, len - 1);
 }
 #else /* HAVE_SYS_UTSNAME_H */
 
@@ -2300,8 +2298,7 @@
 		    retval = FAIL;
 		else
 		{
-		    STRNCPY(buf, fname, p - fname);
-		    buf[p - fname] = NUL;
+		    vim_strncpy(buf, fname, p - fname);
 		    if (mch_chdir((char *)buf))
 			retval = FAIL;
 		    else
@@ -2630,8 +2627,7 @@
 	    STRCPY(buf, "./");
 	else
 	{
-	    STRNCPY(buf, p, e - p);
-	    buf[e - p] = NUL;
+	    vim_strncpy(buf, p, e - p);
 	    add_pathsep(buf);
 	}
 	STRCAT(buf, name);
diff --git a/src/quickfix.c b/src/quickfix.c
index 281cac8..d465787 100644
--- a/src/quickfix.c
+++ b/src/quickfix.c
@@ -443,7 +443,8 @@
 	{
 	    if (buflnum > lnumlast)
 		break;
-	    STRNCPY(IObuff, ml_get_buf(buf, buflnum++, FALSE), CMDBUFFSIZE - 2);
+	    vim_strncpy(IObuff, ml_get_buf(buf, buflnum++, FALSE),
+							     CMDBUFFSIZE - 2);
 	}
 	else if (fgets((char *)IObuff, CMDBUFFSIZE - 2, fd) == NULL)
 	    break;
@@ -516,8 +517,7 @@
 		else if ((i = (int)fmt_ptr->addr[5]) > 0)	/* %m */
 		{
 		    len = (int)(regmatch.endp[i] - regmatch.startp[i]);
-		    STRNCPY(errmsg, regmatch.startp[i], len);
-		    errmsg[len] = NUL;
+		    vim_strncpy(errmsg, regmatch.startp[i], len);
 		}
 		if ((i = (int)fmt_ptr->addr[6]) > 0)		/* %r */
 		    tail = regmatch.startp[i];
diff --git a/src/regexp.c b/src/regexp.c
index ae1bfd1..7ff271b 100644
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -3047,7 +3047,7 @@
  * Copy of "rmm_maxcol": maximum column to search for a match.  Zero when
  * there is no maximum.
  */
-static int	ireg_maxcol;
+static colnr_T	ireg_maxcol;
 
 /*
  * Sometimes need to save a copy of a line.  Since alloc()/free() is very
@@ -6866,10 +6866,7 @@
 		len = submatch_mmatch->endpos[no].col
 					  - submatch_mmatch->startpos[no].col;
 		if (round == 2)
-		{
-		    STRNCPY(retval, s, len);
-		    retval[len] = NUL;
-		}
+		    vim_strncpy(retval, s, len);
 		++len;
 	    }
 	    else
diff --git a/src/regexp.h b/src/regexp.h
index fee6cc4..09c8d0c 100644
--- a/src/regexp.h
+++ b/src/regexp.h
@@ -64,7 +64,7 @@
     lpos_T		startpos[NSUBEXP];
     lpos_T		endpos[NSUBEXP];
     int			rmm_ic;
-    int			rmm_maxcol;	/* when not zero: maximum column */
+    colnr_T		rmm_maxcol;	/* when not zero: maximum column */
 } regmmatch_T;
 
 /*
diff --git a/src/tag.c b/src/tag.c
index a06edeb..f46ae72 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -1558,8 +1558,8 @@
 				{
 				    if (STRLEN(fullpath_ebuf) > LSIZE)
 					  EMSG2(_("E430: Tag file path truncated for %s\n"), ebuf);
-				    STRNCPY(tag_fname, fullpath_ebuf, LSIZE);
-				    tag_fname[LSIZE] = NUL;
+				    vim_strncpy(tag_fname, fullpath_ebuf,
+								    MAXPATHL);
 				    ++incstack_idx;
 				    is_etag = 0; /* we can include anything */
 				}
@@ -2090,8 +2090,7 @@
 				{
 				    mfp->len = len + 1; /* include the NUL */
 				    p = mfp->match;
-				    STRNCPY(p, tagp.command + 2, len);
-				    p[len] = NUL;
+				    vim_strncpy(p, tagp.command + 2, len);
 				}
 			    }
 			    else
@@ -2107,8 +2106,7 @@
 			    {
 				mfp->len = len + 1; /* include the NUL */
 				p = mfp->match;
-				STRNCPY(p, tagp.tagname, len);
-				p[len] = NUL;
+				vim_strncpy(p, tagp.tagname, len);
 			    }
 
 			    /* if wanted, re-read line to get long form too */
@@ -2436,10 +2434,8 @@
 	    STRCPY(gettail(buf), "tags");
 	}
 	else
-	{
-	    STRNCPY(buf, ((char_u **)(tag_fnames.ga_data))[hf_idx++], MAXPATHL);
-	    buf[MAXPATHL - 1] = NUL;
-	}
+	    vim_strncpy(buf, ((char_u **)(tag_fnames.ga_data))[hf_idx++],
+								MAXPATHL - 1);
     }
     else
     {
@@ -3186,8 +3182,8 @@
 	if (retval != NULL)
 	{
 	    STRCPY(retval, tag_fname);
-	    STRNCPY(retval + (p - tag_fname), fname,
-						  MAXPATHL - (p - tag_fname));
+	    vim_strncpy(retval + (p - tag_fname), fname,
+					      MAXPATHL - (p - tag_fname) - 1);
 	    /*
 	     * Translate names like "src/a/../b/file.c" into "src/b/file.c".
 	     */
@@ -3586,7 +3582,7 @@
 	len = end - start;
 	if (len > sizeof(buf) - 1)
 	    len = sizeof(buf) - 1;
-	STRNCPY(buf, start, len);
+	vim_strncpy(buf, start, len);
     }
     buf[len] = NUL;
     return dict_add_nr_str(dict, field_name, 0L, buf);
diff --git a/src/testdir/test59.in b/src/testdir/test59.in
index 61f22d5..6b3a30d 100644
--- a/src/testdir/test59.in
+++ b/src/testdir/test59.in
@@ -10,10 +10,10 @@
 :e!
 :set fenc=
 :" First generate a .spl file from a .dic and a .aff file.
-gg:/^affstart1/+1,/^affend1/-1w Xtest.aff
-gg:/^dicstart/+1,/^dicend/-1w Xtest.dic
+gg:/^affstart1/+1,/^affend1/-1w! Xtest.aff
+gg:/^dicstart/+1,/^dicend/-1w! Xtest.dic
 :set enc=utf-8
-:mkspell Xtest Xtest
+:mkspell! Xtest Xtest
 :"
 :" use that spell file
 :set spl=Xtest.utf-8.spl
@@ -75,30 +75,29 @@
 :" also use an addition file
 gg:/^addstart/+1,/^addend/-1w! Xtest.utf-8.add
 :mkspell! Xtest.utf-8.add.spl Xtest.utf-8.add
-:set spl=en
 :set spellfile=Xtest.utf-8.add
 /^test2:
 ]s:let str = spellbadword()
 :$put =str
-:set spl=en_us
+:set spl=Xtest_us.utf-8.spl
 /^test2:
 ]smm:let str = spellbadword()
 :$put =str
 `m]s:let str = spellbadword()
 :$put =str
-:set spl=en_gb
+:set spl=Xtest_gb.utf-8.spl
 /^test2:
 ]smm:let str = spellbadword()
 :$put =str
 `m]s:let str = spellbadword()
 :$put =str
-:set spl=en_nz
+:set spl=Xtest_nz.utf-8.spl
 /^test2:
 ]smm:let str = spellbadword()
 :$put =str
 `m]s:let str = spellbadword()
 :$put =str
-:set spl=en_ca
+:set spl=Xtest_ca.utf-8.spl
 /^test2:
 ]smm:let str = spellbadword()
 :$put =str