src/string.cpp
author rubidium
Sat, 17 Nov 2007 12:42:15 +0000
changeset 7898 7c6a9c9030b5
parent 7257 a0c906e11895
child 7928 63e18de69e50
permissions -rw-r--r--
(svn r11449) -Fix [FS#1160]: trams could deadlock themselves. As of now trams will turn as roadvehicles do when the player cannot build a tram track piece on the next tile without destroying anything. It will not turn when the player can build the before mentioned track piece on the 'next' tile.
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     1
/* $Id$ */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     2
6420
456c275f3313 (svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents: 6274
diff changeset
     3
/** @file string.cpp */
456c275f3313 (svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents: 6274
diff changeset
     4
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     5
#include "stdafx.h"
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     6
#include "openttd.h"
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     7
#include "functions.h"
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     8
#include "string.h"
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     9
#include "macros.h"
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    10
#include "table/control_codes.h"
5587
167d9a91ef02 (svn r8038) -Merge: the cpp branch. Effort of KUDr, Celestar, glx, Smoovius, stillunknown and pv2b.
rubidium
parents: 5584
diff changeset
    11
#include "helpers.hpp"
7257
a0c906e11895 (svn r10566) -Fix [FS#1025]: a NewGRF could have a information message that is too long for the internal buffers to handle. We should not crash on such a case even though the message is too big for the window anyway.
rubidium
parents: 6420
diff changeset
    12
#include "debug.h"
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    13
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    14
#include <stdarg.h>
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    15
#include <ctype.h> // required for tolower()
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    16
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    17
void ttd_strlcat(char *dst, const char *src, size_t size)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    18
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    19
	assert(size > 0);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    20
	for (; size > 0 && *dst != '\0'; --size, ++dst) {}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    21
	assert(size > 0);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    22
	while (--size > 0 && *src != '\0') *dst++ = *src++;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    23
	*dst = '\0';
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    24
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    25
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    26
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    27
void ttd_strlcpy(char *dst, const char *src, size_t size)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    28
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    29
	assert(size > 0);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    30
	while (--size > 0 && *src != '\0') *dst++ = *src++;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    31
	*dst = '\0';
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    32
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    33
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    34
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    35
char* strecat(char* dst, const char* src, const char* last)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    36
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    37
	assert(dst <= last);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    38
	for (; *dst != '\0'; ++dst)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    39
		if (dst == last) return dst;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    40
	for (; *src != '\0' && dst != last; ++dst, ++src) *dst = *src;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    41
	*dst = '\0';
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    42
	return strecpy(dst, src, last);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    43
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    44
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    45
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    46
char* strecpy(char* dst, const char* src, const char* last)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    47
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    48
	assert(dst <= last);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    49
	for (; *src != '\0' && dst != last; ++dst, ++src) *dst = *src;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    50
	*dst = '\0';
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    51
	if (dst == last && *src != '\0') {
7257
a0c906e11895 (svn r10566) -Fix [FS#1025]: a NewGRF could have a information message that is too long for the internal buffers to handle. We should not crash on such a case even though the message is too big for the window anyway.
rubidium
parents: 6420
diff changeset
    52
#ifdef STRGEN
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    53
		error("String too long for destination buffer");
7257
a0c906e11895 (svn r10566) -Fix [FS#1025]: a NewGRF could have a information message that is too long for the internal buffers to handle. We should not crash on such a case even though the message is too big for the window anyway.
rubidium
parents: 6420
diff changeset
    54
#else /* STRGEN */
a0c906e11895 (svn r10566) -Fix [FS#1025]: a NewGRF could have a information message that is too long for the internal buffers to handle. We should not crash on such a case even though the message is too big for the window anyway.
rubidium
parents: 6420
diff changeset
    55
		DEBUG(misc, 0, "String too long for destination buffer");
a0c906e11895 (svn r10566) -Fix [FS#1025]: a NewGRF could have a information message that is too long for the internal buffers to handle. We should not crash on such a case even though the message is too big for the window anyway.
rubidium
parents: 6420
diff changeset
    56
		*dst = '\0';
a0c906e11895 (svn r10566) -Fix [FS#1025]: a NewGRF could have a information message that is too long for the internal buffers to handle. We should not crash on such a case even though the message is too big for the window anyway.
rubidium
parents: 6420
diff changeset
    57
#endif /* STRGEN */
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    58
	}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    59
	return dst;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    60
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    61
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    62
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    63
char* CDECL str_fmt(const char* str, ...)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    64
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    65
	char buf[4096];
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    66
	va_list va;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    67
	int len;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    68
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    69
	va_start(va, str);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    70
	len = vsnprintf(buf, lengthof(buf), str, va);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    71
	va_end(va);
5609
dc6a58930ba4 (svn r8066) - Codechange: MallocT(), CallocT(), ReallocT() now return the pointer to allocated memory instead of modifying the pointer given as parameter
KUDr
parents: 5587
diff changeset
    72
	char* p = MallocT<char>(len + 1);
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    73
	if (p != NULL) memcpy(p, buf, len + 1);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    74
	return p;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    75
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    76
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    77
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    78
void str_validate(char *str)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    79
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    80
	char *dst = str;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    81
	WChar c;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    82
	size_t len;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    83
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    84
	for (len = Utf8Decode(&c, str); c != '\0'; len = Utf8Decode(&c, str)) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    85
		if (IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END ||
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    86
			IsValidChar(c - SCC_SPRITE_START, CS_ALPHANUMERAL))) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    87
			/* Copy the character back. Even if dst is current the same as str
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    88
			 * (i.e. no characters have been changed) this is quicker than
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    89
			 * moving the pointers ahead by len */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    90
			do {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    91
				*dst++ = *str++;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    92
			} while (--len != 0);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    93
		} else {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    94
			/* Replace the undesirable character with a question mark */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    95
			str += len;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    96
			*dst++ = '?';
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    97
		}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    98
	}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    99
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   100
	*dst = '\0';
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   101
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   102
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   103
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   104
void str_strip_colours(char *str)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   105
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   106
	char *dst = str;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   107
	WChar c;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   108
	size_t len;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   109
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   110
	for (len = Utf8Decode(&c, str); c != '\0'; len = Utf8Decode(&c, str)) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   111
		if (c < SCC_BLUE || c > SCC_BLACK) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   112
			/* Copy the character back. Even if dst is current the same as str
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   113
			 * (i.e. no characters have been changed) this is quicker than
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   114
			 * moving the pointers ahead by len */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   115
			do {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   116
				*dst++ = *str++;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   117
			} while (--len != 0);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   118
		} else {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   119
			/* Just skip (strip) the colour codes */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   120
			str += len;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   121
		}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   122
	}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   123
	*dst = '\0';
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   124
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   125
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   126
/** Convert a given ASCII string to lowercase.
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   127
 * NOTE: only support ASCII characters, no UTF8 fancy. As currently
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   128
 * the function is only used to lowercase data-filenames if they are
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   129
 * not found, this is sufficient. If more, or general functionality is
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   130
 * needed, look to r7271 where it was removed because it was broken when
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   131
 * using certain locales: eg in Turkish the uppercase 'I' was converted to
6420
456c275f3313 (svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents: 6274
diff changeset
   132
 * '?', so just revert to the old functionality
456c275f3313 (svn r9556) -Documentation: doxygen and comment-style changes. 'R', 'S'.. The end of the preliminary work is near
belugas
parents: 6274
diff changeset
   133
 * @param str string to convert */
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   134
void strtolower(char *str)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   135
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   136
	for (; *str != '\0'; str++) *str = tolower(*str);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   137
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   138
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   139
/**
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   140
 * Only allow certain keys. You can define the filter to be used. This makes
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   141
 *  sure no invalid keys can get into an editbox, like BELL.
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   142
 * @param key character to be checked
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   143
 * @param afilter the filter to use
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   144
 * @return true or false depending if the character is printable/valid or not
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   145
 */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   146
bool IsValidChar(WChar key, CharSetFilter afilter)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   147
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   148
	switch (afilter) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   149
		case CS_ALPHANUMERAL: return IsPrintable(key);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   150
		case CS_NUMERAL:      return (key >= '0' && key <= '9');
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   151
		case CS_ALPHA:        return IsPrintable(key) && !(key >= '0' && key <= '9');
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   152
	}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   153
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   154
	return false;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   155
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   156
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   157
#ifdef WIN32
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   158
int CDECL snprintf(char *str, size_t size, const char *format, ...)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   159
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   160
	va_list ap;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   161
	int ret;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   162
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   163
	va_start(ap, format);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   164
	ret = vsnprintf(str, size, format, ap);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   165
	va_end(ap);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   166
	return ret;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   167
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   168
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   169
#ifdef _MSC_VER
5630
2bbfa6ea3545 (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5609
diff changeset
   170
/* *nprintf broken, not POSIX compliant, MSDN description
2bbfa6ea3545 (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5609
diff changeset
   171
 * - If len < count, then len characters are stored in buffer, a null-terminator is appended, and len is returned.
2bbfa6ea3545 (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5609
diff changeset
   172
 * - If len = count, then len characters are stored in buffer, no null-terminator is appended, and len is returned.
2bbfa6ea3545 (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5609
diff changeset
   173
 * - If len > count, then count characters are stored in buffer, no null-terminator is appended, and a negative value is returned
2bbfa6ea3545 (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5609
diff changeset
   174
 */
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   175
int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   176
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   177
	int ret;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   178
	ret = _vsnprintf(str, size, format, ap);
5631
fd4e111c7ce2 (svn r8090) -[win32] Fix (r8089): for *nprintf 'ret = count' NOT 'ret = 0'...
Darkvater
parents: 5630
diff changeset
   179
	if (ret < 0 || ret == size) str[size - 1] = '\0';
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   180
	return ret;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   181
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   182
#endif /* _MSC_VER */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   183
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   184
#endif /* WIN32 */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   185
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   186
5634
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   187
/** Convert the md5sum to a hexadecimal string representation
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   188
 * @param buf buffer to put the md5sum into
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   189
 * @param last last character of buffer (usually lastof(buf))
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   190
 * @param md5sum the md5sum itself
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   191
 * @return a pointer to the next character after the md5sum */
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   192
char *md5sumToString(char *buf, const char *last, const uint8 md5sum[16])
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   193
{
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   194
	char *p = buf;
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   195
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   196
	for (uint i = 0; i < 16; i++) {
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   197
		p += snprintf(p, last + 1 - p, "%02X", md5sum[i]);
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   198
		if (p >= last) break;
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   199
	}
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   200
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   201
	return p;
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   202
}
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   203
ba6b9ebe197a (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5631
diff changeset
   204
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   205
/* UTF-8 handling routines */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   206
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   207
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   208
/* Decode and consume the next UTF-8 encoded character
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   209
 * @param c Buffer to place decoded character.
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   210
 * @param s Character stream to retrieve character from.
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   211
 * @return Number of characters in the sequence.
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   212
 */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   213
size_t Utf8Decode(WChar *c, const char *s)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   214
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   215
	assert(c != NULL);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   216
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   217
	if (!HASBIT(s[0], 7)) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   218
		/* Single byte character: 0xxxxxxx */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   219
		*c = s[0];
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   220
		return 1;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   221
	} else if (GB(s[0], 5, 3) == 6) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   222
		if (IsUtf8Part(s[1])) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   223
			/* Double byte character: 110xxxxx 10xxxxxx */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   224
			*c = GB(s[0], 0, 5) << 6 | GB(s[1], 0, 6);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   225
			if (*c >= 0x80) return 2;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   226
		}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   227
	} else if (GB(s[0], 4, 4) == 14) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   228
		if (IsUtf8Part(s[1]) && IsUtf8Part(s[2])) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   229
			/* Triple byte character: 1110xxxx 10xxxxxx 10xxxxxx */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   230
			*c = GB(s[0], 0, 4) << 12 | GB(s[1], 0, 6) << 6 | GB(s[2], 0, 6);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   231
			if (*c >= 0x800) return 3;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   232
		}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   233
	} else if (GB(s[0], 3, 5) == 30) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   234
		if (IsUtf8Part(s[1]) && IsUtf8Part(s[2]) && IsUtf8Part(s[3])) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   235
			/* 4 byte character: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   236
			*c = GB(s[0], 0, 3) << 18 | GB(s[1], 0, 6) << 12 | GB(s[2], 0, 6) << 6 | GB(s[3], 0, 6);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   237
			if (*c >= 0x10000 && *c <= 0x10FFFF) return 4;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   238
		}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   239
	}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   240
5380
8ea58542b6e0 (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 5165
diff changeset
   241
	//DEBUG(misc, 1, "[utf8] invalid UTF-8 sequence");
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   242
	*c = '?';
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   243
	return 1;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   244
}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   245
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   246
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   247
/* Encode a unicode character and place it in the buffer
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   248
 * @param buf Buffer to place character.
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   249
 * @param c   Unicode character to encode.
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   250
 * @return Number of characters in the encoded sequence.
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   251
 */
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   252
size_t Utf8Encode(char *buf, WChar c)
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   253
{
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   254
	if (c < 0x80) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   255
		*buf = c;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   256
		return 1;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   257
	} else if (c < 0x800) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   258
		*buf++ = 0xC0 + GB(c,  6, 5);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   259
		*buf   = 0x80 + GB(c,  0, 6);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   260
		return 2;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   261
	} else if (c < 0x10000) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   262
		*buf++ = 0xE0 + GB(c, 12, 4);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   263
		*buf++ = 0x80 + GB(c,  6, 6);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   264
		*buf   = 0x80 + GB(c,  0, 6);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   265
		return 3;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   266
	} else if (c < 0x110000) {
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   267
		*buf++ = 0xF0 + GB(c, 18, 3);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   268
		*buf++ = 0x80 + GB(c, 12, 6);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   269
		*buf++ = 0x80 + GB(c,  6, 6);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   270
		*buf   = 0x80 + GB(c,  0, 6);
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   271
		return 4;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   272
	}
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   273
5380
8ea58542b6e0 (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 5165
diff changeset
   274
	//DEBUG(misc, 1, "[utf8] can't UTF-8 encode value 0x%X", c);
5165
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   275
	*buf = '?';
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   276
	return 1;
028df092bebd (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   277
}
6215
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   278
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   279
/**
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   280
 * Properly terminate an UTF8 string to some maximum length
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   281
 * @param s string to check if it needs additional trimming
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   282
 * @param maxlen the maximum length the buffer can have.
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   283
 * @return the new length in bytes of the string (eg. strlen(new_string))
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   284
 * @NOTE maxlen is the string length _INCLUDING_ the terminating '\0'
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   285
 */
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   286
size_t Utf8TrimString(char *s, size_t maxlen)
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   287
{
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   288
	size_t length = 0;
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   289
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   290
	for (const char *ptr = strchr(s, '\0'); *s != '\0';) {
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   291
		size_t len = Utf8EncodedCharLen(*s);
6274
40d2a82c6bd6 (svn r9083) -Codechange: Be more lenient when trimming UTF-8 strings and don't terminate the string when an invalid encoding is encountered, but only focus on maximum length.
Darkvater
parents: 6218
diff changeset
   292
		/* Silently ignore invalid UTF8 sequences, our only concern trimming */
40d2a82c6bd6 (svn r9083) -Codechange: Be more lenient when trimming UTF-8 strings and don't terminate the string when an invalid encoding is encountered, but only focus on maximum length.
Darkvater
parents: 6218
diff changeset
   293
		if (len == 0) len = 1;
6215
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   294
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   295
		/* Take care when a hard cutoff was made for the string and
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   296
		 * the last UTF8 sequence is invalid */
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   297
		if (length + len >= maxlen || (s + len > ptr)) break;
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   298
		s += len;
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   299
		length += len;
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   300
	}
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   301
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   302
	*s = '\0';
bbd141b026b5 (svn r9012) -Fix/Feature (UTF8): When cutting strings into multiple lines also take into consideration whitespace characters of more than 1 byte length (eg IDEOGRAPHIC SPACE, IsWhitespace() function). When trimming such strings, account for multiple-byte long sequences so use *Utf8PrevChar(v) = '\0'.
Darkvater
parents: 5634
diff changeset
   303
	return length;
6218
d41f73299be5 (svn r9015) -Fix
tron
parents: 6215
diff changeset
   304
}