Add more std documentation

This commit is contained in:
Brian Anderson 2011-10-26 16:24:31 -07:00
parent 1b75e5c315
commit 4d669036f3
13 changed files with 861 additions and 83 deletions

View File

@ -145,10 +145,10 @@ Topic Type: Variant
Keywords:
variant, variants
#Alter Topic Type: Type
Alter Topic Type: Type
# Keywords:
# tag, tags
Keywords:
resource, resources
Topic Type: Predicate

View File

@ -1,3 +1,9 @@
/*
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 = "" {

View File

@ -10,15 +10,72 @@ native "llvm" mod llvm {
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 }

View File

@ -1,8 +1,33 @@
/*
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) {
@ -12,6 +37,17 @@ fn format_addr(ip: ip_addr) -> str {
}
}
/*
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"; }

View File

@ -1,4 +1,3 @@
native "c-stack-cdecl" mod rustrt {
fn rust_list_files(path: str) -> [str];
}

View File

@ -1,13 +1,32 @@
// 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); }

View File

@ -1,9 +1,8 @@
/*
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;
@ -11,14 +10,38 @@ native "c-stack-cdecl" mod rustrt {
fn rand_free(c: rctx);
}
type rng =
obj {
/* 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); }

View File

@ -1,4 +1,8 @@
/*
Module: run
Process spawning
*/
import str::sbuf;
export program;
@ -13,6 +17,78 @@ native "c-stack-cdecl" mod rustrt {
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] }); }
@ -20,6 +96,23 @@ fn arg_vec(prog: str, args: [@str]) -> [sbuf] {
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
@ -33,23 +126,42 @@ fn spawn_process(prog: str, args: [str], in_fd: int, out_fd: int, err_fd: int)
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();
@ -110,6 +222,22 @@ fn read_all(rd: io::reader) -> str {
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);
@ -119,15 +247,22 @@ fn program_output(prog: str, args: [str]) ->
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 {
ret waitpid_os(pid);
#[cfg(target_os = "win32")]
fn waitpid_os(pid: int) -> int {
os::waitpid(pid)
}
#[cfg(target_os = "linux")]
#[cfg(target_os = "macos")]
fn waitpid_os(pid: int) -> int {
#[cfg(target_os = "linux")]
fn WIFEXITED(status: int) -> bool {
(status & 0xff) == 0
@ -154,6 +289,7 @@ fn waitpid(pid: int) -> int {
} else {
1
};
}
}
// Local Variables:

View File

@ -1,3 +1,19 @@
/*
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
@ -6,22 +22,49 @@
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;
@ -33,7 +76,11 @@ const k2: u32 = 0x8F1BBCDCu32;
const k3: u32 = 0xCA62C1D6u32;
// Builds a sha1 object
/*
Function: mk_sha1
Construct a <sha1> object
*/
fn mk_sha1() -> sha1 {
type sha1state =
{h: [mutable u32],

View File

@ -1,27 +1,58 @@
/*
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; }
@ -29,10 +60,17 @@ fn get<T>(m: smallintmap<T>, key: uint) -> T {
}
}
/*
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);
}

View File

@ -1,12 +1,25 @@
/*
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] = [];
@ -68,16 +81,19 @@ fn qsort<T>(compare_func: lteq<T>, arr: [mutable T], left: uint,
}
}
/*
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; }
@ -126,6 +142,19 @@ fn qsort3<T>(compare_func_lt: lteq<T>, compare_func_eq: lteq<T>,
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; }

View File

@ -1,3 +1,9 @@
/*
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,
@ -11,10 +17,25 @@ native "c-stack-cdecl" mod rustrt {
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.
@ -38,6 +59,11 @@ const tag_five_b: uint = 248u;
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);
@ -55,28 +81,52 @@ fn is_utf8(v: [u8]) -> bool {
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);
@ -86,6 +136,11 @@ fn byte_len(s: str) -> uint {
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);
@ -93,6 +148,12 @@ fn bytes(s: str) -> [u8] {
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);
@ -100,6 +161,12 @@ fn unsafe_from_bytes(v: [mutable? u8]) -> str {
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) {
@ -131,18 +198,33 @@ 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; }
@ -157,6 +239,37 @@ fn utf8_char_width(b: u8) -> uint {
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);
@ -179,8 +292,18 @@ fn char_range_at(s: str, i: uint) -> {ch: char, next: uint} {
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;
@ -195,6 +318,11 @@ fn char_len(s: str) -> uint {
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;
@ -207,8 +335,22 @@ fn to_chars(s: str) -> [char] {
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; }
@ -218,26 +360,67 @@ fn pop_char(&s: str) -> char {
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;
@ -255,10 +438,30 @@ fn find(haystack: str, needle: str) -> 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);
@ -267,6 +470,14 @@ fn starts_with(haystack: str, needle: str) -> bool {
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);
@ -280,10 +491,35 @@ fn ends_with(haystack: str, needle: str) -> bool {
};
}
/*
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);
@ -298,12 +534,22 @@ fn slice(s: str, begin: uint, end: uint) -> str {
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);
@ -312,6 +558,13 @@ fn shift_byte(&s: str) -> u8 {
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);
@ -320,12 +573,35 @@ fn pop_byte(&s: str) -> u8 {
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 = "";
@ -341,12 +617,22 @@ fn split(s: str, sep: u8) -> [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;
@ -358,6 +644,11 @@ fn connect(v: [str], sep: str) -> str {
}
// 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;
@ -374,6 +665,21 @@ fn to_upper(s: str) -> str {
}
// 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));
@ -388,10 +694,27 @@ fn replace(s: str, from: str, to: str) : is_not_empty(from) -> str {
}
// 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;
@ -406,6 +729,11 @@ fn trim_left(s: str) -> str {
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);
@ -420,8 +748,18 @@ fn trim_right(s: str) -> str {
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
@ -433,10 +771,26 @@ unsafe fn buf(s: str) -> sbuf {
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;

View File

@ -1,7 +1,8 @@
/*
Module: sys
//export rustrt;
//export size_of;
Misc low level stuff
*/
tag type_desc {
type_desc(@type_desc);
}
@ -22,30 +23,63 @@ native "rust-intrinsic" mod rusti {
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();
}