1
Fork 0

Merge remote-tracking branch 'mozilla/master'

This commit is contained in:
Josh Matthews 2012-01-28 11:50:48 -05:00
commit a831e7ce13
32 changed files with 254 additions and 100 deletions

View file

@ -5,6 +5,7 @@ Graydon Hoare <graydon@mozilla.com>
Other authors:
Adam Bozanich <adam.boz@gmail.com>
Aleksander Balicki <balicki.aleksander@gmail.com>
Andreas Gal <gal@mozilla.com>
Austin Seipp <mad.one@gmail.com>
Ben Striegel <ben.striegel@gmail.com>

View file

@ -5,12 +5,12 @@
# Installation macro. Call with source directory as arg 1,
# destination directory as arg 2, and filename/libname-glob as arg 3
ifdef VERBOSE
INSTALL = cp $(1)/$(3) $(2)/$(3)
INSTALL_LIB = cp `ls -rt1 $(1)/$(3) | tail -1` $(2)/
INSTALL = install -m755 -T $(1)/$(3) $(2)/$(3)
INSTALL_LIB = install -m644 `ls -rt1 $(1)/$(3) | tail -1` $(2)/
else
INSTALL = $(Q)$(call E, install: $(2)/$(3)) && cp $(1)/$(3) $(2)/$(3)
INSTALL = $(Q)$(call E, install: $(2)/$(3)) && install -m755 -T $(1)/$(3) $(2)/$(3)
INSTALL_LIB = $(Q)$(call E, install_lib: $(2)/$(3)) && \
cp `ls -rt1 $(1)/$(3) | tail -1` $(2)/
install -m644 `ls -rt1 $(1)/$(3) | tail -1` $(2)/
endif
# The stage we install from

View file

@ -83,7 +83,7 @@ fn item_family(item: ebml::doc) -> u8 {
fn item_symbol(item: ebml::doc) -> str {
let sym = ebml::get_doc(item, tag_items_data_item_symbol);
ret str::unsafe_from_bytes(ebml::doc_data(sym));
ret str::from_bytes(ebml::doc_data(sym));
}
fn variant_enum_id(d: ebml::doc) -> ast::def_id {
@ -162,7 +162,7 @@ fn enum_variant_ids(item: ebml::doc, cdata: cmd) -> [ast::def_id] {
// definition the path refers to.
fn resolve_path(path: [ast::ident], data: @[u8]) -> [ast::def_id] {
fn eq_item(data: [u8], s: str) -> bool {
ret str::eq(str::unsafe_from_bytes(data), s);
ret str::eq(str::from_bytes(data), s);
}
let s = str::connect(path, "::");
let md = ebml::new_doc(data);
@ -178,7 +178,7 @@ fn resolve_path(path: [ast::ident], data: @[u8]) -> [ast::def_id] {
fn item_name(item: ebml::doc) -> ast::ident {
let name = ebml::get_doc(item, tag_paths_data_name);
str::unsafe_from_bytes(ebml::doc_data(name))
str::from_bytes(ebml::doc_data(name))
}
fn lookup_item_name(data: @[u8], id: ast::node_id) -> ast::ident {
@ -325,7 +325,7 @@ fn read_path(d: ebml::doc) -> {path: str, pos: uint} {
let desc = ebml::doc_data(d);
let pos = ebml::be_uint_from_bytes(@desc, 0u, 4u);
let pathbytes = vec::slice::<u8>(desc, 4u, vec::len::<u8>(desc));
let path = str::unsafe_from_bytes(pathbytes);
let path = str::from_bytes(pathbytes);
ret {path: path, pos: pos};
}
@ -358,21 +358,21 @@ fn get_meta_items(md: ebml::doc) -> [@ast::meta_item] {
let items: [@ast::meta_item] = [];
ebml::tagged_docs(md, tag_meta_item_word) {|meta_item_doc|
let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name);
let n = str::unsafe_from_bytes(ebml::doc_data(nd));
let n = str::from_bytes(ebml::doc_data(nd));
items += [attr::mk_word_item(n)];
};
ebml::tagged_docs(md, tag_meta_item_name_value) {|meta_item_doc|
let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name);
let vd = ebml::get_doc(meta_item_doc, tag_meta_item_value);
let n = str::unsafe_from_bytes(ebml::doc_data(nd));
let v = str::unsafe_from_bytes(ebml::doc_data(vd));
let n = str::from_bytes(ebml::doc_data(nd));
let v = str::from_bytes(ebml::doc_data(vd));
// FIXME (#611): Should be able to decode meta_name_value variants,
// but currently they can't be encoded
items += [attr::mk_name_value_item_str(n, v)];
};
ebml::tagged_docs(md, tag_meta_item_list) {|meta_item_doc|
let nd = ebml::get_doc(meta_item_doc, tag_meta_item_name);
let n = str::unsafe_from_bytes(ebml::doc_data(nd));
let n = str::from_bytes(ebml::doc_data(nd));
let subitems = get_meta_items(meta_item_doc);
items += [attr::mk_list_item(n, subitems)];
};
@ -427,7 +427,7 @@ fn get_crate_deps(data: @[u8]) -> [crate_dep] {
let depsdoc = ebml::get_doc(cratedoc, tag_crate_deps);
let crate_num = 1;
ebml::tagged_docs(depsdoc, tag_crate_dep) {|depdoc|
let depname = str::unsafe_from_bytes(ebml::doc_data(depdoc));
let depname = str::from_bytes(ebml::doc_data(depdoc));
deps += [{cnum: crate_num, ident: depname}];
crate_num += 1;
};
@ -447,7 +447,7 @@ fn list_crate_deps(data: @[u8], out: io::writer) {
fn get_crate_hash(data: @[u8]) -> str {
let cratedoc = ebml::new_doc(data);
let hashdoc = ebml::get_doc(cratedoc, tag_crate_hash);
ret str::unsafe_from_bytes(ebml::doc_data(hashdoc));
ret str::from_bytes(ebml::doc_data(hashdoc));
}
fn list_crate_items(bytes: @[u8], md: ebml::doc, out: io::writer) {

View file

@ -661,7 +661,7 @@ fn encode_hash(ebml_w: ebml::writer, hash: str) {
ebml::end_tag(ebml_w);
}
fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str {
fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> [u8] {
let abbrevs = ty::new_ty_hash();
let ecx = @{ccx: cx, type_abbrevs: abbrevs};
@ -694,7 +694,7 @@ fn encode_metadata(cx: @crate_ctxt, crate: @crate) -> str {
// Pad this, since something (LLVM, presumably) is cutting off the
// remaining % 4 bytes.
buf_w.write([0u8, 0u8, 0u8, 0u8]);
io::mem_buffer_str(buf)
io::mem_buffer_buf(buf)
}
// Get the encoded string for a type

View file

@ -39,7 +39,7 @@ fn parse_ident_(st: @pstate, is_last: fn@(char) -> bool) ->
ast::ident {
let rslt = "";
while !is_last(peek(st) as char) {
rslt += str::unsafe_from_byte(next(st));
rslt += str::from_byte(next(st));
}
ret rslt;
}
@ -226,7 +226,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
while peek(st) as char != ']' {
let name = "";
while peek(st) as char != '=' {
name += str::unsafe_from_byte(next(st));
name += str::from_byte(next(st));
}
st.pos = st.pos + 1u;
fields += [{ident: name, mt: parse_mt(st, conv)}];

View file

@ -5,7 +5,7 @@ import syntax::visit;
import syntax::ast_util;
import driver::session::session;
enum deref_t { unbox, field, index, }
enum deref_t { unbox(bool), field, index, }
type deref = @{mut: bool, kind: deref_t, outer_t: ty::t};
@ -20,15 +20,15 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) ->
while true {
alt ty::struct(tcx, t) {
ty::ty_box(mt) {
ds += [@{mut: mt.mut == mut, kind: unbox, outer_t: t}];
ds += [@{mut: mt.mut == mut, kind: unbox(false), outer_t: t}];
t = mt.ty;
}
ty::ty_uniq(mt) {
ds += [@{mut: mt.mut == mut, kind: unbox, outer_t: t}];
ds += [@{mut: mt.mut == mut, kind: unbox(false), outer_t: t}];
t = mt.ty;
}
ty::ty_res(_, inner, tps) {
ds += [@{mut: false, kind: unbox, outer_t: t}];
ds += [@{mut: false, kind: unbox(false), outer_t: t}];
t = ty::substitute_type_params(tcx, tps, inner);
}
ty::ty_enum(did, tps) {
@ -37,7 +37,7 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) ->
vec::len(variants[0].args) != 1u {
break;
}
ds += [@{mut: false, kind: unbox, outer_t: t}];
ds += [@{mut: false, kind: unbox(false), outer_t: t}];
t = ty::substitute_type_params(tcx, tps, variants[0].args[0]);
}
_ { break; }
@ -85,15 +85,16 @@ fn expr_root(tcx: ty::ctxt, ex: @expr, autoderef: bool) ->
expr_unary(op, base) {
if op == deref {
let base_t = ty::expr_ty(tcx, base);
let is_mut = false;
let is_mut = false, ptr = false;
alt ty::struct(tcx, base_t) {
ty::ty_box(mt) { is_mut = mt.mut == mut; }
ty::ty_uniq(mt) { is_mut = mt.mut == mut; }
ty::ty_res(_, _, _) { }
ty::ty_enum(_, _) { }
ty::ty_ptr(mt) { is_mut = mt.mut == mut; }
ty::ty_ptr(mt) { is_mut = mt.mut == mut; ptr = true; }
}
ds += [@{mut: is_mut, kind: unbox, outer_t: base_t}];
ds += [@{mut: is_mut, kind: unbox(ptr && is_mut),
outer_t: base_t}];
ex = base;
} else { break; }
}
@ -187,7 +188,7 @@ fn check_lval(cx: @ctx, dest: @expr, msg: msg) {
} else if !root.ds[0].mut {
let name =
alt root.ds[0].kind {
mut::unbox { "immutable box" }
mut::unbox(_) { "immutable box" }
mut::field { "immutable field" }
mut::index { "immutable vec content" }
};
@ -212,7 +213,8 @@ fn check_move_rhs(cx: @ctx, src: @expr) {
let root = expr_root(cx.tcx, src, false);
// Not a path and no-derefs means this is a temporary.
if vec::len(*root.ds) != 0u {
if vec::len(*root.ds) != 0u &&
root.ds[vec::len(*root.ds) - 1u].kind != unbox(true) {
cx.tcx.sess.span_err(src.span, "moving out of a data structure");
}
}

View file

@ -268,7 +268,7 @@ fn sanitize(s: str) -> str {
c != ' ' as u8 && c != '\t' as u8 && c != ';' as u8
{
let v = [c];
result += str::unsafe_from_bytes(v);
result += str::from_bytes(v);
}
}
}
@ -5412,7 +5412,7 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) {
fn write_metadata(cx: @crate_ctxt, crate: @ast::crate) {
if !cx.sess.building_library { ret; }
let llmeta = C_postr(metadata::encoder::encode_metadata(cx, crate));
let llmeta = C_bytes(metadata::encoder::encode_metadata(cx, crate));
let llconst = C_struct([llmeta]);
let llglobal = str::as_buf("rust_metadata", {|buf|
llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst), buf)

View file

@ -172,6 +172,7 @@ export type_is_str;
export type_is_unique;
export type_is_enum;
export type_is_c_like_enum;
export type_structurally_contains;
export type_structurally_contains_uniques;
export type_autoderef;
export type_param;
@ -2420,7 +2421,8 @@ mod unify {
fn fixup_vars(tcx: ty_ctxt, sp: option::t<span>, vb: @var_bindings,
typ: t) -> fixup_result {
fn subst_vars(tcx: ty_ctxt, sp: option::t<span>, vb: @var_bindings,
unresolved: @mutable option::t<int>, vid: int) -> t {
unresolved: @mutable option::t<int>,
vars_seen: std::list::list<int>, vid: int) -> t {
// Should really return a fixup_result instead of a t, but fold_ty
// doesn't allow returning anything but a t.
if vid as uint >= ufind::set_count(vb.sets) {
@ -2431,21 +2433,28 @@ mod unify {
alt smallintmap::find::<t>(vb.types, root_id) {
none { *unresolved = some(vid); ret ty::mk_var(tcx, vid); }
some(rt) {
if occurs_check_fails(tcx, sp, vid, rt) {
// Return the type unchanged, so we can error out
// downstream
ret rt;
let give_up = false;
std::list::iter(vars_seen) {|v|
if v == vid {
give_up = true;
option::may(sp) {|sp|
tcx.sess.span_fatal(
sp, "can not instantiate infinite type");
}
}
}
ret fold_ty(tcx,
fm_var(bind subst_vars(tcx, sp, vb, unresolved,
_)), rt);
// Return the type unchanged, so we can error out
// downstream
if give_up { ret rt; }
ret fold_ty(tcx, fm_var(bind subst_vars(
tcx, sp, vb, unresolved, std::list::cons(vid, @vars_seen),
_)), rt);
}
}
}
let unresolved = @mutable none::<int>;
let rty =
fold_ty(tcx, fm_var(bind subst_vars(tcx, sp, vb, unresolved, _)),
typ);
let rty = fold_ty(tcx, fm_var(bind subst_vars(
tcx, sp, vb, unresolved, std::list::nil, _)), typ);
let ur = *unresolved;
alt ur {
none { ret fix_ok(rty); }

View file

@ -259,10 +259,9 @@ fn ast_ty_to_ty(tcx: ty::ctxt, mode: mode, &&ast_ty: @ast::ty) -> ty::t {
alt tcx.ast_ty_to_ty_cache.find(ast_ty) {
some(some(ty)) { ret ty; }
some(none) {
tcx.sess.span_fatal(ast_ty.span,
"illegal recursive type \
insert a enum in the cycle, \
if this is desired)");
tcx.sess.span_fatal(ast_ty.span, "illegal recursive type. \
insert a enum in the cycle, \
if this is desired)");
}
none { }
} /* go on */
@ -2298,7 +2297,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
let msg = #fmt["attempted access of field %s on type %s, but \
no method implementation was found",
field, ty_to_str(tcx, t_err)];
tcx.sess.span_fatal(expr.span, msg);
tcx.sess.span_err(expr.span, msg);
// NB: Adding a bogus type to allow typechecking to continue
write::ty_only_fixup(fcx, id, ty::mk_nil(tcx));
}
}
}
@ -2490,7 +2491,7 @@ fn check_const(ccx: @crate_ctxt, _sp: span, e: @ast::expr, id: ast::node_id) {
demand::simple(fcx, e.span, declty, cty);
}
fn check_enum_variants(ccx: @crate_ctxt, _sp: span, vs: [ast::variant],
fn check_enum_variants(ccx: @crate_ctxt, sp: span, vs: [ast::variant],
id: ast::node_id) {
// FIXME: this is kinda a kludge; we manufacture a fake function context
// and statement context for checking the initializer expression.
@ -2512,7 +2513,7 @@ fn check_enum_variants(ccx: @crate_ctxt, _sp: span, vs: [ast::variant],
some(e) {
check_expr(fcx, e);
let cty = expr_ty(fcx.ccx.tcx, e);
let declty =ty::mk_int(fcx.ccx.tcx);
let declty = ty::mk_int(fcx.ccx.tcx);
demand::simple(fcx, e.span, declty, cty);
// FIXME: issue #1417
// Also, check_expr (from check_const pass) doesn't guarantee that
@ -2537,6 +2538,20 @@ fn check_enum_variants(ccx: @crate_ctxt, _sp: span, vs: [ast::variant],
disr_vals += [disr_val];
disr_val += 1;
}
let outer = true, did = local_def(id);
if ty::type_structurally_contains(ccx.tcx, rty, {|sty|
alt sty {
ty::ty_enum(id, _) if id == did {
if outer { outer = false; false }
else { true }
}
_ { false }
}
}) {
ccx.tcx.sess.span_fatal(sp, "illegal recursive enum type. \
wrap the inner value in a box to \
make it represenable");
}
}
// A generic function for checking the pred in a check

View file

@ -672,7 +672,7 @@ fn gather_comments_and_literals(cm: codemap::codemap,
path: str,
srdr: io::reader) ->
{cmnts: [cmnt], lits: [lit]} {
let src = @str::unsafe_from_bytes(srdr.read_whole_stream());
let src = @str::from_bytes(srdr.read_whole_stream());
let itr = @interner::mk::<str>(str::hash, str::eq);
let rdr = new_reader(cm, span_diagnostic,
codemap::new_filemap(path, src, 0u, 0u), itr);

View file

@ -118,7 +118,7 @@ fn ty_to_str(cx: ctxt, typ: t) -> str {
}
ty_var(v) { "<T" + int::str(v) + ">" }
ty_param(id, _) {
"'" + str::unsafe_from_bytes([('a' as u8) + (id as u8)])
"'" + str::from_bytes([('a' as u8) + (id as u8)])
}
_ { ty_to_short_str(cx, typ) }
}

View file

@ -85,7 +85,7 @@ fn readclose(fd: fd_t) -> str {
let buf = "";
while !reader.eof() {
let bytes = reader.read_bytes(4096u);
buf += str::unsafe_from_bytes(bytes);
buf += str::from_bytes(bytes);
}
os::fclose(file);
ret buf;
@ -114,8 +114,8 @@ fn worker(p: port<request>) {
// the alt discriminant are wrong.
alt recv(p) {
exec(lib_path, prog, args, respchan) {
{lib_path: str::unsafe_from_bytes(lib_path),
prog: str::unsafe_from_bytes(prog),
{lib_path: str::from_bytes(lib_path),
prog: str::from_bytes(prog),
args: clone_vecu8str(args),
respchan: respchan}
}
@ -189,7 +189,7 @@ fn clone_vecstr(v: [str]) -> [[u8]] {
fn clone_vecu8str(v: [[u8]]) -> [str] {
let r = [];
for t in vec::slice(v, 0u, vec::len(v)) {
r += [str::unsafe_from_bytes(t)];
r += [str::from_bytes(t)];
}
ret r;
}

View file

@ -390,7 +390,7 @@ mod rt {
fn str_init_elt(n_elts: uint, c: char) -> str {
let svec = vec::init_elt::<u8>(n_elts, c as u8);
ret str::unsafe_from_bytes(svec);
ret str::from_bytes(svec);
}
enum pad_mode { pad_signed, pad_unsigned, pad_nozero, }
fn pad(cv: conv, s: str, mode: pad_mode) -> str {
@ -439,7 +439,8 @@ mod rt {
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 = str::unsafe_from_bytes([head]);
let headstr = str::from_bytes([head]);
// FIXME: not UTF-8 safe
let bytelen = str::byte_len(s);
let numpart = str::substr(s, 1u, bytelen - 1u);
ret headstr + padstr + numpart;

View file

@ -13,6 +13,7 @@ export
// Creating a string
from_bytes,
unsafe_from_bytes,
from_byte,
unsafe_from_byte,
//push_utf8_bytes,
from_char,
@ -117,14 +118,11 @@ Section: Creating a string
/*
Function: from_bytes
Safely convert a vector of bytes to a UTF-8 string, or error
Convert a vector of bytes to a UTF-8 string. Fails if invalid UTF-8.
*/
fn from_bytes(vv: [u8]) -> result::t<str, str> {
if is_utf8(vv) {
ret result::ok(unsafe_from_bytes(vv));
} else {
ret result::err("vector doesn't contain valid UTF-8");
}
fn from_bytes(vv: [u8]) -> str {
assert is_utf8(vv);
ret unsafe_from_bytes(vv);
}
/*
@ -133,7 +131,7 @@ Function: unsafe_from_bytes
Converts a vector of bytes to a string. Does not verify that the
vector contains valid UTF-8.
// FIXME: remove?
FIXME: stop exporting
*/
fn unsafe_from_bytes(v: [const u8]) -> str unsafe {
let vcopy: [u8] = v + [0u8];
@ -148,10 +146,20 @@ Function: unsafe_from_byte
Converts a byte to a string. Does not verify that the byte is
valid UTF-8.
FIXME: rename to 'from_byte'
FIXME: stop exporting
*/
fn unsafe_from_byte(u: u8) -> str { unsafe_from_bytes([u]) }
/*
Function: from_byte
Convert a byte to a UTF-8 string. Fails if invalid UTF-8.
*/
fn from_byte(uu: u8) -> str {
from_bytes([uu])
}
fn push_utf8_bytes(&s: str, ch: char) {
let code = ch as uint;
let bytes =
@ -209,16 +217,16 @@ Function: from_cstr
Create a Rust string from a null-terminated C string
*/
unsafe fn from_cstr(cstr: sbuf) -> str {
let res = "";
let res = [];
let start = cstr;
let curr = start;
let i = 0u;
while *curr != 0u8 {
push_byte(res, *curr);
vec::push(res, *curr);
i += 1u;
curr = ptr::offset(start, i);
}
ret res;
ret from_bytes(res);
}
/*
@ -526,7 +534,7 @@ fn split(s: str, sep: u8) -> [str] {
v += [accum];
accum = "";
ends_with_sep = true;
} else { accum += unsafe_from_byte(c); ends_with_sep = false; }
} else { accum += from_byte(c); ends_with_sep = false; }
}
if byte_len(accum) != 0u || ends_with_sep { v += [accum]; }
ret v;
@ -554,7 +562,7 @@ fn splitn(s: str, sep: u8, count: uint) -> [str] {
v += [accum];
accum = "";
ends_with_sep = true;
} else { accum += unsafe_from_byte(c); ends_with_sep = false; }
} else { accum += from_byte(c); ends_with_sep = false; }
}
if byte_len(accum) != 0u || ends_with_sep { v += [accum]; }
ret v;
@ -575,12 +583,12 @@ FIXME: should behave like split and split_char:
*/
fn split_str(s: str, sep: str) -> [str] {
assert byte_len(sep) > 0u;
let v: [str] = [], accum = "", sep_match = 0u, leading = true;
let v: [str] = [], accum = [], sep_match = 0u, leading = true;
for c: u8 in s {
// Did we match the entire separator?
if sep_match == byte_len(sep) {
if !leading { v += [accum]; }
accum = "";
if !leading { vec::push(v, from_bytes(accum)); }
accum = [];
sep_match = 0u;
}
@ -588,13 +596,13 @@ fn split_str(s: str, sep: str) -> [str] {
sep_match += 1u;
} else {
sep_match = 0u;
accum += unsafe_from_byte(c);
vec::push(accum, c);
leading = false;
}
}
if byte_len(accum) > 0u { v += [accum]; }
if sep_match == byte_len(sep) { v += [""]; }
if vec::len(accum) > 0u { vec::push(v, from_bytes(accum)); }
if sep_match == byte_len(sep) { vec::push(v, ""); }
ret v;
}
@ -1783,7 +1791,24 @@ mod tests {
0x20_u8, 0x4e_u8, 0x61_u8,
0x6d_u8];
assert ss == result::get(from_bytes(bb));
assert ss == from_bytes(bb);
}
#[test]
#[should_fail]
fn test_from_bytes_fail() {
let bb = [0xff_u8, 0xb8_u8, 0xa8_u8,
0xe0_u8, 0xb9_u8, 0x84_u8,
0xe0_u8, 0xb8_u8, 0x97_u8,
0xe0_u8, 0xb8_u8, 0xa2_u8,
0xe4_u8, 0xb8_u8, 0xad_u8,
0xe5_u8, 0x8d_u8, 0x8e_u8,
0x56_u8, 0x69_u8, 0xe1_u8,
0xbb_u8, 0x87_u8, 0x74_u8,
0x20_u8, 0x4e_u8, 0x61_u8,
0x6d_u8];
let _x = from_bytes(bb);
}
#[test]
@ -1821,7 +1846,7 @@ mod tests {
let s1: str = "All mimsy were the borogoves";
let v: [u8] = bytes(s1);
let s2: str = unsafe_from_bytes(v);
let s2: str = from_bytes(v);
let i: uint = 0u;
let n1: uint = byte_len(s1);
let n2: uint = vec::len::<u8>(v);

View file

@ -236,12 +236,12 @@ fn to_str(num: uint, radix: uint) -> str {
if n == 0u { ret "0"; }
let s: str = "";
while n != 0u {
s += str::unsafe_from_byte(digit(n % radix) as u8);
s += str::from_byte(digit(n % radix) as u8);
n /= radix;
}
let s1: str = "";
let len: uint = str::byte_len(s);
while len != 0u { len -= 1u; s1 += str::unsafe_from_byte(s[len]); }
while len != 0u { len -= 1u; s1 += str::from_byte(s[len]); }
ret s1;
}

View file

@ -307,6 +307,14 @@ fn pop<T: copy>(&v: [const T]) -> T {
let e = v[ln];
v = slice(v, 0u, ln);
ret e;
// FIXME use this implementation after the next snapshot (27.01.2012)
/* let new_ln = len(v) - 1u;
assert (new_ln > 0u);
let valptr = ptr::mut_addr_of(v[new_ln]);
let val <- *valptr;
unsafe::set_len(v, new_ln);
val
*/
}
/*

View file

@ -129,7 +129,8 @@ fn dylib_filename(base: str) -> str { ret "lib" + base + ".so"; }
/// followed by a path separator
fn get_exe_path() -> option::t<fs::path> unsafe {
let bufsize = 1023u;
let path = str::unsafe_from_bytes(vec::init_elt(bufsize, 0u8));
// FIXME: path "strings" will likely need fixing...
let path = str::from_bytes(vec::init_elt(bufsize, 0u8));
let mib = [libc_constants::CTL_KERN,
libc_constants::KERN_PROC,
libc_constants::KERN_PROC_PATHNAME, -1i32];

View file

@ -75,7 +75,7 @@ fn getenv(n: str) -> option::t<str> {
unsafe {
vec::unsafe::set_len(v, res);
}
ret option::some(str::unsafe_from_bytes(v));
ret option::some(str::from_bytes(v)); // UTF-8 or fail
} else { nsize = res; }
}
fail;

View file

@ -109,7 +109,7 @@ impl reader_util for reader {
if ch == -1 || ch == 10 { break; }
buf += [ch as u8];
}
str::unsafe_from_bytes(buf)
str::from_bytes(buf)
}
fn read_c_str() -> str {
@ -118,7 +118,7 @@ impl reader_util for reader {
let ch = self.read_byte();
if ch < 1 { break; } else { buf += [ch as u8]; }
}
str::unsafe_from_bytes(buf)
str::from_bytes(buf)
}
// FIXME deal with eof?
@ -461,7 +461,10 @@ fn mk_mem_buffer() -> mem_buffer {
}
fn mem_buffer_writer(b: mem_buffer) -> writer { b as writer }
fn mem_buffer_buf(b: mem_buffer) -> [u8] { vec::from_mut(b.buf) }
fn mem_buffer_str(b: mem_buffer) -> str { str::unsafe_from_bytes(b.buf) }
fn mem_buffer_str(b: mem_buffer) -> str {
let b_ = vec::from_mut(b.buf);
str::from_bytes(b_)
}
// Utility functions
fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) ->
@ -479,7 +482,7 @@ fn seek_in_buf(offset: int, pos: uint, len: uint, whence: seek_style) ->
fn read_whole_file_str(file: str) -> result::t<str, str> {
result::chain(read_whole_file(file), { |bytes|
result::ok(str::unsafe_from_bytes(bytes))
result::ok(str::from_bytes(bytes))
})
}

View file

@ -125,7 +125,8 @@ fn dylib_filename(base: str) -> str { ret "lib" + base + ".so"; }
/// followed by a path separator
fn get_exe_path() -> option::t<fs::path> {
let bufsize = 1023u;
let path = str::unsafe_from_bytes(vec::init_elt(bufsize, 0u8));
// FIXME: path "strings" will likely need fixing...
let path = str::from_bytes(vec::init_elt(bufsize, 0u8));
ret str::as_buf("/proc/self/exe", { |proc_self_buf|
str::as_buf(path, { |path_buf|
if libc::readlink(proc_self_buf, path_buf, bufsize) != -1 {

View file

@ -128,7 +128,7 @@ Function: tail
Returns all but the first element of a list
*/
pure fn tail<T: copy>(ls: list<T>) : is_not_empty(ls) -> list<T> {
pure fn tail<T: copy>(ls: list<T>) -> list<T> {
alt ls {
cons(_, tl) { ret *tl; }
nil { fail "list empty" }

View file

@ -133,8 +133,9 @@ fn dylib_filename(base: str) -> str { ret "lib" + base + ".dylib"; }
fn get_exe_path() -> option::t<fs::path> {
// FIXME: This doesn't handle the case where the buffer is too small
// FIXME: path "strings" will likely need fixing...
let bufsize = 1023u32;
let path = str::unsafe_from_bytes(vec::init_elt(bufsize as uint, 0u8));
let path = str::from_bytes(vec::init_elt(bufsize as uint, 0u8));
ret str::as_buf(path, { |path_buf|
if mac_libc::_NSGetExecutablePath(path_buf,
ptr::mut_addr_of(bufsize)) == 0i32 {

View file

@ -216,7 +216,7 @@ fn read_all(rd: io::reader) -> str {
let buf = "";
while !rd.eof() {
let bytes = rd.read_bytes(4096u);
buf += str::unsafe_from_bytes(bytes);
buf += str::from_bytes(bytes);
}
ret buf;
}
@ -347,7 +347,7 @@ mod tests {
let buf = "";
while !reader.eof() {
let bytes = reader.read_bytes(4096u);
buf += str::unsafe_from_bytes(bytes);
buf += str::from_bytes(bytes);
}
os::fclose(file);
ret buf;

View file

@ -27,6 +27,11 @@ native mod rustrt {
thread: thread,
req_id: u32,
chan: comm::chan<iomsg>);
fn rust_uvtmp_timer(
thread: thread,
timeout: u32,
req_id: u32,
chan: comm::chan<iomsg>);
fn rust_uvtmp_delete_buf(buf: *u8);
fn rust_uvtmp_get_req_id(cd: connect_data) -> u32;
}
@ -39,7 +44,9 @@ enum iomsg {
whatever,
connected(connect_data),
wrote(connect_data),
read(connect_data, *u8, ctypes::ssize_t)
read(connect_data, *u8, ctypes::ssize_t),
timer(u32),
exit
}
fn create_thread() -> thread {
@ -80,6 +87,11 @@ fn read_start(thread: thread, req_id: u32,
rustrt::rust_uvtmp_read_start(thread, req_id, chan);
}
fn timer_start(thread: thread, timeout: u32, req_id: u32,
chan: comm::chan<iomsg>) {
rustrt::rust_uvtmp_timer(thread, timeout, req_id, chan);
}
fn delete_buf(buf: *u8) {
rustrt::rust_uvtmp_delete_buf(buf);
}
@ -138,7 +150,7 @@ fn test_http() {
unsafe {
log(error, len);
let buf = vec::unsafe::from_buf(buf, len as uint);
let str = str::unsafe_from_bytes(buf);
let str = str::from_bytes(buf);
#error("read something");
io::println(str);
}
@ -153,4 +165,4 @@ fn test_http() {
}
join_thread(thread);
delete_thread(thread);
}
}

View file

@ -113,8 +113,9 @@ fn getcwd() -> str { ret rustrt::rust_getcwd(); }
fn get_exe_path() -> option::t<fs::path> {
// FIXME: This doesn't handle the case where the buffer is too small
// FIXME: path "strings" will likely need fixing...
let bufsize = 1023u;
let path = str::unsafe_from_bytes(vec::init_elt(bufsize, 0u8));
let path = str::from_bytes(vec::init_elt(bufsize, 0u8));
ret str::as_buf(path, { |path_buf|
if kernel32::GetModuleFileNameA(0u, path_buf,
bufsize as u32) != 0u32 {

View file

@ -15,9 +15,12 @@ struct connect_data {
chan_handle chan;
};
const intptr_t whatever_tag = 0;
const intptr_t connected_tag = 1;
const intptr_t wrote_tag = 2;
const intptr_t read_tag = 3;
const intptr_t timer_tag = 4;
const intptr_t exit_tag = 5;
struct iomsg {
intptr_t tag;
@ -29,6 +32,7 @@ struct iomsg {
uint8_t *buf;
ssize_t nread;
} read_val;
uint32_t timer_req_id;
} val;
};
@ -44,6 +48,13 @@ struct read_start_data {
chan_handle chan;
};
struct timer_start_data {
rust_uvtmp_thread *thread;
uint32_t timeout;
uint32_t req_id;
chan_handle chan;
};
// FIXME: Copied from rust_builtins.cpp. Could bitrot easily
static void
send(rust_task *task, chan_handle chan, void *data) {
@ -72,7 +83,7 @@ private:
std::queue<connect_data*> close_connection_queue;
std::queue<write_data*> write_queue;
std::queue<read_start_data*> read_start_queue;
std::queue<timer_start_data*> timer_start_queue;
public:
rust_uvtmp_thread() {
@ -139,6 +150,17 @@ public:
read_start_queue.push(rd);
}
void
timer(uint32_t timeout, uint32_t req_id, chan_handle chan) {
scoped_lock with(lock);
timer_start_data *td = new timer_start_data();
td->timeout = timeout;
td->req_id = req_id;
td->chan = chan;
timer_start_queue.push(td);
}
private:
virtual void
@ -159,6 +181,7 @@ private:
close_connections();
write_buffers();
start_reads();
start_timers();
close_idle_if_stop();
}
@ -246,7 +269,7 @@ private:
void
on_write(uv_write_t *handle, write_data *wd) {
iomsg msg;
msg.tag = wrote_tag;
msg.tag = timer_tag;
msg.val.wrote_val = wd->cd;
send(task, wd->chan, &msg);
@ -299,6 +322,40 @@ private:
}
}
void
start_timers() {
assert (lock.lock_held_by_current_thread());
while (!timer_start_queue.empty()) {
timer_start_data *td = timer_start_queue.front();
timer_start_queue.pop();
td->thread = this;
uv_timer_t *timer = (uv_timer_t *)malloc(sizeof(uv_timer_t));
timer->data = td;
uv_timer_init(loop, timer);
uv_timer_start(timer, timer_cb, td->timeout, 0);
}
}
static void
timer_cb(uv_timer_t *handle, int what) {
timer_start_data *td = (timer_start_data*)handle->data;
rust_uvtmp_thread *self = td->thread;
self->on_timer(td);
free(handle);
}
void
on_timer(timer_start_data *rd) {
iomsg msg;
msg.tag = timer_tag;
msg.val.timer_req_id = rd->req_id;
send(task, rd->chan, &msg);
delete rd;
}
void
close_idle_if_stop() {
assert(lock.lock_held_by_current_thread());
@ -353,6 +410,11 @@ rust_uvtmp_read_start(rust_uvtmp_thread *thread, uint32_t req_id,
thread->read_start(req_id, *chan);
}
extern "C" void
rust_uvtmp_timer(rust_uvtmp_thread *thread, uint32_t timeout, uint32_t req_id, chan_handle *chan) {
thread->timer(timeout, req_id, *chan);
}
extern "C" void
rust_uvtmp_delete_buf(uint8_t *buf) {
delete [] buf;

View file

@ -96,6 +96,7 @@ rust_uvtmp_connect
rust_uvtmp_close_connection
rust_uvtmp_write
rust_uvtmp_read_start
rust_uvtmp_timer
rust_uvtmp_delete_buf
rust_uvtmp_get_req_id

View file

@ -32,7 +32,7 @@ import comm::recv;
import comm::send;
fn map(&&filename: [u8], emit: map_reduce::putter<[u8], int>) {
let f = io::file_reader(str::unsafe_from_bytes(filename));
let f = io::file_reader(str::from_bytes(filename));
while true {
alt read_word(f) {

View file

@ -0,0 +1,6 @@
// Check that bogus field access is non-fatal
fn main() {
let x = 0;
log(debug, x.foo); //! ERROR attempted access of field
log(debug, x.bar); //! ERROR attempted access of field
}

View file

@ -1,2 +1,2 @@
// error-pattern: Type inference failed because I could not find
// error-pattern: can not instantiate infinite type
fn main() { let f; f = @f; }

View file

@ -0,0 +1,5 @@
// error-pattern: illegal recursive enum type
enum list<T> { cons(T, list<T>), nil }
fn main() {}

View file

@ -81,7 +81,7 @@ mod map_reduce {
mapper_done { num_mappers -= 1; }
find_reducer(k, cc) {
let c;
alt reducers.find(str::unsafe_from_bytes(k)) {
alt reducers.find(str::from_bytes(k)) {
some(_c) { c = _c; }
none { c = 0; }
}