diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c47898bd369acb9aac3aede2d57cab2b7d6856fc..863575f84f31bc91b6b6253eda911c9d9c4dafc4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,7 @@ default: - runner_system_failure stages: + - lint - build - build:cuda - build:gcc @@ -488,3 +489,58 @@ deploy documentation: tags: - docker - deploy_key + +clang-format: + stage: lint +# only: +# changes: +# - Documentation/**/*.{h,hpp,cpp,cu} +# - src/**/*.{h,hpp,cpp,cu} + script: + # TODO: replace "src/TNL" with "src" + - ./scripts/run-clang-format.py + --color always + --style file + --exclude "src/3rdparty/*" + --recursive + src/TNL Documentation + interruptible: true + # TODO: remove to enforce formatting + allow_failure: true + +clang-tidy: + stage: lint +# only: +# changes: +# - Documentation/**/*.{h,hpp,cpp,cu} +# - src/**/*.{h,hpp,cpp,cu} + variables: + CXX: clang++ + CC: clang + script: + # configure only to generate compile_commands.json + # TODO: set BUILD_EXAMPLES=yes to modernize examples + - cmake -B "./builddir/$CI_JOB_NAME" -S . -G Ninja + -DCMAKE_BUILD_TYPE=Debug + -DWITH_OPENMP=yes + -DWITH_MPI=yes + -DWITH_CUDA=no + -DBUILD_TESTS=yes + -DBUILD_MATRIX_TESTS=yes + -DBUILD_DOC=yes + -DBUILD_BENCHMARKS=yes + -DBUILD_EXAMPLES=no + -DBUILD_TOOLS=yes + -DBUILD_PYTHON=yes + -DWITH_CI_FLAGS=yes + # cmake creates compile_commands.json only on the second run, WTF!? + - cmake -B "./builddir/$CI_JOB_NAME" -S . -G Ninja + - ls -lah "./builddir/$CI_JOB_NAME" + # run-clang-tidy is weird compared to run-clang-format.py: + # - clang-tidy is not executed on header files, but on source files + # - the positional arguments are regexes filtering sources from the compile_commands.json + # - the -header-filter option (or HeaderFilterRegex in the config) allows to filter header files + - run-clang-tidy -p "./builddir/$CI_JOB_NAME" ".*" + interruptible: true + # TODO: remove to enforce + allow_failure: true diff --git a/CMakeLists.txt b/CMakeLists.txt index d74bbb48f398388b2004358e75e5d6c87787d7f0..9d2c2b30973c0485dce51b23816c913f222ea812 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,7 +318,7 @@ endif() set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin ) set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/lib ) include_directories( src ) -include_directories( src/3rdparty ) +include_directories( SYSTEM src/3rdparty ) # Add all subdirectories add_subdirectory( src ) @@ -331,6 +331,10 @@ if( ${BUILD_DOC} ) add_subdirectory( Documentation/Tutorials ) endif() +# export compile_commands.json so it can be used by Clang tools +# https://clang.llvm.org/docs/JSONCompilationDatabase.html +set( CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE INTERNAL "" ) + set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Template Numerical Library") set(CPACK_PACKAGE_VENDOR "MMG") #set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/ReadMe.txt") diff --git a/Documentation/.clang-format b/Documentation/.clang-format new file mode 120000 index 0000000000000000000000000000000000000000..ef1c8aefd945c7c4c963c237128b14408b1f4736 --- /dev/null +++ b/Documentation/.clang-format @@ -0,0 +1 @@ +../src/.clang-format \ No newline at end of file diff --git a/scripts/p-clang-format b/scripts/p-clang-format new file mode 100755 index 0000000000000000000000000000000000000000..f7c56b3e7395ff3789f82723d88713355a35b0e3 --- /dev/null +++ b/scripts/p-clang-format @@ -0,0 +1,112 @@ +#!/bin/bash +# Copyright (c) 2017, Medicine Yeh +# MIT License + +# Upstream page: https://github.com/MedicineYeh/p-clang-format +# Local modifications: +# - https://github.com/MedicineYeh/p-clang-format/pull/2 +# - CUDA_CHEVRON_* hack to protect "<<<" and ">>>" from clang-format +# (see https://github.com/llvm/llvm-project/issues/52881) + +# Turn on this to replace any pragma +#REPLACE_ANY_PRAGMA=1 + +function replace_all() +{ + local prefix="$1" + local keywords=("${!2}") + local pattern="$3" + local file_pathes=("${!4}") + + # echo "Keywords : ${keywords[*]}" + # echo "Pattern : ${pattern}" + # echo "File Path : ${file_pathes[*]}" + + for file_path in "${file_pathes[@]}"; do + [[ ! -r "$file_path" ]] && continue + for w in "${keywords[@]}"; do + # echo "Replace '${prefix}$w' in '$file_path'" + sed -i "s/${prefix}${w}/${pattern}${prefix}${w}/g" "${file_path}" + done + + # HACK: protect "<<<" and ">>>" from clang-format + sed -i "s/<<</CUDA_CHEVRON_OPEN/g" "${file_path}" + sed -i "s/>>>/CUDA_CHEVRON_CLOSE/g" "${file_path}" + done +} + +function re_replace_all() +{ + local prefix="$1" + local keywords=("${!2}") + local pattern="$3" + local file_pathes=("${!4}") + + # echo "Keywords : ${keywords[*]}" + # echo "Anti-Pattern : ${pattern}" + # echo "File Path : ${file_pathes[*]}" + + for file_path in "${file_pathes[@]}"; do + [[ ! -r "$file_path" ]] && continue + for w in "${keywords[@]}"; do + # echo "Re:replace '${prefix}$w' in '$file_path'" + sed -i "s/${pattern}${prefix}${w}/${prefix}${w}/g" "${file_path}" + done + + # HACK: unprotect "<<<" and ">>>" + sed -i "s/CUDA_CHEVRON_OPEN/<<</g" "${file_path}" + sed -i "s/CUDA_CHEVRON_CLOSE/>>>/g" "${file_path}" + done +} + +function format() +{ + clang-format "$@" +} + +function main() +{ + # This is the pattern for replacing to comments + local comment_pattern="\/\/" + # This is the pattern for replacing comments back to original string + local re_comment_pattern="\/\/ *" + # The path of files + local file_pathes=() + # Define the keywords of pragma to be escaped from formatting + local pragma_prefix="#pragma " + local pragma_key_words=() + # Loop specific + pragma_key_words+=(omp simd loop unroll ivdep vector) + # Memory specific + pragma_key_words+=(alloc_section) + # Misc. + pragma_key_words+=("cilk grainsize" offload) + + # Turn on the following line to indent any pragma + [[ "$REPLACE_ANY_PRAGMA" == "1" ]] && pragma_key_words=("") + + # Find all files in the arguments + for var in "$@"; do + if [[ ! "$var" =~ ^-.* ]]; then + file_pathes+=("$var") + fi + done + + # Create and trap a temporary file + tmpfile=$(mktemp --tmpdir="${TMPDIR:-/tmp}" p-clang-format.XXXXXXXXXX) + trap 'rm -f -- "$tmpfile"' INT TERM HUP EXIT + # Append the temporary file to file_pathes so pragmas will be replaced in it + # (this handles the case when the user did not specify -i to edit files in-place) + file_pathes+=("$tmpfile") + + # Replace "#pragma" -> "//#pragma" in the files + replace_all "$pragma_prefix" "pragma_key_words[@]" "$comment_pattern" "file_pathes[@]" + # Run clang-format and redirect its output to the $tmpfile + format "$@" > "$tmpfile" + # Replace "//#pragma" -> "#pragma" in the files + re_replace_all "$pragma_prefix" "pragma_key_words[@]" "$re_comment_pattern" "file_pathes[@]" + # Show the clang-format's stdout after replacement + cat "$tmpfile" +} + +main "$@" diff --git a/scripts/run-clang-format.py b/scripts/run-clang-format.py new file mode 100755 index 0000000000000000000000000000000000000000..235c21c58ccac039e5b069cb30574ba2921afc9d --- /dev/null +++ b/scripts/run-clang-format.py @@ -0,0 +1,417 @@ +#!/usr/bin/env python +"""A wrapper script around clang-format, suitable for linting multiple files +and to use for continuous integration. + +This is an alternative API for the clang-format command line. +It runs over multiple files and directories in parallel. +A diff output is produced and a sensible exit code is returned. + +Upstream page: https://github.com/Sarcasm/run-clang-format +Local modifications: + - DEFAULT_CLANG_FORMAT_EXECUTABLE, p-clang-format +""" + +from __future__ import print_function, unicode_literals + +import argparse +import codecs +import difflib +import fnmatch +import io +import errno +import multiprocessing +import os +import signal +import subprocess +import sys +import traceback + +from functools import partial + +try: + from subprocess import DEVNULL # py3k +except ImportError: + DEVNULL = open(os.devnull, "wb") + + +DEFAULT_EXTENSIONS = 'c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx' +DEFAULT_CLANG_FORMAT_IGNORE = '.clang-format-ignore' +# use a wrapper script which formats #pragmas nicely +_p_clang_format = os.path.join(os.path.dirname(__file__), "p-clang-format") +if os.path.isfile(_p_clang_format): + DEFAULT_CLANG_FORMAT_EXECUTABLE = _p_clang_format +else: + DEFAULT_CLANG_FORMAT_EXECUTABLE = 'clang-format' + + +class ExitStatus: + SUCCESS = 0 + DIFF = 1 + TROUBLE = 2 + +def excludes_from_file(ignore_file): + excludes = [] + try: + with io.open(ignore_file, 'r', encoding='utf-8') as f: + for line in f: + if line.startswith('#'): + # ignore comments + continue + pattern = line.rstrip() + if not pattern: + # allow empty lines + continue + excludes.append(pattern) + except EnvironmentError as e: + if e.errno != errno.ENOENT: + raise + return excludes; + +def list_files(files, recursive=False, extensions=None, exclude=None): + if extensions is None: + extensions = [] + if exclude is None: + exclude = [] + + out = [] + for file in files: + if recursive and os.path.isdir(file): + for dirpath, dnames, fnames in os.walk(file): + fpaths = [os.path.join(dirpath, fname) for fname in fnames] + for pattern in exclude: + # os.walk() supports trimming down the dnames list + # by modifying it in-place, + # to avoid unnecessary directory listings. + dnames[:] = [ + x for x in dnames + if + not fnmatch.fnmatch(os.path.join(dirpath, x), pattern) + ] + fpaths = [ + x for x in fpaths if not fnmatch.fnmatch(x, pattern) + ] + for f in fpaths: + ext = os.path.splitext(f)[1][1:] + if ext in extensions: + out.append(f) + else: + out.append(file) + return out + + +def make_diff(file, original, reformatted): + return list( + difflib.unified_diff( + original, + reformatted, + fromfile='{}\t(original)'.format(file), + tofile='{}\t(reformatted)'.format(file), + n=3)) + + +class DiffError(Exception): + def __init__(self, message, errs=None): + super(DiffError, self).__init__(message) + self.errs = errs or [] + + +class UnexpectedError(Exception): + def __init__(self, message, exc=None): + super(UnexpectedError, self).__init__(message) + self.formatted_traceback = traceback.format_exc() + self.exc = exc + + +def run_clang_format_diff_wrapper(args, file): + try: + ret = run_clang_format_diff(args, file) + return ret + except DiffError: + raise + except Exception as e: + raise UnexpectedError('{}: {}: {}'.format(file, e.__class__.__name__, + e), e) + + +def run_clang_format_diff(args, file): + try: + with io.open(file, 'r', encoding='utf-8') as f: + original = f.readlines() + except IOError as exc: + raise DiffError(str(exc)) + + if args.in_place: + invocation = [args.clang_format_executable, '-i', file] + else: + invocation = [args.clang_format_executable, file] + + if args.style: + invocation.extend(['--style', args.style]) + + if args.dry_run: + print(" ".join(invocation)) + return [], [] + + # Use of utf-8 to decode the process output. + # + # Hopefully, this is the correct thing to do. + # + # It's done due to the following assumptions (which may be incorrect): + # - clang-format will returns the bytes read from the files as-is, + # without conversion, and it is already assumed that the files use utf-8. + # - if the diagnostics were internationalized, they would use utf-8: + # > Adding Translations to Clang + # > + # > Not possible yet! + # > Diagnostic strings should be written in UTF-8, + # > the client can translate to the relevant code page if needed. + # > Each translation completely replaces the format string + # > for the diagnostic. + # > -- http://clang.llvm.org/docs/InternalsManual.html#internals-diag-translation + # + # It's not pretty, due to Python 2 & 3 compatibility. + encoding_py3 = {} + if sys.version_info[0] >= 3: + encoding_py3['encoding'] = 'utf-8' + + try: + proc = subprocess.Popen( + invocation, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + universal_newlines=True, + **encoding_py3) + except OSError as exc: + raise DiffError( + "Command '{}' failed to start: {}".format( + subprocess.list2cmdline(invocation), exc + ) + ) + proc_stdout = proc.stdout + proc_stderr = proc.stderr + if sys.version_info[0] < 3: + # make the pipes compatible with Python 3, + # reading lines should output unicode + encoding = 'utf-8' + proc_stdout = codecs.getreader(encoding)(proc_stdout) + proc_stderr = codecs.getreader(encoding)(proc_stderr) + # hopefully the stderr pipe won't get full and block the process + outs = list(proc_stdout.readlines()) + errs = list(proc_stderr.readlines()) + proc.wait() + if proc.returncode: + raise DiffError( + "Command '{}' returned non-zero exit status {}".format( + subprocess.list2cmdline(invocation), proc.returncode + ), + errs, + ) + if args.in_place: + return [], errs + return make_diff(file, original, outs), errs + + +def bold_red(s): + return '\x1b[1m\x1b[31m' + s + '\x1b[0m' + + +def colorize(diff_lines): + def bold(s): + return '\x1b[1m' + s + '\x1b[0m' + + def cyan(s): + return '\x1b[36m' + s + '\x1b[0m' + + def green(s): + return '\x1b[32m' + s + '\x1b[0m' + + def red(s): + return '\x1b[31m' + s + '\x1b[0m' + + for line in diff_lines: + if line[:4] in ['--- ', '+++ ']: + yield bold(line) + elif line.startswith('@@ '): + yield cyan(line) + elif line.startswith('+'): + yield green(line) + elif line.startswith('-'): + yield red(line) + else: + yield line + + +def print_diff(diff_lines, use_color): + if use_color: + diff_lines = colorize(diff_lines) + if sys.version_info[0] < 3: + sys.stdout.writelines((l.encode('utf-8') for l in diff_lines)) + else: + sys.stdout.writelines(diff_lines) + + +def print_trouble(prog, message, use_colors): + error_text = 'error:' + if use_colors: + error_text = bold_red(error_text) + print("{}: {} {}".format(prog, error_text, message), file=sys.stderr) + + +def main(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument( + '--clang-format-executable', + metavar='EXECUTABLE', + help='path to the clang-format executable', + default=DEFAULT_CLANG_FORMAT_EXECUTABLE) + parser.add_argument( + '--extensions', + help='comma separated list of file extensions (default: {})'.format( + DEFAULT_EXTENSIONS), + default=DEFAULT_EXTENSIONS) + parser.add_argument( + '-r', + '--recursive', + action='store_true', + help='run recursively over directories') + parser.add_argument( + '-d', + '--dry-run', + action='store_true', + help='just print the list of files') + parser.add_argument( + '-i', + '--in-place', + action='store_true', + help='format file instead of printing differences') + parser.add_argument('files', metavar='file', nargs='+') + parser.add_argument( + '-q', + '--quiet', + action='store_true', + help="disable output, useful for the exit code") + parser.add_argument( + '-j', + metavar='N', + type=int, + default=0, + help='run N clang-format jobs in parallel' + ' (default number of cpus + 1)') + parser.add_argument( + '--color', + default='auto', + choices=['auto', 'always', 'never'], + help='show colored diff (default: auto)') + parser.add_argument( + '-e', + '--exclude', + metavar='PATTERN', + action='append', + default=[], + help='exclude paths matching the given glob-like pattern(s)' + ' from recursive search') + parser.add_argument( + '--style', + help='formatting style to apply (LLVM, Google, Chromium, Mozilla, WebKit)') + + args = parser.parse_args() + + # use default signal handling, like diff return SIGINT value on ^C + # https://bugs.python.org/issue14229#msg156446 + signal.signal(signal.SIGINT, signal.SIG_DFL) + try: + signal.SIGPIPE + except AttributeError: + # compatibility, SIGPIPE does not exist on Windows + pass + else: + signal.signal(signal.SIGPIPE, signal.SIG_DFL) + + colored_stdout = False + colored_stderr = False + if args.color == 'always': + colored_stdout = True + colored_stderr = True + elif args.color == 'auto': + colored_stdout = sys.stdout.isatty() + colored_stderr = sys.stderr.isatty() + + version_invocation = [args.clang_format_executable, str("--version")] + try: + subprocess.check_call(version_invocation, stdout=DEVNULL) + except subprocess.CalledProcessError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + return ExitStatus.TROUBLE + except OSError as e: + print_trouble( + parser.prog, + "Command '{}' failed to start: {}".format( + subprocess.list2cmdline(version_invocation), e + ), + use_colors=colored_stderr, + ) + return ExitStatus.TROUBLE + + retcode = ExitStatus.SUCCESS + + excludes = excludes_from_file(DEFAULT_CLANG_FORMAT_IGNORE) + excludes.extend(args.exclude) + + files = list_files( + args.files, + recursive=args.recursive, + exclude=excludes, + extensions=args.extensions.split(',')) + + if not files: + return + + njobs = args.j + if njobs == 0: + njobs = multiprocessing.cpu_count() + 1 + njobs = min(len(files), njobs) + + if njobs == 1: + # execute directly instead of in a pool, + # less overhead, simpler stacktraces + it = (run_clang_format_diff_wrapper(args, file) for file in files) + pool = None + else: + pool = multiprocessing.Pool(njobs) + it = pool.imap_unordered( + partial(run_clang_format_diff_wrapper, args), files) + pool.close() + while True: + try: + outs, errs = next(it) + except StopIteration: + break + except DiffError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + retcode = ExitStatus.TROUBLE + sys.stderr.writelines(e.errs) + except UnexpectedError as e: + print_trouble(parser.prog, str(e), use_colors=colored_stderr) + sys.stderr.write(e.formatted_traceback) + retcode = ExitStatus.TROUBLE + # stop at the first unexpected error, + # something could be very wrong, + # don't process all files unnecessarily + if pool: + pool.terminate() + break + else: + sys.stderr.writelines(errs) + if outs == []: + continue + if not args.quiet: + print_diff(outs, use_color=colored_stdout) + if retcode == ExitStatus.SUCCESS: + retcode = ExitStatus.DIFF + if pool: + pool.join() + return retcode + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/src/.clang-format b/src/.clang-format new file mode 100644 index 0000000000000000000000000000000000000000..b774752240fc4a9c5188e5d3ab97864634cae911 --- /dev/null +++ b/src/.clang-format @@ -0,0 +1,162 @@ +# Documentation: https://clang.llvm.org/docs/ClangFormatStyleOptions.html +--- +Language: Cpp +Standard: c++14 +#BasedOnStyle: Mozilla + +# max line length +ColumnLimit: 128 + +IndentWidth: 3 +ContinuationIndentWidth: 3 +IndentAccessModifiers: false +AccessModifierOffset: -3 +IndentCaseLabels: true +IndentCaseBlocks: true +IndentGotoLabels: false +IndentPPDirectives: BeforeHash +IndentExternBlock: NoIndent +IndentWrappedFunctionNames: false + +NamespaceIndentation: None +FixNamespaceComments: true +CompactNamespaces: false +#ShortnamespaceLines: 10 # Clang 14 + +EmptyLineAfterAccessModifier: Never +EmptyLineBeforeAccessModifier: LogicalBlock +KeepEmptyLinesAtTheStartOfBlocks: false +MaxEmptyLinesToKeep: 1 + +SpacesInParentheses: true +SpacesInSquareBrackets: true +SpacesInAngles: Always +SpacesInConditionalStatement: true +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false + +SpaceAfterCStyleCast: true +SpaceAfterLogicalNot: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +BitFieldColonSpacing: Both +SpaceBeforeParens: Never +SpaceBeforeRangeBasedForLoopColon: true +SpaceBeforeSquareBrackets: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCaseColon: false +SpaceBeforeCpp11BracedList: false +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false + +SpacesBeforeTrailingComments: 2 +Cpp11BracedListStyle: false + +#PackConstructorInitializers: Never # Clang 14 +AllowAllConstructorInitializersOnNextLine: false # deprecated +ConstructorInitializerAllOnOneLineOrOnePerLine: false # deprecated +ConstructorInitializerIndentWidth: 0 + +AlwaysBreakAfterReturnType: All +AlwaysBreakBeforeMultilineStrings: false +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: MultiLine + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeLambdaBody: true + BeforeCatch: true + BeforeElse: true + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: false + SplitEmptyRecord: false + SplitEmptyNamespace: true + +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeTernaryOperators: true +BreakInheritanceList: BeforeColon +BreakConstructorInitializers: BeforeColon +#BreakBeforeConceptDeclarations: true +#BreakStringLiterals: true + +AlwaysBreakTemplateDeclarations: Yes +SpaceAfterTemplateKeyword: false + +AlignAfterOpenBracket: Align +AlignArrayOfStructures: None +AlignConsecutiveMacros: None +AlignConsecutiveAssignments: None +AlignConsecutiveBitFields: None +AlignConsecutiveDeclarations: None +AlignEscapedNewlines: Left +AlignOperands: AlignAfterOperator +AlignTrailingComments: true + +DerivePointerAlignment: false +PointerAlignment: Left +ReferenceAlignment: Pointer + +# statement macros are typically formatted on their own lines +StatementMacros: + - __global__ + - __host__ + - __device__ + - __cuda_callable__ + +AllowAllArgumentsOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortEnumsOnASingleLine: true +AllowShortBlocksOnASingleLine: Never +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortLambdasOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +BinPackArguments: false +BinPackParameters: false + +#CommentPragmas: '^ IWYU pragma:' + +#IncludeBlocks: Preserve +#IncludeCategories: +# - Regex: '^"(llvm|llvm-c|clang|clang-c)/' +# Priority: 2 +# SortPriority: 0 +# CaseSensitive: false +# - Regex: '^(<|"(gtest|gmock|isl|json)/)' +# Priority: 3 +# SortPriority: 0 +# CaseSensitive: false +# - Regex: '.*' +# Priority: 1 +# SortPriority: 0 +# CaseSensitive: false +#IncludeIsMainRegex: '(Test)?$' +#IncludeIsMainSourceRegex: '' +#PenaltyBreakAssignment: 2 +#PenaltyBreakBeforeFirstCallParameter: 19 +#PenaltyBreakComment: 300 +#PenaltyBreakFirstLessLess: 120 +#PenaltyBreakString: 1000 +#PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 500 +#PenaltyIndentedWhitespace: 0 +#PPIndentWidth: -1 +#SortIncludes: CaseSensitive +#SortUsingDeclarations: true + +# FIXME: sorting includes causes a lot of breakage due to cyclic inclusion problems +SortIncludes: Never + +# NOTE: disabling this option breaks indentation of comments, see https://github.com/llvm/llvm-project/issues/53425 +ReflowComments: true + +... +# vim: ft=yaml diff --git a/src/.clang-tidy b/src/.clang-tidy new file mode 100644 index 0000000000000000000000000000000000000000..ba7983218be5f62fa2619121ae9bdec0e1be46dd --- /dev/null +++ b/src/.clang-tidy @@ -0,0 +1,38 @@ +# Documentation: https://clang.llvm.org/extra/clang-tidy/ +--- +HeaderFilterRegex: '.*' +AnalyzeTemporaryDtors: false +FormatStyle: file +User: user +Checks: 'readability-*, + -readability-else-after-return, + -readability-named-parameter, + modernize-*, + -modernize-avoid-c-arrays, + -modernize-use-trailing-return-type, + -modernize-raw-string-literal, + performance-*, + mpi-*' +WarningsAsErrors: 'performance-*,mpi-*' +CheckOptions: + - key: readability-braces-around-statements.ShortStatementLines + value: 99 + - key: readability-function-size.LineThreshold + value: 64 + - key: readability-function-size.ParameterThreshold + value: 15 + - key: readability-magic-numbers.IgnoreAllFloatingPointValues + value: true + - key: readability-magic-numbers.IgnorePowersOf2IntegerValues + value: true + + - key: modernize-use-default-member-init.UseAssignment + value: true + - key: modernize-use-auto.MinTypeNameLength + value: 10 + + - key: cppcoreguidelines-pro-type-member-init.UseAssignment + value: true + +... +# vim: ft=yaml