string.c
author KUDr
Sun, 31 Dec 2006 02:53:23 +0000
branchcustombridgeheads
changeset 5611 11da6bafbfb9
parent 5568 75f13d7bfaed
permissions -rw-r--r--
(svn r7687) [cbh] - Fix: trains can now enter the bridge from side. They still can't leave it from side (pathfinder will need to be invoked when the other ramp is entered). Also the code is not very clear and needs review. It is more proof of concept than final solution. I hope that somebody smarter (Celestar) can do it better.
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"
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
     9
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    10
#include <stdarg.h>
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    11
#include <ctype.h> // required for tolower()
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    12
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    13
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
    14
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    15
	assert(size > 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    16
	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
    17
	assert(size > 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    18
	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
    19
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    20
}
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
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
    24
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    25
	assert(size > 0);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    26
	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
    27
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    28
}
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
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
    32
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    33
	assert(dst <= last);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    34
	for (; *dst != '\0'; ++dst)
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    35
		if (dst == last) return dst;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    36
	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
    37
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    38
	return strecpy(dst, src, last);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    39
}
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
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
    43
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    44
	assert(dst <= last);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    45
	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
    46
	*dst = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    47
#if 1
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    48
	if (dst == last && *src != '\0') {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    49
		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
    50
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    51
#endif
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    52
	return dst;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    53
}
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
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
    57
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    58
	char buf[4096];
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    59
	va_list va;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    60
	int len;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    61
	char* p;
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);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
    66
	p = malloc(len + 1);
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
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   163
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
   164
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   165
	int ret;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   166
	ret = _vsnprintf(str, size, format, ap);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   167
	if (ret < 0) str[size - 1] = '\0';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   168
	return ret;
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
#endif /* _MSC_VER */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   171
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   172
#endif /* WIN32 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   173
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
/* UTF-8 handling routines */
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
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   178
/* 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
   179
 * @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
   180
 * @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
   181
 * @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
   182
 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   183
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
   184
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   185
	assert(c != NULL);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   186
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   187
	if (!HASBIT(s[0], 7)) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   188
		/* Single byte character: 0xxxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   189
		*c = s[0];
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   190
		return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   191
	} 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
   192
		if (IsUtf8Part(s[1])) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   193
			/* Double byte character: 110xxxxx 10xxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   194
			*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
   195
			if (*c >= 0x80) return 2;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   196
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   197
	} 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
   198
		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
   199
			/* Triple byte character: 1110xxxx 10xxxxxx 10xxxxxx */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   200
			*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
   201
			if (*c >= 0x800) return 3;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   202
		}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   203
	} 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
   204
		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
   205
			/* 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
   206
			*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
   207
			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
   208
		}
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
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 5165
diff changeset
   211
	//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
   212
	*c = '?';
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
}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   215
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   216
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   217
/* 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
   218
 * @param buf Buffer to place character.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   219
 * @param c   Unicode character to encode.
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   220
 * @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
   221
 */
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   222
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
   223
{
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   224
	if (c < 0x80) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   225
		*buf = c;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   226
		return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   227
	} else if (c < 0x800) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   228
		*buf++ = 0xC0 + GB(c,  6, 5);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   229
		*buf   = 0x80 + GB(c,  0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   230
		return 2;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   231
	} else if (c < 0x10000) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   232
		*buf++ = 0xE0 + GB(c, 12, 4);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   233
		*buf++ = 0x80 + GB(c,  6, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   234
		*buf   = 0x80 + GB(c,  0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   235
		return 3;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   236
	} else if (c < 0x110000) {
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   237
		*buf++ = 0xF0 + GB(c, 18, 3);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   238
		*buf++ = 0x80 + GB(c, 12, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   239
		*buf++ = 0x80 + GB(c,  6, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   240
		*buf   = 0x80 + GB(c,  0, 6);
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   241
		return 4;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   242
	}
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   243
5568
75f13d7bfaed (svn r7565) -Codechange: Rework DEBUG functionality. Look for appropiate debugging levels to
Darkvater
parents: 5165
diff changeset
   244
	//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
   245
	*buf = '?';
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   246
	return 1;
639e7dd3392a (svn r7272) -Ok, let's hope this one's correct...stupid msvc
Darkvater
parents: 5164
diff changeset
   247
}