Skip to content

Commit 6529696

Browse files
committed
Return unnormalized output, fix tests
1 parent 81e67e8 commit 6529696

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

src/config.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1435,7 +1435,7 @@ fn config_basedirs_overrides() {
14351435
};
14361436

14371437
let config = Config::from_env_and_file_configs(env_conf, file_conf).unwrap();
1438-
assert_eq!(config.basedirs, vec![b"C:\\env\\basedir".to_vec()]);
1438+
assert_eq!(config.basedirs, vec![b"c:/env/basedir".to_vec()]);
14391439

14401440
// Test that file config is used when env is empty
14411441
let env_conf = EnvConfig {
@@ -1451,7 +1451,7 @@ fn config_basedirs_overrides() {
14511451
};
14521452

14531453
let config = Config::from_env_and_file_configs(env_conf, file_conf).unwrap();
1454-
assert_eq!(config.basedirs, vec![b"C:\\file\\basedir".to_vec()]);
1454+
assert_eq!(config.basedirs, vec![b"c:/file/basedir".to_vec()]);
14551455

14561456
// Test that both empty results in empty
14571457
let env_conf = EnvConfig {

src/util.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1041,23 +1041,26 @@ pub fn strip_basedirs(preprocessor_output: &[u8], basedirs: &[Vec<u8>]) -> Vec<u
10411041
// Find all potential matches for each basedir using fast substring search
10421042
// Store as (position, length, basedir_idx) sorted by position
10431043
let mut matches: Vec<(usize, usize, usize)> = Vec::new();
1044+
// We must return the original preprocessor output on all platforms,
1045+
// so we only normalize a copy for searching.
1046+
let normalized_output = preprocessor_output;
10441047
#[cfg(target_os = "windows")]
1045-
let preprocessor_output = &normalize_win_path(preprocessor_output);
1048+
let normalized_output = &normalize_win_path(preprocessor_output);
10461049

10471050
for (idx, basedir_bytes) in basedirs.iter().enumerate() {
10481051
let basedir = basedir_bytes.as_slice();
10491052
#[cfg(target_os = "windows")]
10501053
// Case insensitive
10511054
let basedir = normalize_win_path(basedir);
10521055
// Use memchr's fast substring search
1053-
let finder = memchr::memmem::find_iter(preprocessor_output, &basedir);
1056+
let finder = memchr::memmem::find_iter(normalized_output, &basedir);
10541057

10551058
for pos in finder {
10561059
// Check if this is a valid boundary (start, whitespace, quote, or '<')
10571060
let is_boundary = pos == 0
1058-
|| preprocessor_output[pos - 1].is_ascii_whitespace()
1059-
|| preprocessor_output[pos - 1] == b'"'
1060-
|| preprocessor_output[pos - 1] == b'<';
1061+
|| normalized_output[pos - 1].is_ascii_whitespace()
1062+
|| normalized_output[pos - 1] == b'"'
1063+
|| normalized_output[pos - 1] == b'<';
10611064

10621065
if is_boundary {
10631066
matches.push((pos, basedir.len(), idx));
@@ -1095,14 +1098,14 @@ pub fn strip_basedirs(preprocessor_output: &[u8], basedirs: &[Vec<u8>]) -> Vec<u
10951098

10961099
for (match_pos, match_len) in filtered_matches {
10971100
// Copy everything before the match
1098-
result.extend_from_slice(&preprocessor_output[current_pos..match_pos]);
1101+
result.extend_from_slice(&normalized_output[current_pos..match_pos]);
10991102
// Replace the basedir with "."
11001103
result.push(b'.');
11011104
current_pos = match_pos + match_len;
11021105
}
11031106

11041107
// Copy remaining data
1105-
result.extend_from_slice(&preprocessor_output[current_pos..]);
1108+
result.extend_from_slice(&normalized_output[current_pos..]);
11061109

11071110
result
11081111
}
@@ -1368,34 +1371,36 @@ mod tests {
13681371
fn test_strip_basedir_windows_backslashes() {
13691372
// Without trailing backslash
13701373
let basedir = b"C:\\Users\\test\\project".to_vec();
1371-
let input = b"# 1 \"C:\\Users\\test\\project\\src\\main.c\"";
1374+
let input = b"# 1 \"C:\\Users\\test\\project\\Src\\Main.c\"";
13721375
let output = super::strip_basedirs(input, std::slice::from_ref(&basedir));
13731376
// normalized backslash to slash
1374-
let expected = b"# 1 \"./src/main.c\"";
1377+
let expected = b"# 1 \".\\Src\\Main.c\"";
13751378
assert_eq!(output, expected);
13761379

1377-
// With multiple trailing backslashes
1378-
let basedir = b"C:\\Users\\test\\project\\\\\\".to_vec();
1380+
// Trailing slashes aren't ignored, they must be cleaned in config reader
1381+
let basedir = b"C:\\Users\\test\\project\\".to_vec();
13791382
let input = b"# 1 \"C:\\Users\\test\\project\\src\\main.c\"";
13801383
let output = super::strip_basedirs(input, std::slice::from_ref(&basedir));
1381-
let expected = b"# 1 \"./src/main.c\"";
1384+
let expected = b"# 1 \".\\src\\main.c\"";
13821385
assert_eq!(output, expected);
13831386
}
13841387

13851388
#[cfg(target_os = "windows")]
13861389
#[test]
13871390
fn test_strip_basedir_windows_mixed_slashes() {
1391+
// The slashes may be mixed in preprocessor output, but the uncut output
1392+
// should remain untouched.
13881393
// Mixed forward and backslashes in input (common from certain build systems)
13891394
let basedir = b"C:\\Users\\test\\project".to_vec();
13901395
let input = b"# 1 \"C:/Users\\test\\project\\src/main.c\"";
13911396
let output = super::strip_basedirs(input, std::slice::from_ref(&basedir));
1392-
let expected = b"# 1 \"./src/main.c\"";
1397+
let expected = b"# 1 \".\\src/main.c\"";
13931398
assert_eq!(output, expected, "Failed to strip mixed slash path");
13941399

13951400
// Also test the reverse case
13961401
let input = b"# 1 \"C:\\Users/test/project/src\\main.c\"";
13971402
let output = super::strip_basedirs(input, std::slice::from_ref(&basedir));
1398-
let expected = b"# 1 \"./src/main.c\"";
1403+
let expected = b"# 1 \"./src\\main.c\"";
13991404
assert_eq!(output, expected, "Failed to strip reverse mixed slash path");
14001405
}
14011406
}

0 commit comments

Comments
 (0)