Manikishan updated this revision to Diff 209933.
Repository:
rC Clang
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D64695/new/
https://reviews.llvm.org/D64695
Files:
docs/ClangFormatStyleOptions.rst
include/clang/Format/Format.h
lib/Format/Format.cpp
unittests/Format/SortIncludesTest.cpp
Index: unittests/Format/SortIncludesTest.cpp
===================================================================
--- unittests/Format/SortIncludesTest.cpp
+++ unittests/Format/SortIncludesTest.cpp
@@ -665,6 +665,67 @@
"#include \"a.h\""));
}
+TEST_F(SortIncludesTest, ParamAndTypesCheck) {
+ FmtStyle = getNetBSDStyle();
+ EXPECT_EQ("#include <sys/param.h>\n"
+ "#include <sys/types.h>\n"
+ "#include <sys/ioctl.h>\n"
+ "#include <sys/socket.h>\n"
+ "#include <sys/stat.h>\n"
+ "#include <sys/wait.h>\n",
+ sort("#include <sys/ioctl.h>\n"
+ "#include <sys/stat.h>\n"
+ "#include <sys/socket.h>\n"
+ "#include <sys/types.h>\n"
+ "#include <sys/param.h>\n"
+ "#include <sys/wait.h>\n"));
+
+}
+
+TEST_F(SortIncludesTest, SortedIncludesInSingleBlockReGroupWithNetBSDSpecifications) {
+ FmtStyle = getNetBSDStyle();
+ EXPECT_EQ("#include <sys/param.h>\n"
+ "#include <sys/types.h>\n"
+ "#include <sys/ioctl.h>\n"
+ "#include <sys/socket.h>\n"
+ "#include <sys/stat.h>\n"
+ "#include <sys/wait.h>\n"
+ "\n"
+ "#include <net/if.h>\n"
+ "#include <net/if_dl.h>\n"
+ "#include <net/route.h>\n"
+ "#include <netinet/in.h>\n"
+ "#include <protocols/rwhod.h>\n"
+ "\n"
+ "#include <assert.h>\n"
+ "#include <errno.h>\n"
+ "#include <inttypes.h>\n"
+ "#include <stdio.h>\n"
+ "#include <stdlib.h>\n"
+ "\n"
+ "#include <paths.h>\n"
+ "\n"
+ "#include \"pathnames.h\"\n",
+ sort("#include <sys/param.h>\n"
+ "#include <sys/types.h>\n"
+ "#include <sys/ioctl.h>\n"
+ "#include <net/if_dl.h>\n"
+ "#include <net/route.h>\n"
+ "#include <netinet/in.h>\n"
+ "#include <sys/socket.h>\n"
+ "#include <sys/stat.h>\n"
+ "#include <sys/wait.h>\n"
+ "#include <net/if.h>\n"
+ "#include <protocols/rwhod.h>\n"
+ "#include <assert.h>\n"
+ "#include <paths.h>\n"
+ "#include \"pathnames.h\"\n"
+ "#include <errno.h>\n"
+ "#include <inttypes.h>\n"
+ "#include <stdio.h>\n"
+ "#include <stdlib.h>\n"));
+}
+
} // end namespace
} // end namespace format
} // end namespace clang
Index: lib/Format/Format.cpp
===================================================================
--- lib/Format/Format.cpp
+++ lib/Format/Format.cpp
@@ -278,8 +278,15 @@
}
};
-template <>
-struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
+template <> struct ScalarEnumerationTraits<FormatStyle::IncludeHeadersStyle> {
+ static void enumeration(IO &IO,
+ FormatStyle::IncludeHeadersStyle &Value) {
+ IO.enumCase(Value, "None", FormatStyle::SIS_None);
+ IO.enumCase(Value, "NetBSD", FormatStyle::SIS_NetBSD);
+ }
+};
+
+template <> struct ScalarEnumerationTraits<FormatStyle::SpaceBeforeParensOptions> {
static void enumeration(IO &IO,
FormatStyle::SpaceBeforeParensOptions &Value) {
IO.enumCase(Value, "Never", FormatStyle::SBPO_Never);
@@ -479,6 +486,7 @@
IO.mapOptional("RawStringFormats", Style.RawStringFormats);
IO.mapOptional("ReflowComments", Style.ReflowComments);
IO.mapOptional("SortIncludes", Style.SortIncludes);
+ IO.mapOptional("SortIncludesStyle", Style.SortIncludesStyle);
IO.mapOptional("SortUsingDeclarations", Style.SortUsingDeclarations);
IO.mapOptional("SpaceAfterCStyleCast", Style.SpaceAfterCStyleCast);
IO.mapOptional("SpaceAfterLogicalNot", Style.SpaceAfterLogicalNot);
@@ -609,7 +617,7 @@
return Style;
FormatStyle Expanded = Style;
Expanded.BraceWrapping = {false, false, false, false, false, false,
- false, false, false, false, false,
+ false, false, false, false, false,
false, false, true, true, true};
switch (Style.BreakBeforeBraces) {
case FormatStyle::BS_Linux:
@@ -759,6 +767,7 @@
LLVMStyle.DisableFormat = false;
LLVMStyle.SortIncludes = true;
+ LLVMStyle.SortIncludesStyle = FormatStyle::SIS_None;
LLVMStyle.SortUsingDeclarations = true;
LLVMStyle.StatementMacros.push_back("Q_UNUSED");
LLVMStyle.StatementMacros.push_back("QT_REQUIRE_VERSION");
@@ -919,6 +928,7 @@
"javax",
};
ChromiumStyle.SortIncludes = true;
+ ChromiumStyle.SortIncludesStyle = FormatStyle::SIS_None;
} else if (Language == FormatStyle::LK_JavaScript) {
ChromiumStyle.AllowShortIfStatementsOnASingleLine = FormatStyle::SIS_Never;
ChromiumStyle.AllowShortLoopsOnASingleLine = false;
@@ -1023,6 +1033,30 @@
return Style;
}
+FormatStyle getNetBSDStyle() {
+ FormatStyle NetBSDStyle = getLLVMStyle();
+ NetBSDStyle.AlignTrailingComments = true;
+ NetBSDStyle.AlwaysBreakAfterReturnType = FormatStyle::RTBS_AllDefinitions;
+ NetBSDStyle.AlignConsecutiveMacros = true;
+ NetBSDStyle.BreakBeforeBraces = FormatStyle::BS_Mozilla;
+ NetBSDStyle.ColumnLimit = 80;
+ NetBSDStyle.ContinuationIndentWidth = 4;
+ NetBSDStyle.Cpp11BracedListStyle = false;
+ NetBSDStyle.FixNamespaceComments = true;
+ NetBSDStyle.IndentCaseLabels = false;
+ NetBSDStyle.IndentWidth = 8;
+ NetBSDStyle.IncludeStyle.IncludeBlocks = tooling::IncludeStyle::IBS_Regroup;
+ NetBSDStyle.IncludeStyle.IncludeCategories = {
+ {"^<sys/", 7}, {"^<uvm/", 6}, {"^<(net.*|protocols)/", 5},
+ {"^<(fs*)", 4}, {"^<path*", 3}, {"^<[^\/].*\.h>", 2},
+ {"^\"\w.*\.h\"$", 1}, {".*", 0}};
+ NetBSDStyle.SortIncludes = true;
+ NetBSDStyle.SortIncludesStyle = FormatStyle::SIS_NetBSD;
+ NetBSDStyle.TabWidth = 8;
+ NetBSDStyle.UseTab = FormatStyle::UT_Always;
+ return NetBSDStyle;
+}
+
FormatStyle getNoStyle() {
FormatStyle NoStyle = getLLVMStyle();
NoStyle.DisableFormat = true;
@@ -1047,6 +1081,8 @@
*Style = getGNUStyle();
} else if (Name.equals_lower("microsoft")) {
*Style = getMicrosoftStyle(Language);
+ } else if (Name.equals_lower("netbsd")) {
+ *Style = getNetBSDStyle();
} else if (Name.equals_lower("none")) {
*Style = getNoStyle();
} else {
@@ -1763,6 +1799,81 @@
}
return std::make_pair(CursorIndex, OffsetToEOL);
}
+enum CppIncludeHeadersKind {
+ IHK_KERNELHEADERS,
+ IHK_NETWORKHEADERS,
+ IHK_FILESYSHEADERS,
+ IHK_MACHINESHEADERS,
+ IHK_ARCHHEADERS,
+ IHK_USERHEADERS,
+ IHK_INCLUDESWITHQUOTES,
+};
+
+CppIncludeHeadersKind getHeadersKind(std::string Filename) {
+ SmallVector<StringRef, 4> Matches;
+ const char KernelHeaderPattern[] = R"(^<(sys.*|uvm|dev)/)";
+ const char NetworkHeaderPattern[] = R"(^<(net.*|protocols)/)";
+ const char FilesSystemHeaderPattern[] =
+ R"(^<(fs|miscfs|msdosfs|nfs|ntfs|ufs))";
+ const char MachineHeaderPattern[] = R"(^<machine/)";
+ const char ArchHeadersPattern[] = R"(^<(x86|amd64|i386|xen)/)";
+ const char UserHeaderPattern[] = R"(^<[a-zA-Z0-9]*\.h>)";
+ const char IncludeWithQuotesPattern[] = R"(^\"*$\")";
+ llvm::Regex MatchKernel = llvm::Regex(KernelHeaderPattern);
+ llvm::Regex MatchNetwork = llvm::Regex(NetworkHeaderPattern);
+ llvm::Regex MatchFileSys = llvm::Regex(FilesSystemHeaderPattern);
+ llvm::Regex MatchMachine = llvm::Regex(MachineHeaderPattern);
+ llvm::Regex MatchArch = llvm::Regex(ArchHeadersPattern);
+ llvm::Regex MatchUser = llvm::Regex(UserHeaderPattern);
+ llvm::Regex MatchQuotes = llvm::Regex(IncludeWithQuotesPattern);
+ if (MatchKernel.match(Filename))
+ return IHK_KERNELHEADERS;
+ else if (MatchNetwork.match(Filename))
+ return IHK_NETWORKHEADERS;
+ else if (MatchArch.match(Filename))
+ return IHK_ARCHHEADERS;
+ else if (MatchQuotes.match(Filename))
+ return IHK_INCLUDESWITHQUOTES;
+ else if (MatchUser.match(Filename))
+ return IHK_USERHEADERS;
+ else if (MatchFileSys.match(Filename))
+ return IHK_FILESYSHEADERS;
+ else if (MatchMachine.match(Filename))
+ return IHK_MACHINESHEADERS;
+ return IHK_INCLUDESWITHQUOTES;
+}
+
+unsigned getNetBSDIncludePriority(std::string Filename) {
+ CppIncludeHeadersKind CK = getHeadersKind(Filename);
+ switch (CK) {
+ case IHK_KERNELHEADERS:
+ return llvm::StringSwitch<unsigned>(Filename)
+ .Case("<sys/param.h>", 0)
+ .Case("<sys/types.h>", 1)
+ .StartsWith("<sys/", 2)
+ .StartsWith("<uvm/", 3)
+ .StartsWith("<dev/", 7)
+ .Default(1002);
+ case IHK_NETWORKHEADERS:
+ return llvm::StringSwitch<unsigned>(Filename)
+ .StartsWith("<net", 4)
+ .StartsWith("<protocols", 5)
+ .Default(1002);
+ case IHK_FILESYSHEADERS:
+ return 6;
+ case IHK_MACHINESHEADERS:
+ return 8;
+ case IHK_ARCHHEADERS:
+ return 9;
+ case IHK_USERHEADERS:
+ return llvm::StringSwitch<unsigned>(Filename)
+ .StartsWith("<path",11)
+ .Default(10);
+ case IHK_INCLUDESWITHQUOTES:
+ return 12;
+ }
+ return 100;
+}
// Sorts and deduplicate a block of includes given by 'Includes' alphabetically
// adding the necessary replacement to 'Replaces'. 'Includes' must be in strict
@@ -1774,8 +1885,8 @@
static void sortCppIncludes(const FormatStyle &Style,
const SmallVectorImpl<IncludeDirective> &Includes,
ArrayRef<tooling::Range> Ranges, StringRef FileName,
- StringRef Code,
- tooling::Replacements &Replaces, unsigned *Cursor) {
+ StringRef Code, tooling::Replacements &Replaces,
+ unsigned *Cursor) {
unsigned IncludesBeginOffset = Includes.front().Offset;
unsigned IncludesEndOffset =
Includes.back().Offset + Includes.back().Text.size();
@@ -1783,11 +1894,22 @@
if (!affectsRange(Ranges, IncludesBeginOffset, IncludesEndOffset))
return;
SmallVector<unsigned, 16> Indices;
- for (unsigned i = 0, e = Includes.size(); i != e; ++i)
+ SmallVector<unsigned, 16> IncludesPriority;
+ for (unsigned i = 0, e = Includes.size(); i != e; ++i){
+ if(Style.SortIncludesStyle == FormatStyle::SIS_NetBSD)
+ IncludesPriority.push_back(getNetBSDIncludePriority(Includes[i].Filename));
+ else
+ IncludesPriority.push_back(i);
Indices.push_back(i);
+ }
+
llvm::stable_sort(Indices, [&](unsigned LHSI, unsigned RHSI) {
- return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) <
- std::tie(Includes[RHSI].Category, Includes[RHSI].Filename);
+ if (Style.SortIncludesStyle == FormatStyle::SIS_NetBSD)
+ return std::tie(IncludesPriority[LHSI], Includes[LHSI].Filename) <
+ std::tie(IncludesPriority[RHSI], Includes[RHSI].Filename);
+ else
+ return std::tie(Includes[LHSI].Category, Includes[LHSI].Filename) <
+ std::tie(Includes[RHSI].Category, Includes[RHSI].Filename);
});
// The index of the include on which the cursor will be put after
// sorting/deduplicating.
@@ -1906,8 +2028,8 @@
MainIncludeFound = true;
IncludesInBlock.push_back({IncludeName, Line, Prev, Category});
} else if (!IncludesInBlock.empty() && !EmptyLineSkipped) {
- sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
- Replaces, Cursor);
+ sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code,
+ Replaces, Cursor);
IncludesInBlock.clear();
FirstIncludeBlock = false;
}
@@ -1918,8 +2040,8 @@
SearchFrom = Pos + 1;
}
if (!IncludesInBlock.empty()) {
- sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
- Cursor);
+ sortCppIncludes(Style, IncludesInBlock, Ranges, FileName, Code, Replaces,
+ Cursor);
}
return Replaces;
}
Index: include/clang/Format/Format.h
===================================================================
--- include/clang/Format/Format.h
+++ include/clang/Format/Format.h
@@ -1681,6 +1681,15 @@
/// \endcode
bool SortIncludes;
+/// SortIncludes Style.
+ enum IncludeHeadersStyle{
+ ///Sorts includes lexicographically.
+ SIS_None,
+ ///Sorts includes according to NetBSD Style Guide.
+ SIS_NetBSD
+ };
+ IncludeHeadersStyle SortIncludesStyle;
+
/// If ``true``, clang-format will sort using declarations.
///
/// The order of using declarations is defined as follows:
@@ -1995,6 +2004,7 @@
R.PenaltyBreakTemplateDeclaration &&
PointerAlignment == R.PointerAlignment &&
RawStringFormats == R.RawStringFormats &&
+ SortIncludesStyle == R.SortIncludesStyle &&
SpaceAfterCStyleCast == R.SpaceAfterCStyleCast &&
SpaceAfterLogicalNot == R.SpaceAfterLogicalNot &&
SpaceAfterTemplateKeyword == R.SpaceAfterTemplateKeyword &&
@@ -2083,6 +2093,10 @@
/// http://www.gnu.org/prep/standards/standards.html
FormatStyle getGNUStyle();
+/// Returns a format style complying with NetBSD Coding Standards:
+/// http://cvsweb.netbsd.org/bsdweb.cgi/src/share/misc/style?rev=HEAD&content-type=text/x-cvsweb-markup
+FormatStyle getNetBSDStyle();
+
/// Returns style indicating formatting should be not applied at all.
FormatStyle getNoStyle();
Index: docs/ClangFormatStyleOptions.rst
===================================================================
--- docs/ClangFormatStyleOptions.rst
+++ docs/ClangFormatStyleOptions.rst
@@ -2001,6 +2001,10 @@
#include "b.h" vs. #include "a.h"
#include "a.h" #include "b.h"
+**SortNetBSDIncludes** (``bool``)
+ If ``true``, clang-format will sort ``#includes`` according to NetBSD style.
+
+
**SortUsingDeclarations** (``bool``)
If ``true``, clang-format will sort using declarations.
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits