Remove char::to_lower, char::to_upper, use libc versions instead

As per Graydon's comments on #1985: remove char::to_lower and
char::to_upper. The str versions of these functions now call
libc::tolower and libc::toupper (using wrappers that cast between
char and c_char). Not sure how much better that is, but it at least
makes it clearer that these functions are Unicode-unsafe.
This commit is contained in:
Tim Chevalier 2012-03-23 14:41:02 -07:00
parent cab4f1685b
commit 372673b58c
3 changed files with 17 additions and 56 deletions

View File

@ -38,7 +38,7 @@ export is_alphabetic,
is_lowercase, is_uppercase,
is_whitespace, is_alphanumeric,
is_ascii, is_digit,
to_digit, to_lower, to_upper, cmp;
to_digit, cmp;
import is_alphabetic = unicode::derived_property::Alphabetic;
import is_XID_start = unicode::derived_property::XID_Start;
@ -122,30 +122,6 @@ pure fn to_digit(c: char, radix: uint) -> option<uint> {
else { none }
}
/*
FIXME: works only on ASCII (Issue #1985)
*/
#[doc = "Convert a char to the corresponding lower case."]
pure fn to_lower(c: char) -> char {
assert is_ascii(c);
alt c {
'A' to 'Z' { ((c as u8) + 32u8) as char }
_ { c }
}
}
/*
FIXME: works only on ASCII (Issue 1985)
*/
#[doc = "Convert a char to the corresponding upper case."]
pure fn to_upper(c: char) -> char {
assert is_ascii(c);
alt c {
'a' to 'z' { ((c as u8) - 32u8) as char }
_ { c }
}
}
#[doc = "
Compare two chars
@ -206,24 +182,6 @@ fn test_to_digit() {
assert to_digit('$', 36u) == none;
}
#[test]
fn test_to_lower() {
assert (to_lower('H') == 'h');
assert (to_lower('e') == 'e');
// non-ASCII, shouldn't work (see earlier FIXME)
//assert (to_lower('Ö') == 'ö');
//assert (to_lower('ß') == 'ß');
}
#[test]
fn test_to_upper() {
assert (to_upper('l') == 'L');
assert (to_upper('Q') == 'Q');
// non-ASCII, shouldn't work (see earlier FIXME)
//assert (to_upper('ü') == 'Ü');
//assert (to_upper('ß') == 'ß');
}
#[test]
fn test_is_ascii() unsafe {
assert str::all("banana", char::is_ascii);

View File

@ -736,8 +736,8 @@ mod funcs {
fn isspace(c: c_int) -> c_int;
fn isupper(c: c_int) -> c_int;
fn isxdigit(c: c_int) -> c_int;
fn tolower(c: c_int) -> c_int;
fn toupper(c: c_int) -> c_int;
fn tolower(c: c_char) -> c_char;
fn toupper(c: c_char) -> c_char;
}
#[nolink]

View File

@ -95,7 +95,6 @@ export
unsafe;
#[abi = "cdecl"]
native mod rustrt {
fn rust_str_push(&s: str, ch: u8);
@ -492,14 +491,14 @@ fn words(s: str) -> [str] {
split_nonempty(s, {|c| char::is_whitespace(c)})
}
#[doc = "Convert a string to lowercase"]
#[doc = "Convert a string to lowercase. ASCII only"]
fn to_lower(s: str) -> str {
map(s, char::to_lower)
map(s, {|c| (libc::tolower(c as libc::c_char)) as char})
}
#[doc = "Convert a string to uppercase"]
#[doc = "Convert a string to uppercase. ASCII only"]
fn to_upper(s: str) -> str {
map(s, char::to_upper)
map(s, {|c| (libc::toupper(c as libc::c_char)) as char})
}
#[doc = "
@ -1629,6 +1628,8 @@ mod unsafe {
#[cfg(test)]
mod tests {
import libc::c_char;
#[test]
fn test_eq() {
assert (eq("", ""));
@ -1937,9 +1938,9 @@ mod tests {
#[test]
fn test_to_upper() {
// char::to_upper, and hence str::to_upper
// libc::toupper, and hence str::to_upper
// are culturally insensitive: they only work for ASCII
// (see Issue #1985)
// (see Issue #1347)
let unicode = ""; //"\u65e5\u672c"; // uncomment once non-ASCII works
let input = "abcDEF" + unicode + "xyz:.;";
let expected = "ABCDEF" + unicode + "XYZ:.;";
@ -1949,8 +1950,9 @@ mod tests {
#[test]
fn test_to_lower() {
assert "" == map("", char::to_lower);
assert "ymca" == map("YMCA", char::to_lower);
assert "" == map("", {|c| libc::tolower(c as c_char) as char});
assert "ymca" == map("YMCA",
{|c| libc::tolower(c as c_char) as char});
}
#[test]
@ -2401,8 +2403,9 @@ mod tests {
#[test]
fn test_map() {
assert "" == map("", char::to_upper);
assert "YMCA" == map("ymca", char::to_upper);
assert "" == map("", {|c| libc::toupper(c as c_char) as char});
assert "YMCA" == map("ymca", {|c| libc::toupper(c as c_char)
as char});
}
#[test]