string.c
changeset 5119 7e7fc659218a
parent 5108 dc67d70b5a45
child 5164 a4fb0ede4ce5
equal deleted inserted replaced
5118:5a56a0f12206 5119:7e7fc659218a
     6 #include "string.h"
     6 #include "string.h"
     7 #include "macros.h"
     7 #include "macros.h"
     8 #include "table/control_codes.h"
     8 #include "table/control_codes.h"
     9 
     9 
    10 #include <stdarg.h>
    10 #include <stdarg.h>
    11 #include <ctype.h> // required for tolower()
    11 #include <wctype.h> // required for towlower()
       
    12 #include <locale.h> // required for setlocale()
    12 
    13 
    13 void ttd_strlcat(char *dst, const char *src, size_t size)
    14 void ttd_strlcat(char *dst, const char *src, size_t size)
    14 {
    15 {
    15 	assert(size > 0);
    16 	assert(size > 0);
    16 	for (; size > 0 && *dst != '\0'; --size, ++dst) {}
    17 	for (; size > 0 && *dst != '\0'; --size, ++dst) {}
    66 	p = malloc(len + 1);
    67 	p = malloc(len + 1);
    67 	if (p != NULL) memcpy(p, buf, len + 1);
    68 	if (p != NULL) memcpy(p, buf, len + 1);
    68 	return p;
    69 	return p;
    69 }
    70 }
    70 
    71 
       
    72 
    71 void str_validate(char *str)
    73 void str_validate(char *str)
    72 {
    74 {
    73 	char *dst = str;
    75 	char *dst = str;
    74 	WChar c;
    76 	WChar c;
    75 	size_t len = Utf8Decode(&c, str);
    77 	size_t len;
    76 
    78 
    77 	for (; c != '\0'; len = Utf8Decode(&c, str)) {
    79 	for (len = Utf8Decode(&c, str); c != '\0'; len = Utf8Decode(&c, str)) {
    78 		if (IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END ||
    80 		if (IsPrintable(c) && (c < SCC_SPRITE_START || c > SCC_SPRITE_END ||
    79 			IsValidChar(c - SCC_SPRITE_START, CS_ALPHANUMERAL))) {
    81 			IsValidChar(c - SCC_SPRITE_START, CS_ALPHANUMERAL))) {
    80 			/* Copy the character back. Even if dst is current the same as str
    82 			/* Copy the character back. Even if dst is current the same as str
    81 			 * (i.e. no characters have been changed) this is quicker than
    83 			 * (i.e. no characters have been changed) this is quicker than
    82 			 * moving the pointers ahead by len */
    84 			 * moving the pointers ahead by len */
    83 			do {
    85 			do {
    84 				*dst++ = *str++;
    86 				*dst++ = *str++;
    85 			} while (--len);
    87 			} while (--len != 0);
    86 		} else {
    88 		} else {
    87 			/* Replace the undesirable character with a question mark */
    89 			/* Replace the undesirable character with a question mark */
    88 			str += len;
    90 			str += len;
    89 			*dst++ = '?';
    91 			*dst++ = '?';
    90 		}
    92 		}
    91 	}
    93 	}
    92 
    94 
    93 	*dst = '\0';
    95 	*dst = '\0';
    94 }
    96 }
    95 
    97 
       
    98 
    96 void str_strip_colours(char *str)
    99 void str_strip_colours(char *str)
    97 {
   100 {
    98 	char *dst = str;
   101 	char *dst = str;
    99 	for (; *str != '\0';) {
   102 	WChar c;
   100 		if (*str >= 15 && *str <= 31) { // magic colour codes
   103 	size_t len;
   101 			str++;
   104 
       
   105 	strtolower(str);
       
   106 	for (len = Utf8Decode(&c, str); c != '\0'; len = Utf8Decode(&c, str)) {
       
   107 		if (c < SCC_BLUE || c > SCC_BLACK) {
       
   108 			/* Copy the character back. Even if dst is current the same as str
       
   109 			 * (i.e. no characters have been changed) this is quicker than
       
   110 			 * moving the pointers ahead by len */
       
   111 			do {
       
   112 				*dst++ = *str++;
       
   113 			} while (--len != 0);
   102 		} else {
   114 		} else {
   103 			*dst++ = *str++;
   115 			/* Just skip (strip) the colour codes */
   104 		}
   116 			str += len;
   105 	}
   117 		}
   106 	*dst = '\0';
   118 	}
   107 }
   119 	*dst = '\0';
       
   120 }
       
   121 
       
   122 
       
   123 void strtolower(char *str)
       
   124 {
       
   125 	WChar c;
       
   126 	/* Convert according to native locale, needed for unicode characters
       
   127 	 * We backup the current locale, then set it to native "", the set back */
       
   128 	char *locale = strdup(setlocale(LC_CTYPE, NULL));
       
   129 
       
   130 	setlocale(LC_CTYPE, "");
       
   131 	for (Utf8Decode(&c, str); c != '\0'; Utf8Decode(&c, str)) {
       
   132 		/* XXX - assume lowercase version does not use more bytes */
       
   133 		c = towlower(c);
       
   134 		str += Utf8Encode(str, c);
       
   135 	}
       
   136 	setlocale(LC_CTYPE, locale);
       
   137 	free(locale);
       
   138 }
       
   139 
   108 
   140 
   109 /**
   141 /**
   110  * Only allow certain keys. You can define the filter to be used. This makes
   142  * Only allow certain keys. You can define the filter to be used. This makes
   111  *  sure no invalid keys can get into an editbox, like BELL.
   143  *  sure no invalid keys can get into an editbox, like BELL.
   112  * @param key character to be checked
   144  * @param key character to be checked
   120 		case CS_NUMERAL:      return (key >= '0' && key <= '9');
   152 		case CS_NUMERAL:      return (key >= '0' && key <= '9');
   121 		case CS_ALPHA:        return IsPrintable(key) && !(key >= '0' && key <= '9');
   153 		case CS_ALPHA:        return IsPrintable(key) && !(key >= '0' && key <= '9');
   122 	}
   154 	}
   123 
   155 
   124 	return false;
   156 	return false;
   125 }
       
   126 
       
   127 void strtolower(char *str)
       
   128 {
       
   129 	for (; *str != '\0'; str++) *str = tolower(*str);
       
   130 }
   157 }
   131 
   158 
   132 #ifdef WIN32
   159 #ifdef WIN32
   133 int CDECL snprintf(char *str, size_t size, const char *format, ...)
   160 int CDECL snprintf(char *str, size_t size, const char *format, ...)
   134 {
   161 {