Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 30 additions & 35 deletions tools/validate/validate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
#include <algorithm>
#include <array>
#include <cassert>
#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <filesystem>
#include <format>
#include <print>
#include <string>
#include <string_view>
#include <type_traits>
#include <utility>
#include <vector>
using namespace std;
Expand All @@ -21,7 +23,7 @@ class BinaryFile {
public:
explicit BinaryFile(const filesystem::path& filepath) : m_file(_wfopen(filepath.c_str(), L"rb")) {
if (!m_file) {
fwprintf(stderr, L"Validation failed: %ls couldn't be opened.\n", filepath.c_str());
println(stderr, "Validation failed: {} couldn't be opened.", filepath.string());
}
}

Expand All @@ -39,7 +41,7 @@ class BinaryFile {

~BinaryFile() {
if (fclose(m_file) != 0) {
fwprintf(stderr, L"fclose() failed.\n");
println(stderr, "fclose() failed.");
abort();
}
}
Expand All @@ -51,20 +53,13 @@ class BinaryFile {
FILE* m_file{nullptr};
};

int validation_failure(
bool& any_errors, const filesystem::path& filepath, _Printf_format_string_ const wchar_t* format, ...) {
template <class... Args>
void validation_failure(
bool& any_errors, const filesystem::path& filepath, format_string<type_identity_t<Args>...> fmt, Args&&... args) {
any_errors = true;

fwprintf(stderr, L"##vso[task.logissue type=error;sourcepath=%ls;linenumber=1;columnnumber=1]Validation failed: ",
filepath.c_str());

va_list args;
va_start(args, format);
const int result = vfwprintf(stderr, format, args);
va_end(args);

fwprintf(stderr, L"\n");
return result;
print(stderr, "##vso[task.logissue type=error;sourcepath={};linenumber=1;columnnumber=1]Validation failed: ",
filepath.string());
println(stderr, fmt, forward<Args>(args)...);
}

enum class TabPolicy : bool { Forbidden, Allowed };
Expand Down Expand Up @@ -116,7 +111,7 @@ void scan_file(
++disallowed_characters;
constexpr size_t MaxErrorsForDisallowedCharacters = 10;
if (disallowed_characters <= MaxErrorsForDisallowedCharacters) {
validation_failure(any_errors, filepath, L"file contains disallowed character 0x%02X.",
validation_failure(any_errors, filepath, "file contains disallowed character 0x{:02X}.",
static_cast<unsigned int>(ch));
}
}
Expand All @@ -142,38 +137,38 @@ void scan_file(
}

if (has_cr) {
validation_failure(any_errors, filepath, L"file contains CR line endings (possibly damaged CRLF).");
validation_failure(any_errors, filepath, "file contains CR line endings (possibly damaged CRLF).");
} else if (has_lf && has_crlf) {
validation_failure(any_errors, filepath, L"file contains mixed line endings (both LF and CRLF).");
validation_failure(any_errors, filepath, "file contains mixed line endings (both LF and CRLF).");
} else if (has_lf) {
validation_failure(any_errors, filepath, L"file contains LF line endings.");
validation_failure(any_errors, filepath, "file contains LF line endings.");

if (prev != LF) {
validation_failure(any_errors, filepath, L"file doesn't end with a newline.");
validation_failure(any_errors, filepath, "file doesn't end with a newline.");
} else if (previous2 == LF) {
validation_failure(any_errors, filepath, L"file ends with multiple newlines.");
validation_failure(any_errors, filepath, "file ends with multiple newlines.");
}
} else if (has_crlf) {
if (previous2 != CR || prev != LF) {
validation_failure(any_errors, filepath, L"file doesn't end with a newline.");
validation_failure(any_errors, filepath, "file doesn't end with a newline.");
} else if (previous3 == LF) {
validation_failure(any_errors, filepath, L"file ends with multiple newlines.");
validation_failure(any_errors, filepath, "file ends with multiple newlines.");
}
} else {
validation_failure(any_errors, filepath, L"file doesn't contain any newlines.");
validation_failure(any_errors, filepath, "file doesn't contain any newlines.");
}

if (has_utf8_bom) {
validation_failure(any_errors, filepath, L"file contains UTF-8 BOM characters.");
validation_failure(any_errors, filepath, "file contains UTF-8 BOM characters.");
}

if (tab_policy == TabPolicy::Forbidden && tab_characters != 0) {
validation_failure(any_errors, filepath, L"file contains %zu tab characters.", tab_characters);
validation_failure(any_errors, filepath, "file contains {} tab characters.", tab_characters);
}

if (trailing_whitespace_lines != 0) {
validation_failure(
any_errors, filepath, L"file contains %zu lines with trailing whitespace.", trailing_whitespace_lines);
any_errors, filepath, "file contains {} lines with trailing whitespace.", trailing_whitespace_lines);
}

if (overlength_lines != 0) {
Expand All @@ -192,7 +187,7 @@ void scan_file(
static_assert(ranges::is_sorted(checked_extensions));

if (ranges::binary_search(checked_extensions, filepath.extension().wstring())) {
validation_failure(any_errors, filepath, L"file contains %zu lines with more than %zu columns.\n",
validation_failure(any_errors, filepath, "file contains {} lines with more than {} columns.",
Comment on lines -195 to +190
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No change requested: This fixes a mistake that was introduced by #2671. validation_failure() prints a newline, so we don't want a second one here.

overlength_lines, max_line_length);
}
}
Expand Down Expand Up @@ -254,12 +249,12 @@ int main() {

constexpr size_t maximum_relative_path_length = 120;
if (relative_path.size() > maximum_relative_path_length) {
validation_failure(any_errors, filepath, L"filepath is too long (%zu characters; the limit is %zu).",
validation_failure(any_errors, filepath, "filepath is too long ({} characters; the limit is {}).",
relative_path.size(), maximum_relative_path_length);
}

if (relative_path.find(L' ') != wstring::npos) {
validation_failure(any_errors, filepath, L"filepath contains spaces.");
validation_failure(any_errors, filepath, "filepath contains spaces.");
}

const wstring extension = filepath.extension().wstring();
Expand All @@ -269,7 +264,7 @@ int main() {
}

if (ranges::binary_search(bad_extensions, extension)) {
validation_failure(any_errors, filepath, L"file should not be checked in.");
validation_failure(any_errors, filepath, "file should not be checked in.");
continue;
}

Expand All @@ -280,8 +275,8 @@ int main() {
}

if (any_errors) {
fwprintf(
stderr, L"##vso[task.logissue type=warning]If your build fails here, you need to fix the listed issues.\n");
fwprintf(stderr, L"##vso[task.complete result=Failed]DONE\n");
println(
stderr, "##vso[task.logissue type=warning]If your build fails here, you need to fix the listed issues.");
println(stderr, "##vso[task.complete result=Failed]DONE");
}
}