]>
Commit | Line | Data |
---|---|---|
476ff2be SL |
1 | #![allow(dead_code)] |
2 | ||
3 | use std::env; | |
4 | use std::ffi::OsStr; | |
5 | use std::fs::{self, File}; | |
6 | use std::io::prelude::*; | |
7 | use std::path::PathBuf; | |
8 | ||
ea8adc8c | 9 | use cc; |
476ff2be SL |
10 | use tempdir::TempDir; |
11 | ||
12 | pub struct Test { | |
13 | pub td: TempDir, | |
14 | pub gcc: PathBuf, | |
15 | pub msvc: bool, | |
16 | } | |
17 | ||
18 | pub struct Execution { | |
19 | args: Vec<String>, | |
20 | } | |
21 | ||
22 | impl Test { | |
23 | pub fn new() -> Test { | |
24 | let mut gcc = PathBuf::from(env::current_exe().unwrap()); | |
25 | gcc.pop(); | |
26 | if gcc.ends_with("deps") { | |
27 | gcc.pop(); | |
28 | } | |
29 | gcc.push(format!("gcc-shim{}", env::consts::EXE_SUFFIX)); | |
30 | Test { | |
31 | td: TempDir::new("gcc-test").unwrap(), | |
32 | gcc: gcc, | |
33 | msvc: false, | |
34 | } | |
35 | } | |
36 | ||
37 | pub fn gnu() -> Test { | |
38 | let t = Test::new(); | |
ea8adc8c | 39 | t.shim("cc").shim("c++").shim("ar"); |
8bb4bdeb | 40 | t |
476ff2be SL |
41 | } |
42 | ||
43 | pub fn msvc() -> Test { | |
44 | let mut t = Test::new(); | |
45 | t.shim("cl").shim("lib.exe"); | |
46 | t.msvc = true; | |
8bb4bdeb | 47 | t |
476ff2be SL |
48 | } |
49 | ||
50 | pub fn shim(&self, name: &str) -> &Test { | |
51 | let fname = format!("{}{}", name, env::consts::EXE_SUFFIX); | |
8bb4bdeb XL |
52 | fs::hard_link(&self.gcc, self.td.path().join(&fname)) |
53 | .or_else(|_| fs::copy(&self.gcc, self.td.path().join(&fname)).map(|_| ())) | |
54 | .unwrap(); | |
476ff2be SL |
55 | self |
56 | } | |
57 | ||
ea8adc8c XL |
58 | pub fn gcc(&self) -> cc::Build { |
59 | let mut cfg = cc::Build::new(); | |
8bb4bdeb | 60 | let mut path = env::split_paths(&env::var_os("PATH").unwrap()).collect::<Vec<_>>(); |
476ff2be SL |
61 | path.insert(0, self.td.path().to_owned()); |
62 | let target = if self.msvc { | |
63 | "x86_64-pc-windows-msvc" | |
64 | } else { | |
65 | "x86_64-unknown-linux-gnu" | |
66 | }; | |
67 | ||
8bb4bdeb XL |
68 | cfg.target(target) |
69 | .host(target) | |
70 | .opt_level(2) | |
71 | .debug(false) | |
72 | .out_dir(self.td.path()) | |
73 | .__set_env("PATH", env::join_paths(path).unwrap()) | |
74 | .__set_env("GCCTEST_OUT_DIR", self.td.path()); | |
476ff2be SL |
75 | if self.msvc { |
76 | cfg.compiler(self.td.path().join("cl")); | |
77 | cfg.archiver(self.td.path().join("lib.exe")); | |
78 | } | |
8bb4bdeb | 79 | cfg |
476ff2be SL |
80 | } |
81 | ||
82 | pub fn cmd(&self, i: u32) -> Execution { | |
83 | let mut s = String::new(); | |
8bb4bdeb XL |
84 | File::open(self.td.path().join(format!("out{}", i))) |
85 | .unwrap() | |
86 | .read_to_string(&mut s) | |
87 | .unwrap(); | |
88 | Execution { args: s.lines().map(|s| s.to_string()).collect() } | |
476ff2be SL |
89 | } |
90 | } | |
91 | ||
92 | impl Execution { | |
93 | pub fn must_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution { | |
94 | if !self.has(p.as_ref()) { | |
95 | panic!("didn't find {:?} in {:?}", p.as_ref(), self.args); | |
96 | } else { | |
97 | self | |
98 | } | |
99 | } | |
100 | ||
101 | pub fn must_not_have<P: AsRef<OsStr>>(&self, p: P) -> &Execution { | |
102 | if self.has(p.as_ref()) { | |
103 | panic!("found {:?}", p.as_ref()); | |
104 | } else { | |
105 | self | |
106 | } | |
107 | } | |
108 | ||
109 | pub fn has(&self, p: &OsStr) -> bool { | |
8bb4bdeb | 110 | self.args.iter().any(|arg| OsStr::new(arg) == p) |
476ff2be | 111 | } |
abe05a73 XL |
112 | |
113 | pub fn must_have_in_order(&self, before: &str, after: &str) -> &Execution { | |
114 | let before_position = self.args.iter().rposition(|x| OsStr::new(x) == OsStr::new(before)); | |
115 | let after_position = self.args.iter().rposition(|x| OsStr::new(x) == OsStr::new(after)); | |
116 | match (before_position, after_position) { | |
117 | (Some(b), Some(a)) if b < a => {}, | |
118 | (b, a) => { panic!("{:?} (last position: {:?}) did not appear before {:?} (last position: {:?})", before, b, after, a) }, | |
119 | }; | |
120 | self | |
121 | } | |
476ff2be | 122 | } |