1
Fork 0

Finish cleanup of core::str

Closes #1849
This commit is contained in:
Marijn Haverbeke 2012-02-23 16:59:30 +01:00
parent 1d2b4b97ed
commit 780f8277f4
24 changed files with 359 additions and 500 deletions

View file

@ -109,13 +109,10 @@ mod write {
// Decides what to call an intermediate file, given the name of the output // Decides what to call an intermediate file, given the name of the output
// and the extension to use. // and the extension to use.
fn mk_intermediate_name(output_path: str, extension: str) -> str unsafe { fn mk_intermediate_name(output_path: str, extension: str) -> str unsafe {
let stem = alt str::index(output_path, '.') { let stem = alt str::find_char(output_path, '.') {
option::some(dot_pos) { some(dot_pos) { str::slice(output_path, 0u, dot_pos) }
str::slice(output_path, 0u, dot_pos) none { output_path }
}
option::none { output_path }
}; };
ret stem + "." + extension; ret stem + "." + extension;
} }
@ -566,7 +563,7 @@ fn link_binary(sess: session,
// Converts a library file name into a cc -l argument // Converts a library file name into a cc -l argument
fn unlib(config: @session::config, filename: str) -> str unsafe { fn unlib(config: @session::config, filename: str) -> str unsafe {
let rmlib = fn@(filename: str) -> str { let rmlib = fn@(filename: str) -> str {
let found = str::find(filename, "lib"); let found = str::find_str(filename, "lib");
if config.os == session::os_macos || if config.os == session::os_macos ||
(config.os == session::os_linux || (config.os == session::os_linux ||
config.os == session::os_freebsd) && config.os == session::os_freebsd) &&

View file

@ -157,7 +157,7 @@ fn span_to_lines(sp: span, cm: codemap::codemap) -> @file_lines {
fn get_line(fm: filemap, line: int) -> str unsafe { fn get_line(fm: filemap, line: int) -> str unsafe {
let begin: uint = fm.lines[line].byte - fm.start_pos.byte; let begin: uint = fm.lines[line].byte - fm.start_pos.byte;
let end = alt str::index_from(*fm.src, '\n', begin, str::len(*fm.src)) { let end = alt str::find_char_from(*fm.src, '\n', begin) {
some(e) { e } some(e) { e }
none { str::len(*fm.src) } none { str::len(*fm.src) }
}; };
@ -165,14 +165,12 @@ fn get_line(fm: filemap, line: int) -> str unsafe {
} }
fn lookup_byte_offset(cm: codemap::codemap, chpos: uint) fn lookup_byte_offset(cm: codemap::codemap, chpos: uint)
-> {fm: filemap, pos: uint} -> {fm: filemap, pos: uint} {
{ let {fm, line} = lookup_line(cm, chpos, {|pos| pos.ch});
fn lookup(pos: file_pos) -> uint { ret pos.ch; }
let {fm,line} = lookup_line(cm,chpos,lookup);
let line_offset = fm.lines[line].byte - fm.start_pos.byte; let line_offset = fm.lines[line].byte - fm.start_pos.byte;
let col = chpos - fm.lines[line].ch; let col = chpos - fm.lines[line].ch;
let col_offset = str::substr_len(*fm.src, line_offset, col); let col_offset = str::count_bytes(*fm.src, line_offset, col);
ret {fm: fm, pos: line_offset + col_offset}; {fm: fm, pos: line_offset + col_offset}
} }
fn span_to_snippet(sp: span, cm: codemap::codemap) -> str { fn span_to_snippet(sp: span, cm: codemap::codemap) -> str {

View file

@ -214,7 +214,7 @@ fn finish<T: qq_helper>
if (j < g_len && i == cx.gather[j].lo) { if (j < g_len && i == cx.gather[j].lo) {
assert ch == '$'; assert ch == '$';
let repl = #fmt("$%u ", j); let repl = #fmt("$%u ", j);
state = skip(str::len_chars(repl)); state = skip(str::char_len(repl));
str2 += repl; str2 += repl;
} }
alt state { alt state {

View file

@ -25,7 +25,7 @@ fn load_errors(testfile: str) -> [expected_error] {
fn parse_expected(line_num: uint, line: str) -> [expected_error] unsafe { fn parse_expected(line_num: uint, line: str) -> [expected_error] unsafe {
let error_tag = "//!"; let error_tag = "//!";
let idx; let idx;
alt str::find(line, error_tag) { alt str::find_str(line, error_tag) {
option::none { ret []; } option::none { ret []; }
option::some(nn) { idx = (nn as uint) + str::len(error_tag); } option::some(nn) { idx = (nn as uint) + str::len(error_tag); }
} }

View file

@ -106,7 +106,7 @@ fn parse_name_directive(line: str, directive: str) -> bool {
fn parse_name_value_directive(line: str, fn parse_name_value_directive(line: str,
directive: str) -> option<str> unsafe { directive: str) -> option<str> unsafe {
let keycolon = directive + ":"; let keycolon = directive + ":";
alt str::find(line, keycolon) { alt str::find_str(line, keycolon) {
option::some(colon) { option::some(colon) {
let value = str::slice(line, colon + str::len(keycolon), let value = str::slice(line, colon + str::len(keycolon),
str::len(line)); str::len(line));

View file

@ -198,7 +198,7 @@ fn check_error_patterns(props: test_props,
let next_err_idx = 0u; let next_err_idx = 0u;
let next_err_pat = props.error_patterns[next_err_idx]; let next_err_pat = props.error_patterns[next_err_idx];
for line: str in str::split_byte(procres.stderr, '\n' as u8) { for line: str in str::split_char(procres.stderr, '\n') {
if str::contains(line, next_err_pat) { if str::contains(line, next_err_pat) {
#debug("found error pattern %s", next_err_pat); #debug("found error pattern %s", next_err_pat);
next_err_idx += 1u; next_err_idx += 1u;
@ -245,7 +245,7 @@ fn check_expected_errors(expected_errors: [errors::expected_error],
// filename:line1:col1: line2:col2: *warning:* msg // filename:line1:col1: line2:col2: *warning:* msg
// where line1:col1: is the starting point, line2:col2: // where line1:col1: is the starting point, line2:col2:
// is the ending point, and * represents ANSI color codes. // is the ending point, and * represents ANSI color codes.
for line: str in str::split_byte(procres.stderr, '\n' as u8) { for line: str in str::split_char(procres.stderr, '\n') {
let was_expected = false; let was_expected = false;
vec::iteri(expected_errors) {|i, ee| vec::iteri(expected_errors) {|i, ee|
if !found_flags[i] { if !found_flags[i] {
@ -350,7 +350,7 @@ fn split_maybe_args(argstr: option<str>) -> [str] {
} }
alt argstr { alt argstr {
option::some(s) { rm_whitespace(str::split_byte(s, ' ' as u8)) } option::some(s) { rm_whitespace(str::split_char(s, ' ')) }
option::none { [] } option::none { [] }
} }
} }
@ -410,11 +410,9 @@ fn make_out_name(config: config, testfile: str, extension: str) -> str {
fn output_base_name(config: config, testfile: str) -> str { fn output_base_name(config: config, testfile: str) -> str {
let base = config.build_base; let base = config.build_base;
let filename = let filename = {
{ let parts = str::split_char(fs::basename(testfile), '.');
let parts = str::split_byte(fs::basename(testfile), '.' as u8); str::connect(vec::slice(parts, 0u, vec::len(parts) - 1u), ".")
parts = vec::slice(parts, 0u, vec::len(parts) - 1u);
str::connect(parts, ".")
}; };
#fmt["%s%s.%s", base, filename, config.stage_id] #fmt["%s%s.%s", base, filename, config.stage_id]
} }

View file

@ -320,12 +320,10 @@ mod rt {
fn conv_str(cv: conv, s: str) -> str unsafe { fn conv_str(cv: conv, s: str) -> str unsafe {
// For strings, precision is the maximum characters // For strings, precision is the maximum characters
// displayed // displayed
let unpadded = alt cv.precision {
let unpadded =
alt cv.precision {
count_implied { s } count_implied { s }
count_is(max) { count_is(max) {
if max as uint < str::len_chars(s) { if max as uint < str::char_len(s) {
str::substr(s, 0u, max as uint) str::substr(s, 0u, max as uint)
} else { s } } else { s }
} }
@ -368,7 +366,7 @@ mod rt {
"" ""
} else { } else {
let s = uint::to_str(num, radix); let s = uint::to_str(num, radix);
let len = str::len_chars(s); let len = str::char_len(s);
if len < prec { if len < prec {
let diff = prec - len; let diff = prec - len;
let pad = str_init_elt(diff, '0'); let pad = str_init_elt(diff, '0');
@ -400,7 +398,7 @@ mod rt {
uwidth = width as uint; uwidth = width as uint;
} }
} }
let strlen = str::len_chars(s); let strlen = str::char_len(s);
if uwidth <= strlen { ret s; } if uwidth <= strlen { ret s; }
let padchar = ' '; let padchar = ' ';
let diff = uwidth - strlen; let diff = uwidth - strlen;

View file

@ -44,7 +44,6 @@ export
to_lower, to_lower,
to_upper, to_upper,
replace, replace,
escape,
// Comparing strings // Comparing strings
eq, eq,
@ -52,8 +51,8 @@ export
hash, hash,
// Iterating through strings // Iterating through strings
all, all, any,
any, all_between, any_between,
map, map,
bytes_iter, bytes_iter,
chars_iter, chars_iter,
@ -63,14 +62,11 @@ export
lines_iter, lines_iter,
// Searching // Searching
//index_chars, find, find_from, find_between,
index, rfind, rfind_from, rfind_between,
index_from, find_char, find_char_from, find_char_between,
rindex, rfind_char, rfind_char_from, rfind_char_between,
//rindex_chars, find_str, find_str_from, find_str_between,
find,
find_from,
find_chars,
contains, contains,
starts_with, starts_with,
ends_with, ends_with,
@ -81,29 +77,23 @@ export
is_not_empty, is_not_empty,
is_whitespace, is_whitespace,
len, len,
len_chars, char_len,
// Misc // Misc
// FIXME: perhaps some more of this section shouldn't be exported?
is_utf8, is_utf8,
substr_len, count_chars, count_bytes,
substr_len_chars,
utf8_char_width, utf8_char_width,
char_range_at, char_range_at,
is_char_boundary, is_char_boundary,
char_at, char_at,
substr_all,
escape_char,
as_bytes, as_bytes,
as_buf, as_buf,
//buf,
sbuf, sbuf,
reserve, reserve,
unsafe; unsafe;
#[abi = "cdecl"] #[abi = "cdecl"]
native mod rustrt { native mod rustrt {
fn rust_str_push(&s: str, ch: u8); fn rust_str_push(&s: str, ch: u8);
@ -303,18 +293,14 @@ Function: trim_left
Returns a string with leading whitespace removed. Returns a string with leading whitespace removed.
*/ */
fn trim_left(s: str) -> str { fn trim_left(+s: str) -> str {
fn count_whities(s: [char]) -> uint { alt find(s, {|c| !char::is_whitespace(c)}) {
let i = 0u; none { "" }
while i < vec::len(s) { some(first) {
if !char::is_whitespace(s[i]) { break; } if first == 0u { s }
i += 1u; else unsafe { unsafe::slice_bytes(s, first, len(s)) }
} }
ret i;
} }
let chars = chars(s);
let whities = count_whities(chars);
ret from_chars(vec::slice(chars, whities, vec::len(chars)));
} }
/* /*
@ -322,18 +308,15 @@ Function: trim_right
Returns a string with trailing whitespace removed. Returns a string with trailing whitespace removed.
*/ */
fn trim_right(s: str) -> str { fn trim_right(+s: str) -> str {
fn count_whities(s: [char]) -> uint { alt rfind(s, {|c| !char::is_whitespace(c)}) {
let i = vec::len(s); none { "" }
while 0u < i { some(last) {
if !char::is_whitespace(s[i - 1u]) { break; } let {next, _} = char_range_at(s, last);
i -= 1u; if next == len(s) { s }
else unsafe { unsafe::slice_bytes(s, 0u, next) }
} }
ret i;
} }
let chars = chars(s);
let whities = count_whities(chars);
ret from_chars(vec::slice(chars, 0u, whities));
} }
/* /*
@ -341,8 +324,7 @@ Function: trim
Returns a string with leading and trailing whitespace removed Returns a string with leading and trailing whitespace removed
*/ */
fn trim(s: str) -> str { trim_left(trim_right(s)) } fn trim(+s: str) -> str { trim_left(trim_right(s)) }
/* /*
Section: Transforming strings Section: Transforming strings
@ -376,15 +358,11 @@ fn chars(s: str) -> [char] {
/* /*
Function: substr Function: substr
Take a substring of another. Returns a string containing `len` bytes Take a substring of another. Returns a string containing `n`
starting at char offset `begin`. characters starting at byte offset `begin`.
Failure:
If `begin` + `len` is is greater than the char length of the string
*/ */
fn substr(s: str, begin: uint, len: uint) -> str { fn substr(s: str, begin: uint, n: uint) -> str {
ret slice(s, begin, begin + len); slice(s, begin, begin + count_bytes(s, begin, n))
} }
// Function: slice // Function: slice
@ -633,17 +611,6 @@ fn replace(s: str, from: str, to: str) -> str unsafe {
result result
} }
/*
Function: escape
Escapes special characters inside the string, making it safe for transfer.
*/
fn escape(s: str) -> str {
let r = "";
chars_iter(s) { |c| r += escape_char(c) };
r
}
/* /*
Section: Comparing strings Section: Comparing strings
*/ */
@ -670,7 +637,6 @@ String hash function
fn hash(&&s: str) -> uint { fn hash(&&s: str) -> uint {
// djb hash. // djb hash.
// FIXME: replace with murmur. // FIXME: replace with murmur.
let u: uint = 5381u; let u: uint = 5381u;
for c: u8 in s { u *= 33u; u += c as uint; } for c: u8 in s { u *= 33u; u += c as uint; }
ret u; ret u;
@ -686,8 +652,8 @@ Function: all
Return true if a predicate matches all characters or Return true if a predicate matches all characters or
if the string contains no characters if the string contains no characters
*/ */
fn all(s: str, it: fn(char) -> bool) -> bool{ fn all(s: str, it: fn(char) -> bool) -> bool {
ret substr_all(s, 0u, len(s), it); all_between(s, 0u, len(s), it)
} }
/* /*
@ -708,12 +674,8 @@ Apply a function to each character
fn map(ss: str, ff: fn(char) -> char) -> str { fn map(ss: str, ff: fn(char) -> char) -> str {
let result = ""; let result = "";
reserve(result, len(ss)); reserve(result, len(ss));
chars_iter(ss) {|cc| str::push_char(result, ff(cc));}
chars_iter(ss, {|cc| result
str::push_char(result, ff(cc));
});
ret result;
} }
/* /*
@ -787,172 +749,192 @@ fn lines_iter(ss: str, ff: fn(&&str)) {
Section: Searching Section: Searching
*/ */
// Function: index // Function: find_char
// //
// Returns the byte index of the first matching char // Returns the byte index of the first matching char
// (as option some/none) // (as option some/none)
fn index(ss: str, cc: char) -> option<uint> { fn find_char(s: str, c: char) -> option<uint> {
index_from(ss, cc, 0u, len(ss)) find_char_between(s, c, 0u, len(s))
} }
// Function: index_from // Function: find_char_from
// //
// Returns the byte index of the first matching char // Returns the byte index of the first matching char
// (as option some/none), starting at `nn` // (as option some/none), starting from `start`
fn index_from(ss: str, cc: char, start: uint, end: uint) -> option<uint> { fn find_char_from(s: str, c: char, from: uint) -> option<uint> {
let bii = start; find_char_between(s, c, from, len(s))
while bii < end {
let {ch, next} = char_range_at(ss, bii);
// found here?
if ch == cc {
ret some(bii);
}
bii = next;
}
// wasn't found
ret none;
} }
// Function: index_chars // Function: find_char_between
//
// Returns the char index of the first matching char
// (as option some/none)
// FIXME: delete?
fn index_chars(ss: str, cc: char) -> option<uint> {
let bii = 0u;
let cii = 0u;
let len = len(ss);
while bii < len {
let {ch, next} = char_range_at(ss, bii);
// found here?
if ch == cc {
ret some(cii);
}
cii += 1u;
bii = next;
}
// wasn't found
ret none;
}
// Function: rindex
// //
// Returns the byte index of the first matching char // Returns the byte index of the first matching char
// (as option some/none) // (as option some/none), between `start` and `end`
fn rindex(ss: str, cc: char) -> option<uint> { fn find_char_between(s: str, c: char, start: uint, end: uint)
let bii = len(ss);
while bii > 0u {
let {ch, prev} = char_range_at_reverse(ss, bii);
bii = prev;
// found here?
if ch == cc {
ret some(bii);
}
}
// wasn't found
ret none;
}
// Function: rindex_chars
//
// Returns the char index of the first matching char
// (as option some/none)
// FIXME: delete?
fn rindex_chars(ss: str, cc: char) -> option<uint> {
let bii = len(ss);
let cii = len_chars(ss);
while bii > 0u {
let {ch, prev} = char_range_at_reverse(ss, bii);
cii -= 1u;
bii = prev;
// found here?
if ch == cc {
ret some(cii);
}
}
// wasn't found
ret none;
}
//Function: find
//
// Find the byte position of the first instance of one string
// within another, or return option::none
fn find(haystack: str, needle: str) -> option<uint> {
find_from(haystack, needle, 0u, len(haystack))
}
//Function: find_from
//
// Find the byte position of the first instance of one string
// within another, or return option::none
//
// FIXME: Boyer-Moore should be significantly faster
fn find_from(haystack: str, needle: str, start: uint, end:uint)
-> option<uint> { -> option<uint> {
if c < 128u as char {
assert start <= end;
assert end <= len(s);
let i = start, b = c as u8;
while i < end {
if s[i] == b { ret some(i); }
i += 1u;
}
ret none;
} else {
find_between(s, start, end, {|x| x == c})
}
}
// Function: rfind_char
//
// Returns the byte index of the last matching char
// (as option some/none)
fn rfind_char(s: str, c: char) -> option<uint> {
rfind_char_between(s, c, len(s), 0u)
}
// Function: rfind_char_from
//
// Returns the byte index of the last matching char
// (as option some/none), starting from `start`
fn rfind_char_from(s: str, c: char, start: uint) -> option<uint> {
rfind_char_between(s, c, start, 0u)
}
// Function: rfind_char_between
//
// Returns the byte index of the last matching char (as option
// some/none), between from `start` and `end` (start must be greater
// than or equal to end)
fn rfind_char_between(s: str, c: char, start: uint, end: uint)
-> option<uint> {
if c < 128u as char {
assert start >= end;
assert start <= len(s);
let i = start, b = c as u8;
while i > end {
i -= 1u;
if s[i] == b { ret some(i); }
}
ret none;
} else {
rfind_between(s, start, end, {|x| x == c})
}
}
// Function: find
//
// Returns, as an option, the first character that passes the given
// predicate
fn find(s: str, f: fn(char) -> bool) -> option<uint> {
find_between(s, 0u, len(s), f)
}
// Function: find_from
//
// Returns, as an option, the first character that passes the given
// predicate, starting at byte offset `start`
fn find_from(s: str, start: uint, f: fn(char) -> bool) -> option<uint> {
find_between(s, start, len(s), f)
}
// Function: find_between
//
// Returns, as an option, the first character that passes the given
// predicate, between byte offsets `start` and `end`
fn find_between(s: str, start: uint, end: uint, f: fn(char) -> bool)
-> option<uint> {
assert start <= end;
assert end <= len(s);
assert is_char_boundary(s, start);
let i = start;
while i < end {
let {ch, next} = char_range_at(s, i);
if f(ch) { ret some(i); }
i = next;
}
ret none;
}
// Function: rfind
//
// Returns, as an option, the last character in the string that passes
// the given predicate
fn rfind(s: str, f: fn(char) -> bool) -> option<uint> {
rfind_between(s, len(s), 0u, f)
}
// Function: rfind_from
//
// Returns, as an option, the last character that passes the given
// predicate, up until byte offset `start`
fn rfind_from(s: str, start: uint, f: fn(char) -> bool) -> option<uint> {
rfind_between(s, start, 0u, f)
}
// Function: rfind_between
//
// Returns, as an option, the last character that passes the given
// predicate, between byte offsets `start` and `end` (`start` must be
// greater than or equal to `end`)
fn rfind_between(s: str, start: uint, end: uint, f: fn(char) -> bool)
-> option<uint> {
assert start >= end;
assert start <= len(s);
assert is_char_boundary(s, start);
let i = start;
while i > end {
let {ch, prev} = char_range_at_reverse(s, i);
if f(ch) { ret some(prev); }
i = prev;
}
ret none;
}
// Utility used by various searching functions
fn match_at(haystack: str, needle: str, at: uint) -> bool {
let i = at;
for c in needle { if haystack[i] != c { ret false; } i += 1u; }
ret true;
}
//Function: find_str
//
// Find the byte position of the first instance of one string
// within another, or return option::none
fn find_str(haystack: str, needle: str) -> option<uint> {
find_str_between(haystack, needle, 0u, len(haystack))
}
//Function: find_str_from
//
// Find the byte position of the first instance of one string
// within another, or return option::none
fn find_str_from(haystack: str, needle: str, start: uint)
-> option<uint> {
find_str_between(haystack, needle, start, len(haystack))
}
//Function: find_str_between
//
// Find the byte position of the first instance of one string
// within another, or return option::none
fn find_str_between(haystack: str, needle: str, start: uint, end:uint)
-> option<uint> {
// FIXME: Boyer-Moore should be significantly faster
assert end <= len(haystack); assert end <= len(haystack);
let needle_len = len(needle); let needle_len = len(needle);
if needle_len == 0u { ret some(start); } if needle_len == 0u { ret some(start); }
if needle_len > end { ret none; } if needle_len > end { ret none; }
fn match_at(haystack: str, needle: str, ii: uint) -> bool { let i = start, e = end - needle_len;
let jj = ii; while i <= e {
for c: u8 in needle { if haystack[jj] != c { ret false; } jj += 1u; } if match_at(haystack, needle, i) { ret some(i); }
ret true; i += 1u;
} }
let ii = start;
while ii <= end - needle_len {
if match_at(haystack, needle, ii) { ret some(ii); }
ii += 1u;
}
ret none; ret none;
} }
// Function: find_chars
//
// Find the char position of the first instance of one string
// within another, or return option::none
// FIXME: delete?
fn find_chars(haystack: str, needle: str) -> option<uint> {
alt find(haystack, needle) {
none { ret none; }
some(nn) { ret some(b2c_pos(haystack, nn)); }
}
}
// Function: b2c_pos
//
// Convert a byte position into a char position
// within a given string
fn b2c_pos(ss: str, bpos: uint) -> uint {
assert bpos == 0u || bpos < len(ss);
let ii = 0u;
let cpos = 0u;
while ii < bpos {
let sz = utf8_char_width(ss[ii]);
ii += sz;
cpos += 1u;
}
ret cpos;
}
/* /*
Function: contains Function: contains
@ -964,7 +946,7 @@ haystack - The string to look in
needle - The string to look for needle - The string to look for
*/ */
fn contains(haystack: str, needle: str) -> bool { fn contains(haystack: str, needle: str) -> bool {
option::is_some(find(haystack, needle)) option::is_some(find_str(haystack, needle))
} }
/* /*
@ -978,11 +960,10 @@ haystack - The string to look in
needle - The string to look for needle - The string to look for
*/ */
fn starts_with(haystack: str, needle: str) -> bool unsafe { fn starts_with(haystack: str, needle: str) -> bool unsafe {
let haystack_len: uint = len(haystack); let haystack_len = len(haystack), needle_len = len(needle);
let needle_len: uint = len(needle); if needle_len == 0u { true }
if needle_len == 0u { ret true; } else if needle_len > haystack_len { false }
if needle_len > haystack_len { ret false; } else { match_at(haystack, needle, 0u) }
ret eq(unsafe::slice_bytes(haystack, 0u, needle_len), needle);
} }
/* /*
@ -994,16 +975,10 @@ haystack - The string to look in
needle - The string to look for needle - The string to look for
*/ */
fn ends_with(haystack: str, needle: str) -> bool { fn ends_with(haystack: str, needle: str) -> bool {
let haystack_len: uint = len(haystack); let haystack_len = len(haystack), needle_len = len(needle);
let needle_len: uint = len(needle); if needle_len == 0u { true }
ret if needle_len == 0u { else if needle_len > haystack_len { false }
true else { match_at(haystack, needle, haystack_len - needle_len) }
} else if needle_len > haystack_len {
false
} else {
eq(substr(haystack, haystack_len - needle_len, needle_len),
needle)
};
} }
/* /*
@ -1054,10 +1029,10 @@ pure fn len(s: str) -> uint unsafe {
(*repr).fill - 1u (*repr).fill - 1u
} }
// FIXME: delete? // Function: char_len
fn len_chars(s: str) -> uint { //
substr_len_chars(s, 0u, len(s)) // Returns the number of characters that a string holds
} fn char_len(s: str) -> uint { count_chars(s, 0u, len(s)) }
/* /*
Section: Misc Section: Misc
@ -1086,68 +1061,44 @@ fn is_utf8(v: [u8]) -> bool {
} }
/* /*
Function: substr_len_chars Function: count_chars
As char_len but for a slice of a string As char_len but for a slice of a string
Parameters: Parameters:
s - A valid string s - A valid string
byte_start - The position inside `s` where to start counting in bytes. start - The position inside `s` where to start counting in bytes.
byte_len - The number of bytes of `s` to take into account. end - The position where to stop counting
Returns: Returns:
The number of Unicode characters in `s` in The number of Unicode characters in `s` between the given indices.
segment [byte_start, byte_start+len( .
Safety note:
- This function does not check whether the substring is valid.
- This function fails if `byte_offset` or `byte_len` do not
represent valid positions inside `s`
FIXME: delete?
*/ */
fn substr_len_chars(s: str, byte_start: uint, byte_len: uint) -> uint { fn count_chars(s: str, start: uint, end: uint) -> uint {
let i = byte_start; assert is_char_boundary(s, start);
let byte_stop = i + byte_len; assert is_char_boundary(s, end);
let len = 0u; let i = start, len = 0u;
while i < byte_stop { while i < end {
let chsize = utf8_char_width(s[i]); let {next, _} = char_range_at(s, i);
assert (chsize > 0u);
len += 1u; len += 1u;
i += chsize; i = next;
} }
ret len; ret len;
} }
/* // Function count_bytes
Function: substr_len //
// Counts the number of bytes taken by the `n` in `s` starting from
As byte_len but for a substring // `start`.
fn count_bytes(s: str, start: uint, n: uint) -> uint {
Parameters: assert is_char_boundary(s, start);
s - A string let end = start, cnt = n, l = len(s);
byte_offset - The byte offset at which to start in the string while cnt > 0u {
char_len - The number of chars (not bytes!) in the range assert end < l;
let {next, _} = char_range_at(s, end);
Returns: cnt -= 1u;
The number of bytes in the substring starting at `byte_offset` and end = next;
containing `char_len` chars.
Safety note:
This function fails if `byte_offset` or `char_len` do not represent
valid positions in `s`
*/
fn substr_len(s: str, byte_offset: uint, char_len: uint) -> uint {
let i = byte_offset;
let chars = 0u;
while chars < char_len {
let chsize = utf8_char_width(s[i]);
assert (chsize > 0u);
i += chsize;
chars += 1u;
} }
ret i - byte_offset; end - start
} }
/* /*
@ -1159,10 +1110,8 @@ Given a first byte, determine how many bytes are in this UTF-8 character
pure fn utf8_char_width(b: u8) -> uint { pure fn utf8_char_width(b: u8) -> uint {
let byte: uint = b as uint; let byte: uint = b as uint;
if byte < 128u { ret 1u; } if byte < 128u { ret 1u; }
if byte < 192u { // Not a valid start byte
ret 0u; // Not a valid start byte if byte < 192u { ret 0u; }
}
if byte < 224u { ret 2u; } if byte < 224u { ret 2u; }
if byte < 240u { ret 3u; } if byte < 240u { ret 3u; }
if byte < 248u { ret 4u; } if byte < 248u { ret 4u; }
@ -1170,6 +1119,18 @@ pure fn utf8_char_width(b: u8) -> uint {
ret 6u; ret 6u;
} }
/*
Function is_char_boundary
Returns false if the index points into the middle of a multi-byte
character sequence.
*/
pure fn is_char_boundary(s: str, index: uint) -> bool {
if index == len(s) { ret true; }
let b = s[index];
ret b < 128u8 || b >= 192u8;
}
/* /*
Function: char_range_at Function: char_range_at
@ -1235,18 +1196,6 @@ fn char_range_at(s: str, i: uint) -> {ch: char, next: uint} {
ret {ch: val as char, next: i}; ret {ch: val as char, next: i};
} }
/*
Function is_char_boundary
Returns false if the index points into the middle of a multi-byte
character sequence.
*/
pure fn is_char_boundary(s: str, index: uint) -> bool {
if index == len(s) { ret true; }
let b = s[index];
ret b < 128u8 || b >= 192u8;
}
/* /*
Function: char_at Function: char_at
@ -1274,14 +1223,14 @@ fn char_range_at_reverse(ss: str, start: uint) -> {ch: char, prev: uint} {
} }
/* /*
Function: substr_all Function: all_between
Loop through a substring, char by char Loop through a substring, char by char
Parameters: Parameters:
s - A string to traverse. It may be empty. s - A string to traverse. It may be empty.
byte_offset - The byte offset at which to start in the string. start - The byte offset at which to start in the string.
byte_len - The number of bytes to traverse in the string end - The end of the range to traverse
it - A block to execute with each consecutive character of `s`. it - A block to execute with each consecutive character of `s`.
Return `true` to continue, `false` to stop. Return `true` to continue, `false` to stop.
@ -1295,34 +1244,19 @@ Safety note:
- This function fails if `byte_offset` or `byte_len` do not - This function fails if `byte_offset` or `byte_len` do not
represent valid positions inside `s` represent valid positions inside `s`
*/ */
fn substr_all(s: str, byte_offset: uint, byte_len: uint, fn all_between(s: str, start: uint, end: uint, it: fn(char) -> bool) -> bool {
it: fn(char) -> bool) -> bool { assert is_char_boundary(s, start);
let i = byte_offset; let i = start;
let result = true; while i < end {
while i < byte_len {
let {ch, next} = char_range_at(s, i); let {ch, next} = char_range_at(s, i);
if !it(ch) {result = false; break;} if !it(ch) { ret false; }
i = next; i = next;
} }
ret result; ret true;
} }
fn any_between(s: str, start: uint, end: uint, it: fn(char) -> bool) -> bool {
/* !all_between(s, start, end, {|c| !it(c)})
Function: escape_char
Escapes a single character.
*/
fn escape_char(c: char) -> str {
alt c {
'"' { "\\\"" }
'\\' { "\\\\" }
'\n' { "\\n" }
'\t' { "\\t" }
'\r' { "\\r" }
'\x00' to '\x1f' { #fmt["\\x%02x", c as uint] }
v { from_char(c) }
}
} }
// UTF-8 tags and ranges // UTF-8 tags and ranges
@ -1395,7 +1329,6 @@ mod unsafe {
from_bytes, from_bytes,
from_byte, from_byte,
slice_bytes, slice_bytes,
slice_bytes_safe_range,
push_byte, push_byte,
push_bytes, push_bytes,
pop_byte, pop_byte,
@ -1441,18 +1374,6 @@ mod unsafe {
ret s; ret s;
} }
/*
Function: slice_bytes_safe_range
Like slice_bytes, with a precondition
*/
unsafe fn slice_bytes_safe_range(s: str, begin: uint, end: uint)
: uint::le(begin, end) -> str {
// would need some magic to make this a precondition
assert (end <= len(s));
ret slice_bytes(s, begin, end);
}
// Function: push_byte // Function: push_byte
// //
// Appends a byte to a string. (Not UTF-8 safe). // Appends a byte to a string. (Not UTF-8 safe).
@ -1526,39 +1447,23 @@ mod tests {
assert (len("\u2620") == 3u); assert (len("\u2620") == 3u);
assert (len("\U0001d11e") == 4u); assert (len("\U0001d11e") == 4u);
assert (len_chars("") == 0u); assert (char_len("") == 0u);
assert (len_chars("hello world") == 11u); assert (char_len("hello world") == 11u);
assert (len_chars("\x63") == 1u); assert (char_len("\x63") == 1u);
assert (len_chars("\xa2") == 1u); assert (char_len("\xa2") == 1u);
assert (len_chars("\u03c0") == 1u); assert (char_len("\u03c0") == 1u);
assert (len_chars("\u2620") == 1u); assert (char_len("\u2620") == 1u);
assert (len_chars("\U0001d11e") == 1u); assert (char_len("\U0001d11e") == 1u);
assert (len_chars("ประเทศไทย中华Việt Nam") == 19u); assert (char_len("ประเทศไทย中华Việt Nam") == 19u);
} }
#[test] #[test]
fn test_index_chars() { fn test_rfind_char() {
assert ( index_chars("hello", 'h') == some(0u)); assert rfind_char("hello", 'l') == some(3u);
assert ( index_chars("hello", 'e') == some(1u)); assert rfind_char("hello", 'o') == some(4u);
assert ( index_chars("hello", 'o') == some(4u)); assert rfind_char("hello", 'h') == some(0u);
assert ( index_chars("hello", 'z') == none); assert rfind_char("hello", 'z') == none;
} assert rfind_char("ประเทศไทย中华Việt Nam", '华') == some(30u);
#[test]
fn test_rindex() {
assert rindex("hello", 'l') == some(3u);
assert rindex("hello", 'o') == some(4u);
assert rindex("hello", 'h') == some(0u);
assert rindex("hello", 'z') == none;
assert rindex("ประเทศไทย中华Việt Nam", '华') == some(30u);
}
#[test]
fn test_rindex_chars() {
assert (rindex_chars("hello", 'l') == some(3u));
assert (rindex_chars("hello", 'o') == some(4u));
assert (rindex_chars("hello", 'h') == some(0u));
assert (rindex_chars("hello", 'z') == none);
} }
#[test] #[test]
@ -1752,67 +1657,45 @@ mod tests {
} }
#[test] #[test]
fn test_find() { fn test_find_str() {
// byte positions // byte positions
assert (find("banana", "apple pie") == none); assert find_str("banana", "apple pie") == none;
assert (find("", "") == some(0u)); assert find_str("", "") == some(0u);
let data = "ประเทศไทย中华Việt Nam"; let data = "ประเทศไทย中华Việt Nam";
assert (find(data, "") == some(0u)); assert find_str(data, "") == some(0u);
assert (find(data, "ประเ") == some( 0u)); assert find_str(data, "ประเ") == some( 0u);
assert (find(data, "ะเ") == some( 6u)); assert find_str(data, "ะเ") == some( 6u);
assert (find(data, "中华") == some(27u)); assert find_str(data, "中华") == some(27u);
assert (find(data, "ไท华") == none); assert find_str(data, "ไท华") == none;
} }
#[test] #[test]
fn test_find_from() { fn test_find_str_between() {
// byte positions // byte positions
assert (find_from("", "", 0u, 0u) == some(0u)); assert find_str_between("", "", 0u, 0u) == some(0u);
let data = "abcabc"; let data = "abcabc";
assert find_from(data, "ab", 0u, 6u) == some(0u); assert find_str_between(data, "ab", 0u, 6u) == some(0u);
assert find_from(data, "ab", 2u, 6u) == some(3u); assert find_str_between(data, "ab", 2u, 6u) == some(3u);
assert find_from(data, "ab", 2u, 4u) == none; assert find_str_between(data, "ab", 2u, 4u) == none;
let data = "ประเทศไทย中华Việt Nam"; let data = "ประเทศไทย中华Việt Nam";
data += data; data += data;
assert find_from(data, "", 0u, 43u) == some(0u); assert find_str_between(data, "", 0u, 43u) == some(0u);
assert find_from(data, "", 6u, 43u) == some(6u); assert find_str_between(data, "", 6u, 43u) == some(6u);
assert find_from(data, "ประ", 0u, 43u) == some( 0u); assert find_str_between(data, "ประ", 0u, 43u) == some( 0u);
assert find_from(data, "ทศไ", 0u, 43u) == some(12u); assert find_str_between(data, "ทศไ", 0u, 43u) == some(12u);
assert find_from(data, "ย中", 0u, 43u) == some(24u); assert find_str_between(data, "ย中", 0u, 43u) == some(24u);
assert find_from(data, "iệt", 0u, 43u) == some(34u); assert find_str_between(data, "iệt", 0u, 43u) == some(34u);
assert find_from(data, "Nam", 0u, 43u) == some(40u); assert find_str_between(data, "Nam", 0u, 43u) == some(40u);
assert find_from(data, "ประ", 43u, 86u) == some(43u); assert find_str_between(data, "ประ", 43u, 86u) == some(43u);
assert find_from(data, "ทศไ", 43u, 86u) == some(55u); assert find_str_between(data, "ทศไ", 43u, 86u) == some(55u);
assert find_from(data, "ย中", 43u, 86u) == some(67u); assert find_str_between(data, "ย中", 43u, 86u) == some(67u);
assert find_from(data, "iệt", 43u, 86u) == some(77u); assert find_str_between(data, "iệt", 43u, 86u) == some(77u);
assert find_from(data, "Nam", 43u, 86u) == some(83u); assert find_str_between(data, "Nam", 43u, 86u) == some(83u);
}
#[test]
fn test_find_chars() {
// char positions
assert (find_chars("banana", "apple pie") == none);
assert (find_chars("", "") == some(0u));
let data = "ประเทศไทย中华Việt Nam";
assert (find_chars(data, "") == some(0u));
assert (find_chars(data, "ประเ") == some(0u));
assert (find_chars(data, "ะเ") == some(2u));
assert (find_chars(data, "中华") == some(9u));
assert (find_chars(data, "ไท华") == none);
}
#[test]
fn test_b2c_pos() {
let data = "ประเทศไทย中华Việt Nam";
assert 0u == b2c_pos(data, 0u);
assert 2u == b2c_pos(data, 6u);
assert 9u == b2c_pos(data, 27u);
} }
#[test] #[test]
@ -1822,9 +1705,7 @@ mod tests {
} }
t("hello", "llo", 2); t("hello", "llo", 2);
t("hello", "el", 1); t("hello", "el", 1);
assert "ะเทศไท" == substr("ประเทศไทย中华Việt Nam", 6u, 6u);
assert "ะเทศไท"
== substr("ประเทศไทย中华Việt Nam", 6u, 18u);
} }
#[test] #[test]
@ -2312,19 +2193,6 @@ mod tests {
} }
} }
#[test]
fn test_escape() {
assert(escape("abcdef") == "abcdef");
assert(escape("abc\\def") == "abc\\\\def");
assert(escape("abc\ndef") == "abc\\ndef");
assert(escape("abc\"def") == "abc\\\"def");
}
#[test]
fn test_escape_char() {
assert escape_char('\x1f') == "\\x1f";
}
#[test] #[test]
fn test_map() { fn test_map() {
assert "" == map("", char::to_upper); assert "" == map("", char::to_upper);

View file

@ -33,19 +33,15 @@ A path or fragment of a filesystem path
type path = str; type path = str;
fn splitDirnameBasename (pp: path) -> {dirname: str, basename: str} { fn splitDirnameBasename (pp: path) -> {dirname: str, basename: str} {
let ii; alt str::rfind(pp, {|ch|
alt str::rindex(pp, os_fs::path_sep) { ch == os_fs::path_sep || ch == os_fs::alt_path_sep
option::some(xx) { ii = xx; } }) {
option::none { some(i) {
alt str::rindex(pp, os_fs::alt_path_sep) { {dirname: str::slice(pp, 0u, i),
option::some(xx) { ii = xx; } basename: str::slice(pp, i + 1u, str::len(pp))}
option::none { ret {dirname: ".", basename: pp}; }
} }
none { {dirname: ".", basename: pp} }
} }
}
ret {dirname: str::slice(pp, 0u, ii),
basename: str::slice(pp, ii + 1u, str::len(pp))};
} }
/* /*

View file

@ -3,10 +3,6 @@
import float; import float;
import map; import map;
import core::option;
import option::{some, none};
import str;
import vec;
export json; export json;
export to_str; export to_str;

View file

@ -743,7 +743,7 @@ mod node {
*/ */
fn of_substr(str: @str, byte_start: uint, byte_len: uint) -> @node { fn of_substr(str: @str, byte_start: uint, byte_len: uint) -> @node {
ret of_substr_unsafer(str, byte_start, byte_len, ret of_substr_unsafer(str, byte_start, byte_len,
str::substr_len_chars(*str, byte_start, byte_len)); str::count_chars(*str, byte_start, byte_len));
} }
/* /*
@ -795,7 +795,7 @@ mod node {
if i == 0u { first_leaf_char_len } if i == 0u { first_leaf_char_len }
else { hint_max_leaf_char_len }; else { hint_max_leaf_char_len };
let chunk_byte_len = let chunk_byte_len =
str::substr_len(*str, offset, chunk_char_len); str::count_bytes(*str, offset, chunk_char_len);
nodes[i] = @leaf({ nodes[i] = @leaf({
byte_offset: offset, byte_offset: offset,
byte_len: chunk_byte_len, byte_len: chunk_byte_len,
@ -998,7 +998,7 @@ mod node {
alt(*node) { alt(*node) {
node::leaf(x) { node::leaf(x) {
let char_len = let char_len =
str::substr_len_chars(*x.content, byte_offset, byte_len); str::count_chars(*x.content, byte_offset, byte_len);
ret @leaf({byte_offset: byte_offset, ret @leaf({byte_offset: byte_offset,
byte_len: byte_len, byte_len: byte_len,
char_len: char_len, char_len: char_len,
@ -1059,9 +1059,9 @@ mod node {
ret node; ret node;
} }
let byte_offset = let byte_offset =
str::substr_len(*x.content, 0u, char_offset); str::count_bytes(*x.content, 0u, char_offset);
let byte_len = let byte_len =
str::substr_len(*x.content, byte_offset, char_len); str::count_bytes(*x.content, byte_offset, char_len);
ret @leaf({byte_offset: byte_offset, ret @leaf({byte_offset: byte_offset,
byte_len: byte_len, byte_len: byte_len,
char_len: char_len, char_len: char_len,
@ -1138,7 +1138,7 @@ mod node {
fn loop_chars(node: @node, it: fn(char) -> bool) -> bool { fn loop_chars(node: @node, it: fn(char) -> bool) -> bool {
ret loop_leaves(node, {|leaf| ret loop_leaves(node, {|leaf|
ret str::substr_all(*leaf.content, ret str::all_between(*leaf.content,
leaf.byte_offset, leaf.byte_offset,
leaf.byte_len, it) leaf.byte_len, it)
}) })
@ -1373,7 +1373,7 @@ mod tests {
let sample = @"0123456789ABCDE"; let sample = @"0123456789ABCDE";
let r = of_str(sample); let r = of_str(sample);
assert char_len(r) == str::len_chars(*sample); assert char_len(r) == str::char_len(*sample);
assert rope_to_string(r) == *sample; assert rope_to_string(r) == *sample;
} }
@ -1384,7 +1384,7 @@ mod tests {
while i < 10 { *buf = *buf + *buf; i+=1;} while i < 10 { *buf = *buf + *buf; i+=1;}
let sample = @*buf; let sample = @*buf;
let r = of_str(sample); let r = of_str(sample);
assert char_len(r) == str::len_chars(*sample); assert char_len(r) == str::char_len(*sample);
assert rope_to_string(r) == *sample; assert rope_to_string(r) == *sample;
let string_iter = 0u; let string_iter = 0u;
@ -1427,7 +1427,7 @@ mod tests {
} }
} }
assert len == str::len_chars(*sample); assert len == str::char_len(*sample);
} }
#[test] #[test]

View file

@ -282,7 +282,7 @@ mod test {
astsrv::from_str(source) {|srv| astsrv::from_str(source) {|srv|
let doc = extract::from_srv(srv, ""); let doc = extract::from_srv(srv, "");
let doc = attr_pass::mk_pass()(srv, doc); let doc = attr_pass::mk_pass()(srv, doc);
mk_pass(str::trim)(srv, doc) mk_pass({|s| str::trim(s)})(srv, doc)
} }
} }
} }

View file

@ -56,10 +56,10 @@ fn should_write_modules_last() {
fn d() { }" fn d() { }"
); );
let idx_a = option::get(str::find(markdown, "# Module `a`")); let idx_a = option::get(str::find_str(markdown, "# Module `a`"));
let idx_b = option::get(str::find(markdown, "## Function `b`")); let idx_b = option::get(str::find_str(markdown, "## Function `b`"));
let idx_c = option::get(str::find(markdown, "# Module `c`")); let idx_c = option::get(str::find_str(markdown, "# Module `c`"));
let idx_d = option::get(str::find(markdown, "## Function `d`")); let idx_d = option::get(str::find_str(markdown, "## Function `d`"));
assert idx_b < idx_d; assert idx_b < idx_d;
assert idx_d < idx_a; assert idx_d < idx_a;

View file

@ -10,7 +10,7 @@ is interpreted as the brief description.
export mk_pass; export mk_pass;
fn mk_pass() -> pass { fn mk_pass() -> pass {
desc_pass::mk_pass(str::trim) desc_pass::mk_pass({|s| str::trim(s)})
} }
#[test] #[test]

View file

@ -33,7 +33,7 @@ fn read_grid(f: io::reader) -> grid_t {
let g = vec::init_fn(10u, {|_i| vec::init_elt_mut(10u, 0 as u8) }); let g = vec::init_fn(10u, {|_i| vec::init_elt_mut(10u, 0 as u8) });
while !f.eof() { while !f.eof() {
let comps = str::split_byte(str::trim(f.read_line()), ',' as u8); let comps = str::split_char(str::trim(f.read_line()), ',');
if vec::len(comps) >= 3u { if vec::len(comps) >= 3u {
let row = option::get(uint::from_str(comps[0])) as u8; let row = option::get(uint::from_str(comps[0])) as u8;
let col = option::get(uint::from_str(comps[1])) as u8; let col = option::get(uint::from_str(comps[1])) as u8;

View file

@ -3,7 +3,8 @@ use std;
import str::*; import str::*;
fn main() unsafe { fn main() unsafe {
fn foo(_a: uint, _b: uint) : uint::le(_a, _b) {}
let a: uint = 4u; let a: uint = 4u;
let b: uint = 1u; let b: uint = 1u;
log(error, str::unsafe::slice_bytes_safe_range("kitties", a, b)); log(error, foo(a, b));
} }

View file

@ -1,6 +1,7 @@
// error-pattern:Unsatisfied precondition constraint (for example, uint::le // error-pattern:Unsatisfied precondition constraint (for example, uint::le
fn main() unsafe { fn main() unsafe {
fn foo(_a: uint, _b: uint) : uint::le(_a, _b) {}
let a: uint = 1u; let a: uint = 1u;
let b: uint = 4u; let b: uint = 4u;
let c: uint = 5u; let c: uint = 5u;
@ -13,5 +14,5 @@ fn main() unsafe {
// the next statement, since it's not true in the // the next statement, since it's not true in the
// prestate. // prestate.
let d <- a; let d <- a;
log(debug, str::unsafe::slice_bytes_safe_range("kitties", b, d)); log(debug, foo(b, d));
} }

View file

@ -1,8 +1,9 @@
// error-pattern:Predicate uint::le(a, b) failed // error-pattern:Predicate uint::le(a, b) failed
fn main() unsafe { fn main() unsafe {
fn foo(_a: uint, _b: uint) : uint::le(_a, _b) {}
let a: uint = 4u; let a: uint = 4u;
let b: uint = 1u; let b: uint = 1u;
check (uint::le(a, b)); check (uint::le(a, b));
log(error, str::unsafe::slice_bytes_safe_range("kitties", a, b)); log(error, foo(a, b));
} }

View file

@ -1,9 +1,10 @@
fn main() unsafe { fn main() unsafe {
fn foo(_a: uint, _b: uint) : uint::le(_a, _b) {}
let a: uint = 1u; let a: uint = 1u;
let b: uint = 4u; let b: uint = 4u;
let c: uint = 17u; let c: uint = 17u;
check (uint::le(a, b)); check (uint::le(a, b));
c <- a; c <- a;
log(debug, str::unsafe::slice_bytes_safe_range("kitties", c, b)); log(debug, foo(c, b));
} }

View file

@ -1,7 +1,8 @@
fn main() unsafe { fn main() unsafe {
fn foo(_a: uint, _b: uint) : uint::le(_a, _b) {}
let a: uint = 1u; let a: uint = 1u;
let b: uint = 4u; let b: uint = 4u;
check (uint::le(a, b)); check (uint::le(a, b));
let c <- a; let c <- a;
log(debug, str::unsafe::slice_bytes_safe_range("kitties", c, b)); log(debug, foo(c, b));
} }

View file

@ -1,7 +1,8 @@
fn main() unsafe { fn main() unsafe {
fn foo(_a: uint, _b: uint) : uint::le(_a, _b) {}
let a: uint = 4u; let a: uint = 4u;
let b: uint = 1u; let b: uint = 1u;
check (uint::le(b, a)); check (uint::le(b, a));
b <-> a; b <-> a;
log(debug, str::unsafe::slice_bytes_safe_range("kitties", a, b)); log(debug, foo(a, b));
} }

View file

@ -1,7 +1,8 @@
fn main() unsafe { fn main() unsafe {
fn foo(_a: uint, _b: uint) : uint::le(_a, _b) {}
let a: uint = 1u; let a: uint = 1u;
let b: uint = 4u; let b: uint = 4u;
check (uint::le(a, b)); check uint::le(a, b);
let c = b; let c = b;
log(debug, str::unsafe::slice_bytes_safe_range("kitties", a, c)); log(debug, foo(a, c));
} }

View file

@ -1,6 +1,7 @@
fn main() unsafe { fn main() unsafe {
fn foo(_a: uint, _b: uint) : uint::le(_a, _b) {}
let a: uint = 1u; let a: uint = 1u;
let b: uint = 4u; let b: uint = 4u;
check (uint::le(a, b)); check (uint::le(a, b));
log(debug, str::unsafe::slice_bytes_safe_range("kitties", a, b)); log(debug, foo(a, b));
} }

View file

@ -8,8 +8,8 @@ fn main() {
let s: str = str::from_chars(chs); let s: str = str::from_chars(chs);
assert (str::len(s) == 10u); assert (str::len(s) == 10u);
assert (str::len_chars(s) == 4u); assert (str::char_len(s) == 4u);
assert (vec::len::<char>(str::chars(s)) == 4u); assert (vec::len(str::chars(s)) == 4u);
assert (str::eq(str::from_chars(str::chars(s)), s)); assert (str::eq(str::from_chars(str::chars(s)), s));
assert (str::char_at(s, 0u) == 'e'); assert (str::char_at(s, 0u) == 'e');
assert (str::char_at(s, 1u) == 'é'); assert (str::char_at(s, 1u) == 'é');