Skip to content

Commit 8546fc5

Browse files
committed
Improve error message if version wrong on magic line
1 parent 4d92454 commit 8546fc5

File tree

1 file changed

+57
-6
lines changed

1 file changed

+57
-6
lines changed

src/parsing/parser.rs

Lines changed: 57 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,18 +2098,38 @@ fn analyze_magic_line(content: &str) -> usize {
20982098

20992099
// Point to where "technique" should be if missing or incorrect
21002100
if !trimmed.contains("technique") {
2101-
// Find position after % and whitespace
2102-
return content
2103-
.find('%')
2104-
.unwrap_or(0)
2105-
+ 1;
2101+
// Find position after % and skip whitespace to point to first char of wrong keyword
2102+
if let Some(percent_pos) = content.find('%') {
2103+
let after_percent = percent_pos + 1;
2104+
let remaining = &content[after_percent..];
2105+
for (i, ch) in remaining.char_indices() {
2106+
if !ch.is_whitespace() {
2107+
return after_percent + i;
2108+
}
2109+
}
2110+
return after_percent;
2111+
}
2112+
return 0;
21062113
}
21072114

21082115
// Point to where version should be if missing v1
21092116
if !trimmed.contains("v1") {
21102117
// Find position after "technique"
21112118
if let Some(pos) = content.find("technique") {
2112-
return pos + "technique".len();
2119+
let after_technique = pos + "technique".len();
2120+
// Skip whitespace to find the actual version string
2121+
let remaining = &content[after_technique..];
2122+
for (i, ch) in remaining.char_indices() {
2123+
if !ch.is_whitespace() {
2124+
// If we found a 'v', point to the character after it (the version number)
2125+
if ch == 'v' && i + 1 < remaining.len() {
2126+
return after_technique + i + 1;
2127+
}
2128+
// Otherwise point to where we found the non-whitespace character
2129+
return after_technique + i;
2130+
}
2131+
}
2132+
return after_technique;
21132133
}
21142134
}
21152135

@@ -2418,6 +2438,37 @@ mod check {
24182438
assert!(result.is_err());
24192439
}
24202440

2441+
#[test]
2442+
fn magic_line_wrong_keyword_error_position() {
2443+
// Test that error position points to the first character of the wrong keyword
2444+
assert_eq!(analyze_magic_line("% tecnique v1"), 2); // Points to "t" in "tecnique"
2445+
assert_eq!(analyze_magic_line("% tecnique v1"), 3); // Points to "t" in "tecnique" with extra space
2446+
assert_eq!(analyze_magic_line("% \ttechniqe v1"), 3); // Points to "t" in "techniqe" with tab
2447+
assert_eq!(analyze_magic_line("% wrong v1"), 5); // Points to "w" in "wrong" with multiple spaces
2448+
assert_eq!(analyze_magic_line("% foo v1"), 2); // Points to "f" in "foo"
2449+
assert_eq!(analyze_magic_line("% TECHNIQUE v1"), 2); // Points to "T" in uppercase "TECHNIQUE"
2450+
2451+
// Test missing keyword entirely - should point to position after %
2452+
assert_eq!(analyze_magic_line("% v1"), 2); // Points to "v" when keyword is missing
2453+
assert_eq!(analyze_magic_line("% v1"), 3); // Points to "v" when keyword is missing with space
2454+
}
2455+
2456+
#[test]
2457+
fn magic_line_wrong_version_error_position() {
2458+
// Test that error position points to the version number after "v" in wrong version strings
2459+
assert_eq!(analyze_magic_line("% technique v0"), 13); // Points to "0" in "v0"
2460+
assert_eq!(analyze_magic_line("% technique v2"), 14); // Points to "2" in "v2" with extra space
2461+
assert_eq!(analyze_magic_line("% technique\tv0"), 13); // Points to "0" in "v0" with tab
2462+
assert_eq!(analyze_magic_line("% technique vX"), 15); // Points to "X" in "vX" with multiple spaces
2463+
assert_eq!(analyze_magic_line("% technique v99"), 13); // Points to "9" in "v99"
2464+
assert_eq!(analyze_magic_line("% technique v0.5"), 15); // Points to "0" in "v0.5" with multiple spaces
2465+
2466+
// Test edge case where there's no "v" at all - should point to where version should start
2467+
assert_eq!(analyze_magic_line("% technique 1.0"), 12); // Points to "1" when there's no "v"
2468+
assert_eq!(analyze_magic_line("% technique 2"), 13); // Points to "2" when there's no "v" with extra space
2469+
assert_eq!(analyze_magic_line("% technique beta"), 12); // Points to "b" in "beta" when there's no "v"
2470+
}
2471+
24212472
#[test]
24222473
fn header_spdx() {
24232474
let mut input = Parser::new();

0 commit comments

Comments
 (0)