| David Tolnay | e54f338 | 2020-05-12 19:58:36 -0700 | [diff] [blame] | 1 | use crate::gen::out::OutFile; |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame^] | 2 | use crate::syntax::IncludeKind; |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 3 | use std::fmt::{self, Display}; |
| 4 | |
| David Tolnay | 0e01d64 | 2020-10-16 12:54:44 -0700 | [diff] [blame] | 5 | /// The complete contents of the "rust/cxx.h" header. |
| David Tolnay | 736cbca | 2020-03-11 16:49:18 -0700 | [diff] [blame] | 6 | pub static HEADER: &str = include_str!("include/cxx.h"); |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 7 | |
| David Tolnay | e54f338 | 2020-05-12 19:58:36 -0700 | [diff] [blame] | 8 | pub(super) fn write(out: &mut OutFile, needed: bool, guard: &str) { |
| David Tolnay | 2a1eaac | 2020-02-24 02:01:47 -0800 | [diff] [blame] | 9 | let ifndef = format!("#ifndef {}", guard); |
| David Tolnay | e54f338 | 2020-05-12 19:58:36 -0700 | [diff] [blame] | 10 | let define = format!("#define {}", guard); |
| David Tolnay | 2a1eaac | 2020-02-24 02:01:47 -0800 | [diff] [blame] | 11 | let endif = format!("#endif // {}", guard); |
| David Tolnay | e54f338 | 2020-05-12 19:58:36 -0700 | [diff] [blame] | 12 | |
| 13 | let mut offset = 0; |
| 14 | loop { |
| 15 | let begin = find_line(offset, &ifndef); |
| 16 | let end = find_line(offset, &endif); |
| 17 | if let (Some(begin), Some(end)) = (begin, end) { |
| 18 | if !needed { |
| 19 | return; |
| 20 | } |
| 21 | out.next_section(); |
| 22 | if offset == 0 { |
| 23 | writeln!(out, "{}", ifndef); |
| 24 | writeln!(out, "{}", define); |
| 25 | } |
| 26 | for line in HEADER[begin + ifndef.len()..end].trim().lines() { |
| 27 | if line != define && !line.trim_start().starts_with("//") { |
| 28 | writeln!(out, "{}", line); |
| 29 | } |
| 30 | } |
| 31 | offset = end + endif.len(); |
| 32 | } else if offset == 0 { |
| 33 | panic!("not found in cxx.h header: {}", guard) |
| 34 | } else { |
| 35 | writeln!(out, "{}", endif); |
| 36 | return; |
| 37 | } |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 38 | } |
| 39 | } |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 40 | |
| David Tolnay | e54f338 | 2020-05-12 19:58:36 -0700 | [diff] [blame] | 41 | fn find_line(mut offset: usize, line: &str) -> Option<usize> { |
| David Tolnay | 26ad0bd | 2020-03-17 21:34:05 -0700 | [diff] [blame] | 42 | loop { |
| 43 | offset += HEADER[offset..].find(line)?; |
| 44 | let rest = &HEADER[offset + line.len()..]; |
| 45 | if rest.starts_with('\n') || rest.starts_with('\r') { |
| 46 | return Some(offset); |
| 47 | } |
| 48 | offset += line.len(); |
| 49 | } |
| 50 | } |
| 51 | |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame^] | 52 | #[derive(PartialEq)] |
| 53 | pub struct Include { |
| 54 | pub path: String, |
| 55 | pub kind: IncludeKind, |
| 56 | } |
| 57 | |
| David Tolnay | 3577d45 | 2020-03-17 21:48:13 -0700 | [diff] [blame] | 58 | #[derive(Default, PartialEq)] |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 59 | pub struct Includes { |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame^] | 60 | custom: Vec<Include>, |
| David Tolnay | b7a7cb6 | 2020-03-17 21:18:40 -0700 | [diff] [blame] | 61 | pub array: bool, |
| David Tolnay | 30430f1 | 2020-03-19 20:49:00 -0700 | [diff] [blame] | 62 | pub cstddef: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 63 | pub cstdint: bool, |
| David Tolnay | ebef4a2 | 2020-03-17 15:33:47 -0700 | [diff] [blame] | 64 | pub cstring: bool, |
| David Tolnay | b7a7cb6 | 2020-03-17 21:18:40 -0700 | [diff] [blame] | 65 | pub exception: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 66 | pub memory: bool, |
| David Tolnay | 0ecd05a | 2020-07-29 16:32:03 -0700 | [diff] [blame] | 67 | pub new: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 68 | pub string: bool, |
| 69 | pub type_traits: bool, |
| David Tolnay | 4791f1c | 2020-03-17 21:53:16 -0700 | [diff] [blame] | 70 | pub utility: bool, |
| David Tolnay | 8b7f899 | 2020-04-25 13:06:08 -0700 | [diff] [blame] | 71 | pub vector: bool, |
| David Tolnay | da38b7c | 2020-09-16 11:50:04 -0400 | [diff] [blame] | 72 | pub basetsd: bool, |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 73 | } |
| 74 | |
| 75 | impl Includes { |
| 76 | pub fn new() -> Self { |
| 77 | Includes::default() |
| 78 | } |
| 79 | |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame^] | 80 | pub fn insert(&mut self, include: Include) { |
| 81 | self.custom.push(include); |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 82 | } |
| 83 | } |
| 84 | |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame^] | 85 | impl<'a> Extend<&'a String> for Includes { |
| 86 | fn extend<I: IntoIterator<Item = &'a String>>(&mut self, iter: I) { |
| 87 | self.custom.extend(iter.into_iter().map(|path| Include { |
| 88 | path: path.clone(), |
| 89 | kind: IncludeKind::Quoted, |
| 90 | })); |
| David Tolnay | 33d3029 | 2020-03-18 18:02:02 -0700 | [diff] [blame] | 91 | } |
| 92 | } |
| 93 | |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 94 | impl Display for Includes { |
| 95 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
| 96 | for include in &self.custom { |
| David Tolnay | 4aae7c0 | 2020-10-28 12:35:42 -0700 | [diff] [blame^] | 97 | match include.kind { |
| 98 | IncludeKind::Quoted => { |
| 99 | writeln!(f, "#include \"{}\"", include.path.escape_default())?; |
| 100 | } |
| 101 | IncludeKind::Bracketed => { |
| 102 | writeln!(f, "#include <{}>", include.path)?; |
| 103 | } |
| David Tolnay | bbcf215 | 2020-05-11 19:04:25 -0700 | [diff] [blame] | 104 | } |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 105 | } |
| David Tolnay | b7a7cb6 | 2020-03-17 21:18:40 -0700 | [diff] [blame] | 106 | if self.array { |
| 107 | writeln!(f, "#include <array>")?; |
| 108 | } |
| David Tolnay | 30430f1 | 2020-03-19 20:49:00 -0700 | [diff] [blame] | 109 | if self.cstddef { |
| 110 | writeln!(f, "#include <cstddef>")?; |
| 111 | } |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 112 | if self.cstdint { |
| 113 | writeln!(f, "#include <cstdint>")?; |
| 114 | } |
| David Tolnay | ebef4a2 | 2020-03-17 15:33:47 -0700 | [diff] [blame] | 115 | if self.cstring { |
| 116 | writeln!(f, "#include <cstring>")?; |
| 117 | } |
| David Tolnay | b7a7cb6 | 2020-03-17 21:18:40 -0700 | [diff] [blame] | 118 | if self.exception { |
| 119 | writeln!(f, "#include <exception>")?; |
| 120 | } |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 121 | if self.memory { |
| 122 | writeln!(f, "#include <memory>")?; |
| 123 | } |
| David Tolnay | 0ecd05a | 2020-07-29 16:32:03 -0700 | [diff] [blame] | 124 | if self.new { |
| 125 | writeln!(f, "#include <new>")?; |
| 126 | } |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 127 | if self.string { |
| 128 | writeln!(f, "#include <string>")?; |
| 129 | } |
| 130 | if self.type_traits { |
| 131 | writeln!(f, "#include <type_traits>")?; |
| 132 | } |
| David Tolnay | 4791f1c | 2020-03-17 21:53:16 -0700 | [diff] [blame] | 133 | if self.utility { |
| 134 | writeln!(f, "#include <utility>")?; |
| 135 | } |
| David Tolnay | 122905e | 2020-04-25 13:06:42 -0700 | [diff] [blame] | 136 | if self.vector { |
| 137 | writeln!(f, "#include <vector>")?; |
| 138 | } |
| David Tolnay | da38b7c | 2020-09-16 11:50:04 -0400 | [diff] [blame] | 139 | if self.basetsd { |
| David Tolnay | 59b5ba1 | 2020-04-10 11:32:19 -0700 | [diff] [blame] | 140 | writeln!(f, "#if defined(_WIN32)")?; |
| David Tolnay | da38b7c | 2020-09-16 11:50:04 -0400 | [diff] [blame] | 141 | writeln!(f, "#include <basetsd.h>")?; |
| David Tolnay | 59b5ba1 | 2020-04-10 11:32:19 -0700 | [diff] [blame] | 142 | writeln!(f, "#endif")?; |
| 143 | } |
| David Tolnay | 9c68b1a | 2020-03-06 11:12:55 -0800 | [diff] [blame] | 144 | Ok(()) |
| 145 | } |
| 146 | } |