1
+ use cfg_if:: cfg_if;
1
2
use libloading:: Library ;
2
3
3
4
use marker_api:: context:: AstContext ;
4
5
use marker_api:: lint:: Lint ;
5
6
use marker_api:: LintPass ;
6
7
8
+ use std:: ffi:: { OsStr , OsString } ;
9
+
10
+ /// Splits [`OsStr`] by an ascii character
11
+ fn split_os_str ( s : & OsStr , c : u8 ) -> Vec < OsString > {
12
+ cfg_if ! {
13
+ if #[ cfg( unix) ] {
14
+ unix_split_os_str( s, c)
15
+ } else if #[ cfg( windows) ] {
16
+ windows_split_os_str( s, c)
17
+ } else {
18
+ unimplemented!( "`split_os_str` currently works only on unix and windows" )
19
+ }
20
+ }
21
+ }
22
+
23
+ #[ cfg( unix) ]
24
+ #[ doc( hidden) ]
25
+ fn unix_split_os_str ( s : & OsStr , c : u8 ) -> Vec < OsString > {
26
+ use std:: os:: unix:: ffi:: OsStrExt ;
27
+
28
+ s. as_bytes ( )
29
+ . split ( |byte| * byte == c)
30
+ . map ( |bytes| OsStr :: from_bytes ( bytes) . into ( ) )
31
+ . collect ( )
32
+ }
33
+
34
+ #[ cfg( windows) ]
35
+ #[ doc( hidden) ]
36
+ fn windows_split_os_str ( s : & OsStr , c : u8 ) -> Vec < OsString > {
37
+ use std:: os:: windows:: ffi:: * ;
38
+
39
+ let bytes: Vec < u16 > = s. encode_wide ( ) . collect ( ) ;
40
+
41
+ bytes
42
+ . split ( |v| * v == u16:: from ( c) )
43
+ . map ( |bytes| OsString :: from_wide ( bytes) )
44
+ . collect ( )
45
+ }
46
+
7
47
/// This struct loads external lint crates into memory and provides a safe API
8
48
/// to call the respective methods on all of them.
9
49
#[ derive( Default ) ]
@@ -15,17 +55,16 @@ impl<'ast> LintCrateRegistry<'ast> {
15
55
/// # Errors
16
56
/// This can return errors if the library couldn't be found or if the
17
57
/// required symbols weren't provided.
18
- fn load_external_lib ( & mut self , lib_path : & str ) -> Result < ( ) , LoadingError > {
58
+ fn load_external_lib ( lib_path : & OsStr ) -> Result < LoadedLintCrate < ' ast > , LoadingError > {
19
59
let lib: & ' static Library = Box :: leak ( Box :: new (
20
60
unsafe { Library :: new ( lib_path) } . map_err ( |_| LoadingError :: FileNotFound ) ?,
21
61
) ) ;
22
62
23
63
let pass = LoadedLintCrate :: try_from_lib ( lib) ?;
24
64
25
- self . passes . push ( pass) ;
26
65
// FIXME: Create issue for lifetimes and fix droping and pointer decl stuff
27
66
28
- Ok ( ( ) )
67
+ Ok ( pass )
29
68
}
30
69
31
70
/// # Panics
@@ -34,12 +73,21 @@ impl<'ast> LintCrateRegistry<'ast> {
34
73
pub fn new_from_env ( ) -> Self {
35
74
let mut new_self = Self :: default ( ) ;
36
75
37
- if let Ok ( lint_crates_lst) = std:: env:: var ( "MARKER_LINT_CRATES" ) {
38
- for lint_crate in lint_crates_lst. split ( ';' ) {
39
- if let Err ( err) = new_self. load_external_lib ( lint_crate) {
40
- panic ! ( "Unable to load `{lint_crate}`, reason: {err:?}" ) ;
41
- }
76
+ let Some ( ( _, lint_crates_lst) ) = std:: env:: vars_os ( ) . find ( |( name, _val) | name == "MARKER_LINT_CRATES" ) else {
77
+ panic ! ( "Adapter tried to find `MARKER_LINT_CRATES` env variable, but it was not present" ) ;
78
+ } ;
79
+
80
+ for lib in split_os_str ( & lint_crates_lst, b';' ) {
81
+ if lib. is_empty ( ) {
82
+ continue ;
42
83
}
84
+
85
+ let lib = match Self :: load_external_lib ( & lib) {
86
+ Ok ( v) => v,
87
+ Err ( err) => panic ! ( "Unable to load `{}`, reason: {err:?}" , lib. to_string_lossy( ) ) ,
88
+ } ;
89
+
90
+ new_self. passes . push ( lib) ;
43
91
}
44
92
45
93
new_self
@@ -113,7 +161,7 @@ macro_rules! gen_LoadedLintCrate {
113
161
}
114
162
115
163
let set_ast_context = unsafe {
116
- lib. get:: <for <' ast> unsafe extern "C" fn ( & ' ast AstContext <' ast>) -> ( ) >( b"set_ast_context\0 " )
164
+ lib. get:: <for <' ast> unsafe extern "C" fn ( & ' ast AstContext <' ast>) >( b"set_ast_context\0 " )
117
165
. map_err( |_| LoadingError :: MissingLintDeclaration ) ?
118
166
} ;
119
167
@@ -144,7 +192,7 @@ macro_rules! gen_LoadedLintCrate {
144
192
145
193
// safe wrapper to external functions
146
194
$(
147
- fn $fn_name<' ast>( & $ ( $mut_ ) * self $( , $arg_name: $arg_ty) * ) -> $ret_ty {
195
+ fn $fn_name<' ast>( & self $( , $arg_name: $arg_ty) * ) -> $ret_ty {
148
196
unsafe {
149
197
( self . $fn_name) ( $( $arg_name, ) * )
150
198
}
0 commit comments