| David Tolnay | 30d214c | 2020-03-15 23:54:34 -0700 | [diff] [blame] | 1 | #![allow( |
| David Tolnay | 4bc9815 | 2020-04-09 23:24:01 -0700 | [diff] [blame] | 2 | clippy::cognitive_complexity, |
| David Tolnay | 30d214c | 2020-03-15 23:54:34 -0700 | [diff] [blame] | 3 | clippy::inherent_to_string, |
| 4 | clippy::large_enum_variant, |
| 5 | clippy::new_without_default, |
| David Tolnay | 97b69c6 | 2020-09-01 16:36:42 -0700 | [diff] [blame] | 6 | clippy::or_fun_call, |
| David Tolnay | 30d214c | 2020-03-15 23:54:34 -0700 | [diff] [blame] | 7 | clippy::toplevel_ref_arg |
| 8 | )] |
| 9 | |
| David Tolnay | 39fa366 | 2020-07-30 20:23:18 -0700 | [diff] [blame] | 10 | mod app; |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 11 | mod gen; |
| David Tolnay | e2e47a3 | 2020-09-24 10:23:27 -0400 | [diff] [blame] | 12 | mod output; |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 13 | mod syntax; |
| 14 | |
| David Tolnay | e2e47a3 | 2020-09-24 10:23:27 -0400 | [diff] [blame] | 15 | use crate::gen::error::{report, Result}; |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 16 | use crate::gen::fs; |
| 17 | use crate::gen::include::{self, Include}; |
| David Tolnay | e2e47a3 | 2020-09-24 10:23:27 -0400 | [diff] [blame] | 18 | use crate::output::Output; |
| David Tolnay | 7eb9c6b | 2020-01-27 21:52:09 -0800 | [diff] [blame] | 19 | use std::io::{self, Write}; |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 20 | use std::path::PathBuf; |
| David Tolnay | 9ef74ce | 2020-09-13 23:24:02 -0400 | [diff] [blame] | 21 | use std::process; |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 22 | |
| David Tolnay | 39fa366 | 2020-07-30 20:23:18 -0700 | [diff] [blame] | 23 | #[derive(Debug)] |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 24 | struct Opt { |
| RS | 0a2d117 | 2020-01-27 21:47:37 -0800 | [diff] [blame] | 25 | input: Option<PathBuf>, |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 26 | header: bool, |
| Adrian Taylor | 21f0ff0 | 2020-07-21 16:21:48 -0700 | [diff] [blame] | 27 | cxx_impl_annotations: Option<String>, |
| David Tolnay | 700cd0c | 2020-10-28 12:40:27 -0700 | [diff] [blame] | 28 | include: Vec<Include>, |
| David Tolnay | f027756 | 2020-09-24 10:46:14 -0400 | [diff] [blame] | 29 | outputs: Vec<Output>, |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 30 | } |
| 31 | |
| David Tolnay | 7eb9c6b | 2020-01-27 21:52:09 -0800 | [diff] [blame] | 32 | fn main() { |
| David Tolnay | 9ef74ce | 2020-09-13 23:24:02 -0400 | [diff] [blame] | 33 | if let Err(err) = try_main() { |
| 34 | let _ = writeln!(io::stderr(), "cxxbridge: {}", report(err)); |
| 35 | process::exit(1); |
| 36 | } |
| 37 | } |
| 38 | |
| David Tolnay | f027756 | 2020-09-24 10:46:14 -0400 | [diff] [blame] | 39 | enum Kind { |
| 40 | GeneratedHeader, |
| 41 | GeneratedImplementation, |
| 42 | Header, |
| 43 | } |
| 44 | |
| David Tolnay | 9ef74ce | 2020-09-13 23:24:02 -0400 | [diff] [blame] | 45 | fn try_main() -> Result<()> { |
| David Tolnay | 39fa366 | 2020-07-30 20:23:18 -0700 | [diff] [blame] | 46 | let opt = app::from_args(); |
| RS | 0a2d117 | 2020-01-27 21:47:37 -0800 | [diff] [blame] | 47 | |
| David Tolnay | f027756 | 2020-09-24 10:46:14 -0400 | [diff] [blame] | 48 | let mut outputs = Vec::new(); |
| 49 | let mut gen_header = false; |
| 50 | let mut gen_implementation = false; |
| 51 | for output in opt.outputs { |
| 52 | let kind = if opt.input.is_none() { |
| 53 | Kind::Header |
| 54 | } else if opt.header || output.ends_with(".h") { |
| 55 | gen_header = true; |
| 56 | Kind::GeneratedHeader |
| 57 | } else { |
| 58 | gen_implementation = true; |
| 59 | Kind::GeneratedImplementation |
| 60 | }; |
| 61 | outputs.push((output, kind)); |
| 62 | } |
| David Tolnay | e2e47a3 | 2020-09-24 10:23:27 -0400 | [diff] [blame] | 63 | |
| David Tolnay | 33d3029 | 2020-03-18 18:02:02 -0700 | [diff] [blame] | 64 | let gen = gen::Opt { |
| 65 | include: opt.include, |
| Adrian Taylor | 21f0ff0 | 2020-07-21 16:21:48 -0700 | [diff] [blame] | 66 | cxx_impl_annotations: opt.cxx_impl_annotations, |
| David Tolnay | e2e47a3 | 2020-09-24 10:23:27 -0400 | [diff] [blame] | 67 | gen_header, |
| David Tolnay | f027756 | 2020-09-24 10:46:14 -0400 | [diff] [blame] | 68 | gen_implementation, |
| David Tolnay | 75c2385 | 2020-10-27 21:07:53 -0700 | [diff] [blame] | 69 | ..Default::default() |
| David Tolnay | 33d3029 | 2020-03-18 18:02:02 -0700 | [diff] [blame] | 70 | }; |
| 71 | |
| David Tolnay | f027756 | 2020-09-24 10:46:14 -0400 | [diff] [blame] | 72 | let generated_code = if let Some(input) = opt.input { |
| 73 | gen::generate_from_path(&input, &gen) |
| 74 | } else { |
| 75 | Default::default() |
| David Tolnay | 9ef74ce | 2020-09-13 23:24:02 -0400 | [diff] [blame] | 76 | }; |
| 77 | |
| David Tolnay | f027756 | 2020-09-24 10:46:14 -0400 | [diff] [blame] | 78 | for (output, kind) in outputs { |
| 79 | let content = match kind { |
| 80 | Kind::GeneratedHeader => &generated_code.header, |
| 81 | Kind::GeneratedImplementation => &generated_code.implementation, |
| 82 | Kind::Header => include::HEADER.as_bytes(), |
| 83 | }; |
| 84 | match output { |
| 85 | Output::Stdout => drop(io::stdout().write_all(content)), |
| 86 | Output::File(path) => fs::write(path, content)?, |
| 87 | } |
| RS | 0a2d117 | 2020-01-27 21:47:37 -0800 | [diff] [blame] | 88 | } |
| David Tolnay | 9ef74ce | 2020-09-13 23:24:02 -0400 | [diff] [blame] | 89 | |
| 90 | Ok(()) |
| David Tolnay | 7db7369 | 2019-10-20 14:51:12 -0400 | [diff] [blame] | 91 | } |