Example #1
0
/**
 * @brief Delete a whole (possibly multibyte) character from a string.
 * @param[in] s Start of the string
 * @param[in] pos UTF-8 char offset from the start (not the byte offset)
 * @return Number of bytes deleted
 */
int UTF8_delete_char_at (char* s, int pos)
{
	/* Convert the UTF-8 char offset to byte offset */
	pos = UTF8_char_offset_to_byte_offset(s, pos);

	int start = pos;
	int next = pos;

	while (start > 0 && UTF8_CONTINUATION_BYTE(s[start]))
		start--;
	if (s[next] != 0)
		next++;
	while (s[next] != 0 && UTF8_CONTINUATION_BYTE(s[next]))
		next++;
	/* memmove is the only standard copying function that is guaranteed
	 * to work if the source and destination overlap. */
	memmove(&s[start], &s[next], strlen(&s[next]) + 1);
	return (next - start);
}
Example #2
0
/**
 * @brief copies formatted string with buffer-size checking
 * @param[out] dest Destination buffer
 * @param[in] size Size of the destination buffer
 * @param[in] fmt Stringformat (like printf)
 * @return false if overflowed - true otherwise
 */
bool Com_sprintf (char* dest, size_t size, const char* fmt, ...)
{
	va_list ap;
	int len;

	if (!fmt)
		return false;

	va_start(ap, fmt);
	len = Q_vsnprintf(dest, size, fmt, ap);
	va_end(ap);

	if (len <= size - 1)
		return true;

	/* number of character */
	len = size - 1;

	/* check for UTF8 multibyte sequences */
	if (len > 0 && (unsigned char) dest[len - 1] >= 0x80) {
		int i = len - 1;
		while (i > 0 && UTF8_CONTINUATION_BYTE((unsigned char) dest[i]))
			i--;
		if (UTF8_char_len(dest[i]) + i > len) {
			dest[i] = '\0';
		}
#ifdef DEBUG
		else {
			/* the '\0' is already at the right place */
			len = i + UTF8_char_len(dest[i]);
			assert(dest[len] == '\0');
		}
#endif
	}

	return false;
}