clang-format.bash 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #!/usr/bin/env bash
  2. #=============================================================================
  3. # Copyright 2015-2016 Kitware, Inc.
  4. #
  5. # Licensed under the Apache License, Version 2.0 (the "License");
  6. # you may not use this file except in compliance with the License.
  7. # You may obtain a copy of the License at
  8. #
  9. # http://www.apache.org/licenses/LICENSE-2.0
  10. #
  11. # Unless required by applicable law or agreed to in writing, software
  12. # distributed under the License is distributed on an "AS IS" BASIS,
  13. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. # See the License for the specific language governing permissions and
  15. # limitations under the License.
  16. #=============================================================================
  17. usage='usage: clang-format.bash [<options>] [--]
  18. --help Print usage plus more detailed help.
  19. --clang-format <tool> Use given clang-format tool.
  20. --amend Filter files changed by HEAD.
  21. --cached Filter files locally staged for commit.
  22. --modified Filter files locally modified from HEAD.
  23. --tracked Filter files tracked by Git.
  24. '
  25. help="$usage"'
  26. Example to format locally modified files:
  27. Utilities/Scripts/clang-format.bash --modified
  28. Example to format locally modified files staged for commit:
  29. Utilities/Scripts/clang-format.bash --cached
  30. Example to format files modified by the most recent commit:
  31. Utilities/Scripts/clang-format.bash --amend
  32. Example to format all files:
  33. Utilities/Scripts/clang-format.bash --tracked
  34. Example to format the current topic:
  35. git filter-branch \
  36. --tree-filter "Utilities/Scripts/clang-format.bash --tracked" \
  37. master..
  38. '
  39. die() {
  40. echo "$@" 1>&2; exit 1
  41. }
  42. #-----------------------------------------------------------------------------
  43. # Parse command-line arguments.
  44. clang_format=''
  45. mode=''
  46. while test "$#" != 0; do
  47. case "$1" in
  48. --amend) mode="amend" ;;
  49. --cached) mode="cached" ;;
  50. --clang-format) shift; clang_format="$1" ;;
  51. --help) echo "$help"; exit 0 ;;
  52. --modified) mode="modified" ;;
  53. --tracked) mode="tracked" ;;
  54. --) shift ; break ;;
  55. -*) die "$usage" ;;
  56. *) break ;;
  57. esac
  58. shift
  59. done
  60. test "$#" = 0 || die "$usage"
  61. # Find a default tool.
  62. tools='
  63. clang-format
  64. clang-format-3.8
  65. '
  66. if test "x$clang_format" = "x"; then
  67. for tool in $tools; do
  68. if type -p "$tool" >/dev/null; then
  69. clang_format="$tool"
  70. break
  71. fi
  72. done
  73. fi
  74. # Verify that we have a tool.
  75. if ! type -p "$clang_format" >/dev/null; then
  76. echo "Unable to locate '$clang_format'"
  77. exit 1
  78. fi
  79. # Select listing mode.
  80. case "$mode" in
  81. '') echo "$usage"; exit 0 ;;
  82. amend) git_ls='git diff-tree --diff-filter=AM --name-only HEAD -r --no-commit-id' ;;
  83. cached) git_ls='git diff-index --diff-filter=AM --name-only HEAD --cached' ;;
  84. modified) git_ls='git diff-index --diff-filter=AM --name-only HEAD' ;;
  85. tracked) git_ls='git ls-files' ;;
  86. *) die "invalid mode: $mode" ;;
  87. esac
  88. # Filter sources to which our style should apply.
  89. $git_ls -z -- '*.c' '*.cc' '*.cpp' '*.cxx' '*.h' '*.hh' '*.hpp' '*.hxx' |
  90. # Exclude lexer/parser generator input and output.
  91. egrep -z -v '^Source/cmCommandArgumentLexer\.' |
  92. egrep -z -v '^Source/cmCommandArgumentParser(\.y|\.cxx|Tokens\.h)' |
  93. egrep -z -v '^Source/cmDependsJavaLexer\.' |
  94. egrep -z -v '^Source/cmDependsJavaParser(\.y|\.cxx|Tokens\.h)' |
  95. egrep -z -v '^Source/cmExprLexer\.' |
  96. egrep -z -v '^Source/cmExprParser(\.y|\.cxx|Tokens\.h)' |
  97. egrep -z -v '^Source/cmFortranLexer\.' |
  98. egrep -z -v '^Source/cmFortranParser(\.y|\.cxx|Tokens\.h)' |
  99. egrep -z -v '^Source/cmListFileLexer(\.in\.l|\.c)' |
  100. # Exclude third-party sources.
  101. egrep -z -v '^Source/(cm_sha2|bindexplib)' |
  102. egrep -z -v '^Source/(kwsys|CursesDialog/form)/' |
  103. egrep -z -v '^Utilities/(KW|cm).*/' |
  104. # Exclude reference content.
  105. egrep -z -v '^Tests/RunCMake/GenerateExportHeader/reference/' |
  106. # Exclude manually-formatted sources (e.g. with long lines).
  107. egrep -z -v '^Tests/PositionIndependentTargets/pic_test.h' |
  108. # Exclude sources with encoding not suported by clang-format.
  109. egrep -z -v '^Tests/RunCMake/CommandLine/cmake_depends/test_UTF-16LE.h' |
  110. # Update sources in-place.
  111. xargs -0 "$clang_format" -i