├── test ├── 0 │ └── test.sh ├── 1 │ └── test.sh ├── 2 │ └── test.sh ├── 3 │ └── test.sh ├── 4 │ └── test.sh ├── 5 │ └── test.sh ├── 6 │ └── test.sh ├── toolchain │ ├── gcc.cmake │ └── clang.cmake ├── CMakeLists.txt └── scripts │ ├── install-clang.sh │ ├── lint.sh │ └── build-clang.sh ├── CMakeLists.txt ├── conanfile.py ├── src ├── CMakeLists.txt └── main.cpp ├── .vscode ├── launch.json ├── tasks.json └── settings.json ├── README.md ├── .clang-format ├── LICENSE └── .clang-tidy /test/toolchain/gcc.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_FLAGS "-Werror -Wall -Wextra -Wpedantic") 2 | set(CMAKE_CXX_FLAGS_DEBUG "-fsanitize=undefined") 3 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.13) 2 | project(eg-error-handling) 3 | 4 | add_subdirectory(src) 5 | 6 | include(CTest) 7 | add_subdirectory(test) 8 | -------------------------------------------------------------------------------- /test/toolchain/clang.cmake: -------------------------------------------------------------------------------- 1 | set(CMAKE_CXX_FLAGS_INIT "-stdlib=libstdc++ -Werror -Wall -Wextra -Wpedantic") 2 | set(CMAKE_CXX_FLAGS_DEBUG_INIT "-fsanitize=memory,undefined -g -Og") 3 | -------------------------------------------------------------------------------- /conanfile.py: -------------------------------------------------------------------------------- 1 | from conans import ConanFile, CMake 2 | 3 | class WssConan(ConanFile): 4 | settings = "os", "compiler", "build_type", "arch" 5 | requires = "fmt/7.1.3" 6 | generators = "cmake", "gcc", "txt" 7 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Hint: run test/scripts/install-clang.sh from the build directory. 2 | find_package(fmt REQUIRED CONFIG) 3 | 4 | add_executable(example-program main.cpp) 5 | target_compile_features(example-program PUBLIC cxx_std_20) 6 | target_link_libraries(example-program PRIVATE fmt::fmt) 7 | target_compile_definitions(example-program PRIVATE TRAP_STRATEGY) 8 | -------------------------------------------------------------------------------- /test/0/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Test case: pass 1 and get back A 5 | 6 | BUILD_DIR="$(pwd)/.." 7 | 8 | EXPECTED='A' 9 | ACTUAL=$("${BUILD_DIR}/src/example-program" 1) 10 | 11 | if [ "$EXPECTED" = "$ACTUAL" ]; then 12 | echo "PASS: Strings are equal." 13 | else 14 | echo "FAIL: Strings are not equal." 15 | echo "Expected: $EXPECTED" 16 | echo "Actual: $ACTUAL" 17 | exit 1 18 | fi -------------------------------------------------------------------------------- /test/1/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Test case: pass 26 and get back Z 5 | 6 | BUILD_DIR="$(pwd)/.." 7 | 8 | EXPECTED='Z' 9 | ACTUAL=$("${BUILD_DIR}/src/example-program" 26) 10 | 11 | if [ "$EXPECTED" = "$ACTUAL" ]; then 12 | echo "PASS: Strings are equal." 13 | else 14 | echo "FAIL: Strings are not equal." 15 | echo "Expected: $EXPECTED" 16 | echo "Actual: $ACTUAL" 17 | exit 1 18 | fi -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | enable_testing() 2 | add_test(test0 "${CMAKE_CURRENT_LIST_DIR}/0/test.sh") 3 | add_test(test1 "${CMAKE_CURRENT_LIST_DIR}/1/test.sh") 4 | add_test(test2 "${CMAKE_CURRENT_LIST_DIR}/2/test.sh") 5 | add_test(test3 "${CMAKE_CURRENT_LIST_DIR}/3/test.sh") 6 | add_test(test4 "${CMAKE_CURRENT_LIST_DIR}/4/test.sh") 7 | add_test(test5 "${CMAKE_CURRENT_LIST_DIR}/5/test.sh") 8 | add_test(test6 "${CMAKE_CURRENT_LIST_DIR}/6/test.sh") 9 | -------------------------------------------------------------------------------- /test/scripts/install-clang.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | export CXX=clang++ 5 | PROJECT_DIR=$(cd "$(dirname "$0")/../.."; pwd) 6 | 7 | conan profile new --detect --force ./conan-profile 8 | 9 | conan install \ 10 | --build=missing \ 11 | --generator cmake_find_package_multi \ 12 | --profile ./conan-profile \ 13 | --settings build_type=Debug \ 14 | --settings compiler.libcxx=libstdc++ \ 15 | "${PROJECT_DIR}" 16 | -------------------------------------------------------------------------------- /test/scripts/lint.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | PROJECT_DIR=$(cd "$(dirname "$0")/../.."; pwd) 5 | 6 | find "${PROJECT_DIR}" -name "*.sh" | while read -r FILENAME; do 7 | shellcheck \ 8 | --check-sourced \ 9 | --color=always \ 10 | --external-sources \ 11 | --severity=info \ 12 | --shell=bash \ 13 | "$FILENAME" 14 | done 15 | 16 | find "${PROJECT_DIR}" \( -name "*.cpp" -o -name "*.h" \) | while read -r FILENAME; do 17 | clang-format \ 18 | -i \ 19 | "$FILENAME" 20 | done 21 | -------------------------------------------------------------------------------- /test/6/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Test case: pass '--help' and get back help text 5 | 6 | BUILD_DIR="$(pwd)/.." 7 | 8 | EXPECTED="This program prints the letter of the alphabet at the given position. 9 | Usage: letter N 10 | N: number between 1 and 26" 11 | 12 | ACTUAL=$("${BUILD_DIR}/src/example-program" --help) 13 | 14 | if [ "$EXPECTED" = "$ACTUAL" ]; then 15 | echo "PASS: Strings are equal." 16 | else 17 | echo "FAIL: Strings are not equal." 18 | echo "Expected: $EXPECTED" 19 | echo "Actual: $ACTUAL" 20 | exit 1 21 | fi -------------------------------------------------------------------------------- /test/2/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Test case: pass 0 and get back an error message 5 | 6 | BUILD_DIR="$(pwd)/.." 7 | 8 | EXPECTED="Out-of-range number, 0" 9 | 10 | set +e 11 | ACTUAL=$("${BUILD_DIR}/src/example-program" 0 2>&1 >/dev/null) 12 | EXIT_CODE=$? 13 | set -e 14 | 15 | if [ "$EXPECTED" = "$ACTUAL" ]; then 16 | echo "PASS: Strings are equal." 17 | else 18 | echo "FAIL: Strings are not equal." 19 | echo "Expected: $EXPECTED" 20 | echo "Actual: $ACTUAL" 21 | exit 1 22 | fi 23 | 24 | if [ "1" != "$EXIT_CODE" ]; then 25 | echo "FAIL: Exit code is $EXIT_CODE" 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /test/3/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Test case: pass 27 and get back an error message 5 | 6 | BUILD_DIR="$(pwd)/.." 7 | 8 | EXPECTED="Out-of-range number, 27" 9 | 10 | set +e 11 | ACTUAL=$("${BUILD_DIR}/src/example-program" 27 2>&1 >/dev/null) 12 | EXIT_CODE=$? 13 | set -e 14 | 15 | if [ "$EXPECTED" = "$ACTUAL" ]; then 16 | echo "PASS: Strings are equal." 17 | else 18 | echo "FAIL: Strings are not equal." 19 | echo "Expected: $EXPECTED" 20 | echo "Actual: $ACTUAL" 21 | exit 1 22 | fi 23 | 24 | if [ "1" != "$EXIT_CODE" ]; then 25 | echo "FAIL: Exit code is $EXIT_CODE" 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /test/scripts/build-clang.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | NUM_CPUS="$(nproc)" 5 | PROJECT_DIR=$(cd "$(dirname "$0")/../.."; pwd) 6 | 7 | "${PROJECT_DIR}/test/scripts/install-clang.sh" 8 | 9 | cmake \ 10 | -DCMAKE_BUILD_TYPE=Debug \ 11 | -DCMAKE_CXX_CLANG_TIDY=clang-tidy \ 12 | -DCMAKE_CXX_COMPILER=clang++ \ 13 | -DCMAKE_CXX_COMPILER_LAUNCHER=ccache \ 14 | -DCMAKE_EXPORT_COMPILE_COMMANDS=ON \ 15 | -DCMAKE_PREFIX_PATH="$(pwd)" \ 16 | -DCMAKE_TOOLCHAIN_FILE="${PROJECT_DIR}/test/toolchain/clang.cmake" \ 17 | -G Ninja \ 18 | "$@" \ 19 | "${PROJECT_DIR}" 20 | 21 | cmake \ 22 | --build . \ 23 | -- -j "${NUM_CPUS}" 24 | -------------------------------------------------------------------------------- /test/4/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Test case: pass non number and get back an error message 5 | 6 | BUILD_DIR="$(pwd)/.." 7 | 8 | EXPECTED="Unrecognized number, '1X'" 9 | 10 | set +e 11 | ACTUAL=$("${BUILD_DIR}/src/example-program" 1X 2>&1 >/dev/null) 12 | EXIT_CODE=$? 13 | set -e 14 | 15 | if [ "$EXPECTED" = "$ACTUAL" ]; then 16 | echo "PASS: Strings are equal." 17 | else 18 | echo "FAIL: Strings are not equal." 19 | echo "Expected: $EXPECTED" 20 | echo "Actual: $ACTUAL" 21 | exit 1 22 | fi 23 | 24 | if [ "1" != "$EXIT_CODE" ]; then 25 | echo "FAIL: Exit code is $EXIT_CODE" 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /test/5/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -euo pipefail 3 | 4 | # Test case: pass no parameter and get back an error message 5 | 6 | BUILD_DIR="$(pwd)/.." 7 | 8 | EXPECTED="Wrong number of arguments provided. Expected=1; Actual=0" 9 | 10 | set +e 11 | ACTUAL=$("${BUILD_DIR}/src/example-program" 2>&1 >/dev/null) 12 | EXIT_CODE=$? 13 | set -e 14 | 15 | if [ "$EXPECTED" = "$ACTUAL" ]; then 16 | echo "PASS: Strings are equal." 17 | else 18 | echo "FAIL: Strings are not equal." 19 | echo "Expected: $EXPECTED" 20 | echo "Actual: $ACTUAL" 21 | exit 1 22 | fi 23 | 24 | if [ "1" != "$EXIT_CODE" ]; then 25 | echo "FAIL: Exit code is $EXIT_CODE" 26 | exit 1 27 | fi 28 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "example-program", 9 | "type": "cppdbg", 10 | "request": "launch", 11 | "program": "${workspaceFolder}/build/src/example-program", 12 | "args": ["12"], 13 | "stopAtEntry": true, 14 | "cwd": "${workspaceFolder}", 15 | "environment": [], 16 | "externalConsole": false, 17 | "MIMode": "gdb", 18 | "setupCommands": [ 19 | { 20 | "description": "Enable pretty-printing for gdb", 21 | "text": "-enable-pretty-printing", 22 | "ignoreFailures": true 23 | } 24 | ] 25 | } 26 | ] 27 | } -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "build", 8 | "type": "shell", 9 | "command": "cmake", 10 | "args": [ 11 | "--build", "${workspaceFolder}/build", 12 | "--", "-j8" 13 | ], 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | }, 18 | "presentation": { 19 | "showReuseMessage": false, 20 | "clear": true 21 | }, 22 | // Use the standard MS compiler pattern to detect errors, warnings and infos 23 | "problemMatcher": { 24 | "owner": "cpp", 25 | "fileLocation": ["relative", "${workspaceFolder}"], 26 | "pattern": { 27 | "regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$", 28 | "file": 1, 29 | "line": 2, 30 | "column": 3, 31 | "severity": 4, 32 | "message": 5 33 | } 34 | } 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Error Handling in C++ By Example 2 | 3 | [John McFarlane](mailto:eg-error-handling@john.mcfarlane.name), 2021 4 | 5 | ## Introduction 6 | 7 | This project contains a toy program written in C++ which demonstrates an error-handling 8 | strategy recommended for robust applications. It takes a number and prints the corresponding 9 | letter of the alphabet. 10 | 11 | Most of the comments in the source code are written to explain the error-handling 12 | and bug handling choices made. 13 | 14 | ## Requirements 15 | 16 | The program uses some C++20 features and has only been tested with Clang 11 on Ubuntu 20.04. 17 | 18 | * Clang-11 19 | * CMake 3.16 20 | * fmt 7.1.3 21 | 22 | The build script uses the Conan package manager to install the fmt library. 23 | 24 | ## Instructions 25 | 26 | After cloning the repository and changing to the project root folder, 27 | 28 | 1. Create a build directory e.g. _build_: 29 | 30 | ```shell 31 | mkdir build && cd build 32 | ``` 33 | 34 | 2. Build the project using the script provided: 35 | 36 | ```shell 37 | ../test/scripts/build-clang.sh 38 | ``` 39 | 40 | 3. Run the approval tests: 41 | 42 | ```shell 43 | ctest 44 | ``` 45 | 46 | 4. Study the code to understand the error-handling strategy proposed. 47 | 48 | 5. Send questions, feedback and bug reports to the author via the 49 | [GitHub issues page](https://github.com/johnmcfarlane/eg-error-handling/issues). 50 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "array": "cpp", 4 | "atomic": "cpp", 5 | "*.tcc": "cpp", 6 | "cctype": "cpp", 7 | "clocale": "cpp", 8 | "cmath": "cpp", 9 | "cstdarg": "cpp", 10 | "cstddef": "cpp", 11 | "cstdint": "cpp", 12 | "cstdio": "cpp", 13 | "cstdlib": "cpp", 14 | "cwchar": "cpp", 15 | "cwctype": "cpp", 16 | "deque": "cpp", 17 | "unordered_map": "cpp", 18 | "vector": "cpp", 19 | "exception": "cpp", 20 | "algorithm": "cpp", 21 | "functional": "cpp", 22 | "iterator": "cpp", 23 | "memory": "cpp", 24 | "memory_resource": "cpp", 25 | "numeric": "cpp", 26 | "optional": "cpp", 27 | "random": "cpp", 28 | "string": "cpp", 29 | "string_view": "cpp", 30 | "system_error": "cpp", 31 | "tuple": "cpp", 32 | "type_traits": "cpp", 33 | "utility": "cpp", 34 | "fstream": "cpp", 35 | "initializer_list": "cpp", 36 | "iosfwd": "cpp", 37 | "istream": "cpp", 38 | "limits": "cpp", 39 | "new": "cpp", 40 | "ostream": "cpp", 41 | "sstream": "cpp", 42 | "stdexcept": "cpp", 43 | "streambuf": "cpp", 44 | "typeinfo": "cpp", 45 | "bit": "cpp", 46 | "charconv": "cpp", 47 | "cstring": "cpp", 48 | "gsl_assert": "cpp", 49 | "pointers": "cpp", 50 | "ctime": "cpp", 51 | "span": "cpp", 52 | "gsl_algorithm": "cpp", 53 | "gsl_byte": "cpp", 54 | "gsl_util": "cpp", 55 | "multi_span": "cpp", 56 | "string_span": "cpp", 57 | "chrono": "cpp", 58 | "ratio": "cpp", 59 | "executor": "cpp", 60 | "cinttypes": "cpp", 61 | "cerrno": "cpp", 62 | "filesystem": "cpp", 63 | "bitset": "cpp", 64 | "codecvt": "cpp", 65 | "condition_variable": "cpp", 66 | "iomanip": "cpp", 67 | "mutex": "cpp", 68 | "thread": "cpp", 69 | "__bit_reference": "cpp", 70 | "__config": "cpp", 71 | "__debug": "cpp", 72 | "__errc": "cpp", 73 | "__functional_base": "cpp", 74 | "__hash_table": "cpp", 75 | "__locale": "cpp", 76 | "__mutex_base": "cpp", 77 | "__node_handle": "cpp", 78 | "__nullptr": "cpp", 79 | "__split_buffer": "cpp", 80 | "__string": "cpp", 81 | "__threading_support": "cpp", 82 | "__tuple": "cpp", 83 | "ios": "cpp", 84 | "locale": "cpp", 85 | "queue": "cpp", 86 | "stack": "cpp" 87 | }, 88 | "cmake.configureSettings": { 89 | "CMAKE_BUILD_TYPE": "Debug", 90 | "CMAKE_CXX_CLANG_TIDY": "clang-tidy", 91 | "CMAKE_CXX_COMPILER": "clang++", 92 | "CMAKE_CXX_COMPILER_LAUNCHER": "ccache", 93 | "CMAKE_EXPORT_COMPILE_COMMANDS": "ON", 94 | "CMAKE_PREFIX_PATH": "${workspaceFolder}/build", 95 | "CMAKE_TOOLCHAIN_FILE": "${workspaceFolder}/test/toolchain/clang.cmake", 96 | }, 97 | "cmake.configureEnvironment": { 98 | "CXX": "clang++", 99 | "CC": "clang", 100 | }, 101 | } -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | AccessModifierOffset: -2 4 | AlignAfterOpenBracket: Align 5 | AlignConsecutiveMacros: false 6 | AlignConsecutiveAssignments: false 7 | AlignConsecutiveDeclarations: false 8 | AlignEscapedNewlines: Left 9 | AlignOperands: true 10 | AlignTrailingComments: false 11 | AllowAllArgumentsOnNextLine: true 12 | AllowAllConstructorInitializersOnNextLine: true 13 | AllowAllParametersOfDeclarationOnNextLine: false 14 | AllowShortBlocksOnASingleLine: false 15 | AllowShortCaseLabelsOnASingleLine: false 16 | AllowShortFunctionsOnASingleLine: Empty 17 | AllowShortLambdasOnASingleLine: All 18 | AllowShortIfStatementsOnASingleLine: Never 19 | AllowShortLoopsOnASingleLine: false 20 | AlwaysBreakAfterDefinitionReturnType: None 21 | AlwaysBreakAfterReturnType: None 22 | AlwaysBreakBeforeMultilineStrings: true 23 | AlwaysBreakTemplateDeclarations: Yes 24 | BinPackArguments: false 25 | BinPackParameters: true 26 | BraceWrapping: 27 | AfterCaseLabel: false 28 | AfterClass: false 29 | AfterControlStatement: false 30 | AfterEnum: false 31 | AfterFunction: true 32 | AfterNamespace: false 33 | AfterObjCDeclaration: false 34 | AfterStruct: false 35 | AfterUnion: false 36 | AfterExternBlock: false 37 | BeforeCatch: true 38 | BeforeElse: true 39 | IndentBraces: false 40 | SplitEmptyFunction: true 41 | SplitEmptyRecord: true 42 | SplitEmptyNamespace: true 43 | BreakBeforeBinaryOperators: None 44 | BreakBeforeBraces: Stroustrup 45 | BreakBeforeInheritanceComma: false 46 | BreakInheritanceList: BeforeColon 47 | BreakBeforeTernaryOperators: true 48 | BreakConstructorInitializersBeforeComma: false 49 | BreakConstructorInitializers: BeforeComma 50 | BreakAfterJavaFieldAnnotations: false 51 | BreakStringLiterals: true 52 | ColumnLimit: 120 53 | CommentPragmas: '^ IWYU pragma:' 54 | CompactNamespaces: false 55 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 56 | ConstructorInitializerIndentWidth: 4 57 | ContinuationIndentWidth: 4 58 | Cpp11BracedListStyle: true 59 | DerivePointerAlignment: false 60 | DisableFormat: false 61 | ExperimentalAutoDetectBinPacking: false 62 | FixNamespaceComments: true 63 | ForEachMacros: 64 | - foreach 65 | - Q_FOREACH 66 | - BOOST_FOREACH 67 | IncludeBlocks: Preserve 68 | IncludeCategories: 69 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 70 | Priority: 2 71 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 72 | Priority: 3 73 | - Regex: '.*' 74 | Priority: 1 75 | IncludeIsMainRegex: '(Test)?$' 76 | IndentCaseLabels: true 77 | IndentPPDirectives: None 78 | IndentWidth: 2 79 | IndentWrappedFunctionNames: false 80 | JavaScriptQuotes: Leave 81 | JavaScriptWrapImports: true 82 | KeepEmptyLinesAtTheStartOfBlocks: true 83 | MacroBlockBegin: '' 84 | MacroBlockEnd: '' 85 | MaxEmptyLinesToKeep: 1 86 | NamespaceIndentation: All 87 | ObjCBinPackProtocolList: Auto 88 | ObjCBlockIndentWidth: 2 89 | ObjCSpaceAfterProperty: false 90 | ObjCSpaceBeforeProtocolList: true 91 | PenaltyBreakAssignment: 2 92 | PenaltyBreakBeforeFirstCallParameter: 0 93 | PenaltyBreakComment: 300 94 | PenaltyBreakFirstLessLess: 120 95 | PenaltyBreakString: 1000 96 | PenaltyBreakTemplateDeclaration: 10 97 | PenaltyExcessCharacter: 1000000 98 | PenaltyReturnTypeOnItsOwnLine: 200 99 | PointerAlignment: Left 100 | ReflowComments: true 101 | SortIncludes: false 102 | SortUsingDeclarations: true 103 | SpaceAfterCStyleCast: false 104 | SpaceAfterLogicalNot: false 105 | SpaceAfterTemplateKeyword: true 106 | SpaceBeforeAssignmentOperators: true 107 | SpaceBeforeCpp11BracedList: false 108 | SpaceBeforeCtorInitializerColon: true 109 | SpaceBeforeInheritanceColon: true 110 | SpaceBeforeParens: ControlStatements 111 | SpaceBeforeRangeBasedForLoopColon: true 112 | SpaceInEmptyParentheses: false 113 | SpacesBeforeTrailingComments: 2 114 | SpacesInAngles: false 115 | SpacesInContainerLiterals: true 116 | SpacesInCStyleCastParentheses: false 117 | SpacesInParentheses: false 118 | SpacesInSquareBrackets: false 119 | Standard: Cpp11 120 | StatementMacros: 121 | - Q_UNUSED 122 | - QT_REQUIRE_VERSION 123 | TabWidth: 2 124 | UseTab: Never 125 | ... 126 | 127 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | // Copyright 2021 John McFarlane 2 | // 3 | // Licensed under the Apache License, Version 2.0 (the "License"); 4 | // you may not use this file except in compliance with the License. 5 | // You may obtain a copy of the License at 6 | // 7 | // http://www.apache.org/licenses/LICENSE-2.0 8 | // 9 | // Unless required by applicable law or agreed to in writing, software 10 | // distributed under the License is distributed on an "AS IS" BASIS, 11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | // See the License for the specific language governing permissions and 13 | // limitations under the License. 14 | 15 | /// @file An example of a robust C++ program. 16 | /// @note Please read accompanying comments for explanations... 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include 25 | 26 | /// @brief A minimal assertion function for testing API contracts. 27 | /// @note This function lacks diagnostics and may not be suitable 28 | /// for defective or safety-critical applications. 29 | constexpr void eg_assert(bool condition) 30 | { 31 | if (condition) { 32 | return; 33 | } 34 | 35 | #if defined(LOG_AND_CONTINUE_STRATEGY) 36 | fmt::print(stderr, "a C++ API violation occurred\n"); 37 | #elif defined(TRAP_STRATEGY) 38 | std::terminate(); 39 | #elif defined(PREVENTION_STRATEGY) 40 | __builtin_unreachable(); 41 | #else 42 | #error missing strategy pre-processor definition 43 | #endif 44 | } 45 | 46 | constexpr auto min_number{1}; 47 | constexpr auto max_number{26}; 48 | 49 | /// @brief The letter at the given position in the English alphabet 50 | /// @param number the position of the letter in the alphabet 51 | /// @return the letter at that give position as uppercase 52 | /// @note The position of the first letter, 'A', is 1 53 | /// @note It can be implied from this description 54 | /// that values <1 or >26 violate the contract of this API. 55 | /// Regardless of the assertions within the function, 56 | /// a program in which the contract is violates 57 | /// should be considered to exhibit undefined behavior. 58 | /// However, it rarely hurts to clarify contracts... 59 | /// @pre number is in range [1..26] 60 | constexpr auto number_to_letter(int number) 61 | { 62 | // Assertions - and not logical checks - are appropriate here. 63 | // They are here to help analysis tools, such as UBSan, detect bugs. 64 | // They can also server as documentation. 65 | eg_assert(number >= min_number); 66 | eg_assert(number <= max_number); 67 | 68 | // Just because we can reason about the behavior of 69 | // this implementation of the function doesn't mean 70 | // its behavior is defined when its contract is violated. 71 | // For example, the API provider reserves the right 72 | // to implement the function with a lookup table. 73 | return char(number - min_number + 'A'); 74 | } 75 | 76 | /// @brief Execute the 'business logic' of the program, after sanitization. 77 | /// @pre Requires sanitized data, i.e. number in the range 1<=number<=26. 78 | /// @note This function is safe to make assumptions about the data. 79 | /// @note Any `@pre` precondition violation is a C++ API Contract violation. 80 | void sanitized_run(int number) 81 | { 82 | fmt::print("{}", number_to_letter(number)); 83 | } 84 | 85 | /// @brief Sanitize the user input, testing user violation of End User Contract 86 | /// before passing sanitized input to the 'business logic' of the program. 87 | /// @param args program arguments (excluding executable itself) 88 | /// @return true iff the function was able to do its job 89 | /// @pre arguments are null-terminated strings 90 | /// @note There are no assumptions about the contents of 91 | /// the strings passed into this function. 92 | /// @note The ISO C++ Standard imposes many contractual requirements on the API. 93 | /// For example, the pointers must point to valid memory. 94 | /// But none of those requirements need to be reiterated here. 95 | /// @note The value this function brings to the program is that 96 | /// it makes the code safer by exploiting the type system. 97 | /// `std::span` in inherentely safer than `main` parameters. 98 | /// Type-safety and static checking is generally better 99 | /// than run-time contract and dynamic checking. 100 | auto unsanitized_run(std::span args) 101 | { 102 | using namespace std::literals::string_view_literals; 103 | 104 | // Verify correct number of arguments. 105 | constexpr auto expected_num_params{1}; 106 | auto const actual_num_params{args.size()}; 107 | if (actual_num_params != expected_num_params) { 108 | // End User Contract violation; emit diagnostic and exit with non-zero exit code 109 | fmt::print( 110 | stderr, "Wrong number of arguments provided. Expected={}; Actual={}\n", expected_num_params, actual_num_params); 111 | return false; 112 | } 113 | 114 | // Print help text if requested. 115 | auto const argument{std::string_view{args[0]}}; 116 | if (argument == "--help"sv) { 117 | // **Not** an End User Contract violation; 118 | // print to stdout and exit with zero status code 119 | fmt::print("This program prints the letter of the alphabet at the given position.\n"); 120 | fmt::print("Usage: letter N\n"); 121 | fmt::print("N: number between {} and {}\n", min_number, max_number); 122 | return true; 123 | } 124 | 125 | // Convert the argument to a number. 126 | // Note: this further enhances type safety. 127 | int number; 128 | auto [ptr, ec] = std::from_chars(std::begin(argument), std::end(argument), number); 129 | if (ec == std::errc::invalid_argument || ptr != std::end(argument)) { 130 | // End User Contract violation; emit diagnostic and exit with non-zero exit code 131 | fmt::print(stderr, "Unrecognized number, '{}'\n", argument); 132 | return false; 133 | } 134 | 135 | // Verify the range of number. 136 | if (number < min_number || number > max_number) { 137 | // End User Contract violation; emit diagnostic and exit with non-zero exit code 138 | fmt::print(stderr, "Out-of-range number, {}\n", number); 139 | return false; 140 | } 141 | 142 | // The input is now successfully sanitized. If the program gets this far, 143 | // the End User Contract was not violated by the user. 144 | sanitized_run(number); 145 | 146 | return true; 147 | } 148 | 149 | /// @brief program entry point 150 | /// @note We should assume that the ISO C++ Standard is not violated by calls to main. 151 | /// @note We should **not** assume that the End User Contract is not violated by calls to main. 152 | auto main(int argc, char* argv[]) -> int 153 | { 154 | if (!unsanitized_run(std::span{argv + 1, std::size_t(argc) - 1U})) { 155 | fmt::print("Try --help\n"); 156 | return EXIT_FAILURE; 157 | } 158 | 159 | return EXIT_SUCCESS; 160 | } 161 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: > 3 | *, 4 | -cppcoreguidelines-init-variables, 5 | -cppcoreguidelines-pro-type-member-init, 6 | -fuchsia-*, 7 | -hicpp-member-init, 8 | -llvmlibc-*, 9 | 10 | WarningsAsErrors: '' 11 | HeaderFilterRegex: '' 12 | AnalyzeTemporaryDtors: false 13 | FormatStyle: none 14 | User: jmcfarla 15 | CheckOptions: 16 | - key: abseil-string-find-startswith.AbseilStringsMatchHeader 17 | value: 'absl/strings/match.h' 18 | - key: abseil-string-find-startswith.IncludeStyle 19 | value: llvm 20 | - key: abseil-string-find-startswith.StringLikeClasses 21 | value: '::std::basic_string' 22 | - key: bugprone-argument-comment.CommentBoolLiterals 23 | value: '0' 24 | - key: bugprone-argument-comment.CommentCharacterLiterals 25 | value: '0' 26 | - key: bugprone-argument-comment.CommentFloatLiterals 27 | value: '0' 28 | - key: bugprone-argument-comment.CommentIntegerLiterals 29 | value: '0' 30 | - key: bugprone-argument-comment.CommentNullPtrs 31 | value: '0' 32 | - key: bugprone-argument-comment.CommentStringLiterals 33 | value: '0' 34 | - key: bugprone-argument-comment.CommentUserDefinedLiterals 35 | value: '0' 36 | - key: bugprone-argument-comment.StrictMode 37 | value: '0' 38 | - key: bugprone-assert-side-effect.AssertMacros 39 | value: assert 40 | - key: bugprone-assert-side-effect.CheckFunctionCalls 41 | value: '0' 42 | - key: bugprone-dangling-handle.HandleClasses 43 | value: 'std::basic_string_view;std::experimental::basic_string_view' 44 | - key: bugprone-exception-escape.FunctionsThatShouldNotThrow 45 | value: '' 46 | - key: bugprone-exception-escape.IgnoredExceptions 47 | value: '' 48 | - key: bugprone-misplaced-widening-cast.CheckImplicitCasts 49 | value: '0' 50 | - key: bugprone-sizeof-expression.WarnOnSizeOfCompareToConstant 51 | value: '1' 52 | - key: bugprone-sizeof-expression.WarnOnSizeOfConstant 53 | value: '1' 54 | - key: bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression 55 | value: '0' 56 | - key: bugprone-sizeof-expression.WarnOnSizeOfThis 57 | value: '1' 58 | - key: bugprone-string-constructor.LargeLengthThreshold 59 | value: '8388608' 60 | - key: bugprone-string-constructor.WarnOnLargeLength 61 | value: '1' 62 | - key: bugprone-suspicious-enum-usage.StrictMode 63 | value: '0' 64 | - key: bugprone-suspicious-missing-comma.MaxConcatenatedTokens 65 | value: '5' 66 | - key: bugprone-suspicious-missing-comma.RatioThreshold 67 | value: '0.200000' 68 | - key: bugprone-suspicious-missing-comma.SizeThreshold 69 | value: '5' 70 | - key: bugprone-suspicious-string-compare.StringCompareLikeFunctions 71 | value: '' 72 | - key: bugprone-suspicious-string-compare.WarnOnImplicitComparison 73 | value: '1' 74 | - key: bugprone-suspicious-string-compare.WarnOnLogicalNotComparison 75 | value: '0' 76 | - key: bugprone-too-small-loop-variable.MagnitudeBitsUpperLimit 77 | value: '16' 78 | - key: bugprone-unhandled-self-assignment.WarnOnlyIfThisHasSuspiciousField 79 | value: '1' 80 | - key: bugprone-unused-return-value.CheckedFunctions 81 | value: '::std::async;::std::launder;::std::remove;::std::remove_if;::std::unique;::std::unique_ptr::release;::std::basic_string::empty;::std::vector::empty' 82 | - key: cert-dcl16-c.IgnoreMacros 83 | value: '1' 84 | - key: cert-dcl16-c.NewSuffixes 85 | value: 'L;LL;LU;LLU' 86 | - key: cert-dcl59-cpp.HeaderFileExtensions 87 | value: ',h,hh,hpp,hxx' 88 | - key: cert-err09-cpp.CheckThrowTemporaries 89 | value: '1' 90 | - key: cert-err61-cpp.CheckThrowTemporaries 91 | value: '1' 92 | - key: cert-msc32-c.DisallowedSeedTypes 93 | value: 'time_t,std::time_t' 94 | - key: cert-msc51-cpp.DisallowedSeedTypes 95 | value: 'time_t,std::time_t' 96 | - key: cert-oop11-cpp.IncludeStyle 97 | value: llvm 98 | - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField 99 | value: '0' 100 | - key: cppcoreguidelines-avoid-magic-numbers.IgnoredFloatingPointValues 101 | value: '1.0;100.0;' 102 | - key: cppcoreguidelines-avoid-magic-numbers.IgnoredIntegerValues 103 | value: '1;2;3;4;' 104 | - key: cppcoreguidelines-explicit-virtual-functions.FinalSpelling 105 | value: final 106 | - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors 107 | value: '1' 108 | - key: cppcoreguidelines-explicit-virtual-functions.OverrideSpelling 109 | value: override 110 | - key: cppcoreguidelines-macro-usage.AllowedRegexp 111 | value: '^DEBUG_*' 112 | - key: cppcoreguidelines-macro-usage.CheckCapsOnly 113 | value: '0' 114 | - key: cppcoreguidelines-macro-usage.IgnoreCommandLineMacros 115 | value: '1' 116 | - key: cppcoreguidelines-no-malloc.Allocations 117 | value: '::malloc;::calloc' 118 | - key: cppcoreguidelines-no-malloc.Deallocations 119 | value: '::free' 120 | - key: cppcoreguidelines-no-malloc.Reallocations 121 | value: '::realloc' 122 | - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic 123 | value: '1' 124 | - key: cppcoreguidelines-owning-memory.LegacyResourceConsumers 125 | value: '::free;::realloc;::freopen;::fclose' 126 | - key: cppcoreguidelines-owning-memory.LegacyResourceProducers 127 | value: '::malloc;::aligned_alloc;::realloc;::calloc;::fopen;::freopen;::tmpfile' 128 | - key: cppcoreguidelines-pro-bounds-constant-array-index.GslHeader 129 | value: '' 130 | - key: cppcoreguidelines-pro-bounds-constant-array-index.IncludeStyle 131 | value: 'llvm' 132 | - key: cppcoreguidelines-pro-type-member-init.IgnoreArrays 133 | value: '0' 134 | - key: cppcoreguidelines-pro-type-member-init.UseAssignment 135 | value: '0' 136 | - key: cppcoreguidelines-special-member-functions.AllowMissingMoveFunctions 137 | value: '0' 138 | - key: cppcoreguidelines-special-member-functions.AllowSoleDefaultDtor 139 | value: '0' 140 | - key: fuchsia-header-anon-namespaces.HeaderFileExtensions 141 | value: ',h,hh,hpp,hxx' 142 | - key: fuchsia-restrict-system-includes.Includes 143 | value: '*' 144 | - key: google-build-namespaces.HeaderFileExtensions 145 | value: ',h,hh,hpp,hxx' 146 | - key: google-global-names-in-headers.HeaderFileExtensions 147 | value: ',h,hh,hpp,hxx' 148 | - key: google-readability-braces-around-statements.ShortStatementLines 149 | value: '1' 150 | - key: google-readability-function-size.BranchThreshold 151 | value: '4294967295' 152 | - key: google-readability-function-size.LineThreshold 153 | value: '4294967295' 154 | - key: google-readability-function-size.NestingThreshold 155 | value: '4294967295' 156 | - key: google-readability-function-size.ParameterThreshold 157 | value: '4294967295' 158 | - key: google-readability-function-size.StatementThreshold 159 | value: '800' 160 | - key: google-readability-function-size.VariableThreshold 161 | value: '4294967295' 162 | - key: google-readability-namespace-comments.ShortNamespaceLines 163 | value: '10' 164 | - key: google-readability-namespace-comments.SpacesBeforeComments 165 | value: '2' 166 | - key: google-runtime-int.SignedTypePrefix 167 | value: int 168 | - key: google-runtime-int.TypeSuffix 169 | value: '' 170 | - key: google-runtime-int.UnsignedTypePrefix 171 | value: uint 172 | - key: google-runtime-references.WhiteListTypes 173 | value: '' 174 | - key: hicpp-braces-around-statements.ShortStatementLines 175 | value: '0' 176 | - key: hicpp-function-size.BranchThreshold 177 | value: '4294967295' 178 | - key: hicpp-function-size.LineThreshold 179 | value: '4294967295' 180 | - key: hicpp-function-size.NestingThreshold 181 | value: '4294967295' 182 | - key: hicpp-function-size.ParameterThreshold 183 | value: '4294967295' 184 | - key: hicpp-function-size.StatementThreshold 185 | value: '800' 186 | - key: hicpp-function-size.VariableThreshold 187 | value: '4294967295' 188 | - key: hicpp-member-init.IgnoreArrays 189 | value: '0' 190 | - key: hicpp-member-init.UseAssignment 191 | value: '0' 192 | - key: hicpp-move-const-arg.CheckTriviallyCopyableMove 193 | value: '1' 194 | - key: hicpp-multiway-paths-covered.WarnOnMissingElse 195 | value: '0' 196 | - key: hicpp-named-parameter.IgnoreFailedSplit 197 | value: '0' 198 | - key: hicpp-no-malloc.Allocations 199 | value: '::malloc;::calloc' 200 | - key: hicpp-no-malloc.Deallocations 201 | value: '::free' 202 | - key: hicpp-no-malloc.Reallocations 203 | value: '::realloc' 204 | - key: hicpp-special-member-functions.AllowMissingMoveFunctions 205 | value: '0' 206 | - key: hicpp-special-member-functions.AllowSoleDefaultDtor 207 | value: '0' 208 | - key: hicpp-uppercase-literal-suffix.IgnoreMacros 209 | value: '1' 210 | - key: hicpp-uppercase-literal-suffix.NewSuffixes 211 | value: '' 212 | - key: hicpp-use-auto.MinTypeNameLength 213 | value: '5' 214 | - key: hicpp-use-auto.RemoveStars 215 | value: '0' 216 | - key: hicpp-use-emplace.ContainersWithPushBack 217 | value: '::std::vector;::std::list;::std::deque' 218 | - key: hicpp-use-emplace.SmartPointers 219 | value: '::std::shared_ptr;::std::unique_ptr;::std::auto_ptr;::std::weak_ptr' 220 | - key: hicpp-use-emplace.TupleMakeFunctions 221 | value: '::std::make_pair;::std::make_tuple' 222 | - key: hicpp-use-emplace.TupleTypes 223 | value: '::std::pair;::std::tuple' 224 | - key: hicpp-use-equals-default.IgnoreMacros 225 | value: '1' 226 | - key: hicpp-use-equals-delete.IgnoreMacros 227 | value: '1' 228 | - key: hicpp-use-noexcept.ReplacementString 229 | value: '' 230 | - key: hicpp-use-noexcept.UseNoexceptFalse 231 | value: '1' 232 | - key: hicpp-use-nullptr.NullMacros 233 | value: '' 234 | - key: hicpp-use-override.FinalSpelling 235 | value: final 236 | - key: hicpp-use-override.IgnoreDestructors 237 | value: '0' 238 | - key: hicpp-use-override.OverrideSpelling 239 | value: override 240 | - key: llvm-namespace-comment.ShortNamespaceLines 241 | value: '1' 242 | - key: llvm-namespace-comment.SpacesBeforeComments 243 | value: '1' 244 | - key: misc-definitions-in-headers.HeaderFileExtensions 245 | value: ',h,hh,hpp,hxx' 246 | - key: misc-definitions-in-headers.UseHeaderFileExtension 247 | value: '1' 248 | - key: misc-throw-by-value-catch-by-reference.CheckThrowTemporaries 249 | value: '1' 250 | - key: misc-unused-parameters.StrictMode 251 | value: '0' 252 | - key: modernize-loop-convert.MaxCopySize 253 | value: '16' 254 | - key: modernize-loop-convert.MinConfidence 255 | value: reasonable 256 | - key: modernize-loop-convert.NamingStyle 257 | value: lower_case 258 | - key: modernize-make-shared.IgnoreMacros 259 | value: '1' 260 | - key: modernize-make-shared.IncludeStyle 261 | value: 'llvm' 262 | - key: modernize-make-shared.MakeSmartPtrFunction 263 | value: 'std::make_shared' 264 | - key: modernize-make-shared.MakeSmartPtrFunctionHeader 265 | value: memory 266 | - key: modernize-make-unique.IgnoreMacros 267 | value: '1' 268 | - key: modernize-make-unique.IncludeStyle 269 | value: 'llvm' 270 | - key: modernize-make-unique.MakeSmartPtrFunction 271 | value: 'std::make_unique' 272 | - key: modernize-make-unique.MakeSmartPtrFunctionHeader 273 | value: memory 274 | - key: modernize-pass-by-value.IncludeStyle 275 | value: llvm 276 | - key: modernize-pass-by-value.ValuesOnly 277 | value: '0' 278 | - key: modernize-raw-string-literal.ReplaceShorterLiterals 279 | value: '0' 280 | - key: modernize-replace-auto-ptr.IncludeStyle 281 | value: llvm 282 | - key: modernize-replace-random-shuffle.IncludeStyle 283 | value: llvm 284 | - key: modernize-use-auto.MinTypeNameLength 285 | value: '5' 286 | - key: modernize-use-auto.RemoveStars 287 | value: '0' 288 | - key: modernize-use-default-member-init.IgnoreMacros 289 | value: '1' 290 | - key: modernize-use-default-member-init.UseAssignment 291 | value: '0' 292 | - key: modernize-use-emplace.ContainersWithPushBack 293 | value: '::std::vector;::std::list;::std::deque' 294 | - key: modernize-use-emplace.SmartPointers 295 | value: '::std::shared_ptr;::std::unique_ptr;::std::auto_ptr;::std::weak_ptr' 296 | - key: modernize-use-emplace.TupleMakeFunctions 297 | value: '::std::make_pair;::std::make_tuple' 298 | - key: modernize-use-emplace.TupleTypes 299 | value: '::std::pair;::std::tuple' 300 | - key: modernize-use-equals-default.IgnoreMacros 301 | value: '1' 302 | - key: modernize-use-equals-delete.IgnoreMacros 303 | value: '1' 304 | - key: modernize-use-nodiscard.ReplacementString 305 | value: '[[nodiscard]]' 306 | - key: modernize-use-noexcept.ReplacementString 307 | value: '' 308 | - key: modernize-use-noexcept.UseNoexceptFalse 309 | value: '1' 310 | - key: modernize-use-nullptr.NullMacros 311 | value: 'NULL' 312 | - key: modernize-use-override.FinalSpelling 313 | value: final 314 | - key: modernize-use-override.IgnoreDestructors 315 | value: '0' 316 | - key: modernize-use-override.OverrideSpelling 317 | value: override 318 | - key: modernize-use-transparent-functors.SafeMode 319 | value: '0' 320 | - key: modernize-use-using.IgnoreMacros 321 | value: '1' 322 | - key: objc-forbidden-subclassing.ForbiddenSuperClassNames 323 | value: 'ABNewPersonViewController;ABPeoplePickerNavigationController;ABPersonViewController;ABUnknownPersonViewController;NSHashTable;NSMapTable;NSPointerArray;NSPointerFunctions;NSTimer;UIActionSheet;UIAlertView;UIImagePickerController;UITextInputMode;UIWebView' 324 | - key: openmp-exception-escape.IgnoredExceptions 325 | value: '' 326 | - key: performance-faster-string-find.StringLikeClasses 327 | value: 'std::basic_string' 328 | - key: performance-for-range-copy.AllowedTypes 329 | value: '' 330 | - key: performance-for-range-copy.WarnOnAllAutoCopies 331 | value: '0' 332 | - key: performance-inefficient-string-concatenation.StrictMode 333 | value: '0' 334 | - key: performance-inefficient-vector-operation.VectorLikeClasses 335 | value: '::std::vector' 336 | - key: performance-move-const-arg.CheckTriviallyCopyableMove 337 | value: '1' 338 | - key: performance-move-constructor-init.IncludeStyle 339 | value: llvm 340 | - key: performance-type-promotion-in-math-fn.IncludeStyle 341 | value: llvm 342 | - key: performance-unnecessary-copy-initialization.AllowedTypes 343 | value: '' 344 | - key: performance-unnecessary-value-param.AllowedTypes 345 | value: '' 346 | - key: performance-unnecessary-value-param.IncludeStyle 347 | value: llvm 348 | - key: portability-simd-intrinsics.Std 349 | value: '' 350 | - key: portability-simd-intrinsics.Suggest 351 | value: '0' 352 | - key: readability-braces-around-statements.ShortStatementLines 353 | value: '0' 354 | - key: readability-function-size.BranchThreshold 355 | value: '4294967295' 356 | - key: readability-function-size.LineThreshold 357 | value: '4294967295' 358 | - key: readability-function-size.NestingThreshold 359 | value: '4294967295' 360 | - key: readability-function-size.ParameterThreshold 361 | value: '4294967295' 362 | - key: readability-function-size.StatementThreshold 363 | value: '800' 364 | - key: readability-function-size.VariableThreshold 365 | value: '4294967295' 366 | - key: readability-identifier-naming.IgnoreFailedSplit 367 | value: '0' 368 | - key: readability-identifier-naming.AbstractClassCase 369 | value: lower_case 370 | - key: readability-identifier-naming.AbstractClassPrefix 371 | value: '' 372 | - key: readability-identifier-naming.ClassCase 373 | value: lower_case 374 | - key: readability-identifier-naming.ClassPrefix 375 | value: '' 376 | - key: readability-identifier-naming.ClassConstantCase 377 | value: lower_case 378 | - key: readability-identifier-naming.ClassConstantPrefix 379 | value: '' 380 | - key: readability-identifier-naming.ClassMemberCase 381 | value: lower_case 382 | - key: readability-identifier-naming.ClassMethodCase 383 | value: lower_case 384 | - key: readability-identifier-naming.ConstantCase 385 | value: lower_case 386 | - key: readability-identifier-naming.ConstantSuffix 387 | value: '' 388 | - key: readability-identifier-naming.ConstexprFunctionCase 389 | value: lower_case 390 | - key: readability-identifier-naming.ConstexprMethodCase 391 | value: lower_case 392 | - key: readability-identifier-naming.ConstexprVariableCase 393 | value: lower_case 394 | - key: readability-identifier-naming.EnumCase 395 | value: lower_case 396 | - key: readability-identifier-naming.EnumPrefix 397 | value: '' 398 | - key: readability-identifier-naming.EnumConstantCase 399 | value: lower_case 400 | - key: readability-identifier-naming.FunctionCase 401 | value: lower_case 402 | - key: readability-identifier-naming.GlobalConstantCase 403 | value: lower_case 404 | - key: readability-identifier-naming.GlobalFunctionCase 405 | value: lower_case 406 | - key: readability-identifier-naming.GlobalVariableCase 407 | value: lower_case 408 | - key: readability-identifier-naming.GlobalVariablePrefix 409 | value: '' 410 | - key: readability-identifier-naming.InlineNamespaceCase 411 | value: lower_case 412 | - key: readability-identifier-naming.LocalConstantCase 413 | value: lower_case 414 | - key: readability-identifier-naming.LocalConstantPrefix 415 | value: '' 416 | - key: readability-identifier-naming.LocalVariableCase 417 | value: lower_case 418 | - key: readability-identifier-naming.MemberCase 419 | value: lower_case 420 | - key: readability-identifier-naming.MemberPrefix 421 | value: '' 422 | - key: readability-identifier-naming.ConstantMemberCase 423 | value: lower_case 424 | - key: readability-identifier-naming.PrivateMemberPrefix 425 | value: '' 426 | - key: readability-identifier-naming.ProtectedMemberPrefix 427 | value: '' 428 | - key: readability-identifier-naming.PublicMemberCase 429 | value: lower_case 430 | - key: readability-identifier-naming.MethodCase 431 | value: lower_case 432 | - key: readability-identifier-naming.PrivateMethodPrefix 433 | value: '' 434 | - key: readability-identifier-naming.ProtectedMethodPrefix 435 | value: '' 436 | - key: readability-identifier-naming.NamespaceCase 437 | value: lower_case 438 | - key: readability-identifier-naming.ParameterCase 439 | value: lower_case 440 | - key: readability-identifier-naming.ParameterPrefix 441 | value: '' 442 | - key: readability-identifier-naming.ConstantParameterCase 443 | value: lower_case 444 | - key: readability-identifier-naming.ConstantParameterPrefix 445 | value: '' 446 | - key: readability-identifier-naming.ParameterPackCase 447 | value: lower_case 448 | - key: readability-identifier-naming.PureFunctionCase 449 | value: lower_case 450 | - key: readability-identifier-naming.PureMethodCase 451 | value: lower_case 452 | - key: readability-identifier-naming.StaticConstantCase 453 | value: lower_case 454 | - key: readability-identifier-naming.StaticVariableCase 455 | value: lower_case 456 | - key: readability-identifier-naming.StaticVariablePrefix 457 | value: '' 458 | - key: readability-identifier-naming.StructCase 459 | value: lower_case 460 | - key: readability-identifier-naming.TemplateParameterCase 461 | value: lower_case 462 | - key: readability-identifier-naming.TemplateTemplateParameterCase 463 | value: lower_case 464 | - key: readability-identifier-naming.TemplateUsingCase 465 | value: lower_case 466 | - key: readability-identifier-naming.TemplateUsingPrefix 467 | value: '' 468 | - key: readability-identifier-naming.TypeTemplateParameterCase 469 | value: lower_case 470 | - key: readability-identifier-naming.TypeTemplateParameterSuffix 471 | value: '' 472 | - key: readability-identifier-naming.TypedefCase 473 | value: lower_case 474 | - key: readability-identifier-naming.TypedefSuffix 475 | value: '_t' 476 | - key: readability-identifier-naming.UnionCase 477 | value: lower_case 478 | - key: readability-identifier-naming.UnionPrefix 479 | value: '' 480 | - key: readability-identifier-naming.UsingCase 481 | value: lower_case 482 | - key: readability-identifier-naming.ValueTemplateParameterCase 483 | value: lower_case 484 | - key: readability-identifier-naming.VariableCase 485 | value: lower_case 486 | - key: readability-identifier-naming.VirtualMethodCase 487 | value: lower_case 488 | - key: readability-identifier-naming.VirtualMethodPrefix 489 | value: '' 490 | - key: readability-identifier-naming.IgnoreFailedSplit 491 | value: 0 492 | - key: readability-implicit-bool-conversion.AllowIntegerConditions 493 | value: '0' 494 | - key: readability-implicit-bool-conversion.AllowPointerConditions 495 | value: '0' 496 | - key: readability-inconsistent-declaration-parameter-name.IgnoreMacros 497 | value: '1' 498 | - key: readability-inconsistent-declaration-parameter-name.Strict 499 | value: '0' 500 | - key: readability-magic-numbers.IgnoredFloatingPointValues 501 | value: '1.0;100.0;' 502 | - key: readability-magic-numbers.IgnoredIntegerValues 503 | value: '1;2;3;4;' 504 | - key: readability-redundant-smartptr-get.IgnoreMacros 505 | value: '1' 506 | - key: readability-simplify-boolean-expr.ChainedConditionalAssignment 507 | value: '0' 508 | - key: readability-simplify-boolean-expr.ChainedConditionalReturn 509 | value: '0' 510 | - key: readability-simplify-subscript-expr.Types 511 | value: '::std::basic_string;::std::basic_string_view;::std::vector;::std::array' 512 | - key: readability-static-accessed-through-instance.NameSpecifierNestingThreshold 513 | value: '3' 514 | - key: readability-uppercase-literal-suffix.IgnoreMacros 515 | value: '1' 516 | - key: readability-uppercase-literal-suffix.NewSuffixes 517 | value: '' 518 | - key: zircon-temporary-objects.Names 519 | value: '' 520 | ... 521 | 522 | --------------------------------------------------------------------------------