Keywords:
variant, variants
-#Alter Topic Type: Type
+Alter Topic Type: Type
-# Keywords:
-# tag, tags
+ Keywords:
+ resource, resources
Topic Type: Predicate
+/*
+Module: os
+
+TODO: Restructure and document
+*/
+
// FIXME Somehow merge stuff duplicated here and macosx_os.rs. Made difficult
// by https://github.com/graydon/rust/issues#issue/268
native "cdecl" mod libc = "" {
fn atan(n: float) -> float = "atan.f64";
}
+/*
+Function: sqrt
+
+Returns the square root
+*/
fn sqrt(x: float) -> float { llvm::sqrt(x) }
+
+/*
+Function: sin
+
+Returns the sine of an angle
+*/
fn sin(x: float) -> float { llvm::sin(x) }
+
+/*
+Function: cos
+
+Returns the cosine of an angle
+*/
fn cos(x: float) -> float { llvm::cos(x) }
+
+/*
+Function: tan
+
+Returns the tangent of an angle
+*/
fn tan(x: float) -> float { llvm::tan(x) }
+
+/*
+Function: asin
+
+Returns the arcsine of an angle
+*/
fn asin(x: float) -> float { llvm::asin(x) }
+
+/*
+Function: acos
+
+Returns the arccosine of an angle
+*/
fn acos(x: float) -> float { llvm::acos(x) }
+
+/*
+Function: atan
+
+Returns the arctangent of an angle
+*/
fn atan(x: float) -> float { llvm::atan(x) }
+/*
+Const: pi
+
+Archimedes' constant
+*/
const pi: float = 3.141592653589793;
+/*
+Function: min
+
+Returns the minimum of two values
+*/
fn min<T>(x: T, y: T) -> T { x < y ? x : y }
+
+/*
+Function: max
+
+Returns the maximum of two values
+*/
fn max<T>(x: T, y: T) -> T { x < y ? y : x }
+/*
+Module: net
+*/
+
import vec;
import uint;
-tag ip_addr { ipv4(u8, u8, u8, u8); }
+/* Section: Types */
+
+/*
+Tag: ip_addr
+
+An IP address
+*/
+tag ip_addr {
+ /*
+ Variant: ipv4
+
+ An IPv4 address
+ */
+ ipv4(u8, u8, u8, u8);
+}
+
+/* Section: Operations */
+/*
+Function: format_addr
+
+Convert an <ip_addr> to a str
+*/
fn format_addr(ip: ip_addr) -> str {
alt ip {
ipv4(a, b, c, d) {
}
}
+/*
+Function: parse_addr
+
+Convert a str to <ip_addr>
+
+Converts a string of the format "x.x.x.x" into an ip_addr tag.
+
+Failure:
+
+String must be a valid IPv4 address
+*/
fn parse_addr(ip: str) -> ip_addr {
let parts = vec::map({|s| uint::from_str(s) }, str::split(ip, "."[0]));
if vec::len(parts) != 4u { fail "Too many dots in IP address"; }
-
native "c-stack-cdecl" mod rustrt {
fn rust_list_files(path: str) -> [str];
}
-// Unsafe pointer utility functions.
+/*
+Module: ptr
+Unsafe pointer utility functions
+*/
native "rust-intrinsic" mod rusti {
fn addr_of<T>(val: T) -> *mutable T;
fn ptr_offset<T>(ptr: *T, count: uint) -> *T;
}
+/*
+Function: addr_of
+
+Get an unsafe pointer to a value
+*/
fn addr_of<T>(val: T) -> *mutable T { ret rusti::addr_of(val); }
+
+/*
+Function: offset
+
+Calculate the offset from a pointer
+*/
fn offset<T>(ptr: *T, count: uint) -> *T {
ret rusti::ptr_offset(ptr, count);
}
+/*
+Function: null
+
+Create an unsafe null pointer
+*/
fn null<T>() -> *T { ret unsafe::reinterpret_cast(0u); }
+/*
+Module: rand
-
-
-/**
- * Bindings the runtime's random number generator (ISAAC).
- */
+Random number generation
+*/
native "c-stack-cdecl" mod rustrt {
type rctx;
fn rand_new() -> rctx;
fn rand_free(c: rctx);
}
-type rng =
- obj {
- fn next() -> u32;
- fn next_float() -> float;
- };
+/* Section: Types */
+
+/*
+Obj: rng
+
+A random number generator
+*/
+type rng = obj {
+ /*
+ Method: next
+
+ Return the next random integer
+ */
+ fn next() -> u32;
+
+ /*
+ Method: next_float
+
+ Return the next random float
+ */
+ fn next_float() -> float;
+};
resource rand_res(c: rustrt::rctx) { rustrt::rand_free(c); }
+/* Section: Operations */
+
+/*
+Function: mk_rng
+
+Create a random number generator
+*/
fn mk_rng() -> rng {
obj rt_rng(c: @rand_res) {
fn next() -> u32 { ret rustrt::rand_next(**c); }
+/*
+Module: run
+Process spawning
+*/
import str::sbuf;
export program;
int;
}
+/* Section: Types */
+
+/*
+Resource: program_res
+
+A resource that manages the destruction of a <program> object
+
+program_res ensures that the destroy method is called on a
+program object in order to close open file descriptors.
+*/
+resource program_res(p: program) { p.destroy(); }
+
+/*
+Obj: program
+
+An object representing a child process
+*/
+type program = obj {
+ /*
+ Method: get_id
+
+ Returns the process id of the program
+ */
+ fn get_id() -> int;
+
+ /*
+ Method: input
+
+ Returns an io::writer that can be used to write to stdin
+ */
+ fn input() -> io::writer;
+
+ /*
+ Method: output
+
+ Returns an io::reader that can be used to read from stdout
+ */
+ fn output() -> io::reader;
+
+ /*
+ Method: err
+
+ Returns an io::reader that can be used to read from stderr
+ */
+ fn err() -> io::reader;
+
+ /*
+ Method: close_input
+
+ Closes the handle to the child processes standard input
+ */
+ fn close_input();
+
+ /*
+ Method: finish
+
+ Waits for the child process to terminate. Closes the handle
+ to stdin if necessary.
+ */
+ fn finish() -> int;
+
+ /*
+ Method: destroy
+
+ Closes open handles
+ */
+ fn destroy();
+};
+
+
+/* Section: Operations */
+
fn arg_vec(prog: str, args: [@str]) -> [sbuf] {
let argptrs = str::as_buf(prog, {|buf| [buf] });
for arg in args { argptrs += str::as_buf(*arg, {|buf| [buf] }); }
ret argptrs;
}
+/*
+Function: spawn_process
+
+Run a program, providing stdin, stdout and stderr handles
+
+Parameters:
+
+prog - The path to an executable
+args - Vector of arguments to pass to the child process
+in_fd - A file descriptor for the child to use as std input
+out_fd - A file descriptor for the child to use as std output
+err_fd - A file descriptor for the child to use as std error
+
+Returns:
+
+The process id of the spawned process
+*/
fn spawn_process(prog: str, args: [str], in_fd: int, out_fd: int, err_fd: int)
-> int unsafe {
// Note: we have to hold on to these vector references while we hold a
ret pid;
}
+/*
+Function: run_program
+
+Spawns a process and waits for it to terminate
+
+Parameters:
+
+prog - The path to an executable
+args - Vector of arguments to pass to the child process
+
+Returns:
+
+The process id
+*/
fn run_program(prog: str, args: [str]) -> int {
ret waitpid(spawn_process(prog, args, 0, 0, 0));
}
-type program =
- obj {
- fn get_id() -> int;
- fn input() -> io::writer;
- fn output() -> io::reader;
- fn err() -> io::reader;
- fn close_input();
- fn finish() -> int;
- fn destroy();
- };
+/*
+Function: start_program
-resource program_res(p: program) { p.destroy(); }
+Spawns a process and returns a boxed <program_res>
+
+The returned value is a boxed resource containing a <program> object that can
+be used for sending and recieving data over the standard file descriptors.
+The resource will ensure that file descriptors are closed properly.
+
+Parameters:
+
+prog - The path to an executable
+args - Vector of arguments to pass to the child process
+
+Returns:
+A boxed resource of <program>
+*/
fn start_program(prog: str, args: [str]) -> @program_res {
let pipe_input = os::pipe();
let pipe_output = os::pipe();
ret buf;
}
+/*
+Function: program_output
+
+Spawns a process, waits for it to exit, and returns the exit code, and
+contents of stdout and stderr.
+
+Parameters:
+
+prog - The path to an executable
+args - Vector of arguments to pass to the child process
+
+Returns:
+
+A record, {status: int, out: str, err: str} containing the exit code,
+the contents of stdout and the contents of stderr.
+*/
fn program_output(prog: str, args: [str]) ->
{status: int, out: str, err: str} {
let pr = start_program(prog, args);
ret {status: pr.finish(), out: out, err: err};
}
-/* Returns an exit status */
-#[cfg(target_os = "win32")]
-fn waitpid(pid: int) -> int {
- os::waitpid(pid)
-}
+/*
+Function: waitpid
-#[cfg(target_os = "linux")]
-#[cfg(target_os = "macos")]
+Waits for a process to exit and returns the exit code
+*/
fn waitpid(pid: int) -> int {
- #[cfg(target_os = "linux")]
- fn WIFEXITED(status: int) -> bool {
- (status & 0xff) == 0
- }
+ ret waitpid_os(pid);
- #[cfg(target_os = "macos")]
- fn WIFEXITED(status: int) -> bool {
- (status & 0x7f) == 0
+ #[cfg(target_os = "win32")]
+ fn waitpid_os(pid: int) -> int {
+ os::waitpid(pid)
}
#[cfg(target_os = "linux")]
- fn WEXITSTATUS(status: int) -> int {
- (status >> 8) & 0xff
- }
-
#[cfg(target_os = "macos")]
- fn WEXITSTATUS(status: int) -> int {
- status >> 8
- }
+ fn waitpid_os(pid: int) -> int {
+ #[cfg(target_os = "linux")]
+ fn WIFEXITED(status: int) -> bool {
+ (status & 0xff) == 0
+ }
- let status = os::waitpid(pid);
- ret if WIFEXITED(status) {
- WEXITSTATUS(status)
- } else {
- 1
- };
+ #[cfg(target_os = "macos")]
+ fn WIFEXITED(status: int) -> bool {
+ (status & 0x7f) == 0
+ }
+
+ #[cfg(target_os = "linux")]
+ fn WEXITSTATUS(status: int) -> int {
+ (status >> 8) & 0xff
+ }
+
+ #[cfg(target_os = "macos")]
+ fn WEXITSTATUS(status: int) -> int {
+ status >> 8
+ }
+
+ let status = os::waitpid(pid);
+ ret if WIFEXITED(status) {
+ WEXITSTATUS(status)
+ } else {
+ 1
+ };
+ }
}
// Local Variables:
+/*
+Module: sha1
+
+An implementation of the SHA-1 cryptographic hash.
+
+First create a <sha1> object using the <mk_sha1> constructor, then
+feed it input using the <input> or <input_str> methods, which may be
+called any number of times.
+
+After the entire input has been fed to the hash read the result using
+the <result> or <result_str> methods.
+
+The <sha1> object may be reused to create multiple hashes by calling
+the <reset> method.
+*/
+
/*
* A SHA-1 implementation derived from Paul E. Jones's reference
* implementation, which is written for clarity, not speed. At some
export sha1;
export mk_sha1;
-type sha1 =
- // Provide message input as bytes
- // Provide message input as string
- // Read the digest as a vector of 20 bytes. After calling this no further
- // input may provided until reset is called
- // Same as above, just a hex-string version.
- // Reset the sha1 state for reuse. This is called
- // automatically during construction
- obj {
- fn input([u8]);
- fn input_str(str);
- fn result() -> [u8];
- fn result_str() -> str;
- fn reset();
- };
+/* Section: Types */
+/*
+Obj: sha1
+
+The SHA-1 object
+*/
+type sha1 = obj {
+ /*
+ Method: input
+
+ Provide message input as bytes
+ */
+ fn input([u8]);
+ /*
+ Method: input_str
+
+ Provide message input as string
+ */
+ fn input_str(str);
+ /*
+ Method: result
+
+ Read the digest as a vector of 20 bytes. After calling this no further
+ input may be provided until reset is called.
+ */
+ fn result() -> [u8];
+ /*
+ Method: result_str
+
+ Read the digest as a hex string. After calling this no further
+ input may be provided until reset is called.
+ */
+ fn result_str() -> str;
+ /*
+ Method: reset
+
+ Reset the SHA-1 state for reuse
+ */
+ fn reset();
+};
+
+/* Section: Operations */
// Some unexported constants
const digest_buf_len: uint = 5u;
const k3: u32 = 0xCA62C1D6u32;
-// Builds a sha1 object
+/*
+Function: mk_sha1
+
+Construct a <sha1> object
+*/
fn mk_sha1() -> sha1 {
type sha1state =
{h: [mutable u32],
+/*
+Module: smallintmap
-
-/// A simple map based on a vector for small integer keys. Space requirements
-/// are O(highest integer key).
+A simple map based on a vector for small integer keys. Space requirements
+are O(highest integer key).
+*/
import option::{some, none};
// FIXME: Should not be @; there's a bug somewhere in rustc that requires this
// to be.
+/*
+Type: smallintmap
+*/
type smallintmap<T> = @{mutable v: [mutable option::t<T>]};
+/*
+Function: mk
+
+Create a smallintmap
+*/
fn mk<T>() -> smallintmap<T> {
let v: [mutable option::t<T>] = [mutable];
ret @{mutable v: v};
}
+/*
+Function: insert
+
+Add a value to the map. If the map already contains a value for
+the specified key then the original value is replaced.
+*/
fn insert<T>(m: smallintmap<T>, key: uint, val: T) {
vec::grow_set::<option::t<T>>(m.v, key, none::<T>, some::<T>(val));
}
+/*
+Function: find
+
+Get the value for the specified key. If the key does not exist
+in the map then returns none.
+*/
fn find<T>(m: smallintmap<T>, key: uint) -> option::t<T> {
if key < vec::len::<option::t<T>>(m.v) { ret m.v[key]; }
ret none::<T>;
}
+/*
+Method: get
+
+Get the value for the specified key
+
+Failure:
+
+If the key does not exist in the map
+*/
fn get<T>(m: smallintmap<T>, key: uint) -> T {
alt find::<T>(m, key) {
none::<T>. { log_err "smallintmap::get(): key not present"; fail; }
}
}
+/*
+Method: contains_key
+
+Returns true if the map contains a value for the specified key
+*/
fn contains_key<T>(m: smallintmap<T>, key: uint) -> bool {
ret !option::is_none(find::<T>(m, key));
}
+// FIXME: Are these really useful?
+
fn truncate<T>(m: smallintmap<T>, len: uint) {
m.v = vec::slice_mut::<option::t<T>>(m.v, 0u, len);
}
+/*
+Module: sort
+Sorting methods
+*/
import vec::{len, slice};
export merge_sort;
export quick_sort;
export quick_sort3;
+/* Type: lteq */
type lteq<T> = block(T, T) -> bool;
+/*
+Function: merge_sort
+
+Merge sort. Returns a new vector containing the sorted list.
+
+Has worst case O(n log n) performance, best case O(n), but
+is not space efficient. This is a stable sort.
+*/
fn merge_sort<T>(le: lteq<T>, v: [T]) -> [T] {
fn merge<T>(le: lteq<T>, a: [T], b: [T]) -> [T] {
let rs: [T] = [];
}
}
+/*
+Function: quick_sort
+
+Quicksort. Sorts a mutable vector in place.
+
+Has worst case O(n^2) performance, average case O(n log n).
+This is an unstable sort.
+*/
fn quick_sort<T>(compare_func: lteq<T>, arr: [mutable T]) {
if len::<T>(arr) == 0u { ret; }
qsort::<T>(compare_func, arr, 0u, len::<T>(arr) - 1u);
}
-
-// Based on algorithm presented by Sedgewick and Bentley here:
-// http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf
-// According to these slides this is the algorithm of choice for
-// 'randomly ordered keys, abstract compare' & 'small number of key values'
fn qsort3<T>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
arr: [mutable T], left: int, right: int) {
if right <= left { ret; }
qsort3::<T>(compare_func_lt, compare_func_eq, arr, i, right);
}
+// FIXME: This should take lt and eq types
+/*
+Function: quick_sort3
+
+Fancy quicksort. Sorts a mutable vector in place.
+
+Based on algorithm presented by Sedgewick and Bentley
+<http://www.cs.princeton.edu/~rs/talks/QuicksortIsOptimal.pdf>.
+According to these slides this is the algorithm of choice for
+'randomly ordered keys, abstract compare' & 'small number of key values'.
+
+This is an unstable sort.
+*/
fn quick_sort3<T>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
arr: [mutable T]) {
if len::<T>(arr) == 0u { ret; }
+/*
+Module: str
+
+String manipulation.
+*/
+
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,
fn rust_str_push(&s: str, ch: u8);
}
+/*
+Function: eq
+
+Bytewise string equality
+*/
fn eq(&&a: str, &&b: str) -> bool { a == b }
+/*
+Function: lteq
+
+Bytewise less than or equal
+*/
fn lteq(&&a: str, &&b: str) -> bool { a <= b }
+/*
+Function: hash
+
+String hash function
+*/
fn hash(&&s: str) -> uint {
// djb hash.
// FIXME: replace with murmur.
const max_five_b: uint = 67108864u;
const tag_six_b: uint = 252u;
+/*
+Function: is_utf8
+
+Determines if a vector uf bytes contains valid UTF-8
+*/
fn is_utf8(v: [u8]) -> bool {
let i = 0u;
let total = vec::len::<u8>(v);
ret true;
}
+/*
+Function: is_ascii
+
+Determines if a string contains only ASCII characters
+*/
fn is_ascii(s: str) -> 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
+/*
+Predicate: is_empty
+
+Returns true if the string has length 0
+*/
pure fn is_empty(s: str) -> bool { for c: u8 in s { ret false; } ret true; }
-/// Returns true if the string has length greater than 0
+/*
+Predicate: is_not_empty
+
+Returns true if the string has length greater than 0
+*/
pure fn is_not_empty(s: str) -> bool { !is_empty(s) }
+/*
+Function: is_whitespace
+
+Returns true if the string contains only whitespace
+*/
fn is_whitespace(s: str) -> bool {
let i = 0u;
let len = char_len(s);
while i < len {
+ // FIXME: This is not how char_at works
if !char::is_whitespace(char_at(s, i)) { ret false; }
i += 1u;
}
ret true;
}
+/*
+Function: byte_len
+
+Returns the length in bytes of a string
+*/
fn byte_len(s: str) -> uint {
let v: [u8] = unsafe::reinterpret_cast(s);
let vlen = vec::len(v);
ret vlen - 1u;
}
+/*
+Function: bytes
+
+Converts a string to a vector of bytes
+*/
fn bytes(s: str) -> [u8] {
let v = unsafe::reinterpret_cast(s);
let vcopy = vec::slice(v, 0u, vec::len(v) - 1u);
ret vcopy;
}
+/*
+Function: unsafe_from_bytes
+
+Converts a vector of bytes to a string. Does not verify that the
+vector contains valid UTF-8.
+*/
fn unsafe_from_bytes(v: [mutable? u8]) -> str {
let vcopy: [u8] = v + [0u8];
let scopy: str = unsafe::reinterpret_cast(vcopy);
ret scopy;
}
+/*
+Function: unsafe_from_byte
+
+Converts a byte to a string. Does not verify that the byte is
+valid UTF-8.
+*/
fn unsafe_from_byte(u: u8) -> str { unsafe_from_bytes([u]) }
fn push_utf8_bytes(&s: str, ch: char) {
push_bytes(s, bytes);
}
+/*
+Function: from_char
+
+Convert a char to a string
+*/
fn from_char(ch: char) -> str {
let buf = "";
push_utf8_bytes(buf, ch);
ret buf;
}
+/*
+Function: from_chars
+
+Convert a vector of chars to a string
+*/
fn from_chars(chs: [char]) -> str {
let buf = "";
for ch: char in chs { push_utf8_bytes(buf, ch); }
ret buf;
}
+/*
+Function: utf8_char_width
+
+FIXME: What does this function do?
+*/
fn utf8_char_width(b: u8) -> uint {
let byte: uint = b as uint;
if byte < 128u { ret 1u; }
ret 6u;
}
+/*
+Function: char_range_at
+
+Pluck a character out of a string and return the index of the next character.
+This function can be used to iterate over the unicode characters of a string.
+
+Example:
+
+> let s = "Clam chowder, hot sauce, pork rinds";
+> let i = 0;
+> while i < len(s) {
+> let {ch, next} = char_range_at(s, i);
+> log ch;
+> i = next;
+> }
+
+Parameters:
+
+s - The string
+i - The byte offset of the char to extract
+
+Returns:
+
+A record {ch: char, next: uint} containing the char value and the byte
+index of the next unicode character.
+
+Failure:
+
+If `i` is greater than or equal to the length of the string.
+If `i` is not the index of the beginning of a valid UTF-8 character.
+*/
fn char_range_at(s: str, i: uint) -> {ch: char, next: uint} {
let b0 = s[i];
let w = utf8_char_width(b0);
ret {ch: val as char, next: i};
}
+/*
+Function: char_at
+
+Pluck a character out of a string
+*/
fn char_at(s: str, i: uint) -> char { ret char_range_at(s, i).ch; }
+/*
+Function: char_len
+
+Count the number of unicode characters in a string
+*/
fn char_len(s: str) -> uint {
let i = 0u;
let len = 0u;
ret len;
}
+/*
+Function: to_chars
+
+Convert a string to a vector of characters
+*/
fn to_chars(s: str) -> [char] {
let buf: [char] = [];
let i = 0u;
ret buf;
}
+/*
+Function: push_char
+
+Append a character to a string
+*/
fn push_char(&s: str, ch: char) { s += from_char(ch); }
+/*
+Function: pop_char
+
+Remove the final character from a string and return it.
+
+Failure:
+
+If the string does not contain any characters.
+*/
fn pop_char(&s: str) -> char {
let end = byte_len(s);
while end > 0u && s[end - 1u] & 192u8 == tag_cont_u8 { end -= 1u; }
ret ch;
}
+/*
+Function: shift_char
+
+Remove the first character from a string and return it.
+
+Failure:
+
+If the string does not contain any characters.
+*/
fn shift_char(&s: str) -> char {
let r = char_range_at(s, 0u);
s = substr(s, r.next, byte_len(s) - r.next);
ret r.ch;
}
+/*
+Function: unshift_char
+
+Prepend a char to a string
+*/
fn unshift_char(&s: str, ch: char) { s = from_char(ch) + s; }
+/*
+Function: index
+
+Returns the index of the first matching byte. Returns -1 if
+no match is found.
+*/
fn index(s: str, c: u8) -> int {
let i: int = 0;
for k: u8 in s { if k == c { ret i; } i += 1; }
ret -1;
}
+/*
+Function: rindex
+
+Returns the index of the last matching byte. Returns -1
+if no match is found.
+*/
fn rindex(s: str, c: u8) -> int {
let n: int = byte_len(s) as int;
while n >= 0 { if s[n] == c { ret n; } n -= 1; }
ret n;
}
+/*
+Function: find
+
+Finds the index of the first matching substring.
+Returns -1 if `haystack` does not contain `needle`.
+
+Parameters:
+
+haystack - The string to look in
+needle - The string to look for
+
+Returns:
+
+The index of the first occurance of `needle`, or -1 if not found.
+*/
fn find(haystack: str, needle: str) -> int {
let haystack_len: int = byte_len(haystack) as int;
let needle_len: int = byte_len(needle) as int;
ret -1;
}
+/*
+Function: contains
+
+Returns true if one string contains another
+
+Parameters:
+
+haystack - The string to look in
+needle - The string to look for
+*/
fn contains(haystack: str, needle: str) -> bool {
0 <= find(haystack, needle)
}
+/*
+Function: starts_with
+
+Returns true if one string starts with another
+
+Parameters:
+
+haystack - The string to look in
+needle - The string to look for
+*/
fn starts_with(haystack: str, needle: str) -> bool {
let haystack_len: uint = byte_len(haystack);
let needle_len: uint = byte_len(needle);
ret eq(substr(haystack, 0u, needle_len), needle);
}
+/*
+Function: ends_with
+
+Returns true if one string ends with another
+
+haystack - The string to look in
+needle - The string to look for
+*/
fn ends_with(haystack: str, needle: str) -> bool {
let haystack_len: uint = byte_len(haystack);
let needle_len: uint = byte_len(needle);
};
}
+/*
+Function: substr
+
+Take a substring of another. Returns a string containing `len` bytes
+starting at byte offset `begin`.
+
+This function is not unicode-safe.
+
+Failure:
+
+If `begin` + `len` is is greater than the byte length of the string
+*/
fn substr(s: str, begin: uint, len: uint) -> str {
ret slice(s, begin, begin + len);
}
+/*
+Function: slice
+
+Takes a bytewise slice from a string. Returns the substring from
+[`begin`..`end`).
+
+This function is not unicode-safe.
+
+Failure:
+
+- If begin is greater than end.
+- If end is greater than the length of the string.
+*/
fn slice(s: str, begin: uint, end: uint) -> str {
// FIXME: Typestate precondition
assert (begin <= end);
ret s2;
}
+/*
+Function: safe_slice
+*/
fn safe_slice(s: str, begin: uint, end: uint) : uint::le(begin, end) -> str {
// would need some magic to make this a precondition
assert (end <= byte_len(s));
ret slice(s, begin, end);
}
+/*
+Function: shift_byte
+
+Removes the first byte from a string and returns it.
+
+This function is not unicode-safe.
+*/
fn shift_byte(&s: str) -> u8 {
let len = byte_len(s);
assert (len > 0u);
ret b;
}
+/*
+Function: pop_byte
+
+Removes the last byte from a string and returns it.
+
+This function is not unicode-safe.
+*/
fn pop_byte(&s: str) -> u8 {
let len = byte_len(s);
assert (len > 0u);
ret b;
}
+/*
+Function: push_byte
+
+Appends a byte to a string.
+
+This function is not unicode-safe.
+*/
fn push_byte(&s: str, b: u8) { rustrt::rust_str_push(s, b); }
+/*
+Function: push_bytes
+
+Appends a vector of bytes to a string.
+
+This function is not unicode-safe.
+*/
fn push_bytes(&s: str, bytes: [u8]) {
for byte in bytes { rustrt::rust_str_push(s, byte); }
}
+/*
+Function: split
+
+Split a string at each occurance of a given separator
+
+Returns:
+
+A vector containing all the strings between each occurance of the separator
+*/
fn split(s: str, sep: u8) -> [str] {
let v: [str] = [];
let accum: str = "";
ret v;
}
+/*
+Function: concat
+
+Concatenate a vector of strings
+*/
fn concat(v: [str]) -> str {
let s: str = "";
for ss: str in v { s += ss; }
ret s;
}
+/*
+Function: connect
+
+Concatenate a vector of strings, placing a given separator between each
+*/
fn connect(v: [str], sep: str) -> str {
let s: str = "";
let first: bool = true;
}
// FIXME: This only handles ASCII
+/*
+Function: to_upper
+
+Convert a string to uppercase
+*/
fn to_upper(s: str) -> str {
let outstr = "";
let ascii_a = 'a' as u8;
}
// FIXME: This is super-inefficient
+/*
+Function: replace
+
+Replace all occurances of one string with another
+
+Parameters:
+
+s - The string containing substrings to replace
+from - The string to replace
+to - The replacement string
+
+Returns:
+
+The original string with all occurances of `from` replaced with `to`
+*/
fn replace(s: str, from: str, to: str) : is_not_empty(from) -> str {
// FIXME (694): Shouldn't have to check this
check (is_not_empty(from));
}
// FIXME: Also not efficient
+/*
+Function: char_slice
+
+Unicode-safe slice. Returns a slice of the given string containing
+the characters in the range [`begin`..`end`). `begin` and `end` are
+character indexes, not byte indexes.
+
+Failure:
+
+- If begin is greater than end
+- If end is greater than the character length of the string
+*/
fn char_slice(s: str, begin: uint, end: uint) -> str {
from_chars(vec::slice(to_chars(s), begin, end))
}
+/*
+Function: trim_left
+
+Returns a string with leading whitespace removed.
+*/
fn trim_left(s: str) -> str {
fn count_whities(s: [char]) -> uint {
let i = 0u;
ret from_chars(vec::slice(chars, whities, vec::len(chars)));
}
+/*
+Function: trim_right
+
+Returns a string with trailing whitespace removed.
+*/
fn trim_right(s: str) -> str {
fn count_whities(s: [char]) -> uint {
let i = vec::len(s);
ret from_chars(vec::slice(chars, 0u, whities));
}
+/*
+Function: trim
+
+Returns a string with leading and trailing whitespace removed
+*/
fn trim(s: str) -> str { trim_left(trim_right(s)) }
+/*
+Type: sbuf
+
+An unsafe buffer of bytes. Corresponds to a C char pointer.
+*/
type sbuf = *u8;
// NB: This is intentionally unexported because it's easy to misuse (there's
ret buf;
}
+/*
+Function: as_buf
+
+Work with the byte buffer of a string. Allows for unsafe manipulation
+of strings, which is useful for native interop.
+
+Example:
+
+> let s = str::as_buf("PATH", { |path_buf| libc::getenv(path_buf) });
+
+*/
fn as_buf<T>(s: str, f: block(sbuf) -> T) -> T unsafe {
let buf = buf(s); f(buf)
}
+/*
+Function: str_from_cstr
+
+Create a Rust string from a null-terminated C string
+*/
unsafe fn str_from_cstr(cstr: sbuf) -> str {
let res = "";
let start = cstr;
+/*
+Module: sys
-//export rustrt;
-//export size_of;
-
+Misc low level stuff
+*/
tag type_desc {
type_desc(@type_desc);
}
fn get_type_desc<T>() -> *type_desc;
}
+/*
+Function: get_type_desc
+
+Returns a pointer to a type descriptor. Useful for calling certain
+function in the Rust runtime or otherwise performing dark magick.
+*/
fn get_type_desc<T>() -> *type_desc {
ret rusti::get_type_desc::<T>();
}
+/*
+Function: last_os_error
+
+Get a string representing the platform-dependent last error
+*/
fn last_os_error() -> str {
ret rustrt::last_os_error();
}
+/*
+Function: size_of
+
+Returns the size of a type
+*/
fn size_of<T>() -> uint {
ret rustrt::size_of(get_type_desc::<T>());
}
+/*
+Function: align_of
+
+Returns the alignment of a type
+*/
fn align_of<T>() -> uint {
ret rustrt::align_of(get_type_desc::<T>());
}
+/*
+Function: refcount
+
+Returns the refcount of a shared box
+*/
fn refcount<T>(t: @T) -> uint {
ret rustrt::refcount::<T>(t);
}
+/*
+Function: do_gc
+
+Force a garbage collection
+*/
fn do_gc() -> () {
ret rustrt::do_gc();
}
+// FIXME: There's a wrapper for this in the task module and this really
+// just belongs there
fn unsupervise() -> () {
ret rustrt::unsupervise();
}