Added pragma once option. Issue #510

This commit is contained in:
Igor Sadchenko 2020-04-12 02:43:10 +03:00 committed by Emilio Cobos Álvarez
parent a9a893ee6c
commit 275b36fb09
23 changed files with 118 additions and 2 deletions

View File

@ -335,6 +335,10 @@ trailer = "/* Text to put at the end of the generated file */"
# default: doesn't emit an include guard
include_guard = "mozilla_wr_bindings_h"
# Whether to add a `#pragma once` guard
# default: doesn't emit a `#pragma once`
pragma_once = true
# An optional string of text to output between major sections of the generated
# file as a warning against manual editing
#

View File

@ -133,6 +133,11 @@ impl Bindings {
write!(out, "#define {}", f);
out.new_line();
}
if self.config.pragma_once {
out.new_line_if_not_start();
write!(out, "#pragma once");
out.new_line();
}
if self.config.include_version {
out.new_line_if_not_start();
write!(

View File

@ -72,6 +72,12 @@ impl Builder {
self
}
#[allow(unused)]
pub fn with_pragma_once(mut self, pragma_once: bool) -> Builder {
self.config.pragma_once = pragma_once;
self
}
#[allow(unused)]
pub fn with_autogen_warning<S: AsRef<str>>(mut self, autogen_warning: S) -> Builder {
self.config.autogen_warning = Some(String::from(autogen_warning.as_ref()));

View File

@ -705,6 +705,8 @@ pub struct Config {
pub trailer: Option<String>,
/// Optional name to use for an include guard
pub include_guard: Option<String>,
/// Add a `#pragma once` guard
pub pragma_once: bool,
/// Generates no includes at all. Overrides all other include options
///
/// This option is useful when using cbindgen with tools such as python's cffi which
@ -768,6 +770,7 @@ impl Default for Config {
sys_includes: Vec::new(),
trailer: None,
include_guard: None,
pragma_once: false,
autogen_warning: None,
include_version: false,
no_includes: false,

View File

@ -15,6 +15,7 @@ language = "C++"
# header = "/* Text to put at the beginning of the generated file. Probably a license. */"
# trailer = "/* Text to put at the end of the generated file */"
# include_guard = "my_bindings_h"
# pragma_once = true
# autogen_warning = "/* Warning, this file is autogenerated by cbindgen. Don't modify this manually. */"
include_version = false
# namespace = "my_namespace"

View File

@ -0,0 +1 @@
#include "pragma_once.h"

View File

@ -0,0 +1 @@
#include "pragma_once.compat.h"

View File

@ -0,0 +1,11 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void root(void);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

View File

@ -0,0 +1,3 @@
#pragma once
void root(void);

View File

@ -0,0 +1 @@
#include "pragma_once.h"

View File

@ -0,0 +1 @@
#include "pragma_once.compat.h"

View File

@ -0,0 +1,11 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void root(void);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

View File

@ -0,0 +1 @@
#include "pragma_once.hpp"

View File

@ -0,0 +1,3 @@
#pragma once
void root(void);

View File

@ -0,0 +1,7 @@
#pragma once
extern "C" {
void root();
} // extern "C"

View File

@ -0,0 +1 @@
#include "pragma_once.h"

View File

@ -0,0 +1 @@
#include "pragma_once.compat.h"

View File

@ -0,0 +1,11 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
void root(void);
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus

View File

@ -0,0 +1,3 @@
#pragma once
void root(void);

View File

@ -0,0 +1,3 @@
#[no_mangle]
pub extern "C" fn root() {
}

View File

@ -0,0 +1,2 @@
pragma_once = true
no_includes = true

View File

@ -1,5 +1,5 @@
#ifndef testing_helpers_h
#define testing_helpers_h
#define testing_helpers_h
// This is a helper file to easily add static_asserts to C / C++ tests.

View File

@ -1,6 +1,7 @@
extern crate cbindgen;
use cbindgen::*;
use std::io::Write;
use std::path::Path;
use std::process::Command;
use std::{env, fs, str};
@ -154,9 +155,44 @@ fn run_compile_test(
}
};
output.push(format!("{}.{}", name, ext));
let header_suffix = ".header";
let header_position = name.rfind(&header_suffix);
let is_header = header_position.is_some();
let source_file = format!(
"{}.{}",
if is_header {
&name[0..header_position.unwrap()]
} else {
name
},
&ext
);
output.push(&source_file);
if is_header {
let header_ext = match output.extension().unwrap().to_str().unwrap().as_ref() {
"cpp" => "hpp",
"c" => "h",
_ => "",
};
let mut ofile = fs::File::create(output.as_path()).expect("unable to create surce file");
output.set_extension(header_ext);
let source_file_content = format!(
"#include \"{}\"\n",
output.file_name().unwrap().to_str().unwrap()
);
ofile
.write(source_file_content.as_bytes())
.expect("unable to write source file content");
}
run_cbindgen(cbindgen_path, path, &output, language, cpp_compat, style);
if is_header {
output.set_file_name(source_file);
}
compile(&output, &tests_path, tmp_dir, language, style);
if language == Language::C && cpp_compat {