ICU-2881 hardcode uprv_tolower() and uprv_toupper() for guaranteed locale-independent behavior

X-SVN-Rev: 12013
This commit is contained in:
Markus Scherer 2003-05-19 22:29:22 +00:00
parent 8820a52d8e
commit 0818e3892c
3 changed files with 90 additions and 8 deletions

View file

@ -1,7 +1,7 @@
/*
******************************************************************************
*
* Copyright (C) 1997-2001, International Business Machines
* Copyright (C) 1997-2003, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
@ -26,6 +26,53 @@
#include "cmemory.h"
#include "cstring.h"
/*
* We hardcode case conversion for invariant characters to match our expectation
* and the compiler execution charset.
* This prevents problems on systems
* - with non-default casing behavior, like Turkish system locales where
* tolower('I') maps to dotless i and toupper('i') maps to dotted I
* - where there are no lowercase Latin characters at all, or using different
* codes (some old EBCDIC codepages)
*
* This works because the compiler usually runs on a platform where the execution
* charset includes all of the invariant characters at their expected
* code positions, so that the char * string literals in ICU code match
* the char literals here.
*
* Note that the set of lowercase Latin letters is discontiguous in EBCDIC
* and the set of uppercase Latin letters is discontiguous as well.
*/
U_CAPI char U_EXPORT2
uprv_toupper(char c) {
#if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
if(('a'<=c && c<='i') || ('j'<=c && c<='r') || ('s'<=c && c<='z')) {
c=(char)(c+('A'-'a'));
}
#else
if('a'<=c && c<='z') {
c=(char)(c+('A'-'a'));
}
#endif
return c;
}
U_CAPI char U_EXPORT2
uprv_tolower(char c) {
#if U_CHARSET_FAMILY==U_EBCDIC_FAMILY
if(('A'<=c && c<='I') || ('J'<=c && c<='R') || ('S'<=c && c<='Z')) {
c=(char)(c+('a'-'A'));
}
#else
if('A'<=c && c<='Z') {
c=(char)(c+('a'-'A'));
}
#endif
return c;
}
U_CAPI char* U_EXPORT2
T_CString_toLowerCase(char* str)
{

View file

@ -1,7 +1,7 @@
/*
******************************************************************************
*
* Copyright (C) 1997-2001, International Business Machines
* Copyright (C) 1997-2003, International Business Machines
* Corporation and others. All Rights Reserved.
*
******************************************************************************
@ -41,8 +41,13 @@
#define uprv_strchr(s, c) U_STANDARD_CPP_NAMESPACE strchr(s, c)
#define uprv_strstr(s, c) U_STANDARD_CPP_NAMESPACE strstr(s, c)
#define uprv_strrchr(s, c) U_STANDARD_CPP_NAMESPACE strrchr(s, c)
#define uprv_toupper(c) U_STANDARD_CPP_NAMESPACE toupper(c)
#define uprv_tolower(c) U_STANDARD_CPP_NAMESPACE tolower(c)
U_CAPI char U_EXPORT2
uprv_toupper(char c);
U_CAPI char U_EXPORT2
uprv_tolower(char c);
#define uprv_strtoul(str, end, base) U_STANDARD_CPP_NAMESPACE strtoul(str, end, base)
#define uprv_strtol(str, end, base) U_STANDARD_CPP_NAMESPACE strtol(str, end, base)
#ifdef WIN32

View file

@ -1,6 +1,6 @@
/*
**********************************************************************
* Copyright (C) 1998-2001, International Business Machines Corporation
* Copyright (C) 1998-2003, International Business Machines Corporation
* and others. All Rights Reserved.
**********************************************************************
*
@ -29,11 +29,41 @@ void addCStringTest(TestNode** root) {
static void TestAPI(void)
{
int32_t intValue=0;
char src[30]="HELLO THERE";
char src[30]="HELLO THERE", dest[30];
static const char *const abc="abcdefghijklmnopqrstuvwxyz", *const ABC="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
const char *temp;
int32_t i;
log_verbose("Testing uprv_tolower() and uprv_toupper()\n");
for(i=0; i<=26; ++i) {
dest[i]=uprv_tolower(abc[i]);
}
if(0!=strcmp(abc, dest)) {
log_err("uprv_tolower(abc) failed\n");
}
for(i=0; i<=26; ++i) {
dest[i]=uprv_tolower(ABC[i]);
}
if(0!=strcmp(abc, dest)) {
log_err("uprv_tolower(ABC) failed\n");
}
for(i=0; i<=26; ++i) {
dest[i]=uprv_toupper(abc[i]);
}
if(0!=strcmp(ABC, dest)) {
log_err("uprv_toupper(abc) failed\n");
}
for(i=0; i<=26; ++i) {
dest[i]=uprv_toupper(ABC[i]);
}
if(0!=strcmp(ABC, dest)) {
log_err("uprv_toupper(ABC) failed\n");
}
log_verbose("Testing the API in cstring\n");
T_CString_toLowerCase(src);
if(uprv_strcmp(src, "hello there") != 0){