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:: { OsStrExt , OsStringExt } ;
38
+
39
+ let bytes: Vec < u16 > = s. encode_wide ( ) . collect ( ) ;
40
+
41
+ bytes. split ( |v| * v == u16:: from ( c) ) . map ( OsString :: from_wide) . collect ( )
42
+ }
43
+
7
44
/// This struct loads external lint crates into memory and provides a safe API
8
45
/// to call the respective methods on all of them.
9
46
#[ derive( Default ) ]
@@ -15,17 +52,16 @@ impl<'ast> LintCrateRegistry<'ast> {
15
52
/// # Errors
16
53
/// This can return errors if the library couldn't be found or if the
17
54
/// required symbols weren't provided.
18
- fn load_external_lib ( & mut self , lib_path : & str ) -> Result < ( ) , LoadingError > {
55
+ fn load_external_lib ( lib_path : & OsStr ) -> Result < LoadedLintCrate < ' ast > , LoadingError > {
19
56
let lib: & ' static Library = Box :: leak ( Box :: new (
20
57
unsafe { Library :: new ( lib_path) } . map_err ( |_| LoadingError :: FileNotFound ) ?,
21
58
) ) ;
22
59
23
60
let pass = LoadedLintCrate :: try_from_lib ( lib) ?;
24
61
25
- self . passes . push ( pass) ;
26
62
// FIXME: Create issue for lifetimes and fix droping and pointer decl stuff
27
63
28
- Ok ( ( ) )
64
+ Ok ( pass )
29
65
}
30
66
31
67
/// # Panics
@@ -34,12 +70,21 @@ impl<'ast> LintCrateRegistry<'ast> {
34
70
pub fn new_from_env ( ) -> Self {
35
71
let mut new_self = Self :: default ( ) ;
36
72
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
- }
73
+ let Some ( ( _, lint_crates_lst) ) = std:: env:: vars_os ( ) . find ( |( name, _val) | name == "MARKER_LINT_CRATES" ) else {
74
+ panic ! ( "Adapter tried to find `MARKER_LINT_CRATES` env variable, but it was not present" ) ;
75
+ } ;
76
+
77
+ for lib in split_os_str ( & lint_crates_lst, b';' ) {
78
+ if lib. is_empty ( ) {
79
+ continue ;
42
80
}
81
+
82
+ let lib = match Self :: load_external_lib ( & lib) {
83
+ Ok ( v) => v,
84
+ Err ( err) => panic ! ( "Unable to load `{}`, reason: {err:?}" , lib. to_string_lossy( ) ) ,
85
+ } ;
86
+
87
+ new_self. passes . push ( lib) ;
43
88
}
44
89
45
90
new_self
@@ -113,7 +158,7 @@ macro_rules! gen_LoadedLintCrate {
113
158
}
114
159
115
160
let set_ast_context = unsafe {
116
- lib. get:: <for <' ast> unsafe extern "C" fn ( & ' ast AstContext <' ast>) -> ( ) >( b"set_ast_context\0 " )
161
+ lib. get:: <for <' ast> unsafe extern "C" fn ( & ' ast AstContext <' ast>) >( b"set_ast_context\0 " )
117
162
. map_err( |_| LoadingError :: MissingLintDeclaration ) ?
118
163
} ;
119
164
@@ -144,7 +189,7 @@ macro_rules! gen_LoadedLintCrate {
144
189
145
190
// safe wrapper to external functions
146
191
$(
147
- fn $fn_name<' ast>( & $ ( $mut_ ) * self $( , $arg_name: $arg_ty) * ) -> $ret_ty {
192
+ fn $fn_name<' ast>( & self $( , $arg_name: $arg_ty) * ) -> $ret_ty {
148
193
unsafe {
149
194
( self . $fn_name) ( $( $arg_name, ) * )
150
195
}
0 commit comments