aboutsummaryrefslogtreecommitdiff
path: root/src/lib/_str.rs
diff options
context:
space:
mode:
authorMarijn Haverbeke <[email protected]>2011-05-06 22:13:13 +0200
committerMarijn Haverbeke <[email protected]>2011-05-06 22:51:19 +0200
commita3ec0b1f643d00b9418e4884bd7caa07bf052201 (patch)
tree82000510ac9c9cf3f0c7cf4ae5f3c6b123b559cb /src/lib/_str.rs
parentRegister new snapshots. (diff)
downloadrust-a3ec0b1f643d00b9418e4884bd7caa07bf052201.tar.xz
rust-a3ec0b1f643d00b9418e4884bd7caa07bf052201.zip
Rename std modules to be camelcased
(Have fun mergining your stuff with this.)
Diffstat (limited to 'src/lib/_str.rs')
-rw-r--r--src/lib/_str.rs501
1 files changed, 0 insertions, 501 deletions
diff --git a/src/lib/_str.rs b/src/lib/_str.rs
deleted file mode 100644
index 5239afb1..00000000
--- a/src/lib/_str.rs
+++ /dev/null
@@ -1,501 +0,0 @@
-import rustrt.sbuf;
-
-import _vec.rustrt.vbuf;
-
-native "rust" mod rustrt {
- type sbuf;
- fn str_buf(str s) -> sbuf;
- fn str_vec(str s) -> vec[u8];
- fn str_byte_len(str s) -> uint;
- fn str_alloc(uint n_bytes) -> str;
- fn str_from_vec(vec[mutable? u8] b) -> str;
- fn str_from_cstr(sbuf cstr) -> str;
- fn str_from_buf(sbuf buf, uint len) -> str;
- fn str_push_byte(str s, uint byte) -> str;
- fn refcount[T](str s) -> uint;
-}
-
-fn eq(&str a, &str b) -> bool {
- let uint i = byte_len(a);
- if (byte_len(b) != i) {
- ret false;
- }
- while (i > 0u) {
- i -= 1u;
- auto cha = a.(i);
- auto chb = b.(i);
- if (cha != chb) {
- ret false;
- }
- }
- ret true;
-}
-
-fn lteq(&str a, &str b) -> bool {
- let uint i = byte_len(a);
- let uint j = byte_len(b);
- let uint n = i;
- if (j < n) {
- n = j;
- }
-
- let uint x = 0u;
- while (x < n) {
- auto cha = a.(x);
- auto chb = b.(x);
- if (cha < chb) {
- ret true;
- }
- else if (cha > chb) {
- ret false;
- }
- x += 1u;
- }
-
- ret i <= j;
-}
-
-
-fn hash(&str s) -> uint {
- // djb hash.
- // FIXME: replace with murmur.
- let uint u = 5381u;
- for (u8 c in s) {
- u *= 33u;
- u += (c as uint);
- }
- ret u;
-}
-
-// UTF-8 tags and ranges
-const u8 tag_cont_u8 = 0x80_u8;
-const uint tag_cont = 0x80_u;
-const uint max_one_b = 0x80_u;
-const uint tag_two_b = 0xc0_u;
-const uint max_two_b = 0x800_u;
-const uint tag_three_b = 0xe0_u;
-const uint max_three_b = 0x10000_u;
-const uint tag_four_b = 0xf0_u;
-const uint max_four_b = 0x200000_u;
-const uint tag_five_b = 0xf8_u;
-const uint max_five_b = 0x4000000_u;
-const uint tag_six_b = 0xfc_u;
-
-fn is_utf8(vec[u8] v) -> bool {
- auto i = 0u;
- auto total = _vec.len[u8](v);
- while (i < total) {
- auto 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) & 0xc0_u8 != tag_cont_u8) {ret false;}
- i += 1u;
- chsize -= 1u;
- }
- }
- ret true;
-}
-
-fn is_ascii(str s) -> bool {
- let uint i = byte_len(s);
- while (i > 0u) {
- i -= 1u;
- if ((s.(i) & 0x80_u8) != 0u8) {
- ret false;
- }
- }
- ret true;
-}
-
-fn alloc(uint n_bytes) -> str {
- ret rustrt.str_alloc(n_bytes);
-}
-
-// Returns the number of bytes (a.k.a. UTF-8 code units) in s.
-// Contrast with a function that would return the number of code
-// points (char's), combining character sequences, words, etc. See
-// http://icu-project.org/apiref/icu4c/classBreakIterator.html for a
-// way to implement those.
-fn byte_len(str s) -> uint {
- ret rustrt.str_byte_len(s);
-}
-
-fn buf(str s) -> sbuf {
- ret rustrt.str_buf(s);
-}
-
-fn bytes(str s) -> vec[u8] {
- ret rustrt.str_vec(s);
-}
-
-fn from_bytes(vec[u8] v) : is_utf8(v) -> str {
- ret rustrt.str_from_vec(v);
-}
-
-// FIXME temp thing
-fn unsafe_from_bytes(vec[mutable? u8] v) -> str {
- ret rustrt.str_from_vec(v);
-}
-
-// FIXME even temp-er thing; rustc can use "unsafe_from_bytes" above
-fn unsafe_from_mutable_bytes(vec[mutable u8] mv) -> str {
- let vec[u8] v = vec();
- for (u8 b in mv) {
- v += vec(b);
- }
- ret rustrt.str_from_vec(v);
-}
-
-fn unsafe_from_byte(u8 u) -> str {
- ret rustrt.str_from_vec(vec(u));
-}
-
-fn str_from_cstr(sbuf cstr) -> str {
- ret rustrt.str_from_cstr(cstr);
-}
-
-fn str_from_buf(sbuf buf, uint len) -> str {
- ret rustrt.str_from_buf(buf, len);
-}
-
-fn push_utf8_bytes(&mutable str s, char ch) {
- auto code = ch as uint;
- if (code < max_one_b) {
- s = rustrt.str_push_byte(s, code);
- } else if (code < max_two_b) {
- s = rustrt.str_push_byte(s, ((code >> 6u) & 0x1f_u) | tag_two_b);
- s = rustrt.str_push_byte(s, (code & 0x3f_u) | tag_cont);
- } else if (code < max_three_b) {
- s = rustrt.str_push_byte(s, ((code >> 12u) & 0x0f_u) | tag_three_b);
- s = rustrt.str_push_byte(s, ((code >> 6u) & 0x3f_u) | tag_cont);
- s = rustrt.str_push_byte(s, (code & 0x3f_u) | tag_cont);
- } else if (code < max_four_b) {
- s = rustrt.str_push_byte(s, ((code >> 18u) & 0x07_u) | tag_four_b);
- s = rustrt.str_push_byte(s, ((code >> 12u) & 0x3f_u) | tag_cont);
- s = rustrt.str_push_byte(s, ((code >> 6u) & 0x3f_u) | tag_cont);
- s = rustrt.str_push_byte(s, (code & 0x3f_u) | tag_cont);
- } else if (code < max_five_b) {
- s = rustrt.str_push_byte(s, ((code >> 24u) & 0x03_u) | tag_five_b);
- s = rustrt.str_push_byte(s, ((code >> 18u) & 0x3f_u) | tag_cont);
- s = rustrt.str_push_byte(s, ((code >> 12u) & 0x3f_u) | tag_cont);
- s = rustrt.str_push_byte(s, ((code >> 6u) & 0x3f_u) | tag_cont);
- s = rustrt.str_push_byte(s, (code & 0x3f_u) | tag_cont);
- } else {
- s = rustrt.str_push_byte(s, ((code >> 30u) & 0x01_u) | tag_six_b);
- s = rustrt.str_push_byte(s, ((code >> 24u) & 0x3f_u) | tag_cont);
- s = rustrt.str_push_byte(s, ((code >> 18u) & 0x3f_u) | tag_cont);
- s = rustrt.str_push_byte(s, ((code >> 12u) & 0x3f_u) | tag_cont);
- s = rustrt.str_push_byte(s, ((code >> 6u) & 0x3f_u) | tag_cont);
- s = rustrt.str_push_byte(s, (code & 0x3f_u) | tag_cont);
- }
-}
-
-fn from_char(char ch) -> str {
- auto buf = "";
- push_utf8_bytes(buf, ch);
- ret buf;
-}
-
-fn from_chars(vec[char] chs) -> str {
- auto buf = "";
- for (char ch in chs) {push_utf8_bytes(buf, ch);}
- ret buf;
-}
-
-fn utf8_char_width(u8 b) -> uint {
- let uint byte = b as uint;
- if (byte < 0x80_u) {ret 1u;}
- if (byte < 0xc0_u) {ret 0u;} // Not a valid start byte
- if (byte < 0xe0_u) {ret 2u;}
- if (byte < 0xf0_u) {ret 3u;}
- if (byte < 0xf8_u) {ret 4u;}
- if (byte < 0xfc_u) {ret 5u;}
- ret 6u;
-}
-
-fn char_range_at(str s, uint i) -> tup(char, uint) {
- auto b0 = s.(i);
- auto w = utf8_char_width(b0);
- assert (w != 0u);
- if (w == 1u) {ret tup(b0 as char, i + 1u);}
- auto val = 0u;
- auto end = i + w;
- i += 1u;
- while (i < end) {
- auto byte = s.(i);
- assert (byte & 0xc0_u8 == tag_cont_u8);
- val <<= 6u;
- val += (byte & 0x3f_u8) 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 tup(val as char, i);
-}
-
-fn char_at(str s, uint i) -> char {
- ret char_range_at(s, i)._0;
-}
-
-fn char_len(str s) -> uint {
- auto i = 0u;
- auto len = 0u;
- auto total = byte_len(s);
- while (i < total) {
- auto chsize = utf8_char_width(s.(i));
- assert (chsize > 0u);
- len += 1u;
- i += chsize;
- }
- assert (i == total);
- ret len;
-}
-
-fn to_chars(str s) -> vec[char] {
- let vec[char] buf = vec();
- auto i = 0u;
- auto len = byte_len(s);
- while (i < len) {
- auto cur = char_range_at(s, i);
- _vec.push[char](buf, cur._0);
- i = cur._1;
- }
- ret buf;
-}
-
-fn push_char(&mutable str s, char ch) {
- s += from_char(ch);
-}
-
-fn pop_char(&mutable str s) -> char {
- auto end = byte_len(s);
- while (end > 0u && s.(end - 1u) & 0xc0_u8 == tag_cont_u8) {end -= 1u;}
- assert (end > 0u);
- auto ch = char_at(s, end - 1u);
- s = substr(s, 0u, end - 1u);
- ret ch;
-}
-
-fn shift_char(&mutable str s) -> char {
- auto r = char_range_at(s, 0u);
- s = substr(s, r._1, byte_len(s) - r._1);
- ret r._0;
-}
-
-fn unshift_char(&mutable str s, char ch) {
- // Workaround for rustboot order-of-evaluation issue -- if I put s
- // directly after the +, the string ends up containing (only) the
- // character, twice.
- auto x = s;
- s = from_char(ch) + x;
-}
-
-fn refcount(str s) -> uint {
- auto r = rustrt.refcount[u8](s);
- if (r == dbg.const_refcount) {
- ret r;
- } else {
- // -1 because calling this function incremented the refcount.
- ret r - 1u;
- }
-}
-
-
-// Standard bits from the world of string libraries.
-
-fn index(str s, u8 c) -> int {
- let int i = 0;
- for (u8 k in s) {
- if (k == c) {
- ret i;
- }
- i += 1;
- }
- ret -1;
-}
-
-fn rindex(str s, u8 c) -> int {
- let int n = _str.byte_len(s) as int;
- while (n >= 0) {
- if (s.(n) == c) {
- ret n;
- }
- n -= 1;
- }
- ret n;
-}
-
-fn find(str haystack, str needle) -> int {
-
- let int haystack_len = byte_len(haystack) as int;
- let int needle_len = byte_len(needle) as int;
-
- if (needle_len == 0) {
- ret 0;
- }
-
- fn match_at(&str haystack,
- &str needle,
- int i) -> bool {
- let int j = i;
- for (u8 c in needle) {
- if (haystack.(j) != c) {
- ret false;
- }
- j += 1;
- }
- ret true;
- }
-
- let int i = 0;
- while (i <= haystack_len - needle_len) {
- if (match_at(haystack, needle, i)) {
- ret i;
- }
- i += 1;
- }
- ret -1;
-}
-
-fn starts_with(str haystack, str needle) -> bool {
- let uint haystack_len = byte_len(haystack);
- let uint needle_len = 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(str haystack, str needle) -> bool {
- let uint haystack_len = byte_len(haystack);
- let uint needle_len = byte_len(needle);
- if (needle_len == 0u) {
- ret true;
- }
- if (needle_len > haystack_len) {
- ret false;
- }
- ret eq(substr(haystack,
- haystack_len - needle_len,
- needle_len),
- needle);
-}
-
-fn substr(str s, uint begin, uint len) -> str {
- ret slice(s, begin, begin + len);
-}
-
-fn slice(str s, uint begin, uint end) -> str {
- let str accum = "";
- let uint i = begin;
- while (i < end) {
- push_byte(accum, s.(i));
- i += 1u;
- }
- ret accum;
-}
-
-fn shift_byte(&mutable str s) -> u8 {
- auto len = byte_len(s);
- assert (len > 0u);
- auto b = s.(0);
- s = substr(s, 1u, len - 1u);
- ret b;
-}
-
-fn pop_byte(&mutable str s) -> u8 {
- auto len = byte_len(s);
- assert (len > 0u);
- auto b = s.(len - 1u);
- s = substr(s, 0u, len - 1u);
- ret b;
-}
-
-fn push_byte(&mutable str s, u8 b) {
- s = rustrt.str_push_byte(s, b as uint);
-}
-
-fn unshift_byte(&mutable str s, u8 b) {
- auto res = alloc(byte_len(s) + 1u);
- res += unsafe_from_byte(b);
- res += s;
- s = res;
-}
-
-fn split(str s, u8 sep) -> vec[str] {
- let vec[str] v = vec();
- let str accum = "";
- let bool ends_with_sep = false;
- for (u8 c in s) {
- if (c == sep) {
- v += vec(accum);
- accum = "";
- ends_with_sep = true;
- } else {
- accum += unsafe_from_byte(c);
- ends_with_sep = false;
- }
- }
- if (_str.byte_len(accum) != 0u ||
- ends_with_sep) {
- v += vec(accum);
- }
- ret v;
-}
-
-fn concat(vec[str] v) -> str {
- let str s = "";
- for (str ss in v) {
- s += ss;
- }
- ret s;
-}
-
-fn connect(vec[str] v, str sep) -> str {
- let str s = "";
- let bool first = true;
- for (str ss in v) {
- if (first) {
- first = false;
- } else {
- s += sep;
- }
- s += ss;
- }
- ret s;
-}
-
-// FIXME: This only handles ASCII
-fn to_upper(str s) -> str {
- auto outstr = "";
- auto ascii_a = 'a' as u8;
- auto ascii_z = 'z' as u8;
- auto diff = 32u8;
- for (u8 byte in s) {
- auto next;
- if (ascii_a <= byte && byte <= ascii_z) {
- next = byte - diff;
- } else {
- next = byte;
- }
- push_byte(outstr, next);
- }
- ret outstr;
-}
-
-
-// Local Variables:
-// mode: rust;
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
-// End: