blob: 7bec492b07bc7764eab4d5e1341aea2456824605 [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 Tolnay9c68b1a2020-03-06 11:12:55 -080033 pub cstdint: bool,
David Tolnayebef4a22020-03-17 15:33:47 -070034 pub cstring: bool,
David Tolnayb7a7cb62020-03-17 21:18:40 -070035 pub exception: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080036 pub memory: bool,
37 pub string: bool,
38 pub type_traits: bool,
David Tolnay4791f1c2020-03-17 21:53:16 -070039 pub utility: bool,
David Tolnay9c68b1a2020-03-06 11:12:55 -080040}
41
42impl Includes {
43 pub fn new() -> Self {
44 Includes::default()
45 }
46
47 pub fn insert(&mut self, include: String) {
48 self.custom.push(include);
49 }
50}
51
David Tolnay33d30292020-03-18 18:02:02 -070052impl Extend<String> for Includes {
53 fn extend<I: IntoIterator<Item = String>>(&mut self, iter: I) {
54 self.custom.extend(iter);
55 }
56}
57
David Tolnay9c68b1a2020-03-06 11:12:55 -080058impl Display for Includes {
59 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
60 for include in &self.custom {
61 writeln!(f, "#include \"{}\"", include.escape_default())?;
62 }
David Tolnayb7a7cb62020-03-17 21:18:40 -070063 if self.array {
64 writeln!(f, "#include <array>")?;
65 }
David Tolnay9c68b1a2020-03-06 11:12:55 -080066 if self.cstdint {
67 writeln!(f, "#include <cstdint>")?;
68 }
David Tolnayebef4a22020-03-17 15:33:47 -070069 if self.cstring {
70 writeln!(f, "#include <cstring>")?;
71 }
David Tolnayb7a7cb62020-03-17 21:18:40 -070072 if self.exception {
73 writeln!(f, "#include <exception>")?;
74 }
David Tolnay9c68b1a2020-03-06 11:12:55 -080075 if self.memory {
76 writeln!(f, "#include <memory>")?;
77 }
78 if self.string {
79 writeln!(f, "#include <string>")?;
80 }
81 if self.type_traits {
82 writeln!(f, "#include <type_traits>")?;
83 }
David Tolnay4791f1c2020-03-17 21:53:16 -070084 if self.utility {
85 writeln!(f, "#include <utility>")?;
86 }
David Tolnay3577d452020-03-17 21:48:13 -070087 if *self != Self::default() {
88 writeln!(f)?;
89 }
David Tolnay9c68b1a2020-03-06 11:12:55 -080090 Ok(())
91 }
92}