diff options
author | Thomas Haller <thaller@redhat.com> | 2023-07-25 12:09:01 (GMT) |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2023-07-25 13:34:44 (GMT) |
commit | 45c7aae37960ac973afb69d3fd9b91694972b68c (patch) | |
tree | 9c04be13cce46033cd1ad241aabb93fabcfa843e /tools | |
parent | 5a21bde6ae90cab25c6d14199bb506fc30074015 (diff) | |
download | libnl-45c7aae37960ac973afb69d3fd9b91694972b68c.zip libnl-45c7aae37960ac973afb69d3fd9b91694972b68c.tar.gz libnl-45c7aae37960ac973afb69d3fd9b91694972b68c.tar.bz2 |
clang-format: add "tools/clang-format.sh" script
Historically is libnl3 not formatted with clang-format, as the project
is old.
However, we have a mostly usable ".clang-format" file. Also, various new
files follow the automated formatting.
Add a script for helping with the reformatting.
Also, the script has an exclude list for files that should not be
formatted. That means, new files will be required to follow the
formatting. That is considered a benefit.
Diffstat (limited to 'tools')
-rwxr-xr-x | tools/clang-format.sh | 557 |
1 files changed, 557 insertions, 0 deletions
diff --git a/tools/clang-format.sh b/tools/clang-format.sh new file mode 100755 index 0000000..992a810 --- /dev/null +++ b/tools/clang-format.sh @@ -0,0 +1,557 @@ +#!/bin/bash + +set -e + +die() { + printf '%s\n' "$*" >&2 + exit 1 +} + +EXCLUDE_PATHS_TOPLEVEL=( + "include/linux-private" +) + +# The following files are currently not formatted with clang. +# Exclude them too. +EXCLUDE_PATHS_TOPLEVEL+=( + "include/netlink-private/cache-api.h" + "include/netlink-private/genl.h" + "include/netlink-private/netlink.h" + "include/netlink-private/nl-auto.h" + "include/netlink-private/object-api.h" + "include/netlink-private/route/link/api.h" + "include/netlink-private/route/link/sriov.h" + "include/netlink-private/route/mpls.h" + "include/netlink-private/route/nexthop-encap.h" + "include/netlink-private/route/tc-api.h" + "include/netlink-private/socket.h" + "include/netlink-private/tc.h" + "include/netlink-private/types.h" + "include/netlink-private/utils.h" + "include/netlink/addr.h" + "include/netlink/attr.h" + "include/netlink/cache-api.h" + "include/netlink/cache.h" + "include/netlink/cli/addr.h" + "include/netlink/cli/cls.h" + "include/netlink/cli/link.h" + "include/netlink/cli/mdb.h" + "include/netlink/cli/neigh.h" + "include/netlink/cli/qdisc.h" + "include/netlink/cli/route.h" + "include/netlink/cli/tc.h" + "include/netlink/cli/utils.h" + "include/netlink/data.h" + "include/netlink/errno.h" + "include/netlink/fib_lookup/lookup.h" + "include/netlink/fib_lookup/request.h" + "include/netlink/genl/ctrl.h" + "include/netlink/genl/family.h" + "include/netlink/genl/genl.h" + "include/netlink/genl/mngt.h" + "include/netlink/handlers.h" + "include/netlink/hash.h" + "include/netlink/hashtable.h" + "include/netlink/idiag/idiagnl.h" + "include/netlink/idiag/meminfo.h" + "include/netlink/idiag/msg.h" + "include/netlink/idiag/req.h" + "include/netlink/idiag/vegasinfo.h" + "include/netlink/list.h" + "include/netlink/msg.h" + "include/netlink/netfilter/ct.h" + "include/netlink/netfilter/exp.h" + "include/netlink/netfilter/log.h" + "include/netlink/netfilter/log_msg.h" + "include/netlink/netfilter/netfilter.h" + "include/netlink/netfilter/nfnl.h" + "include/netlink/netfilter/queue.h" + "include/netlink/netfilter/queue_msg.h" + "include/netlink/netlink-compat.h" + "include/netlink/netlink-kernel.h" + "include/netlink/netlink.h" + "include/netlink/object.h" + "include/netlink/route/act/skbedit.h" + "include/netlink/route/action.h" + "include/netlink/route/addr.h" + "include/netlink/route/class.h" + "include/netlink/route/classifier.h" + "include/netlink/route/cls/basic.h" + "include/netlink/route/cls/cgroup.h" + "include/netlink/route/cls/ematch.h" + "include/netlink/route/cls/ematch/cmp.h" + "include/netlink/route/cls/ematch/meta.h" + "include/netlink/route/cls/ematch/nbyte.h" + "include/netlink/route/cls/ematch/text.h" + "include/netlink/route/cls/flower.h" + "include/netlink/route/cls/fw.h" + "include/netlink/route/cls/matchall.h" + "include/netlink/route/cls/police.h" + "include/netlink/route/cls/u32.h" + "include/netlink/route/link.h" + "include/netlink/route/link/api.h" + "include/netlink/route/link/bonding.h" + "include/netlink/route/link/bridge.h" + "include/netlink/route/link/can.h" + "include/netlink/route/link/geneve.h" + "include/netlink/route/link/inet.h" + "include/netlink/route/link/inet6.h" + "include/netlink/route/link/info-api.h" + "include/netlink/route/link/ip6gre.h" + "include/netlink/route/link/ip6tnl.h" + "include/netlink/route/link/ip6vti.h" + "include/netlink/route/link/ipgre.h" + "include/netlink/route/link/ipip.h" + "include/netlink/route/link/ipvlan.h" + "include/netlink/route/link/ipvti.h" + "include/netlink/route/link/macsec.h" + "include/netlink/route/link/macvlan.h" + "include/netlink/route/link/macvtap.h" + "include/netlink/route/link/ppp.h" + "include/netlink/route/link/sit.h" + "include/netlink/route/link/sriov.h" + "include/netlink/route/link/team.h" + "include/netlink/route/link/vlan.h" + "include/netlink/route/link/vxlan.h" + "include/netlink/route/link/xfrmi.h" + "include/netlink/route/mdb.h" + "include/netlink/route/neighbour.h" + "include/netlink/route/neightbl.h" + "include/netlink/route/netconf.h" + "include/netlink/route/nexthop.h" + "include/netlink/route/pktloc.h" + "include/netlink/route/qdisc.h" + "include/netlink/route/qdisc/cbq.h" + "include/netlink/route/qdisc/dsmark.h" + "include/netlink/route/qdisc/fifo.h" + "include/netlink/route/qdisc/fq_codel.h" + "include/netlink/route/qdisc/hfsc.h" + "include/netlink/route/qdisc/htb.h" + "include/netlink/route/qdisc/mqprio.h" + "include/netlink/route/qdisc/netem.h" + "include/netlink/route/qdisc/plug.h" + "include/netlink/route/qdisc/prio.h" + "include/netlink/route/qdisc/red.h" + "include/netlink/route/qdisc/sfq.h" + "include/netlink/route/route.h" + "include/netlink/route/rtnl.h" + "include/netlink/route/rule.h" + "include/netlink/route/tc-api.h" + "include/netlink/route/tc.h" + "include/netlink/socket.h" + "include/netlink/types.h" + "include/netlink/utils.h" + "include/netlink/xfrm/ae.h" + "include/netlink/xfrm/lifetime.h" + "include/netlink/xfrm/sa.h" + "include/netlink/xfrm/selector.h" + "include/netlink/xfrm/sp.h" + "include/netlink/xfrm/template.h" + "lib/addr.c" + "lib/attr.c" + "lib/cache.c" + "lib/cache_mngr.c" + "lib/cache_mngt.c" + "lib/cli/cls/basic.c" + "lib/cli/cls/cgroup.c" + "lib/cli/qdisc/bfifo.c" + "lib/cli/qdisc/blackhole.c" + "lib/cli/qdisc/fq_codel.c" + "lib/cli/qdisc/hfsc.c" + "lib/cli/qdisc/htb.c" + "lib/cli/qdisc/ingress.c" + "lib/cli/qdisc/pfifo.c" + "lib/cli/qdisc/plug.c" + "lib/data.c" + "lib/error.c" + "lib/fib_lookup/lookup.c" + "lib/fib_lookup/request.c" + "lib/genl/ctrl.c" + "lib/genl/family.c" + "lib/genl/genl.c" + "lib/genl/mngt.c" + "lib/handlers.c" + "lib/hash.c" + "lib/hashtable.c" + "lib/idiag/idiag.c" + "lib/idiag/idiag_meminfo_obj.c" + "lib/idiag/idiag_msg_obj.c" + "lib/idiag/idiag_req_obj.c" + "lib/idiag/idiag_vegasinfo_obj.c" + "lib/mpls.c" + "lib/msg.c" + "lib/netfilter/ct.c" + "lib/netfilter/ct_obj.c" + "lib/netfilter/exp.c" + "lib/netfilter/exp_obj.c" + "lib/netfilter/log.c" + "lib/netfilter/log_msg.c" + "lib/netfilter/log_msg_obj.c" + "lib/netfilter/log_obj.c" + "lib/netfilter/netfilter.c" + "lib/netfilter/nfnl.c" + "lib/netfilter/queue.c" + "lib/netfilter/queue_msg.c" + "lib/netfilter/queue_msg_obj.c" + "lib/netfilter/queue_obj.c" + "lib/nl.c" + "lib/object.c" + "lib/route/act.c" + "lib/route/act/gact.c" + "lib/route/act/mirred.c" + "lib/route/act/skbedit.c" + "lib/route/act/vlan.c" + "lib/route/addr.c" + "lib/route/class.c" + "lib/route/classid.c" + "lib/route/cls.c" + "lib/route/cls/basic.c" + "lib/route/cls/cgroup.c" + "lib/route/cls/ematch.c" + "lib/route/cls/ematch/cmp.c" + "lib/route/cls/ematch/container.c" + "lib/route/cls/ematch/meta.c" + "lib/route/cls/ematch/nbyte.c" + "lib/route/cls/ematch/text.c" + "lib/route/cls/flower.c" + "lib/route/cls/fw.c" + "lib/route/cls/mall.c" + "lib/route/cls/police.c" + "lib/route/cls/u32.c" + "lib/route/link.c" + "lib/route/link/api.c" + "lib/route/link/bonding.c" + "lib/route/link/bridge.c" + "lib/route/link/can.c" + "lib/route/link/dummy.c" + "lib/route/link/geneve.c" + "lib/route/link/ifb.c" + "lib/route/link/inet.c" + "lib/route/link/inet6.c" + "lib/route/link/ip6gre.c" + "lib/route/link/ip6tnl.c" + "lib/route/link/ip6vti.c" + "lib/route/link/ipgre.c" + "lib/route/link/ipip.c" + "lib/route/link/ipvlan.c" + "lib/route/link/ipvti.c" + "lib/route/link/macsec.c" + "lib/route/link/macvlan.c" + "lib/route/link/ppp.c" + "lib/route/link/sit.c" + "lib/route/link/sriov.c" + "lib/route/link/team.c" + "lib/route/link/veth.c" + "lib/route/link/vlan.c" + "lib/route/link/vrf.c" + "lib/route/link/vxlan.c" + "lib/route/link/xfrmi.c" + "lib/route/mdb.c" + "lib/route/neigh.c" + "lib/route/netconf.c" + "lib/route/nexthop.c" + "lib/route/nexthop_encap.c" + "lib/route/nh_encap_mpls.c" + "lib/route/pktloc.c" + "lib/route/qdisc.c" + "lib/route/qdisc/blackhole.c" + "lib/route/qdisc/cbq.c" + "lib/route/qdisc/dsmark.c" + "lib/route/qdisc/fifo.c" + "lib/route/qdisc/fq_codel.c" + "lib/route/qdisc/hfsc.c" + "lib/route/qdisc/htb.c" + "lib/route/qdisc/ingress.c" + "lib/route/qdisc/mqprio.c" + "lib/route/qdisc/netem.c" + "lib/route/qdisc/plug.c" + "lib/route/qdisc/prio.c" + "lib/route/qdisc/red.c" + "lib/route/qdisc/sfq.c" + "lib/route/qdisc/tbf.c" + "lib/route/route.c" + "lib/route/route_obj.c" + "lib/route/route_utils.c" + "lib/route/rtnl.c" + "lib/route/rule.c" + "lib/route/tc.c" + "lib/socket.c" + "lib/utils.c" + "lib/version.c" + "lib/xfrm/ae.c" + "lib/xfrm/lifetime.c" + "lib/xfrm/sa.c" + "lib/xfrm/selector.c" + "lib/xfrm/sp.c" + "lib/xfrm/template.c" + "python/netlink/utils.h" + "src/genl-ctrl-list.c" + "src/idiag-socket-details.c" + "src/lib/addr.c" + "src/lib/cls.c" + "src/lib/ct.c" + "src/lib/exp.c" + "src/lib/link.c" + "src/lib/neigh.c" + "src/lib/route.c" + "src/lib/tc.c" + "src/lib/utils.c" + "src/nf-ct-add.c" + "src/nf-ct-events.c" + "src/nf-ct-list.c" + "src/nf-exp-add.c" + "src/nf-exp-delete.c" + "src/nf-exp-list.c" + "src/nf-log.c" + "src/nf-monitor.c" + "src/nf-queue.c" + "src/nl-addr-add.c" + "src/nl-addr-delete.c" + "src/nl-addr-list.c" + "src/nl-class-add.c" + "src/nl-class-delete.c" + "src/nl-class-list.c" + "src/nl-classid-lookup.c" + "src/nl-cls-add.c" + "src/nl-cls-delete.c" + "src/nl-cls-list.c" + "src/nl-fib-lookup.c" + "src/nl-link-enslave.c" + "src/nl-link-list.c" + "src/nl-link-release.c" + "src/nl-link-set.c" + "src/nl-link-stats.c" + "src/nl-list-caches.c" + "src/nl-list-sockets.c" + "src/nl-monitor.c" + "src/nl-neigh-add.c" + "src/nl-neigh-delete.c" + "src/nl-neigh-list.c" + "src/nl-neightbl-list.c" + "src/nl-pktloc-lookup.c" + "src/nl-qdisc-add.c" + "src/nl-qdisc-delete.c" + "src/nl-qdisc-list.c" + "src/nl-route-add.c" + "src/nl-route-delete.c" + "src/nl-route-get.c" + "src/nl-route-list.c" + "src/nl-rule-list.c" + "src/nl-tctree-list.c" + "src/nl-util-addr.c" + "tests/nl-test-util.h" + "tests/test-cache-mngr.c" + "tests/test-complex-HTB-with-hash-filters.c" + "tests/test-create-bridge.c" + "tests/test-create-geneve.c" + "tests/test-create-ip6tnl.c" + "tests/test-create-ipgre.c" + "tests/test-create-ipgretap.c" + "tests/test-create-ipip.c" + "tests/test-create-ipvti.c" + "tests/test-create-macsec.c" + "tests/test-create-macvlan.c" + "tests/test-create-macvtap.c" + "tests/test-create-sit.c" + "tests/test-create-veth.c" + "tests/test-create-xfrmi.c" + "tests/test-genl.c" + "tests/test-nf-cache-mngr.c" + "tests/test-socket-creation.c" + "tests/test-u32-filter-with-actions.c" +) + +DIR_ROOT="$(git rev-parse --show-toplevel)" || die "not inside a git repository" +DIR_PREFIX="$(git rev-parse --show-prefix)" || die "not inside a git repository" + +if [ ! -f "$DIR_ROOT/.clang-format" ]; then + die "Error: the clang-format file in \"$DIR_ROOT\" does not exist" +fi + +if ! command -v clang-format &> /dev/null; then + die "Error: clang-format is not installed. On RHEL/Fedora/CentOS run 'dnf install clang-tools-extra'" +fi + +if test -n "$DIR_PREFIX"; then + EXCLUDE_PATHS=() + for e in "${EXCLUDE_PATHS_TOPLEVEL[@]}"; do + REGEX="^$DIR_PREFIX([^/].*)$" + if [[ "$e" =~ $REGEX ]]; then + EXCLUDE_PATHS+=("${BASH_REMATCH[1]}") + fi + done +else + EXCLUDE_PATHS=("${EXCLUDE_PATHS_TOPLEVEL[@]}") +fi + +FILES=() +HAS_EXPLICIT_FILES=0 +SHOW_FILENAMES=0 +TEST_ONLY=0 +CHECK_UPSTREAM= + +usage() { + printf "Usage: %s [OPTION]... [FILE]...\n" "$(basename "$0")" + printf "Reformat source files using clang-format.\n\n" + printf "If no file is given the script runs on the whole codebase.\n" + printf "OPTIONS:\n" + printf " -h Print this help message.\n" + printf " -i Reformat files (the default).\n" + printf " -n|--dry-run Only check the files (contrary to \"-i\").\n" + printf " -a|--all Check all files (the default).\n" + printf " -u|--upstream COMMIT Check only files from \`git diff --name-only COMMIT\` (contrary to \"-a\").\n" + printf " This also affects directories given in the [FILE] list, but not files.\n" + printf " If this is the last parameter and COMMIT is unspecified/empty, it defaults to \"main\".\n" + printf " -F|--fast Same as \`-u HEAD^\`.\n" + printf " --show-filenames Only print the filenames that would be checked/formatted\n" + printf " -- Separate options from filenames/directories\n" +} + +ls_files_exist() { + local OLD_IFS="$IFS" + local f + + IFS=$'\n' + for f in $(cat) ; do + test -f "$f" && printf '%s\n' "$f" + done + IFS="$OLD_IFS" +} + +ls_files_filter() { + local OLD_IFS="$IFS" + local f + + IFS=$'\n' + for f in $(cat) ; do + local found=1 + local p + for p; do + [[ "$f" = "$p/"* ]] && found= + [[ "$f" = "$p" ]] && found= + done + test -n "$found" && printf '%s\n' "$f" + done + IFS="$OLD_IFS" +} + +g_ls_files() { + local pattern="$1" + shift + + if [ -z "$CHECK_UPSTREAM" ]; then + git ls-files -- "$pattern" + else + git diff --no-renames --name-only "$CHECK_UPSTREAM" -- "$pattern" \ + | ls_files_exist + fi | ls_files_filter "$@" +} + +HAD_DASHDASH=0 +while (( $# )); do + if [ "$HAD_DASHDASH" = 0 ]; then + case "$1" in + -h) + usage + exit 0 + ;; + --show-filenames) + SHOW_FILENAMES=1 + shift + continue + ;; + -a|--all) + CHECK_UPSTREAM= + shift + continue + ;; + -u|--upstream) + shift + CHECK_UPSTREAM="$1" + test -n "$CHECK_UPSTREAM" || CHECK_UPSTREAM=main + shift || : + continue + ;; + -F|--fast) + CHECK_UPSTREAM='HEAD^' + shift + continue + ;; + -n|--dry-run) + TEST_ONLY=1 + shift + continue + ;; + -i) + TEST_ONLY=0 + shift + continue + ;; + --) + HAD_DASHDASH=1 + shift + continue + ;; + esac + fi + if [ -d "$1" ]; then + while IFS='' read -r line; + do FILES+=("$line") + done < <(CHECK_UPSTREAM="$CHECK_UPSTREAM" g_ls_files "${1}/*.[hc]" "${EXCLUDE_PATHS[@]}") + elif [ -f "$1" ]; then + FILES+=("$1") + else + usage >&2 + echo >&2 + die "Unknown argument \"$1\" which also is neither a file nor a directory." + fi + shift + HAS_EXPLICIT_FILES=1 +done + +if [ $HAS_EXPLICIT_FILES = 0 ]; then + while IFS='' read -r line; do + FILES+=("$line") + done < <(CHECK_UPSTREAM="$CHECK_UPSTREAM" g_ls_files '*.[ch]' "${EXCLUDE_PATHS[@]}") +fi + +if [ $SHOW_FILENAMES = 1 ]; then + for f in "${FILES[@]}" ; do + printf '%s\n' "$f" + done + exit 0 +fi + +if [ "${#FILES[@]}" = 0 ]; then + if [ -z "$CHECK_UPSTREAM" ]; then + die "Error: no files to check" + fi + exit 0 +fi + +FLAGS_TEST=( --Werror -n --ferror-limit=1 ) + +if [ $TEST_ONLY = 1 ]; then + # We assume that all formatting is correct. In that mode, passing + # all filenames to clang-format is significantly faster. + # + # Only in case of an error, we iterate over the files one by one + # until we find the first invalid file. + for f in "${FILES[@]}"; do + [ -f "$f" ] || die "Error: file \"$f\" does not exist (or is not a regular file)" + done + clang-format "${FLAGS_TEST[@]}" "${FILES[@]}" &>/dev/null && exit 0 + for f in "${FILES[@]}"; do + [ -f "$f" ] || die "Error: file \"$f\" does not exist (or is not a regular file)" + if ! clang-format "${FLAGS_TEST[@]}" "$f" &>/dev/null; then + FF="$(mktemp)" + trap 'rm -f "$FF"' EXIT + clang-format "$f" 2>/dev/null > "$FF" + git --no-pager diff "$f" "$FF" || : + die "Error: file \"$f\" has style issues."$'\n'"Fix it by running \`\"$0\" -i \"$f\"\` using $(clang-format --version)" + fi + done + die "an unknown error happened." +fi + +clang-format -i "${FILES[@]}" |