]>
Commit | Line | Data |
---|---|---|
1a4d82fc JJ |
1 | // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
c34b1796 AL |
11 | #![allow(deprecated)] // old path, used for compatibility with dynamic lib |
12 | ||
1a4d82fc JJ |
13 | use clean; |
14 | ||
15 | use std::dynamic_lib as dl; | |
16 | use serialize::json; | |
17 | use std::mem; | |
18 | use std::string::String; | |
c34b1796 | 19 | use std::path::PathBuf; |
1a4d82fc JJ |
20 | |
21 | pub type PluginJson = Option<(String, json::Json)>; | |
22 | pub type PluginResult = (clean::Crate, PluginJson); | |
23 | pub type PluginCallback = fn (clean::Crate) -> PluginResult; | |
24 | ||
25 | /// Manages loading and running of plugins | |
26 | pub struct PluginManager { | |
27 | dylibs: Vec<dl::DynamicLibrary> , | |
28 | callbacks: Vec<PluginCallback> , | |
29 | /// The directory plugins will be loaded from | |
c34b1796 | 30 | pub prefix: PathBuf, |
1a4d82fc JJ |
31 | } |
32 | ||
33 | impl PluginManager { | |
34 | /// Create a new plugin manager | |
c34b1796 | 35 | pub fn new(prefix: PathBuf) -> PluginManager { |
1a4d82fc JJ |
36 | PluginManager { |
37 | dylibs: Vec::new(), | |
38 | callbacks: Vec::new(), | |
39 | prefix: prefix, | |
40 | } | |
41 | } | |
42 | ||
43 | /// Load a plugin with the given name. | |
44 | /// | |
45 | /// Turns `name` into the proper dynamic library filename for the given | |
46 | /// platform. On windows, it turns into name.dll, on OS X, name.dylib, and | |
47 | /// elsewhere, libname.so. | |
48 | pub fn load_plugin(&mut self, name: String) { | |
49 | let x = self.prefix.join(libname(name)); | |
50 | let lib_result = dl::DynamicLibrary::open(Some(&x)); | |
51 | let lib = lib_result.unwrap(); | |
52 | unsafe { | |
53 | let plugin = lib.symbol("rustdoc_plugin_entrypoint").unwrap(); | |
54 | self.callbacks.push(mem::transmute::<*mut u8,PluginCallback>(plugin)); | |
55 | } | |
56 | self.dylibs.push(lib); | |
57 | } | |
58 | ||
59 | /// Load a normal Rust function as a plugin. | |
60 | /// | |
61 | /// This is to run passes over the cleaned crate. Plugins run this way | |
62 | /// correspond to the A-aux tag on Github. | |
63 | pub fn add_plugin(&mut self, plugin: PluginCallback) { | |
64 | self.callbacks.push(plugin); | |
65 | } | |
66 | /// Run all the loaded plugins over the crate, returning their results | |
67 | pub fn run_plugins(&self, krate: clean::Crate) -> (clean::Crate, Vec<PluginJson> ) { | |
68 | let mut out_json = Vec::new(); | |
69 | let mut krate = krate; | |
85aaf69f | 70 | for &callback in &self.callbacks { |
1a4d82fc JJ |
71 | let (c, res) = callback(krate); |
72 | krate = c; | |
73 | out_json.push(res); | |
74 | } | |
75 | (krate, out_json) | |
76 | } | |
77 | } | |
78 | ||
79 | #[cfg(target_os = "windows")] | |
80 | fn libname(mut n: String) -> String { | |
81 | n.push_str(".dll"); | |
82 | n | |
83 | } | |
84 | ||
85 | #[cfg(target_os="macos")] | |
86 | fn libname(mut n: String) -> String { | |
87 | n.push_str(".dylib"); | |
88 | n | |
89 | } | |
90 | ||
91 | #[cfg(all(not(target_os="windows"), not(target_os="macos")))] | |
92 | fn libname(n: String) -> String { | |
93 | let mut i = String::from_str("lib"); | |
85aaf69f | 94 | i.push_str(&n); |
1a4d82fc JJ |
95 | i.push_str(".so"); |
96 | i | |
97 | } |