[flang-commits] [flang] [flang][cli] Add diagnostic flags to the CLI (PR #142022)
Peter Klausler via flang-commits
flang-commits at lists.llvm.org
Sat May 31 13:17:38 PDT 2025
================
@@ -107,44 +114,138 @@ static std::optional<char> GetWarningChar(char ch) {
}
}
-static bool WarningNameMatch(const char *a, const char *b) {
+// Check for case and punctuation insensitive string equality.
+// NB, b is probably not null terminated, so don't treat is like a C string.
+static bool InsensitiveWarningNameMatch(
+ std::string_view a, std::string_view b) {
+ size_t j{0}, aSize{a.size()}, k{0}, bSize{b.size()};
while (true) {
- auto ach{GetWarningChar(*a)};
- while (!ach && *a) {
- ach = GetWarningChar(*++a);
+ optional<char> ach{nullopt};
+ while (!ach && j < aSize) {
+ ach = GetWarningChar(a[j++]);
}
- auto bch{GetWarningChar(*b)};
- while (!bch && *b) {
- bch = GetWarningChar(*++b);
+ optional<char> bch{};
+ while (!bch && k < bSize) {
+ bch = GetWarningChar(b[k++]);
}
if (!ach && !bch) {
return true;
} else if (!ach || !bch || *ach != *bch) {
return false;
}
- ++a, ++b;
+ ach = bch = nullopt;
}
}
-template <typename ENUM, std::size_t N>
-std::optional<ENUM> ScanEnum(const char *name) {
- if (name) {
- for (std::size_t j{0}; j < N; ++j) {
- auto feature{static_cast<ENUM>(j)};
- if (WarningNameMatch(name, EnumToString(feature).data())) {
- return feature;
+// Check if lower case hyphenated words are equal to camel case words.
+// Because of out use case we know that 'r' the camel case string is
+// well formed in the sense that it is a sequence [a-zA-Z]+[a-zA-Z0-9]*.
+// This is checked in the enum-class.h file.
+static bool SensitiveWarningNameMatch(llvm::StringRef l, llvm::StringRef r) {
+ size_t ls{l.size()}, rs{r.size()};
+ if (ls < rs) {
+ return false;
+ }
+ bool atStartOfWord{true};
+ size_t wordCount{0}, j{0}; // j is the number of word characters checked in r.
+ for (; j < rs; j++) {
+ if (wordCount + j >= ls) {
+ // `l` was shorter once the hiphens were removed.
+ // If r is null terminated, then we are good.
+ return r[j] == '\0';
+ }
+ if (atStartOfWord) {
+ if (llvm::isUpper(r[j])) {
+ // Upper Case Run
+ if (l[wordCount + j] != llvm::toLower(r[j])) {
+ return false;
+ }
+ } else {
+ atStartOfWord = false;
+ if (l[wordCount + j] != r[j]) {
+ return false;
+ }
}
+ } else {
+ if (llvm::isUpper(r[j])) {
+ atStartOfWord = true;
+ if (l[wordCount + j] != '-') {
+ return false;
+ }
+ ++wordCount;
+ if (l[wordCount + j] != llvm::toLower(r[j])) {
+ return false;
+ }
+ } else if (l[wordCount + j] != r[j]) {
+ return false;
+ }
+ }
+ }
+ // If there are more characters in l after processing all the characters in r.
+ // then fail unless the string is null terminated.
+ if (ls > wordCount + j) {
+ return l[wordCount + j] == '\0';
+ }
+ return true;
+}
+
+// Parse a CLI enum option return the enum index and whether it should be
+// enabled (true) or disabled (false).
+template <typename T>
+optional<std::pair<bool, T>> ParseCLIEnum(llvm::StringRef input,
+ EnumClass::FindIndexType findIndex, bool insensitive) {
+ bool negated{false};
+ EnumClass::Predicate predicate;
+ if (insensitive) {
+ if (input.starts_with_insensitive("no")) {
+ negated = true;
+ input = input.drop_front(2);
+ }
+ predicate = [input](std::string_view r) {
+ return InsensitiveWarningNameMatch(input, r);
+ };
+ } else {
+ if (input.starts_with("no-")) {
+ negated = true;
+ input = input.drop_front(3);
}
+ predicate = [input](std::string_view r) {
+ return SensitiveWarningNameMatch(input, r);
+ };
}
- return std::nullopt;
+ optional<T> x = EnumClass::Find<T>(predicate, findIndex);
+ return MapOption<T, std::pair<bool, T>>(
+ x, [negated](T x) { return std::pair{!negated, x}; });
}
-std::optional<LanguageFeature> FindLanguageFeature(const char *name) {
- return ScanEnum<LanguageFeature, LanguageFeature_enumSize>(name);
+optional<std::pair<bool, UsageWarning>> parseCLIUsageWarning(
+ llvm::StringRef input, bool insensitive) {
+ return ParseCLIEnum<UsageWarning>(input, FindUsageWarningIndex, insensitive);
}
-std::optional<UsageWarning> FindUsageWarning(const char *name) {
- return ScanEnum<UsageWarning, UsageWarning_enumSize>(name);
+optional<std::pair<bool, LanguageFeature>> parseCLILanguageFeature(
+ llvm::StringRef input, bool insensitive) {
+ return ParseCLIEnum<LanguageFeature>(
+ input, FindLanguageFeatureIndex, insensitive);
+}
+
+} // namespace FortranFeaturesHelpers
+
+// Take a string from the CLI and apply it to the LanguageFeatureControl.
+// Return true if the option was applied recognized.
----------------
klausler wrote:
"if the option was recognized"
https://github.com/llvm/llvm-project/pull/142022
More information about the flang-commits
mailing list