Better line breaking in function pointer types
The current implementation never goes to a new line when writing a function pointer type, this can lead to long, difficult to read lines. The goal of this change is to make that a bit more sensible. Here is a rust code example ``` 1 │ pub type MyCallback = Option<unsafe extern "C" fn(a: usize, b: usize)>; 2 │ 3 │ pub type MyOtherCallback = 4 │ Option<unsafe extern "C" fn(a: usize, lot: usize, of: usize, args: usize)>; 5 │ 6 │ #[no_mangle] 7 │ pub extern "C" fn my_function(a: MyCallback, b: MyOtherCallback) {} ``` right when generating the corresponing C header we get ``` 1 │ #include <stdarg.h> 2 │ #include <stdbool.h> 3 │ #include <stdint.h> 4 │ #include <stdlib.h> 5 │ 6 │ typedef void (*MyCallback)(uintptr_t a, uintptr_t b); 7 │ 8 │ typedef void (*MyOtherCallback)(uintptr_t a, uintptr_t lot, uintptr_t of, uintptr_t args); 9 │ 10 │ void my_function(MyCallback a, MyOtherCallback b); ``` line 8 here is already quite long and will be even longer if we add new args to `MyOtherCallback` With the changes in this commit, we now get ``` 1 │ #include <stdarg.h> 2 │ #include <stdbool.h> 3 │ #include <stdint.h> 4 │ #include <stdlib.h> 5 │ 6 │ typedef void (*MyCallback)(uintptr_t a, uintptr_t b); 7 │ 8 │ typedef void (*MyOtherCallback)(uintptr_t a, 9 │ uintptr_t lot, 10 │ uintptr_t of, 11 │ uintptr_t args); 12 │ 13 │ void my_function(MyCallback a, MyOtherCallback b); ``` which is way better and more scalable if new args are atted to `MyOtherCallback` The behavior is configurable using the already existing `fn.args` configuration parameter. In this case setting it to `Horizontal` gives back the same .h as previously and setting it to `Vertical` makes the generator go to a new line even for the shorter `MyCallback` declaration: ``` 1 │ #include <stdarg.h> 2 │ #include <stdbool.h> 3 │ #include <stdint.h> 4 │ #include <stdlib.h> 5 │ 6 │ typedef void (*MyCallback)(uintptr_t a, 7 │ uintptr_t b); 8 │ 9 │ typedef void (*MyOtherCallback)(uintptr_t a, 10 │ uintptr_t lot, 11 │ uintptr_t of, 12 │ uintptr_t args); 13 │ 14 │ void my_function(MyCallback a, 15 │ MyOtherCallback b); ``` Closes #793
This commit is contained in:
parent
a2bda0a1de
commit
5fd38d5417
@ -4,6 +4,7 @@
|
||||
|
||||
use std::io::Write;
|
||||
|
||||
use crate::bindgen::config::Layout;
|
||||
use crate::bindgen::declarationtyperesolver::DeclarationType;
|
||||
use crate::bindgen::ir::{ConstExpr, Function, GenericArgument, Type};
|
||||
use crate::bindgen::writer::{ListType, SourceWriter};
|
||||
@ -22,7 +23,7 @@ enum CDeclarator {
|
||||
Array(String),
|
||||
Func {
|
||||
args: Vec<(Option<String>, CDecl)>,
|
||||
layout_vertical: bool,
|
||||
layout: Layout,
|
||||
never_return: bool,
|
||||
},
|
||||
}
|
||||
@ -79,13 +80,13 @@ impl CDecl {
|
||||
cdecl
|
||||
}
|
||||
|
||||
fn from_func(f: &Function, layout_vertical: bool, config: &Config) -> CDecl {
|
||||
fn from_func(f: &Function, layout: Layout, config: &Config) -> CDecl {
|
||||
let mut cdecl = CDecl::new();
|
||||
cdecl.build_func(f, layout_vertical, config);
|
||||
cdecl.build_func(f, layout, config);
|
||||
cdecl
|
||||
}
|
||||
|
||||
fn build_func(&mut self, f: &Function, layout_vertical: bool, config: &Config) {
|
||||
fn build_func(&mut self, f: &Function, layout: Layout, config: &Config) {
|
||||
let args = f
|
||||
.args
|
||||
.iter()
|
||||
@ -98,7 +99,7 @@ impl CDecl {
|
||||
.collect();
|
||||
self.declarators.push(CDeclarator::Func {
|
||||
args,
|
||||
layout_vertical,
|
||||
layout,
|
||||
never_return: f.never_return,
|
||||
});
|
||||
self.build_type(&f.ret, false, config);
|
||||
@ -182,7 +183,7 @@ impl CDecl {
|
||||
});
|
||||
self.declarators.push(CDeclarator::Func {
|
||||
args,
|
||||
layout_vertical: false,
|
||||
layout: config.function.args.clone(),
|
||||
never_return: *never_return,
|
||||
});
|
||||
self.build_type(ret, false, config);
|
||||
@ -276,7 +277,7 @@ impl CDecl {
|
||||
}
|
||||
CDeclarator::Func {
|
||||
ref args,
|
||||
layout_vertical,
|
||||
ref layout,
|
||||
never_return,
|
||||
} => {
|
||||
if last_was_pointer {
|
||||
@ -287,7 +288,12 @@ impl CDecl {
|
||||
if args.is_empty() && config.language == Language::C {
|
||||
out.write("void");
|
||||
}
|
||||
if layout_vertical {
|
||||
|
||||
fn write_vertical<F: Write>(
|
||||
out: &mut SourceWriter<F>,
|
||||
config: &Config,
|
||||
args: &[(Option<String>, CDecl)],
|
||||
) {
|
||||
let align_length = out.line_length_for_align();
|
||||
out.push_set_spaces(align_length);
|
||||
for (i, &(ref arg_ident, ref arg_ty)) in args.iter().enumerate() {
|
||||
@ -302,7 +308,13 @@ impl CDecl {
|
||||
arg_ty.write(out, arg_ident, config);
|
||||
}
|
||||
out.pop_tab();
|
||||
} else {
|
||||
}
|
||||
|
||||
fn write_horizontal<F: Write>(
|
||||
out: &mut SourceWriter<F>,
|
||||
config: &Config,
|
||||
args: &[(Option<String>, CDecl)],
|
||||
) {
|
||||
for (i, &(ref arg_ident, ref arg_ty)) in args.iter().enumerate() {
|
||||
if i != 0 {
|
||||
out.write(", ");
|
||||
@ -314,6 +326,21 @@ impl CDecl {
|
||||
arg_ty.write(out, arg_ident, config);
|
||||
}
|
||||
}
|
||||
|
||||
match layout {
|
||||
Layout::Vertical => write_vertical(out, config, args),
|
||||
Layout::Horizontal => write_horizontal(out, config, args),
|
||||
Layout::Auto => {
|
||||
if out.line_length_for_align()
|
||||
+ out.measure(|out| write_horizontal(out, config, args))
|
||||
> config.line_length
|
||||
{
|
||||
write_vertical(out, config, args)
|
||||
} else {
|
||||
write_horizontal(out, config, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
out.write(")");
|
||||
|
||||
if never_return && config.language != Language::Cython {
|
||||
@ -332,10 +359,10 @@ impl CDecl {
|
||||
pub fn write_func<F: Write>(
|
||||
out: &mut SourceWriter<F>,
|
||||
f: &Function,
|
||||
layout_vertical: bool,
|
||||
layout: Layout,
|
||||
config: &Config,
|
||||
) {
|
||||
CDecl::from_func(f, layout_vertical, config).write(out, Some(f.path().name()), config);
|
||||
CDecl::from_func(f, layout, config).write(out, Some(f.path().name()), config);
|
||||
}
|
||||
|
||||
pub fn write_field<F: Write>(out: &mut SourceWriter<F>, t: &Type, ident: &str, config: &Config) {
|
||||
|
@ -242,7 +242,7 @@ impl Source for Function {
|
||||
}
|
||||
}
|
||||
}
|
||||
cdecl::write_func(out, func, false, config);
|
||||
cdecl::write_func(out, func, Layout::Horizontal, config);
|
||||
|
||||
if !func.extern_decl {
|
||||
if let Some(ref postfix) = postfix {
|
||||
@ -285,7 +285,7 @@ impl Source for Function {
|
||||
}
|
||||
}
|
||||
}
|
||||
cdecl::write_func(out, func, true, config);
|
||||
cdecl::write_func(out, func, Layout::Vertical, config);
|
||||
if !func.extern_decl {
|
||||
if let Some(ref postfix) = postfix {
|
||||
out.new_line();
|
||||
|
Loading…
x
Reference in New Issue
Block a user