utf_safe_read_char_adv(char_u **s, size_t *n)
{
    int		c, k;

    if (*n == 0) // end of buffer
	return 0;

    k = utf8len_tab_zero[**s];

    if (k == 1)
    {
	// ASCII character or NUL
	(*n)--;
	return *(*s)++;
    }

    if ((size_t)k <= *n)
    {
	// We have a multibyte sequence and it isn't truncated by buffer
	// limits so utf_ptr2char() is safe to use. Or the first byte is
	// illegal (k=0), and it's also safe to use utf_ptr2char().
	c = utf_ptr2char(*s);

	// On failure, utf_ptr2char() returns the first byte, so here we
	// check equality with the first byte. The only non-ASCII character
	// which equals the first byte of its own UTF-8 representation is
	// U+00C3 (UTF-8: 0xC3 0x83), so need to check that special case too.
	// It's safe even if n=1, else we would have k=2 > n.
	if (c != (int)(**s) || (c == 0xC3 && (*s)[1] == 0x83))
	{
	    // byte sequence was successfully decoded
	    *s += k;
	    *n -= k;
	    return c;
	}
    }

    // byte sequence is incomplete or illegal
    return -1;
}
utf_safe_read_char_adv(char_u **s, size_t *n)
{
    int		c, k;

    if (*n == 0)  
	return 0;

    k = utf8len_tab_zero[**s];

    if (k == 1)
    {
	 
	(*n)--;
	return *(*s)++;
    }

    if ((size_t)k <= *n)
    {
	 
	 
	 
	c = utf_ptr2char(*s);

	 
	 
	 
	 
	 
	if (c != (int)(**s) || (c == 0xC3 && (*s)[1] == 0x83))
	{
	     
	    *s += k;
	    *n -= k;
	    return c;
	}
    }

     
    return -1;
}