From b768d27f039e186d863c0fce332d87b9e63167e3 Mon Sep 17 00:00:00 2001 From: Marcus Klaas Date: Sat, 10 Oct 2015 22:53:20 +0200 Subject: [PATCH] Format variadic arguments --- src/items.rs | 52 ++++++++++++++++++++++++++++++++++-------- tests/source/extern.rs | 7 ++++++ tests/target/extern.rs | 9 ++++++++ 3 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/items.rs b/src/items.rs index caf17257578..35d34bbb558 100644 --- a/src/items.rs +++ b/src/items.rs @@ -377,7 +377,8 @@ impl<'a> FmtVisitor<'a> { multi_line_budget, indent, arg_indent, - args_span)); + args_span, + fd.variadic)); result.push_str(&arg_str); if self.config.fn_args_layout == StructLitStyle::Block { result.push('\n'); @@ -475,7 +476,8 @@ impl<'a> FmtVisitor<'a> { multi_line_budget: usize, indent: Indent, arg_indent: Indent, - span: Span) + span: Span, + variadic: bool) -> Option { let context = self.get_context(); let mut arg_item_strs = try_opt!(args.iter() @@ -506,27 +508,59 @@ impl<'a> FmtVisitor<'a> { // without spans for the comment or parens, there is no chance of // getting it right. You also don't get to put a comment on self, unless // it is explicit. - if args.len() >= min_args { + if args.len() >= min_args || variadic { let comment_span_start = if min_args == 2 { span_after(span, ",", self.codemap) } else { span.lo }; + enum ArgumentKind<'a> { + Regular(&'a ast::Arg), + Variadic(BytePos), + } + + let variadic_arg = if variadic { + let variadic_span = codemap::mk_sp(args.last().unwrap().ty.span.hi, span.hi); + let variadic_start = span_after(variadic_span, "...", self.codemap) - BytePos(1); + Some(ArgumentKind::Variadic(variadic_start)) + } else { + None + }; + let more_items = itemize_list(self.codemap, - args[min_args - 1..].iter(), + args[min_args - 1..] + .iter() + .map(ArgumentKind::Regular) + .chain(variadic_arg), ")", - |arg| span_lo_for_arg(arg), - |arg| arg.ty.span.hi, - |_| None, + |arg| { + match *arg { + ArgumentKind::Regular(arg) => + span_lo_for_arg(arg), + ArgumentKind::Variadic(start) => start, + } + }, + |arg| { + match *arg { + ArgumentKind::Regular(arg) => arg.ty.span.hi, + ArgumentKind::Variadic(start) => + start + BytePos(3), + } + }, + |arg| { + match *arg { + ArgumentKind::Regular(..) => None, + ArgumentKind::Variadic(..) => + Some("...".to_owned()), + } + }, comment_span_start, span.hi); arg_items.extend(more_items); } - assert_eq!(arg_item_strs.len(), arg_items.len()); - for (item, arg) in arg_items.iter_mut().zip(arg_item_strs) { item.item = Some(arg); } diff --git a/tests/source/extern.rs b/tests/source/extern.rs index 2e7b6c14646..7d3d0de6200 100644 --- a/tests/source/extern.rs +++ b/tests/source/extern.rs @@ -19,3 +19,10 @@ extern { extern "Rust" { static ext: u32; // Some comment. pub static mut var : SomeType ; } + +extern "C" { + fn syscall(number: libc::c_long /* comment 1 */, /* comm 2 */ ... /* sup? */) -> libc::c_long; + + fn foo (x: *const c_char , ... ) -> +libc::c_long; + } diff --git a/tests/target/extern.rs b/tests/target/extern.rs index 2c6f4936bff..164a6302bb4 100644 --- a/tests/target/extern.rs +++ b/tests/target/extern.rs @@ -27,3 +27,12 @@ extern "Rust" { // Some comment. pub static mut var: SomeType; } + +extern { + fn syscall(number: libc::c_long, // comment 1 + // comm 2 + ... /* sup? */) + -> libc::c_long; + + fn foo(x: *const c_char, ...) -> libc::c_long; +}