@@ -154,6 +154,95 @@ string formatErrorMessage(const(char)* format, va_list ap) nothrow {
154154 return buffer[0 .. buffer.length].dup ;
155155}
156156
157+ /**
158+ Extracts a version number from a string using custom parsing rules.
159+
160+ Params:
161+ toolVersion = The version string to extract from.
162+
163+ Returns:
164+ A cleaned version string, or an empty string if no valid version is found.
165+ */
166+ string extractVersionWithCustomRegex (string toolVersion) nothrow {
167+ size_t index = 0 ;
168+ char [] cleanedVersion;
169+
170+ // Match optional "v" prefix (equivalent to `v?`)
171+ if (index < toolVersion.length && toolVersion[index] == ' v' ) {
172+ index++ ; // Move past 'v' if present
173+ }
174+
175+ // Match one or more digits (equivalent to `\d+`)
176+ bool matchedDigits = matchDigits(index, toolVersion, cleanedVersion);
177+ if (! matchedDigits) {
178+ return " " ; // Return empty if no digits found
179+ }
180+
181+ // Match zero or more dot-separated digits (equivalent to `(\.\d+)*`)
182+ matchDotSeparatedDigits(index, toolVersion, cleanedVersion);
183+
184+ return cast (string ) cleanedVersion;
185+ }
186+
187+ /**
188+ Matches a sequence of digits in the input string.
189+
190+ Params:
191+ index = The current position in the input string (updated by reference).
192+ input = The input string to match against.
193+ buffer = The buffer to store matched digits.
194+
195+ Returns:
196+ `true` if digits were matched; otherwise `false`.
197+ */
198+ bool matchDigits (ref size_t index, string input, ref char [] buffer) nothrow {
199+ bool hasMatched = false ;
200+ while (index < input.length && isDigit(input[index])) {
201+ buffer ~= input[index];
202+ index++ ;
203+ hasMatched = true ;
204+ }
205+ return hasMatched;
206+ }
207+
208+ /**
209+ Matches a dot followed by one or more digits in the input string.
210+
211+ Params:
212+ index = The current position in the input string (updated by reference).
213+ input = The input string to match against.
214+ buffer = The buffer to store matched characters.
215+ */
216+ void matchDotSeparatedDigits (ref size_t index, string input, ref char [] buffer) nothrow {
217+ while (index < input.length && input[index] == ' .' ) {
218+ size_t tempIndex = index + 1 ;
219+ char [] tempBuffer;
220+
221+ // Check if there's a sequence of digits after the dot
222+ if (matchDigits(tempIndex, input, tempBuffer)) {
223+ buffer ~= ' .' ;
224+ buffer ~= tempBuffer;
225+ index = tempIndex;
226+ } else {
227+ break ; // No digits after dot, stop matching
228+ }
229+ }
230+ }
231+
232+ /**
233+ Checks if a character is a digit.
234+
235+ Params:
236+ c = The character to check.
237+
238+ Returns:
239+ `true` if the character is a digit; otherwise `false`.
240+ */
241+ bool isDigit (char c) nothrow
242+ {
243+ return c >= ' 0' && c <= ' 9' ;
244+ }
245+
157246/**
158247Generates a SARIF (Static Analysis Results Interchange Format) report and prints it to `stdout`.
159248
@@ -165,7 +254,7 @@ Params:
165254 format = A format string for constructing the error message.
166255 ap = A variable argument list used with the format string.
167256 kind = The kind of error (error, warning, deprecation, note, or message).
168- executionSuccessful = `true` if execution succeeded; includes an empty `results` array in the SARIF report .
257+ executionSuccessful = `true` for an empty `results` array; `false` for detailed errors .
169258
170259Throws:
171260 This function is marked as `nothrow` and does not throw exceptions.
@@ -179,19 +268,9 @@ void generateSarifReport(const ref SourceLoc loc, const(char)* format, va_list a
179268 OutBuffer ob;
180269 ob.doindent = true ;
181270
182- // Extract and clean the version string
271+ // Use extractVersionWithCustomRegex to get the cleaned version string
183272 string toolVersion = global.versionString();
184- // Remove 'v' prefix if it exists
185- if (toolVersion.length > 0 && toolVersion[0 ] == ' v' ) {
186- toolVersion = toolVersion[1 .. $];
187- }
188- // Find the first non-numeric character after the version number
189- size_t length = toolVersion.length;
190- const (char )* nonNumeric = strchr(toolVersion.ptr, ' -' );
191- if (nonNumeric) {
192- length = cast (size_t )(nonNumeric - toolVersion.ptr);
193- }
194- string cleanedVersion = toolVersion[0 .. length];
273+ string cleanedVersion = extractVersionWithCustomRegex(toolVersion);
195274
196275 // Build SARIF report
197276 ob.level = 0 ;
0 commit comments