]> https://gitweb.dealii.org/ - dealii.git/commitdiff
contrib/utilities/indent: Reorganize script
authorMatthias Maier <tamiko@43-1.org>
Thu, 14 Jun 2018 20:02:39 +0000 (15:02 -0500)
committerMatthias Maier <tamiko@43-1.org>
Thu, 14 Jun 2018 23:29:33 +0000 (18:29 -0500)
This commit

 - reorganizes the core indenting logic into a indent_common.sh file

 - cleans up find and indenting logic to make everything more readable

 - prepares for more specialized indent versions (see #6673)

contrib/utilities/indent
contrib/utilities/indent_common.sh [new file with mode: 0644]

index fdd3e38c575e005cd9aa5d3fdc3aa178cf2ff07a..a33e7be7e6f907bdddc17f77aed6bd3e372735ee 100755 (executable)
 # While we're already touching every file, this script also makes
 # sure we set permissions correctly
 #
-# The script needs to be executed as 
+# The script needs to be executed as
 #   ./contrib/utilities/indent
 # from the top-level directory of the source tree, or via
 #   make indent
 # from a build directory.
 #
 
-if test ! -d source -o ! -d include -o ! -d examples ; then
+if [ ! -f contrib/utilities/indent_common.sh ]; then
   echo "*** This script must be run from the top-level directory of deal.II."
   exit 1
 fi
 
-# Add the location 'download_clang_format' or 'compile_clang_format'
-# installs clang-format to to the local PATH.
-CLANG_FORMAT_PATH="$(cd "$(dirname "$0")" && pwd)/programs/clang-6/bin"
-export PATH="${CLANG_FORMAT_PATH}:${PATH}"
-
-if ! [ -x "$(command -v clang-format)" ]; then
-  echo "*** No clang-format program found."
-  echo "***"
-  echo "*** You can run the 'download_clang_format' script or the"
-  echo "*** 'compile_clang_format' script for obtaining a compatible"
-  echo "*** binary and installing to an appropriate directory."
-  exit 1
-fi
-
-# Make sure to have the right version. We know that clang-6.0.0
-# and clang-6.0.1 work. Hence, test for clang-6.0.
-CLANG_FORMAT_VERSION="$(clang-format --version)"
-CLANG_FORMAT_MAJOR_VERSION=$(echo "${CLANG_FORMAT_VERSION}" | sed 's/^[^0-9]*\([0-9]*\).*$/\1/g')
-CLANG_FORMAT_MINOR_VERSION=$(echo "${CLANG_FORMAT_VERSION}" | sed 's/^[^0-9]*[0-9]*\.\([0-9]*\).*$/\1/g')
-
-if [ "${CLANG_FORMAT_MAJOR_VERSION}" -ne 6 ] || [ "${CLANG_FORMAT_MINOR_VERSION}" -ne 0 ]; then
-  echo "*** Found a version of clang-format different than the required version 6.0."
-  exit 1
-fi
+source contrib/utilities/indent_common.sh
 
 #
-# Collect all header and source files and process them in batches of 50
-# files with up to 10 in parallel
-#
-# The command line is a bit complicated, so let's discuss the more
-# complicated arguments:
-# - For 'find', -print0 makes sure that file names are separated by \0
-#   characters, as opposed to the default \n. That's because, surprisingly,
-#   \n is a valid character in a file name, whereas \0 is not -- so it
-#   serves as a good candidate to separate individual file names.
-# - For 'xargs', -0 does the opposite: it separates filenames that are
-#   delimited by \0
-# - -n 50 calls the following script with up to 50 file names at a time
-# - -P 10 calls the following script up to 10 times in parallel
-#
-find tests include source examples \
-  \( -name '*.cc' -o -name '*.h' -o -name '*.cu' -o -name '*.cuh' \) -print0 |
-  xargs -0 -n 50 -P 10 clang-format -i
-
-#
-# Use the same process to set file permissions for all source files.
+# Run sanity checks:
 #
 
-find tests include source examples \
-  \( -name '*.cc' -o -name '*.h' -o -name '*.cu' -o -name '*.cuh' \) -print0 |
-  xargs -0 -n 50 -P 10 chmod 644
+checks
 
 #
-# Convert DOS formatted files to unix file format by stripping out
-# carriage returns (15=0x0D):
+# Process all source and header files:
 #
 
-dos_to_unix()
-{
-  f=$1
-  tr -d '\015' <"$f" >"$f.tmp"
-  diff -q "$f" "$f.tmp" >/dev/null || mv "$f.tmp" "$f"
-  rm -f "$f.tmp"
-}
-export -f dos_to_unix
-
-find tests include source examples \
-  \( -name '*.cc' -o -name '*.h' -o -name '*.cu' -o -name '*.cuh' \) -print0 |
-  xargs -0 -n 1 -P 10 -I {} bash -c 'dos_to_unix "$@"' _ {}
+process "tests include source examples" ".*\.(cc|h|cu|cuh)" format_file
+process "source" ".*\.inst.in" format_inst
 
 #
-# Format .inst.in files. We need to replace \{ and \} by a sentinel because
-# clang-format happily strips away the backslash. Further, there is a minor
-# caveat: clang-format automatically renames a comment after a closing
-# bracket for a namespace to "} // namespace FooBar". Thus use "namespace"
-# as keyword:
+# Fix permissions and convert to unix line ending if necessary:
 #
 
-format_inst()
-{
-    f=$1
-    cp "$f" "$f.tmp"
-    sed -i.orig 's#\\{#{ // namespace#g' "$f.tmp"
-    sed -i.orig 's#\\}#} // namespace#g' "$f.tmp"
-    clang-format -i "$f.tmp"
-    sed -i.orig 's#{ // namespace#\\{#g' "$f.tmp"
-    sed -i.orig 's#}[ ]*// namespace.*#\\}#g' "$f.tmp"
-    if ! diff -q "$f" "$f.tmp" >/dev/null
-    then
-      cp "$f.tmp" "$f"
-    fi
-    rm "$f.tmp" "$f.tmp.orig"
-}
-export -f format_inst
+process "tests include source examples" \
+  ".*\.(cc|h|cu|cuh|inst.in|output.*|cmake)" fix_permissions
 
-#
-# Now do the formatting. The arguments are as discussed above, plus the
-# following:
-# - '-n 1' implies that the following script is called for each file
-#  individually
-# - '-I {}' tells 'xargs' to substitute '{}' in the following by the
-#   one file name we process at a time
-# - 'bash -c' executes the command that follows. Here, this is
-#   'format_inst "$@"' where 'format_inst' is the macro exported
-#   above, and '$@' expands to the list of arguments passed on the
-#   command line, starting at $1. Because we execute a command with
-#   -c, there is no $0 for this bash invokation, and if we just had
-#   {} following the argument of -c, then the first element of that
-#   list would be ignored. To avoid this, we need a dummy argument
-#   to take the role of $0 so that {} can be expanded into $1. We
-#   simply use '_' here, but any other string would do fine as well.
-#
-find source -name '*.inst.in' -print0 |
-  xargs -0 -n 1 -P 10 -I {} bash -c 'format_inst "$@"' _ {}
+process "tests include source examples" \
+  ".*\.(cc|h|cu|cuh|inst.in|output.*|cmake)" dos_to_unix
diff --git a/contrib/utilities/indent_common.sh b/contrib/utilities/indent_common.sh
new file mode 100644 (file)
index 0000000..48450ff
--- /dev/null
@@ -0,0 +1,173 @@
+#!/bin/bash
+## ---------------------------------------------------------------------
+##
+## Copyright (C) 2018 by the deal.II authors
+##
+## This file is part of the deal.II library.
+##
+## The deal.II library is free software; you can use it, redistribute
+## it, and/or modify it under the terms of the GNU Lesser General
+## Public License as published by the Free Software Foundation; either
+## version 2.1 of the License, or (at your option) any later version.
+## The full text of the license can be found in the file LICENSE at
+## the top level of the deal.II distribution.
+##
+## ---------------------------------------------------------------------
+
+#
+# This file contains a number of common functions used all indent scripts
+#
+
+#
+# This function checks that we are in the root directory and that
+# clang-format is available. It is called by both indent and indent-branch
+# to ensure that the rest of the indentation pipeline makes sense.
+#
+
+checks() {
+  if test ! -d source -o ! -d include -o ! -d examples ; then
+    echo "*** This script must be run from the top-level directory of deal.II."
+    exit 1
+  fi
+
+  # Add the location 'download_clang_format' or 'compile_clang_format'
+  # installs clang-format to to the local PATH.
+  CLANG_FORMAT_PATH="$(cd "$(dirname "$0")" && pwd)/programs/clang-6/bin"
+  export PATH="${CLANG_FORMAT_PATH}:${PATH}"
+
+  if ! [ -x "$(command -v clang-format)" ]; then
+    echo "*** No clang-format program found."
+    echo "***"
+    echo "*** You can run the 'download_clang_format' script or the"
+    echo "*** 'compile_clang_format' script for obtaining a compatible"
+    echo "*** binary and installing to an appropriate directory."
+    exit 1
+  fi
+
+  # Make sure to have the right version. We know that clang-6.0.0
+  # and clang-6.0.1 work. Hence, test for clang-6.0.
+  CLANG_FORMAT_VERSION="$(clang-format --version)"
+  CLANG_FORMAT_MAJOR_VERSION=$(echo "${CLANG_FORMAT_VERSION}" | sed 's/^[^0-9]*\([0-9]*\).*$/\1/g')
+  CLANG_FORMAT_MINOR_VERSION=$(echo "${CLANG_FORMAT_VERSION}" | sed 's/^[^0-9]*[0-9]*\.\([0-9]*\).*$/\1/g')
+
+  if [ "${CLANG_FORMAT_MAJOR_VERSION}" -ne 6 ] || [ "${CLANG_FORMAT_MINOR_VERSION}" -ne 0 ]; then
+    echo "*** Found a version of clang-format different than the required version 6.0."
+    exit 1
+  fi
+}
+
+#
+# Mac OSX's mktemp doesn't know the --tmpdir option without argument. So,
+# let's do all of that by hand:
+#
+export TMPDIR="${TMPDIR:-/tmp}"
+
+#
+# In order to format .cc and .h files we have to make sure that we override
+# the source/header file only if the actual contents changed.
+# Unfortunately, clang-format isn't exactly helpful there. Thus, use a
+# temporary file and diff as a workaround.
+#
+
+format_file()
+{
+  file="${1}"
+  tmpfile="$(mktemp "${TMPDIR}/$(basename "$1").tmp.XXXXXXXX")"
+
+  clang-format "${file}" > "${tmpfile}"
+  diff -q "${file}" "${tmpfile}" >/dev/null || mv "${tmpfile}" "${file}"
+  rm -f "${tmpfile}"
+}
+export -f format_file
+
+#
+# In order to format .inst.in files, we need to replace \{ and \} by a
+# sentinel because clang-format happily strips away the backslash. Further,
+# there is a minor caveat: clang-format automatically renames a comment
+# after a closing bracket for a namespace to "} // namespace FooBar". Thus
+# use "namespace" as keyword:
+#
+
+format_inst()
+{
+  file="${1}"
+  tmpfile="$(mktemp "${TMPDIR}/$(basename "$1").tmp.XXXXXXXX")"
+
+  cp "${file}" "${tmpfile}"
+  sed -i -e 's#\\{#{ // namespace#g' -e 's#\\}#} // namespace#g' "${tmpfile}"
+
+  #
+  # Yes, we have to call clang-format in this weird way to ensure that it
+  # picks up and uses the .clang-format style-sheet in the current
+  # directory.
+  #
+  clang-format < "${tmpfile}" > "${tmpfile}new"
+
+  sed -i -e 's#{ // namespace#\\{#g' -e 's#}[ ]*// namespace.*#\\}#g' \
+    "${tmpfile}new"
+
+  diff -q "${file}" "${tmpfile}new" >/dev/null || mv "${tmpfile}new" "${file}"
+  rm -f "${tmpfile}" "${tmpfile}new"
+}
+export -f format_inst
+
+#
+# Convert DOS formatted files to unix file format by stripping out
+# carriage returns (15=0x0D):
+#
+
+dos_to_unix()
+{
+  file="${1}"
+  tmpfile="$(mktemp "${TMPDIR}/$(basename "$1").tmp.XXXXXXXX")"
+
+  tr -d '\015' <"${file}" >"${tmpfile}"
+  diff -q "${file}" "${tmpfile}" >/dev/null || mv "${tmpfile}" "${file}"
+  rm -f "${tmpfile}"
+}
+export -f dos_to_unix
+
+#
+# Fix permissions
+#
+
+fix_permissions()
+{
+  file="${1}"
+
+  chmod 644 "${file}"
+}
+export -f fix_permissions
+
+#
+# Collect all files found in a list of directories "${1}$" matching a
+# regular expression "${2}$", and process them with a command "${3}" on 10
+# threads in parallel.
+#
+# The command line is a bit complicated, so let's discuss the more
+# complicated arguments:
+# - For 'find', -print0 makes sure that file names are separated by \0
+#   characters, as opposed to the default \n. That's because, surprisingly,
+#   \n is a valid character in a file name, whereas \0 is not -- so it
+#   serves as a good candidate to separate individual file names.
+# - For 'xargs', -0 does the opposite: it separates filenames that are
+#   delimited by \0
+# - the options "-n 1 -P 10" make sure that the following script with be
+#   called exactly with one file name as argument at a time, but we allow
+#   execution for up to 10 times in parallel
+#
+
+process()
+{
+  case "${OSTYPE}" in
+    darwin*)
+      find -E ${1} -regex "${2}" -print0 |
+        xargs -0 -n 1 -P 10 -I {} bash -c "${3} {}"
+      ;;
+    *)
+      find ${1} -regextype egrep -regex "${2}" -print0 |
+        xargs -0 -n 1 -P 10 -I {} bash -c "${3} {}"
+      ;;
+  esac
+}
+

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.