int Priority;
/// The custom priority to sort before grouping.
int SortPriority;
+ /// If the regular expression is case sensitive.
+ bool RegexIsCaseSensitive;
bool operator==(const IncludeCategory &Other) const {
- return Regex == Other.Regex && Priority == Other.Priority;
+ return Regex == Other.Regex && Priority == Other.Priority &&
+ RegexIsCaseSensitive == Other.RegexIsCaseSensitive;
}
};
/// (https://llvm.org/docs/CodingStandards.html#include-style). However, you
/// can also assign negative priorities if you have certain headers that
/// always need to be first.
- ///
+ ///
/// There is a third and optional field ``SortPriority`` which can used while
- /// ``IncludeBloks = IBS_Regroup`` to define the priority in which ``#includes``
- /// should be ordered, and value of ``Priority`` defines the order of
+ /// ``IncludeBloks = IBS_Regroup`` to define the priority in which
+ /// ``#includes`` should be ordered, and value of ``Priority`` defines the
+ /// order of
/// ``#include blocks`` and also enables to group ``#includes`` of different
/// priority for order.``SortPriority`` is set to the value of ``Priority``
/// as default if it is not assigned.
///
+ /// Each regular expression can be marked as case sensitive with the field
+ /// ``CaseSensitive``, per default it is not.
+ ///
/// To configure this in the .clang-format file, use:
/// \code{.yaml}
/// IncludeCategories:
/// - Regex: '^"(llvm|llvm-c|clang|clang-c)/'
/// Priority: 2
/// SortPriority: 2
+ /// CaseSensitive: true
/// - Regex: '^(<|"(gtest|gmock|isl|json)/)'
/// Priority: 3
/// - Regex: '<[[:alnum:].]+>'
LLVMStyle.ForEachMacros.push_back("Q_FOREACH");
LLVMStyle.ForEachMacros.push_back("BOOST_FOREACH");
LLVMStyle.IncludeStyle.IncludeCategories = {
- {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0},
- {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0},
- {".*", 1, 0}};
+ {"^\"(llvm|llvm-c|clang|clang-c)/", 2, 0, false},
+ {"^(<|\"(gtest|gmock|isl|json)/)", 3, 0, false},
+ {".*", 1, 0, false}};
LLVMStyle.IncludeStyle.IncludeIsMainRegex = "(Test)?$";
LLVMStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Preserve;
LLVMStyle.IndentCaseLabels = false;
GoogleStyle.AlwaysBreakTemplateDeclarations = FormatStyle::BTDS_Yes;
GoogleStyle.ConstructorInitializerAllOnOneLineOrOnePerLine = true;
GoogleStyle.DerivePointerAlignment = true;
- GoogleStyle.IncludeStyle.IncludeCategories = {{"^<ext/.*\\.h>", 2, 0},
- {"^<.*\\.h>", 1, 0},
- {"^<.*", 2, 0},
- {".*", 3, 0}};
+ GoogleStyle.IncludeStyle.IncludeCategories = {{"^<ext/.*\\.h>", 2, 0, false},
+ {"^<.*\\.h>", 1, 0, false},
+ {"^<.*", 2, 0, false},
+ {".*", 3, 0, false}};
GoogleStyle.IncludeStyle.IncludeIsMainRegex = "([-_](test|unittest))?$";
GoogleStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
GoogleStyle.IndentCaseLabels = true;
TEST_F(SortIncludesTest, SortedIncludesUsingSortPriorityAttribute) {
FmtStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
FmtStyle.IncludeStyle.IncludeCategories = {
- {"^<sys/param\\.h>", 1, 0},
- {"^<sys/types\\.h>", 1, 1},
- {"^<sys.*/", 1, 2},
- {"^<uvm/", 2, 3},
- {"^<machine/", 3, 4},
- {"^<dev/", 4, 5},
- {"^<net.*/", 5, 6},
- {"^<protocols/", 5, 7},
- {"^<(fs|miscfs|msdosfs|nfs|ntfs|ufs)/", 6, 8},
- {"^<(x86|amd64|i386|xen)/", 7, 8},
- {"<path", 9, 11},
- {"^<[^/].*\\.h>", 8, 10},
- {"^\".*\\.h\"", 10, 12}};
+ {"^<sys/param\\.h>", 1, 0, false},
+ {"^<sys/types\\.h>", 1, 1, false},
+ {"^<sys.*/", 1, 2, false},
+ {"^<uvm/", 2, 3, false},
+ {"^<machine/", 3, 4, false},
+ {"^<dev/", 4, 5, false},
+ {"^<net.*/", 5, 6, false},
+ {"^<protocols/", 5, 7, false},
+ {"^<(fs|miscfs|msdosfs|nfs|ntfs|ufs)/", 6, 8, false},
+ {"^<(x86|amd64|i386|xen)/", 7, 8, false},
+ {"<path", 9, 11, false},
+ {"^<[^/].*\\.h>", 8, 10, false},
+ {"^\".*\\.h\"", 10, 12, false}};
EXPECT_EQ("#include <sys/param.h>\n"
"#include <sys/types.h>\n"
"#include <sys/ioctl.h>\n"
"a_TEST.cc"));
}
+TEST_F(SortIncludesTest, SupportOptionalCaseSensitiveMachting) {
+ Style.IncludeBlocks = clang::tooling::IncludeStyle::IBS_Regroup;
+ Style.IncludeCategories = {{"^\"", 1, 0, false},
+ {"^<.*\\.h>$", 2, 0, false},
+ {"^<Q[A-Z][^\\.]*>", 3, 0, false},
+ {"^<Qt[^\\.]*>", 4, 0, false},
+ {"^<", 5, 0, false}};
+
+ StringRef UnsortedCode = "#include <QWidget>\n"
+ "#include \"qt.h\"\n"
+ "#include <algorithm>\n"
+ "#include <windows.h>\n"
+ "#include <QLabel>\n"
+ "#include \"qa.h\"\n"
+ "#include <queue>\n"
+ "#include <qtwhatever.h>\n"
+ "#include <QtGlobal>\n";
+
+ EXPECT_EQ("#include \"qa.h\"\n"
+ "#include \"qt.h\"\n"
+ "\n"
+ "#include <qtwhatever.h>\n"
+ "#include <windows.h>\n"
+ "\n"
+ "#include <QLabel>\n"
+ "#include <QWidget>\n"
+ "#include <QtGlobal>\n"
+ "#include <queue>\n"
+ "\n"
+ "#include <algorithm>\n",
+ sort(UnsortedCode));
+
+ Style.IncludeCategories[2].RegexIsCaseSensitive = true;
+ Style.IncludeCategories[3].RegexIsCaseSensitive = true;
+ EXPECT_EQ("#include \"qa.h\"\n"
+ "#include \"qt.h\"\n"
+ "\n"
+ "#include <qtwhatever.h>\n"
+ "#include <windows.h>\n"
+ "\n"
+ "#include <QLabel>\n"
+ "#include <QWidget>\n"
+ "\n"
+ "#include <QtGlobal>\n"
+ "\n"
+ "#include <algorithm>\n"
+ "#include <queue>\n",
+ sort(UnsortedCode));
+}
+
TEST_F(SortIncludesTest, NegativePriorities) {
- Style.IncludeCategories = {{".*important_os_header.*", -1, 0}, {".*", 1, 0}};
+ Style.IncludeCategories = {{".*important_os_header.*", -1, 0, false},
+ {".*", 1, 0, false}};
EXPECT_EQ("#include \"important_os_header.h\"\n"
"#include \"c_main.h\"\n"
"#include \"a_other.h\"\n",
}
TEST_F(SortIncludesTest, PriorityGroupsAreSeparatedWhenRegroupping) {
- Style.IncludeCategories = {{".*important_os_header.*", -1, 0}, {".*", 1, 0}};
+ Style.IncludeCategories = {{".*important_os_header.*", -1, 0, false},
+ {".*", 1, 0, false}};
Style.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
EXPECT_EQ("#include \"important_os_header.h\"\n"