From 3ca0e75ed906ae505740657647b08e04cd844f14 Mon Sep 17 00:00:00 2001 From: Tom Solberg Date: Wed, 26 Aug 2020 15:28:17 +0200 Subject: [PATCH] Add support for specifying line ending style (#568) --- src/bindgen/config.rs | 58 +++++++++++++++++++ src/bindgen/writer.rs | 5 +- template.toml | 2 +- tests/expectations/both/linestyle_cr.c | 1 + tests/expectations/both/linestyle_cr.compat.c | 1 + tests/expectations/both/linestyle_crlf.c | 11 ++++ .../expectations/both/linestyle_crlf.compat.c | 19 ++++++ tests/expectations/both/linestyle_lf.c | 11 ++++ tests/expectations/both/linestyle_lf.compat.c | 19 ++++++ tests/expectations/linestyle_cr.c | 1 + tests/expectations/linestyle_cr.compat.c | 1 + tests/expectations/linestyle_cr.cpp | 1 + tests/expectations/linestyle_crlf.c | 11 ++++ tests/expectations/linestyle_crlf.compat.c | 19 ++++++ tests/expectations/linestyle_crlf.cpp | 15 +++++ tests/expectations/linestyle_lf.c | 11 ++++ tests/expectations/linestyle_lf.compat.c | 19 ++++++ tests/expectations/linestyle_lf.cpp | 15 +++++ tests/expectations/tag/linestyle_cr.c | 1 + tests/expectations/tag/linestyle_cr.compat.c | 1 + tests/expectations/tag/linestyle_crlf.c | 11 ++++ .../expectations/tag/linestyle_crlf.compat.c | 19 ++++++ tests/expectations/tag/linestyle_lf.c | 11 ++++ tests/expectations/tag/linestyle_lf.compat.c | 19 ++++++ tests/rust/linestyle_cr.rs | 8 +++ tests/rust/linestyle_cr.toml | 1 + tests/rust/linestyle_crlf.rs | 8 +++ tests/rust/linestyle_crlf.toml | 1 + tests/rust/linestyle_lf.rs | 8 +++ tests/rust/linestyle_lf.toml | 1 + 30 files changed, 307 insertions(+), 2 deletions(-) create mode 100644 tests/expectations/both/linestyle_cr.c create mode 100644 tests/expectations/both/linestyle_cr.compat.c create mode 100644 tests/expectations/both/linestyle_crlf.c create mode 100644 tests/expectations/both/linestyle_crlf.compat.c create mode 100644 tests/expectations/both/linestyle_lf.c create mode 100644 tests/expectations/both/linestyle_lf.compat.c create mode 100644 tests/expectations/linestyle_cr.c create mode 100644 tests/expectations/linestyle_cr.compat.c create mode 100644 tests/expectations/linestyle_cr.cpp create mode 100644 tests/expectations/linestyle_crlf.c create mode 100644 tests/expectations/linestyle_crlf.compat.c create mode 100644 tests/expectations/linestyle_crlf.cpp create mode 100644 tests/expectations/linestyle_lf.c create mode 100644 tests/expectations/linestyle_lf.compat.c create mode 100644 tests/expectations/linestyle_lf.cpp create mode 100644 tests/expectations/tag/linestyle_cr.c create mode 100644 tests/expectations/tag/linestyle_cr.compat.c create mode 100644 tests/expectations/tag/linestyle_crlf.c create mode 100644 tests/expectations/tag/linestyle_crlf.compat.c create mode 100644 tests/expectations/tag/linestyle_lf.c create mode 100644 tests/expectations/tag/linestyle_lf.compat.c create mode 100644 tests/rust/linestyle_cr.rs create mode 100644 tests/rust/linestyle_cr.toml create mode 100644 tests/rust/linestyle_crlf.rs create mode 100644 tests/rust/linestyle_crlf.toml create mode 100644 tests/rust/linestyle_lf.rs create mode 100644 tests/rust/linestyle_lf.toml diff --git a/src/bindgen/config.rs b/src/bindgen/config.rs index be6025a..361ad11 100644 --- a/src/bindgen/config.rs +++ b/src/bindgen/config.rs @@ -48,6 +48,61 @@ impl FromStr for Language { deserialize_enum_str!(Language); +/// Controls what type of line endings are used in the generated code. +#[derive(Debug, Clone, Copy)] +pub enum LineEndingStyle { + /// Use Unix-style linefeed characters + LF, + /// Use classic Mac-style carriage-return characters + CR, + /// Use Windows-style carriage-return and linefeed characters + CRLF, + /// Use the native mode for the platform: CRLF on Windows, LF everywhere else. + Native, +} + +impl Default for LineEndingStyle { + fn default() -> Self { + LineEndingStyle::LF + } +} + +impl LineEndingStyle { + pub fn as_str(&self) -> &'static str { + match self { + Self::LF => "\n", + Self::CR => "\r", + Self::CRLF => "\r\n", + Self::Native => { + #[cfg(target_os = "windows")] + { + Self::CRLF.as_str() + } + #[cfg(not(target_os = "windows"))] + { + Self::LF.as_str() + } + } + } + } +} + +impl FromStr for LineEndingStyle { + type Err = String; + + fn from_str(s: &str) -> Result { + match s.to_lowercase().as_ref() { + "native" => Ok(Self::Native), + "lf" => Ok(Self::LF), + "crlf" => Ok(Self::CRLF), + "cr" => Ok(Self::CR), + _ => Err(format!("Unrecognized line ending style: '{}'.", s)), + } + } +} + +deserialize_enum_str!(LineEndingStyle); + /// A style of braces to use for generating code. #[derive(Debug, Clone, PartialEq)] pub enum Braces { @@ -745,6 +800,8 @@ pub struct Config { pub line_length: usize, /// The amount of spaces in a tab pub tab_width: usize, + /// The type of line endings to generate + pub line_endings: LineEndingStyle, /// The language to output bindings for pub language: Language, /// Include preprocessor defines in C bindings to ensure C++ compatibility @@ -801,6 +858,7 @@ impl Default for Config { braces: Braces::SameLine, line_length: 100, tab_width: 2, + line_endings: LineEndingStyle::default(), language: Language::Cxx, cpp_compat: false, style: Style::Type, diff --git a/src/bindgen/writer.rs b/src/bindgen/writer.rs index 06bec0d..1761518 100644 --- a/src/bindgen/writer.rs +++ b/src/bindgen/writer.rs @@ -65,6 +65,7 @@ pub struct SourceWriter<'a, F: Write> { line_number: usize, max_line_length: usize, } + pub type MeasureWriter<'a> = SourceWriter<'a, NullFile>; impl<'a, F: Write> SourceWriter<'a, F> { @@ -137,7 +138,9 @@ impl<'a, F: Write> SourceWriter<'a, F> { } pub fn new_line(&mut self) { - writeln!(self.out).unwrap(); + self.out + .write(self.bindings.config.line_endings.as_str().as_bytes()) + .unwrap(); self.line_started = false; self.line_length = 0; self.line_number += 1; diff --git a/template.toml b/template.toml index 545dac3..01e77fc 100644 --- a/template.toml +++ b/template.toml @@ -35,7 +35,7 @@ braces = "SameLine" line_length = 100 tab_width = 2 documentation_style = "auto" - +line-endings = "LF" # also "CR", "CRLF", "Native" diff --git a/tests/expectations/both/linestyle_cr.c b/tests/expectations/both/linestyle_cr.c new file mode 100644 index 0000000..2fa7d17 --- /dev/null +++ b/tests/expectations/both/linestyle_cr.c @@ -0,0 +1 @@ +#include #include #include #include typedef struct Dummy { int32_t x; float y; } Dummy; void root(Dummy d); \ No newline at end of file diff --git a/tests/expectations/both/linestyle_cr.compat.c b/tests/expectations/both/linestyle_cr.compat.c new file mode 100644 index 0000000..2fc759a --- /dev/null +++ b/tests/expectations/both/linestyle_cr.compat.c @@ -0,0 +1 @@ +#include #include #include #include typedef struct Dummy { int32_t x; float y; } Dummy; #ifdef __cplusplus extern "C" { #endif // __cplusplus void root(Dummy d); #ifdef __cplusplus } // extern "C" #endif // __cplusplus \ No newline at end of file diff --git a/tests/expectations/both/linestyle_crlf.c b/tests/expectations/both/linestyle_crlf.c new file mode 100644 index 0000000..2a67a86 --- /dev/null +++ b/tests/expectations/both/linestyle_crlf.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +typedef struct Dummy { + int32_t x; + float y; +} Dummy; + +void root(Dummy d); diff --git a/tests/expectations/both/linestyle_crlf.compat.c b/tests/expectations/both/linestyle_crlf.compat.c new file mode 100644 index 0000000..f46efe8 --- /dev/null +++ b/tests/expectations/both/linestyle_crlf.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +typedef struct Dummy { + int32_t x; + float y; +} Dummy; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(Dummy d); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/both/linestyle_lf.c b/tests/expectations/both/linestyle_lf.c new file mode 100644 index 0000000..c624ea3 --- /dev/null +++ b/tests/expectations/both/linestyle_lf.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +typedef struct Dummy { + int32_t x; + float y; +} Dummy; + +void root(Dummy d); diff --git a/tests/expectations/both/linestyle_lf.compat.c b/tests/expectations/both/linestyle_lf.compat.c new file mode 100644 index 0000000..b697b7c --- /dev/null +++ b/tests/expectations/both/linestyle_lf.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +typedef struct Dummy { + int32_t x; + float y; +} Dummy; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(Dummy d); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/linestyle_cr.c b/tests/expectations/linestyle_cr.c new file mode 100644 index 0000000..cd4c9e7 --- /dev/null +++ b/tests/expectations/linestyle_cr.c @@ -0,0 +1 @@ +#include #include #include #include typedef struct { int32_t x; float y; } Dummy; void root(Dummy d); \ No newline at end of file diff --git a/tests/expectations/linestyle_cr.compat.c b/tests/expectations/linestyle_cr.compat.c new file mode 100644 index 0000000..e8b5e52 --- /dev/null +++ b/tests/expectations/linestyle_cr.compat.c @@ -0,0 +1 @@ +#include #include #include #include typedef struct { int32_t x; float y; } Dummy; #ifdef __cplusplus extern "C" { #endif // __cplusplus void root(Dummy d); #ifdef __cplusplus } // extern "C" #endif // __cplusplus \ No newline at end of file diff --git a/tests/expectations/linestyle_cr.cpp b/tests/expectations/linestyle_cr.cpp new file mode 100644 index 0000000..6a6a1c0 --- /dev/null +++ b/tests/expectations/linestyle_cr.cpp @@ -0,0 +1 @@ +#include #include #include #include struct Dummy { int32_t x; float y; }; extern "C" { void root(Dummy d); } // extern "C" \ No newline at end of file diff --git a/tests/expectations/linestyle_crlf.c b/tests/expectations/linestyle_crlf.c new file mode 100644 index 0000000..16fca1c --- /dev/null +++ b/tests/expectations/linestyle_crlf.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +typedef struct { + int32_t x; + float y; +} Dummy; + +void root(Dummy d); diff --git a/tests/expectations/linestyle_crlf.compat.c b/tests/expectations/linestyle_crlf.compat.c new file mode 100644 index 0000000..e105589 --- /dev/null +++ b/tests/expectations/linestyle_crlf.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +typedef struct { + int32_t x; + float y; +} Dummy; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(Dummy d); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/linestyle_crlf.cpp b/tests/expectations/linestyle_crlf.cpp new file mode 100644 index 0000000..0811113 --- /dev/null +++ b/tests/expectations/linestyle_crlf.cpp @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +struct Dummy { + int32_t x; + float y; +}; + +extern "C" { + +void root(Dummy d); + +} // extern "C" diff --git a/tests/expectations/linestyle_lf.c b/tests/expectations/linestyle_lf.c new file mode 100644 index 0000000..b848a63 --- /dev/null +++ b/tests/expectations/linestyle_lf.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +typedef struct { + int32_t x; + float y; +} Dummy; + +void root(Dummy d); diff --git a/tests/expectations/linestyle_lf.compat.c b/tests/expectations/linestyle_lf.compat.c new file mode 100644 index 0000000..41aeec9 --- /dev/null +++ b/tests/expectations/linestyle_lf.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +typedef struct { + int32_t x; + float y; +} Dummy; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(Dummy d); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/linestyle_lf.cpp b/tests/expectations/linestyle_lf.cpp new file mode 100644 index 0000000..da5355f --- /dev/null +++ b/tests/expectations/linestyle_lf.cpp @@ -0,0 +1,15 @@ +#include +#include +#include +#include + +struct Dummy { + int32_t x; + float y; +}; + +extern "C" { + +void root(Dummy d); + +} // extern "C" diff --git a/tests/expectations/tag/linestyle_cr.c b/tests/expectations/tag/linestyle_cr.c new file mode 100644 index 0000000..583f681 --- /dev/null +++ b/tests/expectations/tag/linestyle_cr.c @@ -0,0 +1 @@ +#include #include #include #include struct Dummy { int32_t x; float y; }; void root(struct Dummy d); \ No newline at end of file diff --git a/tests/expectations/tag/linestyle_cr.compat.c b/tests/expectations/tag/linestyle_cr.compat.c new file mode 100644 index 0000000..01708bd --- /dev/null +++ b/tests/expectations/tag/linestyle_cr.compat.c @@ -0,0 +1 @@ +#include #include #include #include struct Dummy { int32_t x; float y; }; #ifdef __cplusplus extern "C" { #endif // __cplusplus void root(struct Dummy d); #ifdef __cplusplus } // extern "C" #endif // __cplusplus \ No newline at end of file diff --git a/tests/expectations/tag/linestyle_crlf.c b/tests/expectations/tag/linestyle_crlf.c new file mode 100644 index 0000000..2ee5ff1 --- /dev/null +++ b/tests/expectations/tag/linestyle_crlf.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +struct Dummy { + int32_t x; + float y; +}; + +void root(struct Dummy d); diff --git a/tests/expectations/tag/linestyle_crlf.compat.c b/tests/expectations/tag/linestyle_crlf.compat.c new file mode 100644 index 0000000..8be6001 --- /dev/null +++ b/tests/expectations/tag/linestyle_crlf.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +struct Dummy { + int32_t x; + float y; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(struct Dummy d); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/expectations/tag/linestyle_lf.c b/tests/expectations/tag/linestyle_lf.c new file mode 100644 index 0000000..8cb9bb9 --- /dev/null +++ b/tests/expectations/tag/linestyle_lf.c @@ -0,0 +1,11 @@ +#include +#include +#include +#include + +struct Dummy { + int32_t x; + float y; +}; + +void root(struct Dummy d); diff --git a/tests/expectations/tag/linestyle_lf.compat.c b/tests/expectations/tag/linestyle_lf.compat.c new file mode 100644 index 0000000..8d53f1c --- /dev/null +++ b/tests/expectations/tag/linestyle_lf.compat.c @@ -0,0 +1,19 @@ +#include +#include +#include +#include + +struct Dummy { + int32_t x; + float y; +}; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +void root(struct Dummy d); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus diff --git a/tests/rust/linestyle_cr.rs b/tests/rust/linestyle_cr.rs new file mode 100644 index 0000000..49a317b --- /dev/null +++ b/tests/rust/linestyle_cr.rs @@ -0,0 +1,8 @@ +#[repr(C)] +struct Dummy { + x: i32, + y: f32, +} + +#[no_mangle] +pub extern "C" fn root(d: Dummy) {} diff --git a/tests/rust/linestyle_cr.toml b/tests/rust/linestyle_cr.toml new file mode 100644 index 0000000..43a1517 --- /dev/null +++ b/tests/rust/linestyle_cr.toml @@ -0,0 +1 @@ +line_endings = "CR" diff --git a/tests/rust/linestyle_crlf.rs b/tests/rust/linestyle_crlf.rs new file mode 100644 index 0000000..49a317b --- /dev/null +++ b/tests/rust/linestyle_crlf.rs @@ -0,0 +1,8 @@ +#[repr(C)] +struct Dummy { + x: i32, + y: f32, +} + +#[no_mangle] +pub extern "C" fn root(d: Dummy) {} diff --git a/tests/rust/linestyle_crlf.toml b/tests/rust/linestyle_crlf.toml new file mode 100644 index 0000000..c0ae218 --- /dev/null +++ b/tests/rust/linestyle_crlf.toml @@ -0,0 +1 @@ +line_endings = "CRLF" diff --git a/tests/rust/linestyle_lf.rs b/tests/rust/linestyle_lf.rs new file mode 100644 index 0000000..49a317b --- /dev/null +++ b/tests/rust/linestyle_lf.rs @@ -0,0 +1,8 @@ +#[repr(C)] +struct Dummy { + x: i32, + y: f32, +} + +#[no_mangle] +pub extern "C" fn root(d: Dummy) {} diff --git a/tests/rust/linestyle_lf.toml b/tests/rust/linestyle_lf.toml new file mode 100644 index 0000000..446fd30 --- /dev/null +++ b/tests/rust/linestyle_lf.toml @@ -0,0 +1 @@ +line_endings = "LF"