Skip to content

Commit d082f9b

Browse files
committed
fix(regex): Add custom regex-like parsing for version extraction
Signed-off-by: royalpinto007 <royalpinto007@gmail.com> fix(regex): Add custom regex-like parsing Signed-off-by: royalpinto007 <royalpinto007@gmail.com>
1 parent e85d6f9 commit d082f9b

File tree

1 file changed

+92
-13
lines changed

1 file changed

+92
-13
lines changed

compiler/src/dmd/sarif.d

Lines changed: 92 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -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
/**
158247
Generates 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
170259
Throws:
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

Comments
 (0)