We recently learned how to use
clang-format and created our own formatting style.
Today I'd like to show you some of the scripts I use to wrap
clang-format for different purposes. For any non-trivial use of
clang-format, you probably want to use a wrapper.
Some Notes on Options
You'll see some common arguments used in the script samples below, so I want to explain them up front.
style argument below always indicates that I want to pull my formatting rules from the
.clang-format file in my repository:
I use the in-place argument to indicate that I want files to be modified:
I also set the
none so that
clang-format will fail if there is no
.clang-format file in the tree.
Formatting all C and C++ Files in a Repo
In this example, I use the
find command to get all the
.cpp files in my tree. The list of files is then passed to
#!/bin/bash find . -iname *.h -o -iname *.c -o -iname *.cpp -o -iname *.hpp \ | xargs clang-format -style=file -i -fallback-style=none exit 0
Formatting all C and C++ Files in a Repo, with Exclusions
In this example, I supply a list of directory paths to
find that I want excluded from my list. This is useful for handling parts of the source tree that you don't want to reformat, such as external libraries.
#!/bin/bash find . -type d \( -path ./lib/external -o -path ./os -o -path ./lib/libc -o -path ./lib/libmemory \) -prune \ -o -iname *.h -o -iname *.c -o -iname *.cpp -o -iname *.hpp \ | xargs clang-format -style=file -i -fallback-style=none exit 0
Formatting all C and C++ Files in a Directory
This example uses the
find command with a directory name supplied as a script argument. All source files in that directory will be formatted.
#!/bin/bash if [ -z "$1" ] then echo "Please supply a directory or path with this script." exit 1 fi find $1 -iname *.h -o -iname *.c -o -iname *.cpp -o -iname *.hpp \ | xargs clang-format -style=file -i -fallback-style=none exit 0
Format a List of Files (Supplied as Arguments)
This example allows you to provide a list of files as an argument to the script. Arguments are simply forwarded to
#!/bin/bash # This script propagates all arguments to the clang-format command clang-format -style=file -i -fallback-style=none $@ exit 0
Format Files in a
This example gets the list of modified files from
git ls-files and formats them. This is a useful script to run as a pre-commit exercise.
#!/bin/bash clang-format -style=file -fallback-style=none -i `git ls-files -om "*.[ch]" "*.[hc]pp"` exit 0
clang-format and Create a Patch
This example is used by my continuous integration build to verify formatting compliance. After
clang-format is run, we use
git diff to generate a patch file. If the file is empty, formatting is OK and we delete the file. The build server uses the presence of the patch file to determine if formatting should pass or fail.
#!/bin/bash find . -iname *.h -o -iname *.c -o -iname *.cpp -o -iname *.hpp \ | xargs clang-format -style=file -i -fallback-style=none git diff > clang_format.patch # Delete if 0 size if [ ! -s clang_format.patch ] then rm clang_format.patch fi exit 0 exit 0