Skip to content

Commit

Permalink
stdlib: Use spans for #fmt errors originating in std
Browse files Browse the repository at this point in the history
  • Loading branch information
brson authored and paulstansifer committed Jun 9, 2011
1 parent 6689e57 commit 5a9aa5f
Show file tree
Hide file tree
Showing 5 changed files with 34 additions and 11 deletions.
8 changes: 7 additions & 1 deletion src/comp/front/extfmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,17 @@ fn expand_syntax_ext(&ext_ctxt cx,
}

auto fmt = expr_to_str(cx, args.(0));
auto fmtspan = args.(0).span;

log "Format string:";
log fmt;

auto pieces = parse_fmt_string(fmt);
fn parse_fmt_err_(&ext_ctxt cx, common::span sp, str msg) -> ! {
cx.span_err(sp, msg);
}

auto parse_fmt_err = bind parse_fmt_err_(cx, fmtspan, _);
auto pieces = parse_fmt_string(fmt, parse_fmt_err);
auto args_len = vec::len[@ast::expr](args);
auto fmt_args = vec::slice[@ast::expr](args, 1u, args_len - 1u);
ret pieces_to_expr(cx, sp, pieces, args);
Expand Down
22 changes: 12 additions & 10 deletions src/lib/extfmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ mod ct {
piece_conv(conv);
}

fn parse_fmt_string(str s) -> vec[piece] {
type error_fn = fn (str) -> !;

fn parse_fmt_string(str s, error_fn error) -> vec[piece] {
let vec[piece] pieces = [];
auto lim = str::byte_len(s);
auto buf = "";
Expand All @@ -97,15 +99,14 @@ mod ct {
if (str::eq(curr, "%")) {
i += 1u;
if (i >= lim) {
log_err "unterminated conversion at end of string";
fail;
error("unterminated conversion at end of string");
}
auto curr2 = str::substr(s, i, 1u);
if (str::eq(curr2, "%")) {
i += 1u;
} else {
buf = flush_buf(buf, pieces);
auto res = parse_conversion(s, i, lim);
auto res = parse_conversion(s, i, lim, error);
pieces += [res._0];
i = res._1;
}
Expand Down Expand Up @@ -141,12 +142,13 @@ mod ct {
};
}

fn parse_conversion(str s, uint i, uint lim) -> tup(piece, uint) {
fn parse_conversion(str s, uint i, uint lim,
error_fn error) -> tup(piece, uint) {
auto parm = parse_parameter(s, i, lim);
auto flags = parse_flags(s, parm._1, lim);
auto width = parse_count(s, flags._1, lim);
auto prec = parse_precision(s, width._1, lim);
auto ty = parse_type(s, prec._1, lim);
auto ty = parse_type(s, prec._1, lim, error);
ret tup(piece_conv(rec(param = parm._0,
flags = flags._0,
width = width._0,
Expand Down Expand Up @@ -258,10 +260,9 @@ mod ct {
};
}

fn parse_type(str s, uint i, uint lim) -> tup(ty, uint) {
fn parse_type(str s, uint i, uint lim, error_fn error) -> tup(ty, uint) {
if (i >= lim) {
log_err "missing type in conversion";
fail;
error("missing type in conversion");
}

auto tstr = str::substr(s, i, 1u);
Expand All @@ -287,7 +288,8 @@ mod ct {
} else if (str::eq(tstr, "o")) {
ty_octal
} else {
log_err "unknown type in conversion";
// FIXME: Shouldn't need explicit fail here. Issue #542
error("unknown type in conversion: " + tstr);
fail
};

Expand Down
5 changes: 5 additions & 0 deletions src/test/compile-fail/extfmt-missing-type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// error-pattern:missing type

fn main() {
#fmt("%+");
}
5 changes: 5 additions & 0 deletions src/test/compile-fail/extfmt-unknown-type.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// error-pattern:unknown type

fn main() {
#fmt("%w");
}
5 changes: 5 additions & 0 deletions src/test/compile-fail/extfmt-unterminated-conv.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// error-pattern:unterminated conversion

fn main() {
#fmt("%");
}

0 comments on commit 5a9aa5f

Please sign in to comment.