From ab6bb035e50f735cb36cc1959e5a097f076a3b74 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 1 Sep 2011 17:27:58 -0700 Subject: Rename std::istr to std::str. Issue #855 --- src/lib/aio.rs | 4 +- src/lib/extifmt.rs | 54 +++--- src/lib/fs.rs | 28 +-- src/lib/generic_os.rs | 18 +- src/lib/getopts.rs | 22 +-- src/lib/io.rs | 34 ++-- src/lib/istr.rs | 462 ------------------------------------------------- src/lib/linux_os.rs | 16 +- src/lib/macos_os.rs | 16 +- src/lib/map.rs | 2 +- src/lib/net.rs | 2 +- src/lib/posix_fs.rs | 2 +- src/lib/run_program.rs | 8 +- src/lib/sha1.rs | 2 +- src/lib/std.rc | 2 +- src/lib/str.rs | 462 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib/term.rs | 2 +- src/lib/test.rs | 4 +- src/lib/uint.rs | 8 +- src/lib/win32_fs.rs | 4 +- src/lib/win32_os.rs | 12 +- 21 files changed, 582 insertions(+), 582 deletions(-) delete mode 100644 src/lib/istr.rs create mode 100644 src/lib/str.rs (limited to 'src/lib') diff --git a/src/lib/aio.rs b/src/lib/aio.rs index e1c8625352b..cdb0e3fb90d 100644 --- a/src/lib/aio.rs +++ b/src/lib/aio.rs @@ -47,8 +47,8 @@ type ctx = chan; fn ip_to_sbuf(ip: net::ip_addr) -> *u8 { // FIXME: This is broken. We're creating a vector, getting a pointer // to its buffer, then dropping the vector. On top of that, the vector - // created by istr::bytes is not null-terminated. - vec::to_ptr(istr::bytes(net::format_addr(ip))) + // created by str::bytes is not null-terminated. + vec::to_ptr(str::bytes(net::format_addr(ip))) } fn connect_task(ip: net::ip_addr, portnum: int, evt: chan) { diff --git a/src/lib/extifmt.rs b/src/lib/extifmt.rs index ea602891868..7f363b661da 100644 --- a/src/lib/extifmt.rs +++ b/src/lib/extifmt.rs @@ -72,10 +72,10 @@ mod ct { fn parse_fmt_string(s: &istr, error: error_fn) -> [piece] { let pieces: [piece] = []; - let lim = istr::byte_len(s); + let lim = str::byte_len(s); let buf = ~""; fn flush_buf(buf: &istr, pieces: &mutable [piece]) -> istr { - if istr::byte_len(buf) > 0u { + if str::byte_len(buf) > 0u { let piece = piece_string(buf); pieces += [piece]; } @@ -83,14 +83,14 @@ mod ct { } let i = 0u; while i < lim { - let curr = istr::substr(s, i, 1u); - if istr::eq(curr, ~"%") { + let curr = str::substr(s, i, 1u); + if str::eq(curr, ~"%") { i += 1u; if i >= lim { error(~"unterminated conversion at end of string"); } - let curr2 = istr::substr(s, i, 1u); - if istr::eq(curr2, ~"%") { + let curr2 = str::substr(s, i, 1u); + if str::eq(curr2, ~"%") { i += 1u; } else { buf = flush_buf(buf, pieces); @@ -217,27 +217,27 @@ mod ct { fn parse_type(s: &istr, i: uint, lim: uint, error: error_fn) -> {ty: ty, next: uint} { if i >= lim { error(~"missing type in conversion"); } - let tstr = istr::substr(s, i, 1u); + let tstr = str::substr(s, i, 1u); // TODO: Do we really want two signed types here? // How important is it to be printf compatible? let t = - if istr::eq(tstr, ~"b") { + if str::eq(tstr, ~"b") { ty_bool - } else if istr::eq(tstr, ~"s") { + } else if str::eq(tstr, ~"s") { ty_str - } else if istr::eq(tstr, ~"c") { + } else if str::eq(tstr, ~"c") { ty_char - } else if istr::eq(tstr, ~"d") || istr::eq(tstr, ~"i") { + } else if str::eq(tstr, ~"d") || str::eq(tstr, ~"i") { ty_int(signed) - } else if istr::eq(tstr, ~"u") { + } else if str::eq(tstr, ~"u") { ty_int(unsigned) - } else if istr::eq(tstr, ~"x") { + } else if str::eq(tstr, ~"x") { ty_hex(case_lower) - } else if istr::eq(tstr, ~"X") { + } else if str::eq(tstr, ~"X") { ty_hex(case_upper) - } else if istr::eq(tstr, ~"t") { + } else if str::eq(tstr, ~"t") { ty_bits - } else if istr::eq(tstr, ~"o") { + } else if str::eq(tstr, ~"o") { ty_octal } else { error(~"unknown type in conversion: " + tstr) }; ret {ty: t, next: i + 1u}; @@ -289,7 +289,7 @@ mod rt { alt cv.ty { ty_default. { uint_to_str_prec(u, 10u, prec) } ty_hex_lower. { uint_to_str_prec(u, 16u, prec) } - ty_hex_upper. { istr::to_upper(uint_to_str_prec(u, 16u, prec)) } + ty_hex_upper. { str::to_upper(uint_to_str_prec(u, 16u, prec)) } ty_bits. { uint_to_str_prec(u, 2u, prec) } ty_octal. { uint_to_str_prec(u, 8u, prec) } }; @@ -303,7 +303,7 @@ mod rt { ret conv_str(cv, s); } fn conv_char(cv: &conv, c: char) -> istr { - ret pad(cv, istr::from_char(c), pad_nozero); + ret pad(cv, str::from_char(c), pad_nozero); } fn conv_str(cv: &conv, s: &istr) -> istr { // For strings, precision is the maximum characters @@ -314,8 +314,8 @@ mod rt { alt cv.precision { count_implied. { s } count_is(max) { - if max as uint < istr::char_len(s) { - istr::substr(s, 0u, max as uint) + if max as uint < str::char_len(s) { + str::substr(s, 0u, max as uint) } else { s } } }; @@ -338,7 +338,7 @@ mod rt { ~"" } else { let s = uint::to_str(num, radix); - let len = istr::char_len(s); + let len = str::char_len(s); if len < prec { let diff = prec - len; let pad = str_init_elt('0', diff); @@ -357,7 +357,7 @@ mod rt { fn str_init_elt(c: char, n_elts: uint) -> istr { let svec = vec::init_elt::(c as u8, n_elts); - ret istr::unsafe_from_bytes(svec); + ret str::unsafe_from_bytes(svec); } tag pad_mode { pad_signed; pad_unsigned; pad_nozero; } fn pad(cv: &conv, s: &istr, mode: pad_mode) -> istr { @@ -370,7 +370,7 @@ mod rt { uwidth = width as uint; } } - let strlen = istr::char_len(s); + let strlen = str::char_len(s); if uwidth <= strlen { ret s; } let padchar = ' '; let diff = uwidth - strlen; @@ -403,12 +403,12 @@ mod rt { // zeros. It may make sense to convert zero padding to a precision // instead. - if signed && zero_padding && istr::byte_len(s) > 0u { + if signed && zero_padding && str::byte_len(s) > 0u { let head = s[0]; if head == '+' as u8 || head == '-' as u8 || head == ' ' as u8 { - let headstr = istr::unsafe_from_bytes([head]); - let bytelen = istr::byte_len(s); - let numpart = istr::substr(s, 1u, bytelen - 1u); + let headstr = str::unsafe_from_bytes([head]); + let bytelen = str::byte_len(s); + let numpart = str::substr(s, 1u, bytelen - 1u); ret headstr + padstr + numpart; } } diff --git a/src/lib/fs.rs b/src/lib/fs.rs index 297c27cb2a8..745c30c80b3 100644 --- a/src/lib/fs.rs +++ b/src/lib/fs.rs @@ -3,37 +3,37 @@ import os::getcwd; import os_fs; native "rust" mod rustrt { - fn rust_file_is_dir(path: istr::sbuf) -> int; + fn rust_file_is_dir(path: str::sbuf) -> int; } -fn path_sep() -> istr { ret istr::from_char(os_fs::path_sep); } +fn path_sep() -> istr { ret str::from_char(os_fs::path_sep); } type path = istr; fn dirname(p: &path) -> path { - let i: int = istr::rindex(p, os_fs::path_sep as u8); + let i: int = str::rindex(p, os_fs::path_sep as u8); if i == -1 { - i = istr::rindex(p, os_fs::alt_path_sep as u8); + i = str::rindex(p, os_fs::alt_path_sep as u8); if i == -1 { ret ~"."; } } - ret istr::substr(p, 0u, i as uint); + ret str::substr(p, 0u, i as uint); } fn basename(p: &path) -> path { - let i: int = istr::rindex(p, os_fs::path_sep as u8); + let i: int = str::rindex(p, os_fs::path_sep as u8); if i == -1 { - i = istr::rindex(p, os_fs::alt_path_sep as u8); + i = str::rindex(p, os_fs::alt_path_sep as u8); if i == -1 { ret p; } } - let len = istr::byte_len(p); + let len = str::byte_len(p); if i + 1 as uint >= len { ret p; } - ret istr::slice(p, i + 1 as uint, len); + ret str::slice(p, i + 1 as uint, len); } // FIXME: Need some typestate to avoid bounds check when len(pre) == 0 fn connect(pre: &path, post: &path) -> path { - let len = istr::byte_len(pre); + let len = str::byte_len(pre); ret if pre[len - 1u] == os_fs::path_sep as u8 { // Trailing '/'? @@ -42,19 +42,19 @@ fn connect(pre: &path, post: &path) -> path { } fn file_is_dir(p: &path) -> bool { - ret istr::as_buf(p, { |buf| + ret str::as_buf(p, { |buf| rustrt::rust_file_is_dir(buf) != 0 }); } fn list_dir(p: &path) -> [istr] { let p = p; - let pl = istr::byte_len(p); + let pl = str::byte_len(p); if pl == 0u || p[pl - 1u] as char != os_fs::path_sep { p += path_sep(); } let full_paths: [istr] = []; for filename: istr in os_fs::list_dir(p) { - if !istr::eq(filename, ~".") { - if !istr::eq(filename, ~"..") { full_paths += [p + filename]; } + if !str::eq(filename, ~".") { + if !str::eq(filename, ~"..") { full_paths += [p + filename]; } } } ret full_paths; diff --git a/src/lib/generic_os.rs b/src/lib/generic_os.rs index 32df07b9c76..169548d106a 100644 --- a/src/lib/generic_os.rs +++ b/src/lib/generic_os.rs @@ -1,17 +1,17 @@ -import istr::sbuf; +import str::sbuf; #[cfg(target_os = "linux")] #[cfg(target_os = "macos")] fn getenv(n: &istr) -> option::t { - let s = istr::as_buf(n, { |buf| + let s = str::as_buf(n, { |buf| os::libc::getenv(buf) }); ret if unsafe::reinterpret_cast(s) == 0 { option::none:: } else { let s = unsafe::reinterpret_cast(s); - option::some::(istr::str_from_cstr(s)) + option::some::(str::str_from_cstr(s)) }; } @@ -19,9 +19,9 @@ fn getenv(n: &istr) -> option::t { #[cfg(target_os = "macos")] fn setenv(n: &istr, v: &istr) { // FIXME (868) - let _: () = istr::as_buf(n, { |nbuf| + let _: () = str::as_buf(n, { |nbuf| // FIXME (868) - let _: () = istr::as_buf(v, { |vbuf| + let _: () = str::as_buf(v, { |vbuf| os::libc::setenv(nbuf, vbuf, 1); }); }); @@ -33,7 +33,7 @@ fn getenv(n: &istr) -> option::t { while true { let v: [u8] = []; vec::reserve(v, nsize); - let res = istr::as_buf(n, { |nbuf| + let res = str::as_buf(n, { |nbuf| let vbuf = vec::to_ptr(v); os::kernel32::GetEnvironmentVariableA(nbuf, vbuf, nsize) }); @@ -41,7 +41,7 @@ fn getenv(n: &istr) -> option::t { ret option::none; } else if res < nsize { vec::unsafe::set_len(v, res); - ret option::some(istr::unsafe_from_bytes(v)); + ret option::some(str::unsafe_from_bytes(v)); } else { nsize = res; } } fail; @@ -50,8 +50,8 @@ fn getenv(n: &istr) -> option::t { #[cfg(target_os = "win32")] fn setenv(n: &istr, v: &istr) { // FIXME (868) - let _: () = istr::as_buf(n, { |nbuf| - let _: () = istr::as_buf(v, { |vbuf| + let _: () = str::as_buf(n, { |nbuf| + let _: () = str::as_buf(v, { |vbuf| os::kernel32::SetEnvironmentVariableA(nbuf, vbuf); }); }); diff --git a/src/lib/getopts.rs b/src/lib/getopts.rs index c38b93ee8b0..3df28220651 100644 --- a/src/lib/getopts.rs +++ b/src/lib/getopts.rs @@ -38,8 +38,8 @@ tag occur { req; optional; multi; } type opt = {name: name, hasarg: hasarg, occur: occur}; fn mkname(nm: &istr) -> name { - ret if istr::char_len(nm) == 1u { - short(istr::char_at(nm, 0u)) + ret if str::char_len(nm) == 1u { + short(str::char_at(nm, 0u)) } else { long(nm) }; } @@ -68,11 +68,11 @@ tag optval { val(istr); given; } type match = {opts: [opt], vals: [mutable [optval]], free: [istr]}; fn is_arg(arg: &istr) -> bool { - ret istr::byte_len(arg) > 1u && arg[0] == '-' as u8; + ret str::byte_len(arg) > 1u && arg[0] == '-' as u8; } fn name_str(nm: &name) -> istr { - ret alt nm { short(ch) { istr::from_char(ch) } long(s) { s } }; + ret alt nm { short(ch) { str::from_char(ch) } long(s) { s } }; } fn find_opt(opts: &[opt], nm: &name) -> option::t { @@ -117,10 +117,10 @@ fn getopts(args: &[istr], opts: &[opt]) -> result { let i = 0u; while i < l { let cur = args[i]; - let curlen = istr::byte_len(cur); + let curlen = str::byte_len(cur); if !is_arg(cur) { free += [cur]; - } else if istr::eq(cur, ~"--") { + } else if str::eq(cur, ~"--") { let j = i + 1u; while j < l { free += [args[j]]; j += 1u; } break; @@ -128,14 +128,14 @@ fn getopts(args: &[istr], opts: &[opt]) -> result { let names; let i_arg = option::none::; if cur[1] == '-' as u8 { - let tail = istr::slice(cur, 2u, curlen); - let eq = istr::index(tail, '=' as u8); + let tail = str::slice(cur, 2u, curlen); + let eq = str::index(tail, '=' as u8); if eq == -1 { names = [long(tail)]; } else { - names = [long(istr::slice(tail, 0u, eq as uint))]; + names = [long(str::slice(tail, 0u, eq as uint))]; i_arg = - option::some::(istr::slice(tail, + option::some::(str::slice(tail, (eq as uint) + 1u, curlen - 2u)); } @@ -143,7 +143,7 @@ fn getopts(args: &[istr], opts: &[opt]) -> result { let j = 1u; names = []; while j < curlen { - let range = istr::char_range_at(cur, j); + let range = str::char_range_at(cur, j); names += [short(range.ch)]; j = range.next; } diff --git a/src/lib/io.rs b/src/lib/io.rs index 50cb1c668c3..57ebb806f52 100644 --- a/src/lib/io.rs +++ b/src/lib/io.rs @@ -88,7 +88,7 @@ obj new_reader(rdr: buf_reader) { } let b0 = c0 as u8; - let w = istr::utf8_char_width(b0); + let w = str::utf8_char_width(b0); assert (w > 0u); if w == 1u { ret b0 as char; } let val = 0u; @@ -117,7 +117,7 @@ obj new_reader(rdr: buf_reader) { go_on = false; } else { buf += [ch as u8]; } } - ret istr::unsafe_from_bytes(buf); + ret str::unsafe_from_bytes(buf); } fn read_c_str() -> istr { let buf: [u8] = []; @@ -126,7 +126,7 @@ obj new_reader(rdr: buf_reader) { let ch = rdr.read_byte(); if ch < 1 { go_on = false; } else { buf += [ch as u8]; } } - ret istr::unsafe_from_bytes(buf); + ret str::unsafe_from_bytes(buf); } // FIXME deal with eof? @@ -175,8 +175,8 @@ fn stdin() -> reader { } fn file_reader(path: &istr) -> reader { - let f = istr::as_buf(path, { |pathbuf| - istr::as_buf(~"r", { |modebuf| + let f = str::as_buf(path, { |pathbuf| + str::as_buf(~"r", { |modebuf| os::libc::fopen(pathbuf, modebuf) }) }); @@ -220,7 +220,7 @@ fn new_byte_buf_reader(buf: &[u8]) -> buf_reader { } fn string_reader(s: &istr) -> reader { - ret new_reader(new_byte_buf_reader(istr::bytes(s))); + ret new_reader(new_byte_buf_reader(str::bytes(s))); } @@ -290,7 +290,7 @@ fn file_buf_writer(path: &istr, flags: &[fileflag]) -> buf_writer { none. { } } } - let fd = istr::as_buf(path, { |pathbuf| + let fd = str::as_buf(path, { |pathbuf| os::libc::open(pathbuf, fflags, os::libc_constants::S_IRUSR() | os::libc_constants::S_IWUSR()) @@ -334,19 +334,19 @@ fn uint_to_be_bytes(n: uint, size: uint) -> [u8] { obj new_writer(out: buf_writer) { fn get_buf_writer() -> buf_writer { ret out; } - fn write_str(s: &istr) { out.write(istr::bytes(s)); } + fn write_str(s: &istr) { out.write(str::bytes(s)); } fn write_line(s: &istr) { - out.write(istr::bytes(s)); - out.write(istr::bytes(~"\n")); + out.write(str::bytes(s)); + out.write(str::bytes(~"\n")); } fn write_char(ch: char) { // FIXME needlessly consy - out.write(istr::bytes(istr::from_char(ch))); + out.write(str::bytes(str::from_char(ch))); } - fn write_int(n: int) { out.write(istr::bytes( + fn write_int(n: int) { out.write(str::bytes( int::to_str(n, 10u))); } - fn write_uint(n: uint) { out.write(istr::bytes( + fn write_uint(n: uint) { out.write(str::bytes( uint::to_str(n, 10u))); } fn write_bytes(bytes: &[u8]) { out.write(bytes); } fn write_le_uint(n: uint, size: uint) { @@ -367,8 +367,8 @@ fn file_writer(path: &istr, flags: &[fileflag]) -> writer { // FIXME: fileflags fn buffered_file_buf_writer(path: &istr) -> buf_writer { - let f = istr::as_buf(path, { |pathbuf| - istr::as_buf(~"w", { |modebuf| + let f = str::as_buf(path, { |pathbuf| + str::as_buf(~"w", { |modebuf| os::libc::fopen(pathbuf, modebuf) }) }); @@ -427,7 +427,7 @@ fn string_writer() -> str_writer { let buf: mutable_byte_buf = @{mutable buf: b, mutable pos: 0u}; obj str_writer_wrap(wr: writer, buf: mutable_byte_buf) { fn get_writer() -> writer { ret wr; } - fn get_str() -> istr { ret istr::unsafe_from_bytes(buf.buf); } + fn get_str() -> istr { ret str::unsafe_from_bytes(buf.buf); } } ret str_writer_wrap(new_writer(byte_buf_writer(buf)), buf); } @@ -448,7 +448,7 @@ fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) -> } fn read_whole_file_str(file: &istr) -> istr { - istr::unsafe_from_bytes(read_whole_file(file)) + str::unsafe_from_bytes(read_whole_file(file)) } fn read_whole_file(file: &istr) -> [u8] { diff --git a/src/lib/istr.rs b/src/lib/istr.rs deleted file mode 100644 index 662d0d0c228..00000000000 --- a/src/lib/istr.rs +++ /dev/null @@ -1,462 +0,0 @@ -export eq, lteq, hash, is_empty, is_not_empty, is_whitespace, byte_len, -index, rindex, find, starts_with, ends_with, substr, slice, split, -concat, connect, to_upper, replace, char_slice, trim_left, trim_right, trim, -unshift_char, shift_char, pop_char, push_char, is_utf8, from_chars, to_chars, -char_len, char_at, bytes, is_ascii, shift_byte, pop_byte, unsafe_from_byte, -unsafe_from_bytes, from_char, char_range_at, str_from_cstr, sbuf, -as_buf, push_byte, utf8_char_width, safe_slice; - -native "rust" mod rustrt { - fn rust_istr_push(s: &mutable istr, ch: u8); -} - -fn eq(a: &istr, b: &istr) -> bool { a == b } - -fn lteq(a: &istr, b: &istr) -> bool { a <= b } - -fn hash(s: &istr) -> uint { - // djb hash. - // FIXME: replace with murmur. - - let u: uint = 5381u; - for c: u8 in s { u *= 33u; u += c as uint; } - ret u; -} - -// UTF-8 tags and ranges -const tag_cont_u8: u8 = 128u8; -const tag_cont: uint = 128u; -const max_one_b: uint = 128u; -const tag_two_b: uint = 192u; -const max_two_b: uint = 2048u; -const tag_three_b: uint = 224u; -const max_three_b: uint = 65536u; -const tag_four_b: uint = 240u; -const max_four_b: uint = 2097152u; -const tag_five_b: uint = 248u; -const max_five_b: uint = 67108864u; -const tag_six_b: uint = 252u; - -fn is_utf8(v: &[u8]) -> bool { - let i = 0u; - let total = vec::len::(v); - while i < total { - let chsize = utf8_char_width(v[i]); - if chsize == 0u { ret false; } - if i + chsize > total { ret false; } - i += 1u; - while chsize > 1u { - if v[i] & 192u8 != tag_cont_u8 { ret false; } - i += 1u; - chsize -= 1u; - } - } - ret true; -} - -fn is_ascii(s: &istr) -> bool { - let i: uint = byte_len(s); - while i > 0u { i -= 1u; if s[i] & 128u8 != 0u8 { ret false; } } - ret true; -} - -/// Returns true if the string has length 0 -pure fn is_empty(s: &istr) -> bool { - for c: u8 in s { ret false; } ret true; -} - -/// Returns true if the string has length greater than 0 -pure fn is_not_empty(s: &istr) -> bool { - !is_empty(s) -} - -fn is_whitespace(s: &istr) -> bool { - let i = 0u; - let len = char_len(s); - while i < len { - if !char::is_whitespace(char_at(s, i)) { ret false; } - i += 1u - } - ret true; -} - -fn byte_len(s: &istr) -> uint { - let v: [u8] = unsafe::reinterpret_cast(s); - let vlen = vec::len(v); - unsafe::leak(v); - // There should always be a null terminator - assert vlen > 0u; - ret vlen - 1u; -} - -fn bytes(s: &istr) -> [u8] { - let v = unsafe::reinterpret_cast(s); - let vcopy = vec::slice(v, 0u, vec::len(v) - 1u); - unsafe::leak(v); - ret vcopy; -} - -fn unsafe_from_bytes(v: &[mutable? u8]) -> istr { - let vcopy: [u8] = v + [0u8]; - let scopy: istr = unsafe::reinterpret_cast(vcopy); - unsafe::leak(vcopy); - ret scopy; -} - -fn unsafe_from_byte(u: u8) -> istr { - unsafe_from_bytes([u]) -} - -fn push_utf8_bytes(s: &mutable istr, ch: char) { - let code = ch as uint; - let bytes = if code < max_one_b { - [code as u8] - } else if code < max_two_b { - [(code >> 6u & 31u | tag_two_b) as u8, - (code & 63u | tag_cont) as u8] - } else if code < max_three_b { - [(code >> 12u & 15u | tag_three_b) as u8, - (code >> 6u & 63u | tag_cont) as u8, - (code & 63u | tag_cont) as u8] - } else if code < max_four_b { - [(code >> 18u & 7u | tag_four_b) as u8, - (code >> 12u & 63u | tag_cont) as u8, - (code >> 6u & 63u | tag_cont) as u8, - (code & 63u | tag_cont) as u8] - } else if code < max_five_b { - [(code >> 24u & 3u | tag_five_b) as u8, - (code >> 18u & 63u | tag_cont) as u8, - (code >> 12u & 63u | tag_cont) as u8, - (code >> 6u & 63u | tag_cont) as u8, - (code & 63u | tag_cont) as u8] - } else { - [(code >> 30u & 1u | tag_six_b) as u8, - (code >> 24u & 63u | tag_cont) as u8, - (code >> 18u & 63u | tag_cont) as u8, - (code >> 12u & 63u | tag_cont) as u8, - (code >> 6u & 63u | tag_cont) as u8, - (code & 63u | tag_cont) as u8] - }; - push_bytes(s, bytes); -} - -fn from_char(ch: char) -> istr { - let buf = ~""; - push_utf8_bytes(buf, ch); - ret buf; -} - -fn from_chars(chs: &[char]) -> istr { - let buf = ~""; - for ch: char in chs { push_utf8_bytes(buf, ch); } - ret buf; -} - -fn utf8_char_width(b: u8) -> uint { - let byte: uint = b as uint; - if byte < 128u { ret 1u; } - if byte < 192u { - ret 0u; // Not a valid start byte - - } - if byte < 224u { ret 2u; } - if byte < 240u { ret 3u; } - if byte < 248u { ret 4u; } - if byte < 252u { ret 5u; } - ret 6u; -} - -fn char_range_at(s: &istr, i: uint) -> {ch: char, next: uint} { - let b0 = s[i]; - let w = utf8_char_width(b0); - assert (w != 0u); - if w == 1u { ret {ch: b0 as char, next: i + 1u}; } - let val = 0u; - let end = i + w; - i += 1u; - while i < end { - let byte = s[i]; - assert (byte & 192u8 == tag_cont_u8); - val <<= 6u; - val += byte & 63u8 as uint; - i += 1u; - } - // Clunky way to get the right bits from the first byte. Uses two shifts, - // the first to clip off the marker bits at the left of the byte, and then - // a second (as uint) to get it to the right position. - val += (b0 << (w + 1u as u8) as uint) << (w - 1u) * 6u - w - 1u; - ret {ch: val as char, next: i}; -} - -fn char_at(s: &istr, i: uint) -> char { ret char_range_at(s, i).ch; } - -fn char_len(s: &istr) -> uint { - let i = 0u; - let len = 0u; - let total = byte_len(s); - while i < total { - let chsize = utf8_char_width(s[i]); - assert (chsize > 0u); - len += 1u; - i += chsize; - } - assert (i == total); - ret len; -} - -fn to_chars(s: &istr) -> [char] { - let buf: [char] = []; - let i = 0u; - let len = byte_len(s); - while i < len { - let cur = char_range_at(s, i); - buf += [cur.ch]; - i = cur.next; - } - ret buf; -} - -fn push_char(s: &mutable istr, ch: char) { s += from_char(ch); } - -fn pop_char(s: &mutable istr) -> char { - let end = byte_len(s); - while end > 0u && s[end - 1u] & 192u8 == tag_cont_u8 { end -= 1u; } - assert (end > 0u); - let ch = char_at(s, end - 1u); - s = substr(s, 0u, end - 1u); - ret ch; -} - -fn shift_char(s: &mutable istr) -> char { - let r = char_range_at(s, 0u); - s = substr(s, r.next, byte_len(s) - r.next); - ret r.ch; -} - -fn unshift_char(s: &mutable istr, ch: char) { s = from_char(ch) + s; } - -fn index(s: &istr, c: u8) -> int { - let i: int = 0; - for k: u8 in s { if k == c { ret i; } i += 1; } - ret -1; -} - -fn rindex(s: &istr, c: u8) -> int { - let n: int = byte_len(s) as int; - while n >= 0 { if s[n] == c { ret n; } n -= 1; } - ret n; -} - -fn find(haystack: &istr, needle: &istr) -> int { - let haystack_len: int = byte_len(haystack) as int; - let needle_len: int = byte_len(needle) as int; - if needle_len == 0 { ret 0; } - fn match_at(haystack: &istr, needle: &istr, i: int) -> bool { - let j: int = i; - for c: u8 in needle { if haystack[j] != c { ret false; } j += 1; } - ret true; - } - let i: int = 0; - while i <= haystack_len - needle_len { - if match_at(haystack, needle, i) { ret i; } - i += 1; - } - ret -1; -} - -fn starts_with(haystack: &istr, needle: &istr) -> bool { - let haystack_len: uint = byte_len(haystack); - let needle_len: uint = byte_len(needle); - if needle_len == 0u { ret true; } - if needle_len > haystack_len { ret false; } - ret eq(substr(haystack, 0u, needle_len), needle); -} - -fn ends_with(haystack: &istr, needle: &istr) -> bool { - let haystack_len: uint = byte_len(haystack); - let needle_len: uint = byte_len(needle); - ret if needle_len == 0u { - true - } else if needle_len > haystack_len { - false - } else { - eq(substr(haystack, haystack_len - needle_len, needle_len), - needle) - }; -} - -fn substr(s: &istr, begin: uint, len: uint) -> istr { - ret slice(s, begin, begin + len); -} - -fn slice(s: &istr, begin: uint, end: uint) -> istr { - // FIXME: Typestate precondition - assert (begin <= end); - assert (end <= byte_len(s)); - - let v: [u8] = unsafe::reinterpret_cast(s); - let v2 = vec::slice(v, begin, end); - unsafe::leak(v); - v2 += [0u8]; - let s2: istr = unsafe::reinterpret_cast(v2); - unsafe::leak(v2); - ret s2; -} - -fn safe_slice(s: &istr, begin: uint, end: uint) - : uint::le(begin, end) -> istr { - // would need some magic to make this a precondition - assert (end <= byte_len(s)); - ret slice(s, begin, end); -} - -fn shift_byte(s: &mutable istr) -> u8 { - let len = byte_len(s); - assert (len > 0u); - let b = s[0]; - s = substr(s, 1u, len - 1u); - ret b; -} - -fn pop_byte(s: &mutable istr) -> u8 { - let len = byte_len(s); - assert (len > 0u); - let b = s[len - 1u]; - s = substr(s, 0u, len - 1u); - ret b; -} - -fn push_byte(s: &mutable istr, b: u8) { - rustrt::rust_istr_push(s, b); -} - -fn push_bytes(s: &mutable istr, bytes: &[u8]) { - for byte in bytes { - rustrt::rust_istr_push(s, byte); - } -} - -fn split(s: &istr, sep: u8) -> [istr] { - let v: [istr] = []; - let accum: istr = ~""; - let ends_with_sep: bool = false; - for c: u8 in s { - if c == sep { - v += [accum]; - accum = ~""; - ends_with_sep = true; - } else { accum += unsafe_from_byte(c); ends_with_sep = false; } - } - if byte_len(accum) != 0u || ends_with_sep { v += [accum]; } - ret v; -} - -fn concat(v: &[istr]) -> istr { - let s: istr = ~""; - for ss: istr in v { s += ss; } - ret s; -} - -fn connect(v: &[istr], sep: &istr) -> istr { - let s: istr = ~""; - let first: bool = true; - for ss: istr in v { - if first { first = false; } else { s += sep; } - s += ss; - } - ret s; -} - -// FIXME: This only handles ASCII -fn to_upper(s: &istr) -> istr { - let outstr = ~""; - let ascii_a = 'a' as u8; - let ascii_z = 'z' as u8; - let diff = 32u8; - for byte: u8 in s { - let next; - if ascii_a <= byte && byte <= ascii_z { - next = byte - diff; - } else { next = byte; } - push_byte(outstr, next); - } - ret outstr; -} - -// FIXME: This is super-inefficient -fn replace(s: &istr, from: &istr, to: &istr) : is_not_empty(from) -> istr { - // FIXME (694): Shouldn't have to check this - check (is_not_empty(from)); - if byte_len(s) == 0u { - ret ~""; - } else if starts_with(s, from) { - ret to + replace(slice(s, byte_len(from), byte_len(s)), from, to); - } else { - ret unsafe_from_byte(s[0]) + - replace(slice(s, 1u, byte_len(s)), from, to); - } -} - -// FIXME: Also not efficient -fn char_slice(s: &istr, begin: uint, end: uint) -> istr { - from_chars(vec::slice(to_chars(s), begin, end)) -} - -fn trim_left(s: &istr) -> istr { - fn count_whities(s: &[char]) -> uint { - let i = 0u; - while i < vec::len(s) { - if !char::is_whitespace(s[i]) { break; } - i += 1u; - } - ret i; - } - let chars = to_chars(s); - let whities = count_whities(chars); - ret from_chars(vec::slice(chars, whities, vec::len(chars))); -} - -fn trim_right(s: &istr) -> istr { - fn count_whities(s: &[char]) -> uint { - let i = vec::len(s); - while 0u < i { - if !char::is_whitespace(s[i - 1u]) { break; } - i -= 1u; - } - ret i; - } - let chars = to_chars(s); - let whities = count_whities(chars); - ret from_chars(vec::slice(chars, 0u, whities)); -} - -fn trim(s: &istr) -> istr { - trim_left(trim_right(s)) -} - -type sbuf = *u8; - -fn buf(s: &istr) -> sbuf { - let saddr = ptr::addr_of(s); - let vaddr: *[u8] = unsafe::reinterpret_cast(saddr); - let buf = vec::to_ptr(*vaddr); - ret buf; -} - -fn as_buf(s: &istr, f: &block(sbuf) -> T) -> T { - let buf = buf(s); - f(buf) -} - -fn str_from_cstr(cstr: sbuf) -> istr { - let res = ~""; - let start = cstr; - let curr = start; - let i = 0u; - while *curr != 0u8 { - push_byte(res, *curr); - i += 1u; - curr = ptr::offset(start, i); - } - ret res; -} \ No newline at end of file diff --git a/src/lib/linux_os.rs b/src/lib/linux_os.rs index be8b99bac80..0081aa18265 100644 --- a/src/lib/linux_os.rs +++ b/src/lib/linux_os.rs @@ -7,11 +7,11 @@ native "cdecl" mod libc = "" { fn write(fd: int, buf: *u8, count: uint) -> int; fn fread(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; fn fwrite(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; - fn open(s: istr::sbuf, flags: int, mode: uint) -> int; + fn open(s: str::sbuf, flags: int, mode: uint) -> int; fn close(fd: int) -> int; type FILE; - fn fopen(path: istr::sbuf, mode: istr::sbuf) -> FILE; - fn fdopen(fd: int, mode: istr::sbuf) -> FILE; + fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE; + fn fdopen(fd: int, mode: str::sbuf) -> FILE; fn fclose(f: FILE); fn fgetc(f: FILE) -> int; fn ungetc(c: int, f: FILE); @@ -19,13 +19,13 @@ native "cdecl" mod libc = "" { fn fseek(f: FILE, offset: int, whence: int) -> int; fn ftell(f: FILE) -> int; type dir; - fn opendir(d: istr::sbuf) -> dir; + fn opendir(d: str::sbuf) -> dir; fn closedir(d: dir) -> int; type dirent; fn readdir(d: dir) -> dirent; - fn getenv(n: istr::sbuf) -> istr::sbuf; - fn setenv(n: istr::sbuf, v: istr::sbuf, overwrite: int) -> int; - fn unsetenv(n: istr::sbuf) -> int; + fn getenv(n: str::sbuf) -> str::sbuf; + fn setenv(n: str::sbuf, v: str::sbuf, overwrite: int) -> int; + fn unsetenv(n: str::sbuf) -> int; fn pipe(buf: *mutable int) -> int; fn waitpid(pid: int, status: &mutable int, options: int) -> int; } @@ -63,7 +63,7 @@ fn pipe() -> {in: int, out: int} { } fn fd_FILE(fd: int) -> libc::FILE { - ret istr::as_buf(~"r", { |modebuf| + ret str::as_buf(~"r", { |modebuf| libc::fdopen(fd, modebuf) }); } diff --git a/src/lib/macos_os.rs b/src/lib/macos_os.rs index ce9a2089bf7..2c244048113 100644 --- a/src/lib/macos_os.rs +++ b/src/lib/macos_os.rs @@ -4,11 +4,11 @@ native "cdecl" mod libc = "" { fn write(fd: int, buf: *u8, count: uint) -> int; fn fread(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; fn fwrite(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; - fn open(s: istr::sbuf, flags: int, mode: uint) -> int; + fn open(s: str::sbuf, flags: int, mode: uint) -> int; fn close(fd: int) -> int; type FILE; - fn fopen(path: istr::sbuf, mode: istr::sbuf) -> FILE; - fn fdopen(fd: int, mode: istr::sbuf) -> FILE; + fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE; + fn fdopen(fd: int, mode: str::sbuf) -> FILE; fn fclose(f: FILE); fn fgetc(f: FILE) -> int; fn ungetc(c: int, f: FILE); @@ -16,13 +16,13 @@ native "cdecl" mod libc = "" { fn fseek(f: FILE, offset: int, whence: int) -> int; fn ftell(f: FILE) -> int; type dir; - fn opendir(d: istr::sbuf) -> dir; + fn opendir(d: str::sbuf) -> dir; fn closedir(d: dir) -> int; type dirent; fn readdir(d: dir) -> dirent; - fn getenv(n: istr::sbuf) -> istr::sbuf; - fn setenv(n: istr::sbuf, v: istr::sbuf, overwrite: int) -> int; - fn unsetenv(n: istr::sbuf) -> int; + fn getenv(n: str::sbuf) -> str::sbuf; + fn setenv(n: str::sbuf, v: str::sbuf, overwrite: int) -> int; + fn unsetenv(n: str::sbuf) -> int; fn pipe(buf: *mutable int) -> int; fn waitpid(pid: int, status: &mutable int, options: int) -> int; } @@ -60,7 +60,7 @@ fn pipe() -> {in: int, out: int} { } fn fd_FILE(fd: int) -> libc::FILE { - ret istr::as_buf(~"r", { |modebuf| + ret str::as_buf(~"r", { |modebuf| libc::fdopen(fd, modebuf) }); } diff --git a/src/lib/map.rs b/src/lib/map.rs index 7a46e28e67d..a608e7b877b 100644 --- a/src/lib/map.rs +++ b/src/lib/map.rs @@ -195,7 +195,7 @@ fn mk_hashmap<@K, @V>(hasher: &hashfn, eqer: &eqfn) -> hashmap { // Hash map constructors for basic types fn new_str_hash<@V>() -> hashmap { - ret mk_hashmap(istr::hash, istr::eq); + ret mk_hashmap(str::hash, str::eq); } fn new_int_hash<@V>() -> hashmap { diff --git a/src/lib/net.rs b/src/lib/net.rs index 4dac4eee04c..e7d8d13df2b 100644 --- a/src/lib/net.rs +++ b/src/lib/net.rs @@ -15,7 +15,7 @@ fn format_addr(ip: ip_addr) -> istr { fn parse_addr(ip: &istr) -> ip_addr { let parts = vec::map( { |&s| uint::from_str(s) }, - istr::split(ip, ~"."[0])); + str::split(ip, ~"."[0])); if vec::len(parts) != 4u { fail "Too many dots in IP address"; } for i in parts { if i > 255u { fail "Invalid IP Address part."; } } ipv4(parts[0] as u8, parts[1] as u8, parts[2] as u8, parts[3] as u8) diff --git a/src/lib/posix_fs.rs b/src/lib/posix_fs.rs index 1a346ed661a..2aebc49619b 100644 --- a/src/lib/posix_fs.rs +++ b/src/lib/posix_fs.rs @@ -31,7 +31,7 @@ fn list_dir(path: &istr) -> [istr] { } -fn path_is_absolute(p: &istr) -> bool { ret istr::char_at(p, 0u) == '/'; } +fn path_is_absolute(p: &istr) -> bool { ret str::char_at(p, 0u) == '/'; } const path_sep: char = '/'; diff --git a/src/lib/run_program.rs b/src/lib/run_program.rs index 4fc546b07b1..3558da2388a 100644 --- a/src/lib/run_program.rs +++ b/src/lib/run_program.rs @@ -1,5 +1,5 @@ -import istr::sbuf; +import str::sbuf; export program; export run_program; @@ -13,9 +13,9 @@ native "rust" mod rustrt { } fn arg_vec(prog: &istr, args: &[@istr]) -> [sbuf] { - let argptrs = istr::as_buf(prog, { |buf| [buf] }); + let argptrs = str::as_buf(prog, { |buf| [buf] }); for arg in args { - argptrs += istr::as_buf(*arg, { |buf| [buf] }); + argptrs += str::as_buf(*arg, { |buf| [buf] }); } argptrs += [unsafe::reinterpret_cast(0)]; ret argptrs; @@ -106,7 +106,7 @@ fn read_all(rd: &io::reader) -> istr { let buf = ~""; while !rd.eof() { let bytes = rd.read_bytes(4096u); - buf += istr::unsafe_from_bytes(bytes); + buf += str::unsafe_from_bytes(bytes); } ret buf; } diff --git a/src/lib/sha1.rs b/src/lib/sha1.rs index c2d63af9a18..b1c1a2ac229 100644 --- a/src/lib/sha1.rs +++ b/src/lib/sha1.rs @@ -215,7 +215,7 @@ fn mk_sha1() -> sha1 { st.computed = false; } fn input(msg: &[u8]) { add_input(st, msg); } - fn input_str(msg: &istr) { add_input(st, istr::bytes(msg)); } + fn input_str(msg: &istr) { add_input(st, str::bytes(msg)); } fn result() -> [u8] { ret mk_result(st); } fn result_str() -> istr { let r = mk_result(st); diff --git a/src/lib/std.rc b/src/lib/std.rc index 21b09312860..3f3832f05b4 100644 --- a/src/lib/std.rc +++ b/src/lib/std.rc @@ -15,7 +15,7 @@ mod uint; mod u8; mod u64; mod vec; -mod istr; +mod str; // General io and system-services modules. diff --git a/src/lib/str.rs b/src/lib/str.rs new file mode 100644 index 00000000000..662d0d0c228 --- /dev/null +++ b/src/lib/str.rs @@ -0,0 +1,462 @@ +export eq, lteq, hash, is_empty, is_not_empty, is_whitespace, byte_len, +index, rindex, find, starts_with, ends_with, substr, slice, split, +concat, connect, to_upper, replace, char_slice, trim_left, trim_right, trim, +unshift_char, shift_char, pop_char, push_char, is_utf8, from_chars, to_chars, +char_len, char_at, bytes, is_ascii, shift_byte, pop_byte, unsafe_from_byte, +unsafe_from_bytes, from_char, char_range_at, str_from_cstr, sbuf, +as_buf, push_byte, utf8_char_width, safe_slice; + +native "rust" mod rustrt { + fn rust_istr_push(s: &mutable istr, ch: u8); +} + +fn eq(a: &istr, b: &istr) -> bool { a == b } + +fn lteq(a: &istr, b: &istr) -> bool { a <= b } + +fn hash(s: &istr) -> uint { + // djb hash. + // FIXME: replace with murmur. + + let u: uint = 5381u; + for c: u8 in s { u *= 33u; u += c as uint; } + ret u; +} + +// UTF-8 tags and ranges +const tag_cont_u8: u8 = 128u8; +const tag_cont: uint = 128u; +const max_one_b: uint = 128u; +const tag_two_b: uint = 192u; +const max_two_b: uint = 2048u; +const tag_three_b: uint = 224u; +const max_three_b: uint = 65536u; +const tag_four_b: uint = 240u; +const max_four_b: uint = 2097152u; +const tag_five_b: uint = 248u; +const max_five_b: uint = 67108864u; +const tag_six_b: uint = 252u; + +fn is_utf8(v: &[u8]) -> bool { + let i = 0u; + let total = vec::len::(v); + while i < total { + let chsize = utf8_char_width(v[i]); + if chsize == 0u { ret false; } + if i + chsize > total { ret false; } + i += 1u; + while chsize > 1u { + if v[i] & 192u8 != tag_cont_u8 { ret false; } + i += 1u; + chsize -= 1u; + } + } + ret true; +} + +fn is_ascii(s: &istr) -> bool { + let i: uint = byte_len(s); + while i > 0u { i -= 1u; if s[i] & 128u8 != 0u8 { ret false; } } + ret true; +} + +/// Returns true if the string has length 0 +pure fn is_empty(s: &istr) -> bool { + for c: u8 in s { ret false; } ret true; +} + +/// Returns true if the string has length greater than 0 +pure fn is_not_empty(s: &istr) -> bool { + !is_empty(s) +} + +fn is_whitespace(s: &istr) -> bool { + let i = 0u; + let len = char_len(s); + while i < len { + if !char::is_whitespace(char_at(s, i)) { ret false; } + i += 1u + } + ret true; +} + +fn byte_len(s: &istr) -> uint { + let v: [u8] = unsafe::reinterpret_cast(s); + let vlen = vec::len(v); + unsafe::leak(v); + // There should always be a null terminator + assert vlen > 0u; + ret vlen - 1u; +} + +fn bytes(s: &istr) -> [u8] { + let v = unsafe::reinterpret_cast(s); + let vcopy = vec::slice(v, 0u, vec::len(v) - 1u); + unsafe::leak(v); + ret vcopy; +} + +fn unsafe_from_bytes(v: &[mutable? u8]) -> istr { + let vcopy: [u8] = v + [0u8]; + let scopy: istr = unsafe::reinterpret_cast(vcopy); + unsafe::leak(vcopy); + ret scopy; +} + +fn unsafe_from_byte(u: u8) -> istr { + unsafe_from_bytes([u]) +} + +fn push_utf8_bytes(s: &mutable istr, ch: char) { + let code = ch as uint; + let bytes = if code < max_one_b { + [code as u8] + } else if code < max_two_b { + [(code >> 6u & 31u | tag_two_b) as u8, + (code & 63u | tag_cont) as u8] + } else if code < max_three_b { + [(code >> 12u & 15u | tag_three_b) as u8, + (code >> 6u & 63u | tag_cont) as u8, + (code & 63u | tag_cont) as u8] + } else if code < max_four_b { + [(code >> 18u & 7u | tag_four_b) as u8, + (code >> 12u & 63u | tag_cont) as u8, + (code >> 6u & 63u | tag_cont) as u8, + (code & 63u | tag_cont) as u8] + } else if code < max_five_b { + [(code >> 24u & 3u | tag_five_b) as u8, + (code >> 18u & 63u | tag_cont) as u8, + (code >> 12u & 63u | tag_cont) as u8, + (code >> 6u & 63u | tag_cont) as u8, + (code & 63u | tag_cont) as u8] + } else { + [(code >> 30u & 1u | tag_six_b) as u8, + (code >> 24u & 63u | tag_cont) as u8, + (code >> 18u & 63u | tag_cont) as u8, + (code >> 12u & 63u | tag_cont) as u8, + (code >> 6u & 63u | tag_cont) as u8, + (code & 63u | tag_cont) as u8] + }; + push_bytes(s, bytes); +} + +fn from_char(ch: char) -> istr { + let buf = ~""; + push_utf8_bytes(buf, ch); + ret buf; +} + +fn from_chars(chs: &[char]) -> istr { + let buf = ~""; + for ch: char in chs { push_utf8_bytes(buf, ch); } + ret buf; +} + +fn utf8_char_width(b: u8) -> uint { + let byte: uint = b as uint; + if byte < 128u { ret 1u; } + if byte < 192u { + ret 0u; // Not a valid start byte + + } + if byte < 224u { ret 2u; } + if byte < 240u { ret 3u; } + if byte < 248u { ret 4u; } + if byte < 252u { ret 5u; } + ret 6u; +} + +fn char_range_at(s: &istr, i: uint) -> {ch: char, next: uint} { + let b0 = s[i]; + let w = utf8_char_width(b0); + assert (w != 0u); + if w == 1u { ret {ch: b0 as char, next: i + 1u}; } + let val = 0u; + let end = i + w; + i += 1u; + while i < end { + let byte = s[i]; + assert (byte & 192u8 == tag_cont_u8); + val <<= 6u; + val += byte & 63u8 as uint; + i += 1u; + } + // Clunky way to get the right bits from the first byte. Uses two shifts, + // the first to clip off the marker bits at the left of the byte, and then + // a second (as uint) to get it to the right position. + val += (b0 << (w + 1u as u8) as uint) << (w - 1u) * 6u - w - 1u; + ret {ch: val as char, next: i}; +} + +fn char_at(s: &istr, i: uint) -> char { ret char_range_at(s, i).ch; } + +fn char_len(s: &istr) -> uint { + let i = 0u; + let len = 0u; + let total = byte_len(s); + while i < total { + let chsize = utf8_char_width(s[i]); + assert (chsize > 0u); + len += 1u; + i += chsize; + } + assert (i == total); + ret len; +} + +fn to_chars(s: &istr) -> [char] { + let buf: [char] = []; + let i = 0u; + let len = byte_len(s); + while i < len { + let cur = char_range_at(s, i); + buf += [cur.ch]; + i = cur.next; + } + ret buf; +} + +fn push_char(s: &mutable istr, ch: char) { s += from_char(ch); } + +fn pop_char(s: &mutable istr) -> char { + let end = byte_len(s); + while end > 0u && s[end - 1u] & 192u8 == tag_cont_u8 { end -= 1u; } + assert (end > 0u); + let ch = char_at(s, end - 1u); + s = substr(s, 0u, end - 1u); + ret ch; +} + +fn shift_char(s: &mutable istr) -> char { + let r = char_range_at(s, 0u); + s = substr(s, r.next, byte_len(s) - r.next); + ret r.ch; +} + +fn unshift_char(s: &mutable istr, ch: char) { s = from_char(ch) + s; } + +fn index(s: &istr, c: u8) -> int { + let i: int = 0; + for k: u8 in s { if k == c { ret i; } i += 1; } + ret -1; +} + +fn rindex(s: &istr, c: u8) -> int { + let n: int = byte_len(s) as int; + while n >= 0 { if s[n] == c { ret n; } n -= 1; } + ret n; +} + +fn find(haystack: &istr, needle: &istr) -> int { + let haystack_len: int = byte_len(haystack) as int; + let needle_len: int = byte_len(needle) as int; + if needle_len == 0 { ret 0; } + fn match_at(haystack: &istr, needle: &istr, i: int) -> bool { + let j: int = i; + for c: u8 in needle { if haystack[j] != c { ret false; } j += 1; } + ret true; + } + let i: int = 0; + while i <= haystack_len - needle_len { + if match_at(haystack, needle, i) { ret i; } + i += 1; + } + ret -1; +} + +fn starts_with(haystack: &istr, needle: &istr) -> bool { + let haystack_len: uint = byte_len(haystack); + let needle_len: uint = byte_len(needle); + if needle_len == 0u { ret true; } + if needle_len > haystack_len { ret false; } + ret eq(substr(haystack, 0u, needle_len), needle); +} + +fn ends_with(haystack: &istr, needle: &istr) -> bool { + let haystack_len: uint = byte_len(haystack); + let needle_len: uint = byte_len(needle); + ret if needle_len == 0u { + true + } else if needle_len > haystack_len { + false + } else { + eq(substr(haystack, haystack_len - needle_len, needle_len), + needle) + }; +} + +fn substr(s: &istr, begin: uint, len: uint) -> istr { + ret slice(s, begin, begin + len); +} + +fn slice(s: &istr, begin: uint, end: uint) -> istr { + // FIXME: Typestate precondition + assert (begin <= end); + assert (end <= byte_len(s)); + + let v: [u8] = unsafe::reinterpret_cast(s); + let v2 = vec::slice(v, begin, end); + unsafe::leak(v); + v2 += [0u8]; + let s2: istr = unsafe::reinterpret_cast(v2); + unsafe::leak(v2); + ret s2; +} + +fn safe_slice(s: &istr, begin: uint, end: uint) + : uint::le(begin, end) -> istr { + // would need some magic to make this a precondition + assert (end <= byte_len(s)); + ret slice(s, begin, end); +} + +fn shift_byte(s: &mutable istr) -> u8 { + let len = byte_len(s); + assert (len > 0u); + let b = s[0]; + s = substr(s, 1u, len - 1u); + ret b; +} + +fn pop_byte(s: &mutable istr) -> u8 { + let len = byte_len(s); + assert (len > 0u); + let b = s[len - 1u]; + s = substr(s, 0u, len - 1u); + ret b; +} + +fn push_byte(s: &mutable istr, b: u8) { + rustrt::rust_istr_push(s, b); +} + +fn push_bytes(s: &mutable istr, bytes: &[u8]) { + for byte in bytes { + rustrt::rust_istr_push(s, byte); + } +} + +fn split(s: &istr, sep: u8) -> [istr] { + let v: [istr] = []; + let accum: istr = ~""; + let ends_with_sep: bool = false; + for c: u8 in s { + if c == sep { + v += [accum]; + accum = ~""; + ends_with_sep = true; + } else { accum += unsafe_from_byte(c); ends_with_sep = false; } + } + if byte_len(accum) != 0u || ends_with_sep { v += [accum]; } + ret v; +} + +fn concat(v: &[istr]) -> istr { + let s: istr = ~""; + for ss: istr in v { s += ss; } + ret s; +} + +fn connect(v: &[istr], sep: &istr) -> istr { + let s: istr = ~""; + let first: bool = true; + for ss: istr in v { + if first { first = false; } else { s += sep; } + s += ss; + } + ret s; +} + +// FIXME: This only handles ASCII +fn to_upper(s: &istr) -> istr { + let outstr = ~""; + let ascii_a = 'a' as u8; + let ascii_z = 'z' as u8; + let diff = 32u8; + for byte: u8 in s { + let next; + if ascii_a <= byte && byte <= ascii_z { + next = byte - diff; + } else { next = byte; } + push_byte(outstr, next); + } + ret outstr; +} + +// FIXME: This is super-inefficient +fn replace(s: &istr, from: &istr, to: &istr) : is_not_empty(from) -> istr { + // FIXME (694): Shouldn't have to check this + check (is_not_empty(from)); + if byte_len(s) == 0u { + ret ~""; + } else if starts_with(s, from) { + ret to + replace(slice(s, byte_len(from), byte_len(s)), from, to); + } else { + ret unsafe_from_byte(s[0]) + + replace(slice(s, 1u, byte_len(s)), from, to); + } +} + +// FIXME: Also not efficient +fn char_slice(s: &istr, begin: uint, end: uint) -> istr { + from_chars(vec::slice(to_chars(s), begin, end)) +} + +fn trim_left(s: &istr) -> istr { + fn count_whities(s: &[char]) -> uint { + let i = 0u; + while i < vec::len(s) { + if !char::is_whitespace(s[i]) { break; } + i += 1u; + } + ret i; + } + let chars = to_chars(s); + let whities = count_whities(chars); + ret from_chars(vec::slice(chars, whities, vec::len(chars))); +} + +fn trim_right(s: &istr) -> istr { + fn count_whities(s: &[char]) -> uint { + let i = vec::len(s); + while 0u < i { + if !char::is_whitespace(s[i - 1u]) { break; } + i -= 1u; + } + ret i; + } + let chars = to_chars(s); + let whities = count_whities(chars); + ret from_chars(vec::slice(chars, 0u, whities)); +} + +fn trim(s: &istr) -> istr { + trim_left(trim_right(s)) +} + +type sbuf = *u8; + +fn buf(s: &istr) -> sbuf { + let saddr = ptr::addr_of(s); + let vaddr: *[u8] = unsafe::reinterpret_cast(saddr); + let buf = vec::to_ptr(*vaddr); + ret buf; +} + +fn as_buf(s: &istr, f: &block(sbuf) -> T) -> T { + let buf = buf(s); + f(buf) +} + +fn str_from_cstr(cstr: sbuf) -> istr { + let res = ~""; + let start = cstr; + let curr = start; + let i = 0u; + while *curr != 0u8 { + push_byte(res, *curr); + i += 1u; + curr = ptr::offset(start, i); + } + ret res; +} \ No newline at end of file diff --git a/src/lib/term.rs b/src/lib/term.rs index cd5b1122a59..f5189c49a43 100644 --- a/src/lib/term.rs +++ b/src/lib/term.rs @@ -52,7 +52,7 @@ fn color_supported() -> bool { ret alt generic_os::getenv(~"TERM") { option::some(env) { for term: istr in supported_terms { - if istr::eq(term, env) { ret true; } + if str::eq(term, env) { ret true; } } false } diff --git a/src/lib/test.rs b/src/lib/test.rs index 85b2accdb9e..77936e2b572 100644 --- a/src/lib/test.rs +++ b/src/lib/test.rs @@ -265,7 +265,7 @@ fn filter_tests(opts: &test_opts, tests: &[test_desc]) -> [test_desc] { let filter = bind fn (test: &test_desc, filter_str: &istr) -> option::t { - if istr::find(test.name, filter_str) >= 0 { + if str::find(test.name, filter_str) >= 0 { ret option::some(test); } else { ret option::none; } }(_, filter_str); @@ -296,7 +296,7 @@ fn filter_tests(opts: &test_opts, tests: &[test_desc]) -> [test_desc] { filtered = { fn lteq(t1: &test_desc, t2: &test_desc) -> bool { - istr::lteq(t1.name, t2.name) + str::lteq(t1.name, t2.name) } sort::merge_sort(lteq, filtered) }; diff --git a/src/lib/uint.rs b/src/lib/uint.rs index 7fb0c5d179c..e7f85074ef2 100644 --- a/src/lib/uint.rs +++ b/src/lib/uint.rs @@ -56,7 +56,7 @@ fn parse_buf(buf: &[u8], radix: uint) -> uint { fail; } -fn from_str(s: &istr) -> uint { parse_buf(istr::bytes(s), 10u) } +fn from_str(s: &istr) -> uint { parse_buf(str::bytes(s), 10u) } fn to_str(num: uint, radix: uint) -> istr { let n = num; @@ -85,12 +85,12 @@ fn to_str(num: uint, radix: uint) -> istr { if n == 0u { ret ~"0"; } let s: istr = ~""; while n != 0u { - s += istr::unsafe_from_byte(digit(n % radix) as u8); + s += str::unsafe_from_byte(digit(n % radix) as u8); n /= radix; } let s1: istr = ~""; - let len: uint = istr::byte_len(s); - while len != 0u { len -= 1u; s1 += istr::unsafe_from_byte(s[len]); } + let len: uint = str::byte_len(s); + while len != 0u { len -= 1u; s1 += str::unsafe_from_byte(s[len]); } ret s1; } fn str(i: uint) -> istr { ret to_str(i, 10u); } diff --git a/src/lib/win32_fs.rs b/src/lib/win32_fs.rs index 228773ef6db..3633a014ca4 100644 --- a/src/lib/win32_fs.rs +++ b/src/lib/win32_fs.rs @@ -11,8 +11,8 @@ fn list_dir(path: &istr) -> [istr] { } fn path_is_absolute(p: &istr) -> bool { - ret istr::char_at(p, 0u) == '/' || - istr::char_at(p, 1u) == ':' && istr::char_at(p, 2u) == '\\'; + ret str::char_at(p, 0u) == '/' || + str::char_at(p, 1u) == ':' && str::char_at(p, 2u) == '\\'; } /* FIXME: win32 path handling actually accepts '/' or '\' and has subtly diff --git a/src/lib/win32_os.rs b/src/lib/win32_os.rs index 99ec04f6ff7..9dccbcc679d 100644 --- a/src/lib/win32_os.rs +++ b/src/lib/win32_os.rs @@ -4,11 +4,11 @@ native "cdecl" mod libc = "" { fn write(fd: int, buf: *u8, count: uint) -> int; fn fread(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; fn fwrite(buf: *u8, size: uint, n: uint, f: libc::FILE) -> uint; - fn open(s: istr::sbuf, flags: int, mode: uint) -> int = "_open"; + fn open(s: str::sbuf, flags: int, mode: uint) -> int = "_open"; fn close(fd: int) -> int = "_close"; type FILE; - fn fopen(path: istr::sbuf, mode: istr::sbuf) -> FILE; - fn _fdopen(fd: int, mode: istr::sbuf) -> FILE; + fn fopen(path: str::sbuf, mode: str::sbuf) -> FILE; + fn _fdopen(fd: int, mode: str::sbuf) -> FILE; fn fclose(f: FILE); fn fgetc(f: FILE) -> int; fn ungetc(c: int, f: FILE); @@ -40,9 +40,9 @@ mod libc_constants { } native "x86stdcall" mod kernel32 { - fn GetEnvironmentVariableA(n: istr::sbuf, v: istr::sbuf, + fn GetEnvironmentVariableA(n: str::sbuf, v: str::sbuf, nsize: uint) -> uint; - fn SetEnvironmentVariableA(n: istr::sbuf, v: istr::sbuf) -> int; + fn SetEnvironmentVariableA(n: str::sbuf, v: str::sbuf) -> int; } fn exec_suffix() -> istr { ret ~".exe"; } @@ -69,7 +69,7 @@ fn pipe() -> {in: int, out: int} { } fn fd_FILE(fd: int) -> libc::FILE { - ret istr::as_buf(~"r", { |modebuf| + ret str::as_buf(~"r", { |modebuf| libc::_fdopen(fd, modebuf) }); } -- cgit 1.4.1-3-g733a5