blob: 129a8e6251899de2fee1d17bd5b766f228edb3e7 [file] [log] [blame]
David Tolnay9c68b1a2020-03-06 11:12:55 -08001use std::fmt::{self, Display};
2
David Tolnay736cbca2020-03-11 16:49:18 -07003pub static HEADER: &str = include_str!("include/cxx.h");
David Tolnay7db73692019-10-20 14:51:12 -04004
5pub fn get(guard: &str) -> &'static str {
David Tolnay2a1eaac2020-02-24 02:01:47 -08006 let ifndef = format!("#ifndef {}", guard);
7 let endif = format!("#endif // {}", guard);
David Tolnay26ad0bd2020-03-17 21:34:05 -07008 let begin = find_line(&ifndef);
9 let end = find_line(&endif);
David Tolnay7db73692019-10-20 14:51:12 -040010 if let (Some(begin), Some(end)) = (begin, end) {
11 &HEADER[begin..end + endif.len()]
12 } else {
David Tolnay736cbca2020-03-11 16:49:18 -070013 panic!("not found in cxx.h header: {}", guard)
David Tolnay7db73692019-10-20 14:51:12 -040014 }
15}
David Tolnay9c68b1a2020-03-06 11:12:55 -080016
David Tolnay26ad0bd2020-03-17 21:34:05 -070017fn find_line(line: &str) -> Option<usize> {
18 let mut offset = 0;
19 loop {
20 offset += HEADER[offset..].find(line)?;
21 let rest = &HEADER[offset + line.len()..];
22 if rest.starts_with('\n') || rest.starts_with('\r') {
23 return Some(offset);
24 }
25 offset += line.len();
26 }
27}
28
David Tolnay3577d452020-03-17 21:48:13 -070029#[derive(Default, PartialEq)]
David Tolnay9c68b1a2020-03-06 11:12:55 -080030pub struct Includes {
31 custom: Vec<String>,
David Tolnayb7a7cb62020-03-17 21:18:40 -070032 pub array: bool,
David Tolnay30430f12020-03-19 20:49:00 -070033 pub cstddef: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080034 pub cstdint: bool,
David Tolnayebef4a22020-03-17 15:33:47 -070035 pub cstring: bool,
David Tolnayb7a7cb62020-03-17 21:18:40 -070036 pub exception: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080037 pub memory: bool,
38 pub string: bool,
39 pub type_traits: bool,
David Tolnay4791f1c2020-03-17 21:53:16 -070040 pub utility: bool,
David Tolnay8b7f8992020-04-25 13:06:08 -070041 pub vector: bool,
David Tolnay59b5ba12020-04-10 11:32:19 -070042 pub base_tsd: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080043}
44
45impl Includes {
46 pub fn new() -> Self {
47 Includes::default()
48 }
49
50 pub fn insert(&mut self, include: String) {
51 self.custom.push(include);
52 }
53}
54
David Tolnay33d30292020-03-18 18:02:02 -070055impl Extend<String> for Includes {
56 fn extend<I: IntoIterator<Item = String>>(&mut self, iter: I) {
57 self.custom.extend(iter);
58 }
59}
60
David Tolnay9c68b1a2020-03-06 11:12:55 -080061impl Display for Includes {
62 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
63 for include in &self.custom {
64 writeln!(f, "#include \"{}\"", include.escape_default())?;
65 }
David Tolnayb7a7cb62020-03-17 21:18:40 -070066 if self.array {
67 writeln!(f, "#include <array>")?;
68 }
David Tolnay30430f12020-03-19 20:49:00 -070069 if self.cstddef {
70 writeln!(f, "#include <cstddef>")?;
71 }
David Tolnay9c68b1a2020-03-06 11:12:55 -080072 if self.cstdint {
73 writeln!(f, "#include <cstdint>")?;
74 }
David Tolnayebef4a22020-03-17 15:33:47 -070075 if self.cstring {
76 writeln!(f, "#include <cstring>")?;
77 }
David Tolnayb7a7cb62020-03-17 21:18:40 -070078 if self.exception {
79 writeln!(f, "#include <exception>")?;
80 }
David Tolnay9c68b1a2020-03-06 11:12:55 -080081 if self.memory {
82 writeln!(f, "#include <memory>")?;
83 }
84 if self.string {
85 writeln!(f, "#include <string>")?;
86 }
87 if self.type_traits {
88 writeln!(f, "#include <type_traits>")?;
89 }
David Tolnay4791f1c2020-03-17 21:53:16 -070090 if self.utility {
91 writeln!(f, "#include <utility>")?;
92 }
David Tolnay122905e2020-04-25 13:06:42 -070093 if self.vector {
94 writeln!(f, "#include <vector>")?;
95 }
David Tolnay59b5ba12020-04-10 11:32:19 -070096 if self.base_tsd {
97 writeln!(f, "#if defined(_WIN32)")?;
98 writeln!(f, "#include <BaseTsd.h>")?;
99 writeln!(f, "#endif")?;
100 }
David Tolnay3577d452020-03-17 21:48:13 -0700101 if *self != Self::default() {
102 writeln!(f)?;
103 }
David Tolnay9c68b1a2020-03-06 11:12:55 -0800104 Ok(())
105 }
106}