Skip to content
Open
Show file tree
Hide file tree
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
1 change: 1 addition & 0 deletions clang/docs/ClangFormat.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ to format C/C++/Java/JavaScript/JSON/Objective-C/Protobuf/C# code.
--output-replacements-xml - Output replacements as XML.
--qualifier-alignment=<string> - If set, overrides the qualifier alignment style
determined by the QualifierAlignment style flag
-r - Recursively format files in any specified directories
--sort-includes - If set, overrides the include sorting behavior
determined by the SortIncludes style flag
--style=<string> - Set coding style. <string> can be:
Expand Down
1 change: 1 addition & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,7 @@ clang-format
literals.
- Add ``Leave`` suboption to ``IndentPPDirectives``.
- Add ``AllowBreakBeforeQtProperty`` option.
- Add ``-r`` option for recursing into specified directories when formatting.

libclang
--------
Expand Down
21 changes: 21 additions & 0 deletions clang/test/Format/recursive.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
RUN: rm -rf %t && mkdir %t
RUN: split-file %s %t

RUN: clang-format -i -r --verbose %t 2>&1 | FileCheck %s -DDIR=%t -DSEP=%{fs-sep}

CHECK: Formatting [1/4] [[DIR]][[SEP]]1.cpp
CHECK: Formatting [2/4] [[DIR]][[SEP]]2[[SEP]]3.cpp
CHECK: Formatting [3/4] [[DIR]][[SEP]]2[[SEP]]4[[SEP]]5.cpp
CHECK: Formatting [4/4] [[DIR]][[SEP]]2[[SEP]]6.cpp

#--- 1.cpp
int x;

#--- 2/3.cpp
int x;

#--- 2/4/5.cpp
int x;

#--- 2/6.cpp
int x;
30 changes: 30 additions & 0 deletions clang/tools/clang-format/ClangFormat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@ static cl::opt<std::string> Files(
cl::desc("A file containing a list of files to process, one per line."),
cl::value_desc("filename"), cl::init(""), cl::cat(ClangFormatCategory));

static cl::opt<bool>
Recursive("r",
cl::desc("Recursively format files in any specified directories"),
cl::cat(ClangFormatCategory));

static cl::opt<bool>
Verbose("verbose", cl::desc("If set, shows the list of processed files"),
cl::cat(ClangFormatCategory));
Expand Down Expand Up @@ -700,6 +705,31 @@ int main(int argc, const char **argv) {
errs() << "Clang-formatting " << LineNo << " files\n";
}

if (Recursive) {
SmallVector<std::string> ExpandedNames;
for (const std::string &Path : FileNames) {
if (sys::fs::is_directory(Path)) {
std::error_code ErrorCode;
for (sys::fs::recursive_directory_iterator I(Path, ErrorCode), E;
I != E && !ErrorCode; I.increment(ErrorCode)) {
bool Result = false;
ErrorCode = sys::fs::is_regular_file(I->path(), Result);
// Conservatively assume that any unopenable entries are also regular
// files. Later code will emit an error when trying to format them, if
// they aren't valid by then.
if (ErrorCode || Result)
ExpandedNames.push_back(I->path());
}
} else {
ExpandedNames.push_back(std::move(Path));
}
}

FileNames.clear();
for (const std::string &Name : ExpandedNames)
FileNames.push_back(Name);
}

if (FileNames.empty()) {
if (isIgnored(AssumeFileName))
return 0;
Expand Down