1
+ use std:: ffi:: OsStr ;
2
+ use std:: path:: { Component , Path } ;
3
+
1
4
use crate :: prelude:: * ;
2
5
3
6
use syntax:: source_map:: FileName ;
@@ -8,22 +11,49 @@ use gimli::write::{
8
11
Address , AttributeValue , FileId , LineProgram , LineString , LineStringTable , UnitEntryId ,
9
12
} ;
10
13
14
+ // OPTIMIZATION: It is cheaper to do this in one pass than using `.parent()` and `.file_name()`.
15
+ fn split_path_dir_and_file ( path : & Path ) -> ( & Path , & OsStr ) {
16
+ let mut iter = path. components ( ) ;
17
+ let file_name = match iter. next_back ( ) {
18
+ Some ( Component :: Normal ( p) ) => p,
19
+ component => {
20
+ panic ! ( "Path component {:?} of path {} is an invalid filename" , component, path. display( ) ) ;
21
+ }
22
+ } ;
23
+ let parent = iter. as_path ( ) ;
24
+ ( parent, file_name)
25
+ }
26
+
27
+ // OPTIMIZATION: Avoid UTF-8 validation on UNIX.
28
+ fn osstr_as_utf8_bytes ( path : & OsStr ) -> & [ u8 ] {
29
+ #[ cfg( unix) ] {
30
+ use std:: os:: unix:: ffi:: OsStrExt ;
31
+ return path. as_bytes ( ) ;
32
+ }
33
+ #[ cfg( not( unix) ) ] {
34
+ return path. to_str ( ) . unwrap ( ) . as_bytes ( ) ;
35
+ }
36
+ }
37
+
11
38
fn line_program_add_file (
12
39
line_program : & mut LineProgram ,
13
40
line_strings : & mut LineStringTable ,
14
41
file : & FileName ,
15
42
) -> FileId {
16
43
match file {
17
44
FileName :: Real ( path) => {
18
- let dir_name = path. parent ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . as_bytes ( ) ;
45
+ let ( dir_path, file_name) = split_path_dir_and_file ( path) ;
46
+ let dir_name = osstr_as_utf8_bytes ( dir_path. as_os_str ( ) ) ;
47
+ let file_name = osstr_as_utf8_bytes ( file_name) ;
48
+
19
49
let dir_id = if !dir_name. is_empty ( ) {
20
50
let dir_name = LineString :: new ( dir_name, line_program. encoding ( ) , line_strings) ;
21
51
line_program. add_directory ( dir_name)
22
52
} else {
23
53
line_program. default_directory ( )
24
54
} ;
25
55
let file_name = LineString :: new (
26
- path . file_name ( ) . unwrap ( ) . to_str ( ) . unwrap ( ) . as_bytes ( ) ,
56
+ file_name,
27
57
line_program. encoding ( ) ,
28
58
line_strings,
29
59
) ;
0 commit comments