src/string.cpp
author celestar
Wed, 21 Mar 2007 11:46:54 +0000
branchgamebalance
changeset 9899 cde52f745560
parent 9895 7bd07f43b0e3
child 6719 4cc327ad39d5
permissions -rw-r--r--
(svn r9386) [gamebalance] -Feature: Selling and buying land costs now take proximity to town centers into account. Move some code around while I'm at it. Also selling land gives as much money as buying land costs.
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     1
/* $Id$ */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     2
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     3
#include "stdafx.h"
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     4
#include "openttd.h"
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     5
#include "functions.h"
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     6
#include "string.h"
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     7
#include "macros.h"
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     8
#include "table/control_codes.h"
5838
9c3129cb019b (svn r8038) -Merge: the cpp branch. Effort of KUDr, Celestar, glx, Smoovius, stillunknown and pv2b.
rubidium
parents: 5835
diff changeset
     9
#include "helpers.hpp"
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    10
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    11
#include <stdarg.h>
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    12
#include <ctype.h> // required for tolower()
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    13
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    14
void ttd_strlcat(char *dst, const char *src, size_t size)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    15
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    16
	assert(size > 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    17
	for (; size > 0 && *dst != '\0'; --size, ++dst) {}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    18
	assert(size > 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    19
	while (--size > 0 && *src != '\0') *dst++ = *src++;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    20
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    21
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    22
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    23
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    24
void ttd_strlcpy(char *dst, const char *src, size_t size)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    25
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    26
	assert(size > 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    27
	while (--size > 0 && *src != '\0') *dst++ = *src++;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    28
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    29
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    30
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    31
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    32
char* strecat(char* dst, const char* src, const char* last)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    33
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    34
	assert(dst <= last);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    35
	for (; *dst != '\0'; ++dst)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    36
		if (dst == last) return dst;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    37
	for (; *src != '\0' && dst != last; ++dst, ++src) *dst = *src;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    38
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    39
	return strecpy(dst, src, last);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    40
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    41
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    42
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    43
char* strecpy(char* dst, const char* src, const char* last)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    44
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    45
	assert(dst <= last);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    46
	for (; *src != '\0' && dst != last; ++dst, ++src) *dst = *src;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    47
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    48
#if 1
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    49
	if (dst == last && *src != '\0') {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    50
		error("String too long for destination buffer");
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    51
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    52
#endif
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    53
	return dst;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    54
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    55
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    56
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    57
char* CDECL str_fmt(const char* str, ...)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    58
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    59
	char buf[4096];
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    60
	va_list va;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    61
	int len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    62
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    63
	va_start(va, str);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    64
	len = vsnprintf(buf, lengthof(buf), str, va);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    65
	va_end(va);
5860
7fdc9b423ba1 (svn r8066) - Codechange: MallocT(), CallocT(), ReallocT() now return the pointer to allocated memory instead of modifying the pointer given as parameter
KUDr
parents: 5838
diff changeset
    66
	char* p = MallocT<char>(len + 1);
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    67
	if (p != NULL) memcpy(p, buf, len + 1);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    68
	return p;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    69
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    70
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    71
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    72
void str_validate(char *str)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    73
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    74
	char *dst = str;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    75
	WChar c;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    76
	size_t len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    77
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    78
	for (len = Utf8Decode(&c, str); c != '\0'; len = Utf8Decode(&c, str)) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    79
		if (IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END ||
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    80
			IsValidChar(c - SCC_SPRITE_START, CS_ALPHANUMERAL))) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    81
			/* Copy the character back. Even if dst is current the same as str
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    82
			 * (i.e. no characters have been changed) this is quicker than
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    83
			 * moving the pointers ahead by len */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    84
			do {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    85
				*dst++ = *str++;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    86
			} while (--len != 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    87
		} else {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    88
			/* Replace the undesirable character with a question mark */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    89
			str += len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    90
			*dst++ = '?';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    91
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    92
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    93
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    94
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    95
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    96
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    97
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    98
void str_strip_colours(char *str)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    99
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   100
	char *dst = str;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   101
	WChar c;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   102
	size_t len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   103
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   104
	for (len = Utf8Decode(&c, str); c != '\0'; len = Utf8Decode(&c, str)) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   105
		if (c < SCC_BLUE || c > SCC_BLACK) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   106
			/* Copy the character back. Even if dst is current the same as str
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   107
			 * (i.e. no characters have been changed) this is quicker than
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   108
			 * moving the pointers ahead by len */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   109
			do {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   110
				*dst++ = *str++;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   111
			} while (--len != 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   112
		} else {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   113
			/* Just skip (strip) the colour codes */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   114
			str += len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   115
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   116
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   117
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   118
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   119
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   120
/** Convert a given ASCII string to lowercase.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   121
 * NOTE: only support ASCII characters, no UTF8 fancy. As currently
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   122
 * the function is only used to lowercase data-filenames if they are
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   123
 * not found, this is sufficient. If more, or general functionality is
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   124
 * needed, look to r7271 where it was removed because it was broken when
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   125
 * using certain locales: eg in Turkish the uppercase 'I' was converted to
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   126
 * '?', so just revert to the old functionality */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   127
void strtolower(char *str)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   128
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   129
	for (; *str != '\0'; str++) *str = tolower(*str);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   130
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   131
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   132
/**
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   133
 * Only allow certain keys. You can define the filter to be used. This makes
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   134
 *  sure no invalid keys can get into an editbox, like BELL.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   135
 * @param key character to be checked
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   136
 * @param afilter the filter to use
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   137
 * @return true or false depending if the character is printable/valid or not
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   138
 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   139
bool IsValidChar(WChar key, CharSetFilter afilter)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   140
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   141
	switch (afilter) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   142
		case CS_ALPHANUMERAL: return IsPrintable(key);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   143
		case CS_NUMERAL:      return (key >= '0' && key <= '9');
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   144
		case CS_ALPHA:        return IsPrintable(key) && !(key >= '0' && key <= '9');
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   145
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   146
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   147
	return false;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   148
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   149
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   150
#ifdef WIN32
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   151
int CDECL snprintf(char *str, size_t size, const char *format, ...)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   152
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   153
	va_list ap;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   154
	int ret;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   155
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   156
	va_start(ap, format);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   157
	ret = vsnprintf(str, size, format, ap);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   158
	va_end(ap);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   159
	return ret;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   160
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   161
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   162
#ifdef _MSC_VER
5881
72272107128e (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5860
diff changeset
   163
/* *nprintf broken, not POSIX compliant, MSDN description
72272107128e (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5860
diff changeset
   164
 * - If len < count, then len characters are stored in buffer, a null-terminator is appended, and len is returned.
72272107128e (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5860
diff changeset
   165
 * - If len = count, then len characters are stored in buffer, no null-terminator is appended, and len is returned.
72272107128e (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5860
diff changeset
   166
 * - If len > count, then count characters are stored in buffer, no null-terminator is appended, and a negative value is returned
72272107128e (svn r8089) -[win32] MS-borkedness: All *nprintf functions are broken, but we didn't test to fix it ourselves when 'len = count'.
Darkvater
parents: 5860
diff changeset
   167
 */
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   168
int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   169
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   170
	int ret;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   171
	ret = _vsnprintf(str, size, format, ap);
5882
5ba219322829 (svn r8090) -[win32] Fix (r8089): for *nprintf 'ret = count' NOT 'ret = 0'...
Darkvater
parents: 5881
diff changeset
   172
	if (ret < 0 || ret == size) str[size - 1] = '\0';
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   173
	return ret;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   174
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   175
#endif /* _MSC_VER */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   176
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   177
#endif /* WIN32 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   178
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   179
5885
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   180
/** Convert the md5sum to a hexadecimal string representation
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   181
 * @param buf buffer to put the md5sum into
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   182
 * @param last last character of buffer (usually lastof(buf))
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   183
 * @param md5sum the md5sum itself
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   184
 * @return a pointer to the next character after the md5sum */
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   185
char *md5sumToString(char *buf, const char *last, const uint8 md5sum[16])
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   186
{
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   187
	char *p = buf;
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   188
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   189
	for (uint i = 0; i < 16; i++) {
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   190
		p += snprintf(p, last + 1 - p, "%02X", md5sum[i]);
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   191
		if (p >= last) break;
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   192
	}
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   193
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   194
	return p;
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   195
}
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   196
262234e81333 (svn r8093) -Codechange: Add a function to get a string representation of an MD5SUM and use it.
Darkvater
parents: 5882
diff changeset
   197
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   198
/* UTF-8 handling routines */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   199
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   200
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   201
/* Decode and consume the next UTF-8 encoded character
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   202
 * @param c Buffer to place decoded character.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   203
 * @param s Character stream to retrieve character from.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   204
 * @return Number of characters in the sequence.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   205
 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   206
size_t Utf8Decode(WChar *c, const char *s)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   207
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   208
	assert(c != NULL);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   209
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   210
	if (!HASBIT(s[0], 7)) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   211
		/* Single byte character: 0xxxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   212
		*c = s[0];
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   213
		return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   214
	} else if (GB(s[0], 5, 3) == 6) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   215
		if (IsUtf8Part(s[1])) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   216
			/* Double byte character: 110xxxxx 10xxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   217
			*c = GB(s[0], 0, 5) << 6 | GB(s[1], 0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   218
			if (*c >= 0x80) return 2;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   219
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   220
	} else if (GB(s[0], 4, 4) == 14) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   221
		if (IsUtf8Part(s[1]) && IsUtf8Part(s[2])) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   222
			/* Triple byte character: 1110xxxx 10xxxxxx 10xxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   223
			*c = GB(s[0], 0, 4) << 12 | GB(s[1], 0, 6) << 6 | GB(s[2], 0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   224
			if (*c >= 0x800) return 3;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   225
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   226
	} else if (GB(s[0], 3, 5) == 30) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   227
		if (IsUtf8Part(s[1]) && IsUtf8Part(s[2]) && IsUtf8Part(s[3])) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   228
			/* 4 byte character: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   229
			*c = GB(s[0], 0, 3) << 18 | GB(s[1], 0, 6) << 12 | GB(s[2], 0, 6) << 6 | GB(s[3], 0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   230
			if (*c >= 0x10000 && *c <= 0x10FFFF) return 4;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   231
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   232
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   233
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 5165
diff changeset
   234
	//DEBUG(misc, 1, "[utf8] invalid UTF-8 sequence");
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   235
	*c = '?';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   236
	return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   237
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   238
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   239
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   240
/* Encode a unicode character and place it in the buffer
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   241
 * @param buf Buffer to place character.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   242
 * @param c   Unicode character to encode.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   243
 * @return Number of characters in the encoded sequence.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   244
 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   245
size_t Utf8Encode(char *buf, WChar c)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   246
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   247
	if (c < 0x80) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   248
		*buf = c;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   249
		return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   250
	} else if (c < 0x800) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   251
		*buf++ = 0xC0 + GB(c,  6, 5);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   252
		*buf   = 0x80 + GB(c,  0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   253
		return 2;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   254
	} else if (c < 0x10000) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   255
		*buf++ = 0xE0 + GB(c, 12, 4);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   256
		*buf++ = 0x80 + GB(c,  6, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   257
		*buf   = 0x80 + GB(c,  0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   258
		return 3;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   259
	} else if (c < 0x110000) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   260
		*buf++ = 0xF0 + GB(c, 18, 3);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   261
		*buf++ = 0x80 + GB(c, 12, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   262
		*buf++ = 0x80 + GB(c,  6, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   263
		*buf   = 0x80 + GB(c,  0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   264
		return 4;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   265
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   266
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 5165
diff changeset
   267
	//DEBUG(misc, 1, "[utf8] can't UTF-8 encode value 0x%X", c);
5165
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   268
	*buf = '?';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   269
	return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   270
}
6541
ff575414f0d2 (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: 5885
diff changeset
   271
ff575414f0d2 (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: 5885
diff changeset
   272
/**
ff575414f0d2 (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: 5885
diff changeset
   273
 * Properly terminate an UTF8 string to some maximum length
ff575414f0d2 (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: 5885
diff changeset
   274
 * @param s string to check if it needs additional trimming
ff575414f0d2 (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: 5885
diff changeset
   275
 * @param maxlen the maximum length the buffer can have.
ff575414f0d2 (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: 5885
diff changeset
   276
 * @return the new length in bytes of the string (eg. strlen(new_string))
ff575414f0d2 (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: 5885
diff changeset
   277
 * @NOTE maxlen is the string length _INCLUDING_ the terminating '\0'
ff575414f0d2 (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: 5885
diff changeset
   278
 */
ff575414f0d2 (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: 5885
diff changeset
   279
size_t Utf8TrimString(char *s, size_t maxlen)
ff575414f0d2 (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: 5885
diff changeset
   280
{
ff575414f0d2 (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: 5885
diff changeset
   281
	size_t length = 0;
ff575414f0d2 (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: 5885
diff changeset
   282
ff575414f0d2 (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: 5885
diff changeset
   283
	for (const char *ptr = strchr(s, '\0'); *s != '\0';) {
ff575414f0d2 (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: 5885
diff changeset
   284
		size_t len = Utf8EncodedCharLen(*s);
9895
7bd07f43b0e3 (svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents: 6544
diff changeset
   285
		/* Silently ignore invalid UTF8 sequences, our only concern trimming */
7bd07f43b0e3 (svn r9321) [gamebalance] -Sync: r9025:9314 from trunk
celestar
parents: 6544
diff changeset
   286
		if (len == 0) len = 1;
6541
ff575414f0d2 (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: 5885
diff changeset
   287
ff575414f0d2 (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: 5885
diff changeset
   288
		/* Take care when a hard cutoff was made for the string and
ff575414f0d2 (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: 5885
diff changeset
   289
		 * the last UTF8 sequence is invalid */
ff575414f0d2 (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: 5885
diff changeset
   290
		if (length + len >= maxlen || (s + len > ptr)) break;
ff575414f0d2 (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: 5885
diff changeset
   291
		s += len;
ff575414f0d2 (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: 5885
diff changeset
   292
		length += len;
ff575414f0d2 (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: 5885
diff changeset
   293
	}
ff575414f0d2 (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: 5885
diff changeset
   294
ff575414f0d2 (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: 5885
diff changeset
   295
	*s = '\0';
ff575414f0d2 (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: 5885
diff changeset
   296
	return length;
6544
a5f64ee6e4d6 (svn r9015) -Fix
tron
parents: 6541
diff changeset
   297
}