@@ -113,7 +113,11 @@ impl Filter {
113113 let mut should_filter_this_source = false ;
114114 for variant_path in path_variants {
115115 for filter in source_filters {
116- if variant_path. starts_with ( & filter. path ) {
116+ // Normalize both paths for comparison to handle platform differences
117+ let normalized_variant = self . normalize_path_for_comparison ( & variant_path) ;
118+ let normalized_filter = self . normalize_path_for_comparison ( & filter. path ) ;
119+
120+ if normalized_variant. starts_with ( & normalized_filter) {
117121 match filter. ignore {
118122 config:: Ignore :: Always => {
119123 should_filter_this_source = true ;
@@ -173,6 +177,38 @@ impl Filter {
173177 variants
174178 }
175179
180+ /// Normalizes a path for cross-platform comparison by converting to absolute form
181+ /// and using consistent separators. Handles non-existing files by normalizing
182+ /// the parent directory and appending the filename.
183+ fn normalize_path_for_comparison ( & self , path : & Path ) -> PathBuf {
184+ // First try to make the path absolute
185+ let absolute_path = match std:: path:: absolute ( path) {
186+ Ok ( abs) => abs,
187+ Err ( _) => path. to_path_buf ( ) ,
188+ } ;
189+
190+ // Try to canonicalize if possible (for existing paths)
191+ match absolute_path. canonicalize ( ) {
192+ Ok ( canonical) => canonical,
193+ Err ( _) => {
194+ // If canonicalize fails (e.g., path doesn't exist), try to canonicalize
195+ // the parent directory and append the filename
196+ if let Some ( parent) = absolute_path. parent ( ) {
197+ if let Some ( filename) = absolute_path. file_name ( ) {
198+ match parent. canonicalize ( ) {
199+ Ok ( canonical_parent) => canonical_parent. join ( filename) ,
200+ Err ( _) => absolute_path,
201+ }
202+ } else {
203+ absolute_path
204+ }
205+ } else {
206+ absolute_path
207+ }
208+ }
209+ }
210+ }
211+
176212 /// Validates the compiler configuration.
177213 fn validate_compiler_configuration (
178214 compilers : & [ config:: Compiler ] ,
@@ -707,4 +743,67 @@ mod tests {
707743 assert ! ( result_with_access_nonexisting. is_some( ) ) ;
708744 assert ! ( result_without_access_nonexisting. is_some( ) ) ;
709745 }
746+
747+ #[ test]
748+ fn test_cross_platform_path_normalization ( ) {
749+ use std:: fs;
750+ use tempfile:: tempdir;
751+
752+ let temp_dir = tempdir ( ) . unwrap ( ) ;
753+ let temp_path = temp_dir. path ( ) ;
754+
755+ // Create an existing file
756+ let existing_file = temp_path. join ( "test.c" ) ;
757+ fs:: write ( & existing_file, "test content" ) . unwrap ( ) ;
758+
759+ let compilers = vec ! [ ] ;
760+ let sources = SourceFilter {
761+ only_existing_files : true ,
762+ paths : vec ! [ DirectoryFilter {
763+ path: temp_path. to_path_buf( ) ,
764+ ignore: Ignore :: Always ,
765+ } ] ,
766+ } ;
767+
768+ let filter =
769+ Filter :: try_from ( ( compilers. as_slice ( ) , & sources) ) . expect ( "Failed to create filter" ) ;
770+
771+ // Test with various path formats that might occur cross-platform
772+ let test_cases = vec ! [
773+ // Relative path
774+ "test.c" , // Path with current directory reference
775+ "./test.c" ,
776+ ] ;
777+
778+ for source_file in test_cases {
779+ let cmd = CompilerCommand :: from_strings (
780+ temp_path. to_str ( ) . unwrap ( ) ,
781+ "/usr/bin/gcc" ,
782+ vec ! [ ( ArgumentKind :: Source , vec![ source_file] ) ] ,
783+ ) ;
784+
785+ let result = filter. should_filter_sources ( & cmd, & filter. source_filters ) ;
786+ assert ! (
787+ result. is_some( ) ,
788+ "Failed to filter source file: {} in temp dir: {:?}" ,
789+ source_file,
790+ temp_path
791+ ) ;
792+ }
793+
794+ // Test with non-existing file to ensure it's also filtered
795+ let cmd_nonexisting = CompilerCommand :: from_strings (
796+ temp_path. to_str ( ) . unwrap ( ) ,
797+ "/usr/bin/gcc" ,
798+ vec ! [ ( ArgumentKind :: Source , vec![ "nonexisting.c" ] ) ] ,
799+ ) ;
800+
801+ let result_nonexisting =
802+ filter. should_filter_sources ( & cmd_nonexisting, & filter. source_filters ) ;
803+ assert ! (
804+ result_nonexisting. is_some( ) ,
805+ "Failed to filter non-existing source file in temp dir: {:?}" ,
806+ temp_path
807+ ) ;
808+ }
710809}
0 commit comments