From 573ab70bfe4c6239a3fffda89b1a95e4e7ca10aa Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Mon, 16 Dec 2019 10:58:32 -0500 Subject: [PATCH] Temporary clang-format configuration and script. The format is the same as in my previous efforts here. The script is a little tricky, since it invokes both clang-format and codetool, and it makes sure that files do not have a changed mtime unless there is actually some change in the file. --- .clang-format | 166 ++++++++++++++++++++++++++++++++++ scripts/maint/clang-format.sh | 34 +++++++ 2 files changed, 200 insertions(+) create mode 100644 .clang-format create mode 100755 scripts/maint/clang-format.sh diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000000..31b76a0025 --- /dev/null +++ b/.clang-format @@ -0,0 +1,166 @@ +--- +Language: Cpp +# Out of all supported styles, LLVM seems closest to our own. +BasedOnStyle: LLVM + +################ +# +# Deviations from LLVM's style. +# +################ + +# We prefer an indentation width of 4 columns; LLVM likes 2. +## OVERRIDE FOR COMPARISON +IndentWidth: 2 + +## OVERRIDE FOR COMPARISON +## for now i'm not sorting includes, since that makes every file get touched. +SortIncludes: false + +# We prefer 79; llvm likes 80. +ColumnLimit: 79 + +# Where do we want to put backslashes on multiline macros? Our choices are +# "as far left as possible", "as far right as possible", and "make no changes." +# LLVM defaults to right, but we don't dig that. +AlignEscapedNewlines: Left + +# When we see a bunch of things in a row with comments after them, should we +# try to align those comments? Doing so makes some of our code pretty ugly. +AlignTrailingComments: false + +# We use a function declaration style much closer to BSD KNF than to LLVM's. +# We say: +# int foo(int x); +# int +# foo(int x) +# { +# ... +# } +# whereas llvm prefers: +# int foo(int x); +# int foo(int x) { +# ... +# } +# or even: +# int foo(int x) { ... } +# +BreakBeforeBraces: Custom +BraceWrapping: + AfterFunction: true +AllowShortFunctionsOnASingleLine: None +AlwaysBreakAfterReturnType: AllDefinitions + +# We don't like blocks to start with an empty line. +# +KeepEmptyLinesAtTheStartOfBlocks: false + +################ +# +# Tor-specific magic +# +################ + +# +# These comments are magical, and should not be changed. +# +CommentPragmas: 'LCOV_EXCL|COVERITY' + +# +# Remove duplicate empty lines. +# +MaxEmptyLinesToKeep: 1 + +# +# Indent preprocessor directives, for clarity. +# +IndentPPDirectives: AfterHash + +# +# These introduce an iteration, and work a bit like a for loop. +# +# Note that we can NOT include ones that don't work like "for". For example, +# if the body is an argument to the macro, we can't list it here. +# +ForEachMacros: + - MAP_FOREACH + - MAP_FOREACH_MODIFY + - TOR_SIMPLEQ_FOREACH + - TOR_SIMPLEQ_FOREACH_SAFE + - TOR_SLIST_FOREACH + - TOR_SLIST_FOREACH_SAFE + - TOR_LIST_FOREACH + - TOR_LIST_FOREACH_SAFE + - TOR_TAILQ_FOREACH + - TOR_TAILQ_FOREACH_SAFE + - TOR_TAILQ_FOREACH_REVERSE + - TOR_TAILQ_FOREACH_REVERSE_SAFE + - TOR_CIRCLEQ_FOREACH + - TOR_CIRCLEQ_FOREACH_SAFE + - TOR_CIRCLEQ_FOREACH_REVERSE + - TOR_CIRCLEQ_FOREACH_REVERSE_SAFE + - HT_FOREACH + - SMARTLIST_FOREACH_BEGIN + - DIGESTMAP_FOREACH + - DIGESTMAP_FOREACH_MODIFY + - DIGEST256MAP_FOREACH + - DIGEST256MAP_FOREACH_MODIFY + - SDMAP_FOREACH + - RIMAP_FOREACH + - EIMAP_FOREACH + +# +# Omitting: +# +# - SMARTLIST_FOREACH, since the body of the loop is an argument. + +# +# This explains how to sort our headers. +# +# This is more complex than it truly should be, but I've edited this till +# compilation still mostly passes. +# +# I'm disabling this, however, since it's a distraction from the other +# formatting issues. See SortIncludes above. +# +IncludeCategories: + - Regex: '^"orconfig.h' + Priority: -30 + - Regex: '^"ext/' + Priority: -18 + - Regex: '^"lib/' + Priority: -10 + - Regex: '^"core/or/or.h' + Priority: -5 + - Regex: '^"core/' + Priority: 5 + - Regex: '^"feature/' + Priority: 10 + - Regex: '^"app/' + Priority: 20 + +# +# These macros should always cause indentation, as though they were { and }. +# +# Do NOT put macros here unless you want an extra level of indentation between +# them whenever they appear. +# +MacroBlockBegin: "^STMT_BEGIN|TT_STMT_BEGIN$" +MacroBlockEnd: "^STMT_END|TT_STMT_END$" + +# +# These macros don't need to have semicolons afterwards. +# +StatementMacros: + - HT_PROTOTYPE + - HT_GENERATE + - HT_GENERATE2 + +# +# These macros are interpreted as types. +# (Not supported in my clang-format) +# +# TypenameMacros: +# - "STACK_OF" + +... diff --git a/scripts/maint/clang-format.sh b/scripts/maint/clang-format.sh new file mode 100755 index 0000000000..86430b9b26 --- /dev/null +++ b/scripts/maint/clang-format.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# Copyright 2020, The Tor Project, Inc. +# See LICENSE for licensing information. + +# This script runs "clang-format" and "codetool" in sequence over each of +# our source files, and replaces the original file only if it has changed. +# +# We can't just use clang-format -i, since we also want to use codetool to +# reformat a few things back to how we want them, and we want avoid changing +# the mtime on files that didn't actually change. + +set -e + +cd "$(dirname "$0")/../../src/" + +# Shellcheck complains that a for loop over find's output is unreliable, +# since there might be special characters in the output. But we happen +# to know that none of our C files have special characters or spaces in +# their names, so this is safe. +# +# shellcheck disable=SC2044 +for fname in $(find lib core feature app test tools -name '[^.]*.[ch]'); do + tmpfname="${fname}.clang_fmt.tmp" + rm -f "${tmpfname}" + clang-format --style=file "${fname}" > "${tmpfname}" + ../scripts/maint/codetool.py "${tmpfname}" + if cmp "${fname}" "${tmpfname}" >/dev/null 2>&1; then + echo "No change in ${fname}" + rm -f "${tmpfname}" + else + echo "Change in ${fname}" + mv "${tmpfname}" "${fname}" + fi +done