Skip to content

Commit

Permalink
fix(regex): Add custom regex-like parsing for version extraction
Browse files Browse the repository at this point in the history
Signed-off-by: royalpinto007 <[email protected]>

fix(regex): Add custom regex-like parsing

Signed-off-by: royalpinto007 <[email protected]>
  • Loading branch information
royalpinto007 committed Nov 6, 2024
1 parent e85d6f9 commit d082f9b
Showing 1 changed file with 92 additions and 13 deletions.
105 changes: 92 additions & 13 deletions compiler/src/dmd/sarif.d
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,95 @@ string formatErrorMessage(const(char)* format, va_list ap) nothrow {
return buffer[0 .. buffer.length].dup;
}

/**
Extracts a version number from a string using custom parsing rules.
Params:
toolVersion = The version string to extract from.
Returns:
A cleaned version string, or an empty string if no valid version is found.
*/
string extractVersionWithCustomRegex(string toolVersion) nothrow {
size_t index = 0;
char[] cleanedVersion;

// Match optional "v" prefix (equivalent to `v?`)
if (index < toolVersion.length && toolVersion[index] == 'v') {
index++; // Move past 'v' if present
}

// Match one or more digits (equivalent to `\d+`)
bool matchedDigits = matchDigits(index, toolVersion, cleanedVersion);
if (!matchedDigits) {
return ""; // Return empty if no digits found
}

// Match zero or more dot-separated digits (equivalent to `(\.\d+)*`)
matchDotSeparatedDigits(index, toolVersion, cleanedVersion);

return cast(string) cleanedVersion;
}

/**
Matches a sequence of digits in the input string.
Params:
index = The current position in the input string (updated by reference).
input = The input string to match against.
buffer = The buffer to store matched digits.
Returns:
`true` if digits were matched; otherwise `false`.
*/
bool matchDigits(ref size_t index, string input, ref char[] buffer) nothrow {
bool hasMatched = false;
while (index < input.length && isDigit(input[index])) {
buffer ~= input[index];
index++;
hasMatched = true;
}
return hasMatched;
}

/**
Matches a dot followed by one or more digits in the input string.
Params:
index = The current position in the input string (updated by reference).
input = The input string to match against.
buffer = The buffer to store matched characters.
*/
void matchDotSeparatedDigits(ref size_t index, string input, ref char[] buffer) nothrow {
while (index < input.length && input[index] == '.') {
size_t tempIndex = index + 1;
char[] tempBuffer;

// Check if there's a sequence of digits after the dot
if (matchDigits(tempIndex, input, tempBuffer)) {
buffer ~= '.';
buffer ~= tempBuffer;
index = tempIndex;
} else {
break; // No digits after dot, stop matching
}
}
}

/**
Checks if a character is a digit.
Params:
c = The character to check.
Returns:
`true` if the character is a digit; otherwise `false`.
*/
bool isDigit(char c) nothrow
{
return c >= '0' && c <= '9';
}

/**
Generates a SARIF (Static Analysis Results Interchange Format) report and prints it to `stdout`.
Expand All @@ -165,7 +254,7 @@ Params:
format = A format string for constructing the error message.
ap = A variable argument list used with the format string.
kind = The kind of error (error, warning, deprecation, note, or message).
executionSuccessful = `true` if execution succeeded; includes an empty `results` array in the SARIF report.
executionSuccessful = `true` for an empty `results` array; `false` for detailed errors.
Throws:
This function is marked as `nothrow` and does not throw exceptions.
Expand All @@ -179,19 +268,9 @@ void generateSarifReport(const ref SourceLoc loc, const(char)* format, va_list a
OutBuffer ob;
ob.doindent = true;

// Extract and clean the version string
// Use extractVersionWithCustomRegex to get the cleaned version string
string toolVersion = global.versionString();
// Remove 'v' prefix if it exists
if (toolVersion.length > 0 && toolVersion[0] == 'v') {
toolVersion = toolVersion[1 .. $];
}
// Find the first non-numeric character after the version number
size_t length = toolVersion.length;
const(char)* nonNumeric = strchr(toolVersion.ptr, '-');
if (nonNumeric) {
length = cast(size_t)(nonNumeric - toolVersion.ptr);
}
string cleanedVersion = toolVersion[0 .. length];
string cleanedVersion = extractVersionWithCustomRegex(toolVersion);

// Build SARIF report
ob.level = 0;
Expand Down

0 comments on commit d082f9b

Please sign in to comment.