diff --git a/src/libcore/path.rs b/src/libcore/path.rs index 75ca4cb035e..a771f2b9928 100644 --- a/src/libcore/path.rs +++ b/src/libcore/path.rs @@ -136,7 +136,7 @@ fn connect_many(paths: [path]) -> path { } #[doc = " -Split a path into it's individual components +Split a path into its individual components Splits a given path by path separators and returns a vector containing each piece of the path. On Windows, if the path is absolute then diff --git a/src/librustsyntax/ext/base.rs b/src/librustsyntax/ext/base.rs index 170ba112e31..92b6acba5b0 100644 --- a/src/librustsyntax/ext/base.rs +++ b/src/librustsyntax/ext/base.rs @@ -153,10 +153,37 @@ fn make_new_lit(cx: ext_ctxt, sp: codemap::span, lit: ast::lit_) -> ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp}; } -fn get_mac_arg(cx: ext_ctxt, sp: span, arg: ast::mac_arg) -> @ast::expr { - alt (arg) { - some(expr) {expr} - none {cx.span_fatal(sp, "missing macro args")} +fn get_mac_args_no_max(cx: ext_ctxt, sp: span, arg: ast::mac_arg, + min: uint, name: str) -> [@ast::expr] { + ret get_mac_args(cx, sp, arg, min, none, name); +} + +fn get_mac_args(cx: ext_ctxt, sp: span, arg: ast::mac_arg, + min: uint, max: option, name: str) -> [@ast::expr] { + alt arg { + some(expr) { + alt expr.node { + ast::expr_vec(elts, _) { + let elts_len = vec::len(elts); + alt max { + some(max) if ! (min <= elts_len && elts_len <= max) { + cx.span_fatal(sp, + #fmt["#%s takes between %u and %u arguments.", + name, min, max]); + } + none if ! (min <= elts_len) { + cx.span_fatal(sp, #fmt["#%s needs at least %u arguments.", + name, min]); + } + _ { ret elts; /* we're good */} + } + } + _ { + cx.span_fatal(sp, #fmt["#%s: malformed invocation", name]) + } + } + } + none {cx.span_fatal(sp, #fmt["#%s: missing arguments", name])} } } diff --git a/src/librustsyntax/ext/concat_idents.rs b/src/librustsyntax/ext/concat_idents.rs index 409a38b378d..278321ec8bc 100644 --- a/src/librustsyntax/ext/concat_idents.rs +++ b/src/librustsyntax/ext/concat_idents.rs @@ -2,14 +2,7 @@ import base::*; fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { - let arg = get_mac_arg(cx,sp,arg); - let args: [@ast::expr] = - alt arg.node { - ast::expr_vec(elts, _) { elts } - _ { - cx.span_fatal(sp, "#concat_idents requires a vector argument .") - } - }; + let args = get_mac_args_no_max(cx,sp,arg,1u,"concat_idents"); let mut res: ast::ident = ""; for args.each {|e| res += expr_to_ident(cx, e, "expected an ident"); diff --git a/src/librustsyntax/ext/env.rs b/src/librustsyntax/ext/env.rs index 616c816a66d..6a4d937f083 100644 --- a/src/librustsyntax/ext/env.rs +++ b/src/librustsyntax/ext/env.rs @@ -9,17 +9,8 @@ export expand_syntax_ext; fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { - let arg = get_mac_arg(cx,sp,arg); - let args: [@ast::expr] = - alt arg.node { - ast::expr_vec(elts, _) { elts } - _ { - cx.span_fatal(sp, "#env requires arguments of the form `[...]`.") - } - }; - if vec::len::<@ast::expr>(args) != 1u { - cx.span_fatal(sp, "malformed #env call"); - } + let args = get_mac_args(cx, sp, arg, 1u, option::some(1u), "env"); + // FIXME: if this was more thorough it would manufacture an // option rather than just an maybe-empty string. (Issue #2248) diff --git a/src/librustsyntax/ext/fmt.rs b/src/librustsyntax/ext/fmt.rs index 1ab340c9c0e..aceeed4b9e8 100644 --- a/src/librustsyntax/ext/fmt.rs +++ b/src/librustsyntax/ext/fmt.rs @@ -13,17 +13,7 @@ export expand_syntax_ext; fn expand_syntax_ext(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { - let arg = get_mac_arg(cx,sp,arg); - let args: [@ast::expr] = - alt arg.node { - ast::expr_vec(elts, _) { elts } - _ { - cx.span_fatal(sp, "#fmt requires arguments of the form `[...]`.") - } - }; - if vec::len::<@ast::expr>(args) == 0u { - cx.span_fatal(sp, "#fmt requires a format string"); - } + let args = get_mac_args_no_max(cx, sp, arg, 1u, "fmt"); let fmt = expr_to_str(cx, args[0], "first argument to #fmt must be a string literal."); diff --git a/src/librustsyntax/ext/ident_to_str.rs b/src/librustsyntax/ext/ident_to_str.rs index cb7c604a489..7dfb70f1520 100644 --- a/src/librustsyntax/ext/ident_to_str.rs +++ b/src/librustsyntax/ext/ident_to_str.rs @@ -1,21 +1,11 @@ import base::*; +import option; fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { - let arg = get_mac_arg(cx,sp,arg); - let args: [@ast::expr] = - alt arg.node { - ast::expr_vec(elts, _) { elts } - _ { - cx.span_fatal(sp, "#ident_to_str requires a vector argument .") - } - }; - if vec::len::<@ast::expr>(args) != 1u { - cx.span_fatal(sp, "malformed #ident_to_str call"); - } + let args = get_mac_args(cx,sp,arg,1u,option::some(1u),"ident_to_str"); ret make_new_lit(cx, sp, ast::lit_str(expr_to_ident(cx, args[0u], "expected an ident"))); - } diff --git a/src/librustsyntax/ext/include.rs b/src/librustsyntax/ext/include.rs index a31d2835e8a..e9391adb222 100644 --- a/src/librustsyntax/ext/include.rs +++ b/src/librustsyntax/ext/include.rs @@ -14,18 +14,8 @@ export str; mod str { fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { - let arg = get_mac_arg(cx,sp,arg); - let args: [@ast::expr] = - alt arg.node { - ast::expr_vec(elts, _) { elts } - _ { - cx.span_fatal(sp, "#include_str requires arguments \ - of the form `[...]`.") - } - }; - if vec::len::<@ast::expr>(args) != 1u { - cx.span_fatal(sp, "malformed #include_str call"); - } + let args = get_mac_args(cx,sp,arg,1u,option::some(1u),"include_str"); + let mut path = expr_to_str(cx, args[0], "#include_str requires \ a string"); diff --git a/src/librustsyntax/ext/log_syntax.rs b/src/librustsyntax/ext/log_syntax.rs index 4ae212047f3..5ccbb143b97 100644 --- a/src/librustsyntax/ext/log_syntax.rs +++ b/src/librustsyntax/ext/log_syntax.rs @@ -3,9 +3,12 @@ import io::writer_util; fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg, _body: ast::mac_body) -> @ast::expr { - let arg = get_mac_arg(cx,sp,arg); + let args = get_mac_args_no_max(cx,sp,arg,0u,"log_syntax"); cx.print_backtrace(); - io::stdout().write_line(print::pprust::expr_to_str(arg)); + io::stdout().write_line( + str::connect(vec::map(args, + {|&&ex| print::pprust::expr_to_str(ex)}), ", ") + ); //trivial expression ret @{id: cx.next_id(), node: ast::expr_rec([], option::none), span: sp}; diff --git a/src/librustsyntax/ext/simplext.rs b/src/librustsyntax/ext/simplext.rs index 81eaa193f95..792618f2bde 100644 --- a/src/librustsyntax/ext/simplext.rs +++ b/src/librustsyntax/ext/simplext.rs @@ -668,15 +668,7 @@ fn p_t_s_r_actual_vector(cx: ext_ctxt, elts: [@expr], _repeat_after: bool, fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body) -> base::macro_def { - let arg = get_mac_arg(cx,sp,arg); - let args: [@ast::expr] = - alt arg.node { - ast::expr_vec(elts, _) { elts } - _ { - cx.span_fatal(sp, - "#macro requires arguments of the form `[...]`.") - } - }; + let args = get_mac_args_no_max(cx, sp, arg, 0u, "macro"); let mut macro_name: option = none; let mut clauses: [@clause] = []; @@ -712,9 +704,13 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, "macro name must not be a path"); } } + let arg = alt invoc_arg { + some(arg) { arg } + none { cx.span_fatal(mac.span, + "macro must have arguments")} + }; clauses += - [@{params: pattern_to_selectors - (cx, get_mac_arg(cx,mac.span,invoc_arg)), + [@{params: pattern_to_selectors(cx, arg), body: elts[1u]}]; // FIXME: check duplicates (or just simplify @@ -746,16 +742,18 @@ fn add_new_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, alt macro_name { some(id) { id } none { - cx.span_fatal(sp, - "macro definition must have " + - "at least one clause") + cx.span_fatal(sp, "macro definition must have " + + "at least one clause") } }, - ext: normal({expander: ext, span: some(arg.span)})}; + ext: normal({expander: ext, span: some(option::get(arg).span)})}; fn generic_extension(cx: ext_ctxt, sp: span, arg: ast::mac_arg, _body: ast::mac_body, clauses: [@clause]) -> @expr { - let arg = get_mac_arg(cx,sp,arg); + let arg = alt arg { + some(arg) { arg } + none { cx.span_fatal(sp, "macro must have arguments")} + }; for clauses.each {|c| alt use_selectors_to_bind(c.params, arg) { some(bindings) { ret transcribe(cx, bindings, c.body); } diff --git a/src/test/compile-fail/extenv-no-args.rs b/src/test/compile-fail/extenv-no-args.rs index ec73f0a7a45..44611424079 100644 --- a/src/test/compile-fail/extenv-no-args.rs +++ b/src/test/compile-fail/extenv-no-args.rs @@ -1,3 +1,3 @@ -// error-pattern:malformed #env call +// error-pattern:#env takes between 1 and 1 arguments fn main() { #env[]; } diff --git a/src/test/compile-fail/extenv-too-many-args.rs b/src/test/compile-fail/extenv-too-many-args.rs index 945546fd6cb..6e70b67f9c4 100644 --- a/src/test/compile-fail/extenv-too-many-args.rs +++ b/src/test/compile-fail/extenv-too-many-args.rs @@ -1,3 +1,3 @@ -// error-pattern:malformed #env call +// error-pattern:#env takes between 1 and 1 arguments fn main() { #env["one", "two"]; } diff --git a/src/test/compile-fail/extfmt-no-args.rs b/src/test/compile-fail/extfmt-no-args.rs index 7c13ef99dc5..f88d74dd166 100644 --- a/src/test/compile-fail/extfmt-no-args.rs +++ b/src/test/compile-fail/extfmt-no-args.rs @@ -1,3 +1,3 @@ -// error-pattern:format string +// error-pattern:#fmt needs at least 1 arguments fn main() { #fmt[]; }