├── .clang-tidy ├── .gitattributes ├── .github ├── actions │ ├── clang-tidy │ │ └── action.yml │ ├── configure-cmake │ │ └── action.yml │ ├── cppcheck │ │ └── action.yml │ ├── create-release │ │ └── action.yml │ ├── install-packages │ │ └── action.yml │ ├── process-artifacts │ │ └── action.yml │ └── runtime-checks │ │ └── action.yml └── workflows │ └── cmake.yml ├── .gitignore ├── CMakeLists.txt ├── README.md ├── cmake ├── CompilerFlags.cmake ├── CopyHelper.cmake ├── CustomStdlibAndSanitizers.cmake ├── DetectLibcpp.cmake └── Options.cmake ├── disable_modules.props ├── generated ├── include │ └── Helper.h └── src │ └── Helper.cpp ├── launcher.command ├── main.cpp ├── scripts ├── build_cppcheck.sh ├── cmake.sh └── run_cppcheck.sh └── tastatura.txt /.clang-tidy: -------------------------------------------------------------------------------- 1 | # Generated from CLion Inspection settings 2 | --- 3 | Checks: '-*, 4 | bugprone-argument-comment, 5 | bugprone-assert-side-effect, 6 | bugprone-bad-signal-to-kill-thread, 7 | bugprone-branch-clone, 8 | bugprone-copy-constructor-init, 9 | bugprone-dangling-handle, 10 | bugprone-dynamic-static-initializers, 11 | bugprone-fold-init-type, 12 | bugprone-forward-declaration-namespace, 13 | bugprone-forwarding-reference-overload, 14 | bugprone-inaccurate-erase, 15 | bugprone-incorrect-roundings, 16 | bugprone-integer-division, 17 | bugprone-lambda-function-name, 18 | bugprone-macro-parentheses, 19 | bugprone-macro-repeated-side-effects, 20 | bugprone-misplaced-operator-in-strlen-in-alloc, 21 | bugprone-misplaced-pointer-arithmetic-in-alloc, 22 | bugprone-misplaced-widening-cast, 23 | bugprone-move-forwarding-reference, 24 | bugprone-multiple-statement-macro, 25 | bugprone-no-escape, 26 | bugprone-parent-virtual-call, 27 | bugprone-posix-return, 28 | bugprone-reserved-identifier, 29 | bugprone-sizeof-container, 30 | bugprone-sizeof-expression, 31 | bugprone-spuriously-wake-up-functions, 32 | bugprone-string-constructor, 33 | bugprone-string-integer-assignment, 34 | bugprone-string-literal-with-embedded-nul, 35 | bugprone-suspicious-enum-usage, 36 | bugprone-suspicious-include, 37 | bugprone-suspicious-memset-usage, 38 | bugprone-suspicious-missing-comma, 39 | bugprone-suspicious-semicolon, 40 | bugprone-suspicious-string-compare, 41 | bugprone-suspicious-memory-comparison, 42 | bugprone-suspicious-realloc-usage, 43 | bugprone-swapped-arguments, 44 | bugprone-terminating-continue, 45 | bugprone-throw-keyword-missing, 46 | bugprone-too-small-loop-variable, 47 | bugprone-undefined-memory-manipulation, 48 | bugprone-undelegated-constructor, 49 | bugprone-unhandled-self-assignment, 50 | bugprone-unused-raii, 51 | bugprone-unused-return-value, 52 | bugprone-use-after-move, 53 | bugprone-virtual-near-miss, 54 | cert-dcl21-cpp, 55 | cert-dcl58-cpp, 56 | cert-err34-c, 57 | cert-err52-cpp, 58 | cert-err60-cpp, 59 | cert-flp30-c, 60 | cert-msc50-cpp, 61 | cert-msc51-cpp, 62 | cert-str34-c, 63 | cppcoreguidelines-interfaces-global-init, 64 | cppcoreguidelines-narrowing-conversions, 65 | cppcoreguidelines-pro-type-member-init, 66 | cppcoreguidelines-pro-type-static-cast-downcast, 67 | cppcoreguidelines-slicing, 68 | google-default-arguments, 69 | google-explicit-constructor, 70 | google-runtime-operator, 71 | hicpp-exception-baseclass, 72 | hicpp-multiway-paths-covered, 73 | misc-misplaced-const, 74 | misc-new-delete-overloads, 75 | misc-no-recursion, 76 | misc-non-copyable-objects, 77 | misc-throw-by-value-catch-by-reference, 78 | misc-unconventional-assign-operator, 79 | misc-uniqueptr-reset-release, 80 | modernize-avoid-bind, 81 | modernize-concat-nested-namespaces, 82 | modernize-deprecated-headers, 83 | modernize-deprecated-ios-base-aliases, 84 | modernize-loop-convert, 85 | modernize-make-shared, 86 | modernize-make-unique, 87 | modernize-pass-by-value, 88 | modernize-raw-string-literal, 89 | modernize-redundant-void-arg, 90 | modernize-replace-auto-ptr, 91 | modernize-replace-disallow-copy-and-assign-macro, 92 | modernize-replace-random-shuffle, 93 | modernize-return-braced-init-list, 94 | modernize-shrink-to-fit, 95 | modernize-unary-static-assert, 96 | modernize-use-auto, 97 | modernize-use-bool-literals, 98 | modernize-use-emplace, 99 | modernize-use-equals-default, 100 | modernize-use-equals-delete, 101 | modernize-use-nodiscard, 102 | modernize-use-noexcept, 103 | modernize-use-nullptr, 104 | modernize-use-override, 105 | modernize-use-transparent-functors, 106 | modernize-use-uncaught-exceptions, 107 | mpi-buffer-deref, 108 | mpi-type-mismatch, 109 | openmp-use-default-none, 110 | performance-faster-string-find, 111 | performance-for-range-copy, 112 | performance-implicit-conversion-in-loop, 113 | performance-inefficient-algorithm, 114 | performance-inefficient-string-concatenation, 115 | performance-inefficient-vector-operation, 116 | performance-move-const-arg, 117 | performance-move-constructor-init, 118 | performance-no-automatic-move, 119 | performance-noexcept-move-constructor, 120 | performance-trivially-destructible, 121 | performance-type-promotion-in-math-fn, 122 | performance-unnecessary-copy-initialization, 123 | performance-unnecessary-value-param, 124 | portability-simd-intrinsics, 125 | readability-avoid-const-params-in-decls, 126 | readability-const-return-type, 127 | readability-container-size-empty, 128 | readability-convert-member-functions-to-static, 129 | readability-delete-null-pointer, 130 | readability-deleted-default, 131 | readability-inconsistent-declaration-parameter-name, 132 | readability-make-member-function-const, 133 | readability-misleading-indentation, 134 | readability-misplaced-array-index, 135 | readability-non-const-parameter, 136 | readability-redundant-control-flow, 137 | readability-redundant-declaration, 138 | readability-redundant-function-ptr-dereference, 139 | readability-redundant-smartptr-get, 140 | readability-redundant-string-cstr, 141 | readability-redundant-string-init, 142 | readability-simplify-subscript-expr, 143 | readability-static-accessed-through-instance, 144 | readability-static-definition-in-anonymous-namespace, 145 | readability-string-compare, 146 | readability-uniqueptr-delete-release, 147 | readability-use-anyofallof' -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | generated/** linguist-generated 2 | ext/** linguist-vendored 3 | -------------------------------------------------------------------------------- /.github/actions/clang-tidy/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Run clang-tidy' 2 | description: 'Install and run clang-tidy' 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - name: Setup compiler env vars 8 | shell: bash 9 | run: | 10 | echo "CC=clang-${CLANG_VER}" >> $GITHUB_ENV 11 | echo "CXX=clang++-${CLANG_VER}" >> $GITHUB_ENV 12 | 13 | # Also see https://github.com/actions/runner-images/discussions/9446#discussioncomment-8668538 14 | - name: Install Clang ${{ env.CLANG_VER }} 15 | shell: bash 16 | run: | 17 | wget https://apt.llvm.org/llvm.sh 18 | chmod +x ./llvm.sh 19 | sudo ./llvm.sh ${CLANG_VER} 20 | 21 | - name: Install clang-tidy 22 | shell: bash 23 | run: | 24 | sudo apt-get update 25 | sudo apt-get install --no-install-recommends clang-tidy-${{ env.CLANG_VER }} libc++-${{ env.CLANG_VER }}-dev libc++abi-${{ env.CLANG_VER }}-dev ninja-build 26 | 27 | - name: Configure CMake 28 | uses: ./.github/actions/configure-cmake 29 | with: 30 | custom_flags: '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON -GNinja' 31 | cache_key: 'cache-clang-tidy' 32 | 33 | - name: Clang-Tidy 34 | continue-on-error: true 35 | shell: bash 36 | # clang-tidy is not able to follow symbolic links: https://bugs.llvm.org/show_bug.cgi?id=47460 37 | # need to use | as sed separator because / is used in paths 38 | run: | 39 | sed -i "s|$(which ${CXX})|$(realpath $(which ${CXX}))|g" "${BUILD_DIR}"/compile_commands.json 40 | 41 | cat "${BUILD_DIR}"/compile_commands.json | 42 | jq -r '.[] | .file' | # select source file paths from CMake project; -r to strip quotes 43 | grep -v "/${BUILD_DIR}/_deps/" | # ignore external dependencies 44 | grep -v "/${EXT_DIR}/" | # ignore external vendored dependencies 45 | xargs clang-tidy-${{ env.CLANG_VER }} -p "${BUILD_DIR}" 46 | -------------------------------------------------------------------------------- /.github/actions/configure-cmake/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Configure CMake' 2 | description: 'Common logic for CMake configuration' 3 | inputs: 4 | warnings_as_errors: 5 | description: 'Treat warnings as errors' 6 | required: false 7 | default: 'OFF' 8 | custom_flags: 9 | description: 'Custom CMake configuration flags' 10 | required: false 11 | cache_key: 12 | description: 'Deps cache key' 13 | required: false 14 | default: 'cache-deps' 15 | 16 | runs: 17 | using: "composite" 18 | steps: 19 | # Uncomment when using external dependencies, so they will be cached 20 | # - name: Cache deps 21 | # uses: actions/cache@v4 22 | # id: cache-deps 23 | # # make the key depend on the dependency version 24 | # with: 25 | # path: | 26 | # ${{ env.BUILD_DIR }}/_deps 27 | # key: ${{ inputs.cache_key }}-${{ matrix.cmake_generator }}-${{ matrix.os }}-${{ matrix.cxx }}-${{ matrix.asan_name }}-${{ env.BUILD_TYPE }} 28 | 29 | # NOTE: GH Actions does not allow updating the cache yet 30 | # Using the workaround found here: https://github.com/actions/cache/issues/171 31 | # Since this cache is small, it should not fill the cache too much 32 | - name: Cache Ninja deps 33 | uses: actions/cache@v4 34 | if: matrix.cmake_generator == 'Ninja' 35 | id: cache-deps-ninja 36 | with: 37 | path: | 38 | ${{ env.BUILD_DIR }}/.ninja_deps 39 | ${{ env.BUILD_DIR }}/.ninja_log 40 | key: ${{ matrix.os }}-${{ matrix.cxx }}-${{ matrix.asan_name }}-ninja-cache-${{ hashFiles('CMakeLists.txt') }} 41 | restore-keys: ${{ matrix.os }}-${{ matrix.cxx }}-${{ matrix.asan_name }}-ninja-cache- 42 | 43 | - name: Cache MinGW 44 | uses: actions/cache@v4 45 | id: cache-mingw 46 | if: runner.os == 'Windows' && matrix.cxx == 'g++' 47 | with: 48 | path: gcc 49 | key: ${{ runner.os }}-${{ env.MINGW_VER }} 50 | 51 | - name: Download toolchain (MinGW) 52 | uses: suisei-cn/actions-download-file@v1.6.0 53 | id: download-mingw-gcc 54 | if: runner.os == 'Windows' && matrix.cxx == 'g++' && steps.cache-mingw.outputs.cache-hit != 'true' 55 | with: 56 | url: "https://github.com/brechtsanders/winlibs_mingw/releases/download/${{ env.MINGW_VER }}" 57 | target: compiler/ 58 | 59 | - name: Install toolchain (MinGW) 60 | shell: bash 61 | if: runner.os == 'Windows' && matrix.cxx == 'g++' && steps.cache-mingw.outputs.cache-hit != 'true' 62 | run: | 63 | 7z x compiler/${{ steps.download-mingw-gcc.outputs.filename }} -ogcc 64 | 65 | - name: Configure CMake (MinGW) 66 | shell: bash 67 | if: runner.os == 'Windows' && matrix.cxx == 'g++' 68 | run: | 69 | PATH="$(pwd)/gcc/mingw64/bin:${PATH}" 70 | # because GH Actions does not properly prepend to $PATH and still chooses VM gcc 71 | # CMake generator not passed as option to script since it might not be defined 72 | export CMAKE_GENERATOR=${{ matrix.cmake_generator }} 73 | bash ./scripts/cmake.sh configure \ 74 | -b ${{ env.BUILD_DIR }} \ 75 | -c ${{ env.BUILD_TYPE }} \ 76 | -e "-DPROJECT_WARNINGS_AS_ERRORS=${{ inputs.warnings_as_errors }} -DGITHUB_ACTIONS=${GITHUB_ACTIONS} ${{ inputs.custom_flags }}" \ 77 | -i ${GITHUB_WORKSPACE}/artifacts \ 78 | -s ${GITHUB_WORKSPACE} 79 | 80 | - name: Configure CMake 81 | shell: bash 82 | if: ${{ !(runner.os == 'Windows' && matrix.cxx == 'g++') }} 83 | run: | 84 | export CMAKE_GENERATOR=${{ matrix.cmake_generator }} 85 | bash ./scripts/cmake.sh configure \ 86 | -b ${{ env.BUILD_DIR }} \ 87 | -c ${{ env.BUILD_TYPE }} \ 88 | -e "-DPROJECT_WARNINGS_AS_ERRORS=${{ inputs.warnings_as_errors }} -DGITHUB_ACTIONS=${GITHUB_ACTIONS} ${{ inputs.custom_flags }}" \ 89 | -i ${GITHUB_WORKSPACE}/artifacts \ 90 | -s ${GITHUB_WORKSPACE} 91 | 92 | # https://docs.github.com/en/actions/creating-actions/creating-a-composite-action 93 | # https://github.com/GuillaumeFalourd/poc-github-actions/blob/main/.github/workflows/36-local-action.yml 94 | -------------------------------------------------------------------------------- /.github/actions/cppcheck/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Run cppcheck' 2 | description: 'Install and run cppcheck' 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - name: Cache cppcheck 8 | uses: actions/cache/restore@v4 9 | id: cache-cppcheck 10 | with: 11 | path: cppcheck 12 | key: cppcheck-${{ env.CPPCHECK_VER }} 13 | 14 | - name: Build cppcheck 15 | shell: bash 16 | if: steps.cache-cppcheck.outputs.cache-hit != 'true' 17 | run: | 18 | bash ./scripts/build_cppcheck.sh -v ${CPPCHECK_VER} 19 | 20 | - name: Save cppcheck cache 21 | uses: actions/cache/save@v4 22 | if: steps.cache-cppcheck.outputs.cache-hit != 'true' 23 | with: 24 | path: cppcheck 25 | key: cppcheck-${{ env.CPPCHECK_VER }} 26 | 27 | - name: Install cppcheck 28 | shell: bash 29 | # this step is fast, no need for caching 30 | run: | 31 | cd cppcheck 32 | sudo cmake --install build 33 | 34 | # The flag CMAKE_EXPORT_COMPILE_COMMANDS generates compile_commands.json 35 | # which is used by cppcheck and clang-tidy 36 | - name: Configure CMake 37 | uses: ./.github/actions/configure-cmake 38 | with: 39 | custom_flags: '-DCMAKE_EXPORT_COMPILE_COMMANDS=ON' 40 | cache_key: 'cache-cppcheck' 41 | 42 | - name: Cppcheck 43 | shell: bash 44 | run: | 45 | bash ./scripts/run_cppcheck.sh 46 | -------------------------------------------------------------------------------- /.github/actions/create-release/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Create release' 2 | description: 'Create releases for tags' 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - name: Set Tag Name 8 | shell: bash 9 | if: startsWith(github.ref, 'refs/tags/') 10 | # trim prefix from ref to get tag name 11 | # replace `/` since we use the tag name as part of a file name 12 | run: echo "TAG_NAME=$(echo ${GITHUB_REF#'refs/tags/'} | sed "s|/|_|g")" >> ${GITHUB_ENV} 13 | 14 | - name: Add tag to folder name 15 | shell: bash 16 | if: startsWith(github.ref, 'refs/tags/') 17 | run: | 18 | mv ${{ env.ZIP_NAME }} ${{ env.ZIP_NAME }}_${{ env.TAG_NAME }} 19 | 20 | - name: Archive Release 21 | uses: thedoctor0/zip-release@master 22 | if: startsWith(github.ref, 'refs/tags/') 23 | with: 24 | type: 'zip' 25 | path: ${{ env.ZIP_NAME }}_${{ env.TAG_NAME }} 26 | filename: ${{ env.ZIP_NAME }}_${{ env.TAG_NAME }}.zip 27 | 28 | - name: Generate artifact attestation 29 | uses: actions/attest-build-provenance@v1 30 | if: ${{ startsWith(github.ref, 'refs/tags/') && ! env.PRIVATE_REPO }} 31 | with: 32 | subject-path: ${{ env.ZIP_NAME }}_${{ env.TAG_NAME }}.zip 33 | 34 | - name: Release 35 | uses: softprops/action-gh-release@v2 36 | if: startsWith(github.ref, 'refs/tags/') 37 | with: 38 | files: | 39 | ${{ env.ZIP_NAME }}_${{ env.TAG_NAME }}.zip 40 | -------------------------------------------------------------------------------- /.github/actions/install-packages/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Install packages' 2 | description: 'Install required packages' 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | # Common Linux dependencies 8 | - name: Install Linux Dependencies 9 | shell: bash 10 | if: runner.os == 'Linux' 11 | run: | 12 | sudo apt-get update 13 | sudo apt-get install ninja-build 14 | # https://github.com/llvm/llvm-project/issues/78354 15 | sudo sysctl vm.mmap_rnd_bits=28 16 | 17 | # Also see https://github.com/actions/runner-images/discussions/9446#discussioncomment-8668538 18 | - name: Install Clang ${{ matrix.clang_ver }} 19 | shell: bash 20 | if: runner.os == 'Linux' && matrix.runs_msan == true 21 | run: | 22 | wget https://apt.llvm.org/llvm.sh 23 | chmod +x ./llvm.sh 24 | sudo ./llvm.sh ${{ matrix.clang_ver }} 25 | 26 | - name: Install libc++ (Linux Clang ${{ matrix.clang_ver }}) 27 | shell: bash 28 | if: runner.os == 'Linux' && matrix.runs_msan == true 29 | run: | 30 | # sudo apt-get update 31 | sudo apt-get install --no-install-recommends libc++-${{ matrix.clang_ver }}-dev libc++abi-${{ matrix.clang_ver }}-dev 32 | 33 | - name: Install valgrind 34 | shell: bash 35 | if: runner.os == 'Linux' && matrix.runs_valgrind == true 36 | run: | 37 | # sudo apt-get update 38 | sudo apt-get install --no-install-recommends valgrind 39 | -------------------------------------------------------------------------------- /.github/actions/process-artifacts/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Process artifacts' 2 | description: 'Process artifact files' 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - name: Patch macOS launcher 8 | shell: bash 9 | if: runner.os == 'macOS' 10 | run: | 11 | sed -i '' -e "s/oop/${EXECUTABLE_NAME}/" "${{ env.ZIP_NAME }}/launcher.command" 12 | chmod +x "${{ env.ZIP_NAME }}/launcher.command" 13 | 14 | - name: Copy missing dylibs 15 | shell: bash 16 | if: runner.os == 'macOS' && matrix.cxx == 'clang++' 17 | # FIXME: temp disable asan for macOS due to github issues 18 | run: | 19 | if [[ "${BUILD_TYPE}" =~ "Deb" ]]; then 20 | mkdir lib 21 | # cp /Library/Developer/CommandLineTools/usr/lib/clang/16/lib/darwin/libclang_rt.asan_osx_dynamic.dylib lib 22 | # install_name_tool -change @rpath/libclang_rt.asan_osx_dynamic.dylib @executable_path/lib/libclang_rt.asan_osx_dynamic.dylib ${{ env.ZIP_NAME }}/${{ env.EXECUTABLE_NAME }} 23 | mv lib ${{ env.ZIP_NAME }}/ 24 | fi 25 | 26 | - name: Copy missing dylibs (g++) 27 | shell: bash 28 | if: runner.os == 'macOS' && startsWith(matrix.cxx, 'g++') 29 | run: | 30 | mkdir lib 31 | cp /opt/homebrew/lib/gcc/13/libstdc++.6.dylib /opt/homebrew/lib/gcc/13/libgcc_s.1.1.dylib lib 32 | install_name_tool -change /opt/homebrew/lib/gcc/13/libstdc++.6.dylib @executable_path/lib/libstdc++.6.dylib ${{ env.ZIP_NAME }}/${{ env.EXECUTABLE_NAME }} 33 | install_name_tool -change /opt/homebrew/lib/gcc/13/libgcc_s.1.1.dylib @executable_path/lib/libgcc_s.1.1.dylib ${{ env.ZIP_NAME }}/${{ env.EXECUTABLE_NAME }} 34 | mv lib ${{ env.ZIP_NAME }}/ 35 | 36 | - name: Copy missing dlls 37 | shell: bash 38 | if: runner.os == 'Windows' && matrix.cxx == 'cl' 39 | run: | 40 | if [[ "${BUILD_TYPE}" =~ "Deb" ]]; then 41 | # runtime debug DLLs 42 | cp "$(which ucrtbased.dll)" \ 43 | "$(which VCRUNTIME140_1D.dll)" \ 44 | "$(which MSVCP140D.dll)" \ 45 | "$(which VCRUNTIME140D.dll)" \ 46 | ${GITHUB_WORKSPACE}/${{ env.ZIP_NAME }} 47 | 48 | # sanitizers DLLs 49 | vcver=$(cat "C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Auxiliary/Build/Microsoft.VCToolsVersion.default.txt") 50 | vcbindir="C:/Program Files/Microsoft Visual Studio/2022/Enterprise/VC/Tools/MSVC/${vcver}/bin/Hostx64/x64/" 51 | cp "${vcbindir}/clang_rt.asan_dynamic-x86_64.dll" \ 52 | "${vcbindir}/clang_rt.asan_dbg_dynamic-x86_64.dll" \ 53 | ${GITHUB_WORKSPACE}/${{ env.ZIP_NAME }} 54 | fi 55 | 56 | # runtime release DLLs 57 | # if [[ "${BUILD_TYPE}" =~ "Rel" ]]; then 58 | cp "$(which ucrtbase.dll)" \ 59 | "$(which VCRUNTIME140_1.dll)" \ 60 | "$(which MSVCP140.dll)" \ 61 | "$(which VCRUNTIME140.dll)" \ 62 | ${GITHUB_WORKSPACE}/${{ env.ZIP_NAME }} 63 | # fi 64 | 65 | - name: Copy stdlib (MinGW) 66 | shell: bash 67 | if: runner.os == 'Windows' && matrix.cxx == 'g++' 68 | # static linking might not work with MinGW, might be easier this way 69 | run: | 70 | cp gcc/mingw64/bin/libstdc++-6.dll \ 71 | gcc/mingw64/bin/libgcc_s_seh-1.dll \ 72 | gcc/mingw64/bin/libwinpthread-1.dll \ 73 | ${GITHUB_WORKSPACE}/${{ env.ZIP_NAME }} 74 | -------------------------------------------------------------------------------- /.github/actions/runtime-checks/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Runtime checks' 2 | description: 'Run dynamic analysis tools' 3 | 4 | runs: 5 | using: "composite" 6 | steps: 7 | - name: Cache restore tools 8 | uses: actions/cache/restore@v4 9 | if: runner.os == 'Linux' && matrix.runs_msan == true 10 | id: cache-tools 11 | with: 12 | path: tools 13 | key: tools-clang-${{ matrix.clang_ver }}-stdlib-msan 14 | 15 | - name: Setup memory sanitizer 16 | shell: bash 17 | if: runner.os == 'Linux' && matrix.runs_msan == true && steps.cache-tools.outputs.cache-hit != 'true' 18 | run: | 19 | mkdir -p tools 20 | cd tools 21 | git clone --depth=1 --branch=llvmorg-${{ matrix.clang_ver_full }} https://github.com/llvm/llvm-project 22 | cd llvm-project 23 | # mkdir build; cd build 24 | sudo ln -s -f /usr/bin/$CC /usr/bin/clang 25 | sudo ln -s -f /usr/bin/$CXX /usr/bin/clang++ 26 | # https://github.com/llvm/llvm-project/issues/78354 27 | sudo sysctl vm.mmap_rnd_bits=28 28 | cmake -G Ninja -S runtimes -B build \ 29 | -DCMAKE_BUILD_TYPE=Release \ 30 | -DLLVM_ENABLE_RUNTIMES="libcxx;libcxxabi;libunwind" \ 31 | -DCMAKE_C_COMPILER=clang \ 32 | -DCMAKE_CXX_COMPILER=clang++ \ 33 | -DLLVM_USE_SANITIZER=MemoryWithOrigins \ 34 | -DCMAKE_BUILD_WITH_INSTALL_RPATH=true 35 | cmake --build build -j6 -- cxx cxxabi 36 | 37 | - name: Cache save tools 38 | uses: actions/cache/save@v4 39 | if: runner.os == 'Linux' && matrix.runs_msan == true && steps.cache-tools.outputs.cache-hit != 'true' 40 | with: 41 | path: tools 42 | key: tools-clang-${{ matrix.clang_ver }}-stdlib-msan 43 | 44 | - name: Sanitizers 45 | shell: bash 46 | # run one sanitizer for each env to avoid building extra binaries on one env 47 | if: (matrix.runs_asan == true || matrix.runs_msan == true) && runner.os != 'Windows' 48 | # detect_leaks is not supported on macOS 49 | # env: 50 | # ASAN_OPTIONS: detect_leaks=1 51 | run: | 52 | cat "${INPUT_FILENAME}" | tr -d '\r' | ./${{ env.ZIP_NAME }}/"${EXECUTABLE_NAME}" 53 | 54 | - name: Sanitizers (Windows MSVC) 55 | shell: bash 56 | # run one sanitizer for each OS to avoid building extra binaries 57 | if: matrix.cxx == 'cl' && matrix.runs_asan == true 58 | continue-on-error: true 59 | run: | 60 | cat "${INPUT_FILENAME}" | ./${{ env.ZIP_NAME }}/"${EXECUTABLE_NAME}".exe 61 | 62 | - name: Valgrind 63 | shell: bash 64 | if: runner.os == 'Linux' && matrix.runs_valgrind == true 65 | run: | 66 | # remove --show-leak-kinds=all (and --track-origins=yes) if there are many leaks in external libs 67 | cat "${INPUT_FILENAME}" | tr -d '\r' | valgrind \ 68 | --leak-check=full --show-leak-kinds=all --track-origins=yes \ 69 | --error-exitcode=1 \ 70 | ./${{ env.ZIP_NAME }}/"${EXECUTABLE_NAME}" 71 | -------------------------------------------------------------------------------- /.github/workflows/cmake.yml: -------------------------------------------------------------------------------- 1 | name: C++ CI 2 | 3 | on: 4 | push: 5 | branches: ['**'] # NOTE: replace/update with appropriate branch name(s) 6 | tags: ['**'] 7 | # pull_request: 8 | # branches: ['**'] # NOTE: replace/update with appropriate branch name(s) 9 | workflow_dispatch: 10 | inputs: 11 | build_type: 12 | description: Build type 13 | required: false 14 | default: 'Debug' 15 | type: choice 16 | options: 17 | - Debug 18 | - Release 19 | - RelWithDebInfo 20 | - MinSizeRel 21 | 22 | env: 23 | BUILD_TYPE: ${{ inputs.build_type || 'Debug' }} 24 | # NOTE: update executable name if it is changed in CMakeLists.txt 25 | EXECUTABLE_NAME: "oop" 26 | INPUT_FILENAME: "tastatura.txt" 27 | BIN_DIR: "bin" # update in cmake/Options.cmake:6 if changing name here 28 | BUILD_DIR: "build" 29 | EXT_DIR: "ext" 30 | GEN_DIR: "generated" 31 | 32 | defaults: 33 | run: 34 | # Use a bash shell, so we can use the same syntax for environment variable 35 | # access regardless of the host operating system 36 | # https://github.com/saxbophone/CPP20-Cross-Platform-Template 37 | shell: bash 38 | 39 | jobs: 40 | cppcheck: 41 | name: "Cppcheck" 42 | # concurrency: 43 | # group: "Cppcheck" 44 | runs-on: ubuntu-22.04 45 | timeout-minutes: 5 46 | env: 47 | # check https://github.com/danmar/cppcheck/releases for latest version 48 | # NOTE: consider updating this value in scripts/build_cppcheck.sh:4 when changing this value 49 | CPPCHECK_VER: "2.14.2" 50 | steps: 51 | - name: Checkout repo 52 | uses: actions/checkout@v4 53 | 54 | - name: Run cppcheck 55 | uses: ./.github/actions/cppcheck 56 | 57 | clang-tidy: 58 | name: "Clang-Tidy" 59 | # concurrency: 60 | # group: "Clang-Tidy" 61 | runs-on: ubuntu-22.04 62 | timeout-minutes: 5 63 | env: 64 | CLANG_VER: 18 65 | steps: 66 | - name: Checkout repo 67 | uses: actions/checkout@v4 68 | 69 | - name: Run clang-tidy 70 | uses: ./.github/actions/clang-tidy 71 | 72 | 73 | build: 74 | name: ${{ matrix.name }} 75 | # concurrency: 76 | # group: ${{ matrix.name }} 77 | runs-on: ${{ matrix.os }} 78 | timeout-minutes: 8 79 | permissions: 80 | attestations: write 81 | contents: write 82 | id-token: write 83 | 84 | env: 85 | CC: ${{ matrix.c }} 86 | CXX: ${{ matrix.cxx }} 87 | VSCMD_SKIP_SENDTELEMETRY: 1 88 | 89 | # NOTE: replace with another version if this one does not work 90 | # For more versions, see https://winlibs.com or 91 | # https://github.com/brechtsanders/winlibs_mingw/releases/ 92 | MINGW_VER: "13.3.0posix-11.0.1-msvcrt-r1/winlibs-x86_64-posix-seh-gcc-13.3.0-mingw-w64msvcrt-11.0.1-r1.7z" 93 | # Example: 94 | # MINGW_VER: "13.3.0posix-11.0.1-ucrt-r1/winlibs-x86_64-posix-seh-gcc-13.3.0-mingw-w64ucrt-11.0.1-r1.7z" 95 | # MINGW_VER: "14.1.0posix-18.1.7-12.0.0-ucrt-r2/winlibs-x86_64-posix-seh-gcc-14.1.0-mingw-w64ucrt-12.0.0-r2.7z" 96 | # MINGW_VER: "14.1.0posix-18.1.7-12.0.0-msvcrt-r2/winlibs-x86_64-posix-seh-gcc-14.1.0-mingw-w64msvcrt-12.0.0-r2.7z" 97 | 98 | 99 | strategy: 100 | fail-fast: false 101 | matrix: 102 | include: 103 | - os: ubuntu-22.04 104 | c: clang-18 105 | cxx: clang++-18 106 | clang_ver: "18" 107 | clang_ver_full: "18.1.8" 108 | name: "MSan: Ubuntu 22.04 Clang 18" 109 | cmake_flags: "-DUSE_MSAN=ON" 110 | cmake_generator: Ninja 111 | # This env runs memory sanitizers 112 | runs_msan: true 113 | 114 | - os: ubuntu-22.04 115 | c: gcc-12 116 | cxx: g++-12 117 | name: "ASan: Ubuntu 22.04 GCC 12" 118 | cmake_flags: "-DUSE_ASAN=ON" 119 | cmake_generator: Ninja 120 | # This env runs address sanitizers 121 | runs_asan: true 122 | # this is used to add a suffix to the archive name since we use the same compiler version 123 | asan_name: "-asan" 124 | 125 | - os: ubuntu-22.04 126 | c: gcc-12 127 | cxx: g++-12 128 | name: "Valgrind: Ubuntu 22.04 GCC 12" 129 | # cmake_flags: 130 | cmake_generator: Ninja 131 | # This env runs valgrind 132 | runs_valgrind: true 133 | 134 | - os: macos-14 135 | c: clang 136 | cxx: clang++ 137 | name: "macOS 14 Apple Clang 15" 138 | cmake_flags: "-DUSE_ASAN=OFF" 139 | # cmake_generator: 140 | # This env runs address sanitizers 141 | runs_asan: false 142 | 143 | - os: macos-14 144 | c: gcc-13 145 | cxx: g++-13 146 | name: "macOS 14 GCC 13" 147 | # cmake_flags: 148 | # cmake_generator: Ninja 149 | 150 | - os: windows-2022 151 | c: cl 152 | cxx: cl 153 | name: "ASan: Windows 2022 MSVC 19.43" 154 | cmake_flags: "-DUSE_ASAN=ON" 155 | # Ninja is not faster on MSVC because... MSVC 156 | # cmake_generator: "Ninja" 157 | # cmake_generator: "Ninja Multi-Config" 158 | # This env runs address sanitizers 159 | runs_asan: true 160 | 161 | - os: windows-2022 162 | c: gcc 163 | cxx: g++ 164 | name: "Windows 2022 MinGW GCC 13" 165 | # cmake_flags: 166 | cmake_generator: Ninja 167 | 168 | steps: 169 | - name: Checkout repo 170 | uses: actions/checkout@v4 171 | 172 | - name: Set timestamp, zip name, repo visibility 173 | env: 174 | GH_TOKEN: ${{ github.token }} 175 | run: | 176 | echo "TIMESTAMP=$(date +%Y-%m-%d-%H-%M-%S)" >> ${GITHUB_ENV} 177 | 178 | # use the full name as prefix: {user_name}_{repo_name} (replace / with _) 179 | echo "ZIP_NAME=$(echo "${GITHUB_REPOSITORY}_${{ env.BUILD_TYPE }}_${{ matrix.os }}_${{ matrix.cxx }}${{ matrix.asan_name }}" | sed 's|/|_|')" >> ${GITHUB_ENV} 180 | 181 | # or use only the repo name (github does not have a predefined environment variable for this) 182 | # the regex splits by / and keeps everything after / without the / character 183 | # echo "ZIP_NAME=$(echo "${GITHUB_REPOSITORY}_${{ env.BUILD_TYPE }}_${{ matrix.os }}_${{ matrix.cxx }}${{ matrix.asan_name }}" | sed -E 's|.+/(.+)|\1|')" >> ${GITHUB_ENV} 184 | if [[ $(gh repo view "${{ github.repository }}" --json isPrivate -q ".isPrivate") == "true" ]]; then 185 | echo "PRIVATE_REPO=true" >> ${GITHUB_ENV} 186 | else 187 | echo "Public repo" 188 | fi 189 | 190 | - name: Install packages 191 | uses: ./.github/actions/install-packages 192 | 193 | - name: Configure CMake 194 | uses: ./.github/actions/configure-cmake 195 | with: 196 | custom_flags: ${{ matrix.cmake_flags }} 197 | warnings_as_errors: 'ON' 198 | 199 | - name: Build 200 | run: | 201 | bash ./scripts/cmake.sh build -c ${{ env.BUILD_TYPE }} 202 | 203 | - name: Install 204 | # Use CMake to "install" build artifacts (only interested in CMake registered targets) to our custom artifacts directory 205 | run: | 206 | bash ./scripts/cmake.sh install -c ${{ env.BUILD_TYPE }} -i artifacts 207 | 208 | - name: Move artifacts 209 | run: | 210 | mkdir ${{ env.ZIP_NAME }} 211 | shopt -s dotglob 212 | mv artifacts/${{ env.BIN_DIR }}/* ${{ env.ZIP_NAME }} 213 | ls -la ${{ env.ZIP_NAME }} 214 | 215 | - name: Process artifacts 216 | uses: ./.github/actions/process-artifacts 217 | 218 | - name: Upload Artifacts 219 | uses: actions/upload-artifact@v4 220 | with: 221 | name: ${{ env.ZIP_NAME }}_${{ env.TIMESTAMP }} 222 | include-hidden-files: true 223 | path: ${{ env.ZIP_NAME }} 224 | retention-days: 30 225 | 226 | - name: Runtime checks 227 | uses: ./.github/actions/runtime-checks 228 | 229 | - name: Create release 230 | uses: ./.github/actions/create-release 231 | if: startsWith(github.ref, 'refs/tags/') 232 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | build/ 3 | install_dir/ 4 | 5 | # Created by https://www.toptal.com/developers/gitignore/api/c++,clion,cmake,codeblocks,emacs,gcov,sublimetext,vim,visualstudio,visualstudiocode,xcode 6 | # Edit at https://www.toptal.com/developers/gitignore?templates=c++,clion,cmake,codeblocks,emacs,gcov,sublimetext,vim,visualstudio,visualstudiocode,xcode 7 | 8 | ### C++ ### 9 | # Prerequisites 10 | *.d 11 | 12 | # Compiled Object files 13 | *.slo 14 | *.lo 15 | *.o 16 | *.obj 17 | 18 | # Precompiled Headers 19 | *.gch 20 | *.pch 21 | 22 | # Compiled Dynamic libraries 23 | *.so 24 | *.dylib 25 | *.dll 26 | 27 | # Fortran module files 28 | *.mod 29 | *.smod 30 | 31 | # Compiled Static libraries 32 | *.lai 33 | *.la 34 | *.a 35 | *.lib 36 | 37 | # Executables 38 | *.exe 39 | *.out 40 | *.app 41 | 42 | ### CLion ### 43 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 44 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 45 | 46 | # User-specific stuff 47 | .idea/**/workspace.xml 48 | .idea/**/tasks.xml 49 | .idea/**/usage.statistics.xml 50 | .idea/**/dictionaries 51 | .idea/**/shelf 52 | 53 | # AWS User-specific 54 | .idea/**/aws.xml 55 | 56 | # Generated files 57 | .idea/**/contentModel.xml 58 | 59 | # Sensitive or high-churn files 60 | .idea/**/dataSources/ 61 | .idea/**/dataSources.ids 62 | .idea/**/dataSources.local.xml 63 | .idea/**/sqlDataSources.xml 64 | .idea/**/dynamic.xml 65 | .idea/**/uiDesigner.xml 66 | .idea/**/dbnavigator.xml 67 | 68 | # Gradle 69 | .idea/**/gradle.xml 70 | .idea/**/libraries 71 | 72 | # Gradle and Maven with auto-import 73 | # When using Gradle or Maven with auto-import, you should exclude module files, 74 | # since they will be recreated, and may cause churn. Uncomment if using 75 | # auto-import. 76 | # .idea/artifacts 77 | # .idea/compiler.xml 78 | # .idea/jarRepositories.xml 79 | # .idea/modules.xml 80 | # .idea/*.iml 81 | # .idea/modules 82 | # *.iml 83 | # *.ipr 84 | 85 | # CMake 86 | cmake-build-*/ 87 | 88 | # Mongo Explorer plugin 89 | .idea/**/mongoSettings.xml 90 | 91 | # File-based project format 92 | *.iws 93 | 94 | # IntelliJ 95 | out/ 96 | 97 | # mpeltonen/sbt-idea plugin 98 | .idea_modules/ 99 | 100 | # JIRA plugin 101 | atlassian-ide-plugin.xml 102 | 103 | # Cursive Clojure plugin 104 | .idea/replstate.xml 105 | 106 | # SonarLint plugin 107 | .idea/sonarlint/ 108 | 109 | # Crashlytics plugin (for Android Studio and IntelliJ) 110 | com_crashlytics_export_strings.xml 111 | crashlytics.properties 112 | crashlytics-build.properties 113 | fabric.properties 114 | 115 | # Editor-based Rest Client 116 | .idea/httpRequests 117 | 118 | # Android studio 3.1+ serialized cache file 119 | .idea/caches/build_file_checksums.ser 120 | 121 | ### CLion Patch ### 122 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 123 | 124 | # *.iml 125 | # modules.xml 126 | # .idea/misc.xml 127 | # *.ipr 128 | 129 | # Sonarlint plugin 130 | # https://plugins.jetbrains.com/plugin/7973-sonarlint 131 | .idea/**/sonarlint/ 132 | 133 | # SonarQube Plugin 134 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin 135 | .idea/**/sonarIssues.xml 136 | 137 | # Markdown Navigator plugin 138 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced 139 | .idea/**/markdown-navigator.xml 140 | .idea/**/markdown-navigator-enh.xml 141 | .idea/**/markdown-navigator/ 142 | 143 | # Cache file creation bug 144 | # See https://youtrack.jetbrains.com/issue/JBR-2257 145 | .idea/$CACHE_FILE$ 146 | 147 | # CodeStream plugin 148 | # https://plugins.jetbrains.com/plugin/12206-codestream 149 | .idea/codestream.xml 150 | 151 | ### CMake ### 152 | CMakeLists.txt.user 153 | CMakeCache.txt 154 | CMakeFiles 155 | CMakeScripts 156 | Testing 157 | Makefile 158 | cmake_install.cmake 159 | install_manifest.txt 160 | compile_commands.json 161 | CTestTestfile.cmake 162 | _deps 163 | 164 | ### CMake Patch ### 165 | # External projects 166 | *-prefix/ 167 | 168 | ### CodeBlocks ### 169 | # specific to CodeBlocks IDE 170 | *.layout 171 | *.depend 172 | # generated directories 173 | bin/ 174 | obj/ 175 | 176 | ### Emacs ### 177 | # -*- mode: gitignore; -*- 178 | *~ 179 | \#*\# 180 | /.emacs.desktop 181 | /.emacs.desktop.lock 182 | *.elc 183 | auto-save-list 184 | tramp 185 | .\#* 186 | 187 | # Org-mode 188 | .org-id-locations 189 | *_archive 190 | 191 | # flymake-mode 192 | *_flymake.* 193 | 194 | # eshell files 195 | /eshell/history 196 | /eshell/lastdir 197 | 198 | # elpa packages 199 | /elpa/ 200 | 201 | # reftex files 202 | *.rel 203 | 204 | # AUCTeX auto folder 205 | /auto/ 206 | 207 | # cask packages 208 | .cask/ 209 | dist/ 210 | 211 | # Flycheck 212 | flycheck_*.el 213 | 214 | # server auth directory 215 | /server/ 216 | 217 | # projectiles files 218 | .projectile 219 | 220 | # directory configuration 221 | .dir-locals.el 222 | 223 | # network security 224 | /network-security.data 225 | 226 | 227 | ### Gcov ### 228 | # gcc coverage testing tool files 229 | 230 | *.gcno 231 | *.gcda 232 | *.gcov 233 | 234 | ### SublimeText ### 235 | # Cache files for Sublime Text 236 | *.tmlanguage.cache 237 | *.tmPreferences.cache 238 | *.stTheme.cache 239 | 240 | # Workspace files are user-specific 241 | *.sublime-workspace 242 | 243 | # Project files should be checked into the repository, unless a significant 244 | # proportion of contributors will probably not be using Sublime Text 245 | # *.sublime-project 246 | 247 | # SFTP configuration file 248 | sftp-config.json 249 | sftp-config-alt*.json 250 | 251 | # Package control specific files 252 | Package Control.last-run 253 | Package Control.ca-list 254 | Package Control.ca-bundle 255 | Package Control.system-ca-bundle 256 | Package Control.cache/ 257 | Package Control.ca-certs/ 258 | Package Control.merged-ca-bundle 259 | Package Control.user-ca-bundle 260 | oscrypto-ca-bundle.crt 261 | bh_unicode_properties.cache 262 | 263 | # Sublime-github package stores a github token in this file 264 | # https://packagecontrol.io/packages/sublime-github 265 | GitHub.sublime-settings 266 | 267 | ### Vim ### 268 | # Swap 269 | [._]*.s[a-v][a-z] 270 | !*.svg # comment out if you don't need vector files 271 | [._]*.sw[a-p] 272 | [._]s[a-rt-v][a-z] 273 | [._]ss[a-gi-z] 274 | [._]sw[a-p] 275 | 276 | # Session 277 | Session.vim 278 | Sessionx.vim 279 | 280 | # Temporary 281 | .netrwhist 282 | # Auto-generated tag files 283 | tags 284 | # Persistent undo 285 | [._]*.un~ 286 | 287 | ### VisualStudioCode ### 288 | .vscode/* 289 | !.vscode/settings.json 290 | !.vscode/tasks.json 291 | !.vscode/launch.json 292 | !.vscode/extensions.json 293 | !.vscode/*.code-snippets 294 | 295 | # Local History for Visual Studio Code 296 | .history/ 297 | 298 | # Built Visual Studio Code Extensions 299 | *.vsix 300 | 301 | ### VisualStudioCode Patch ### 302 | # Ignore all local history of files 303 | .history 304 | .ionide 305 | 306 | # Support for Project snippet scope 307 | 308 | ### Xcode ### 309 | ## User settings 310 | xcuserdata/ 311 | 312 | ## Xcode 8 and earlier 313 | *.xcscmblueprint 314 | *.xccheckout 315 | 316 | ### Xcode Patch ### 317 | *.xcodeproj/* 318 | !*.xcodeproj/project.pbxproj 319 | !*.xcodeproj/xcshareddata/ 320 | !*.xcworkspace/contents.xcworkspacedata 321 | /*.gcno 322 | **/xcshareddata/WorkspaceSettings.xcsettings 323 | 324 | ### VisualStudio ### 325 | ## Ignore Visual Studio temporary files, build results, and 326 | ## files generated by popular Visual Studio add-ons. 327 | ## 328 | ## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore 329 | 330 | # User-specific files 331 | *.rsuser 332 | *.suo 333 | *.user 334 | *.userosscache 335 | *.sln.docstates 336 | 337 | # User-specific files (MonoDevelop/Xamarin Studio) 338 | *.userprefs 339 | 340 | # Mono auto generated files 341 | mono_crash.* 342 | 343 | # Build results 344 | [Dd]ebug/ 345 | [Dd]ebugPublic/ 346 | [Rr]elease/ 347 | [Rr]eleases/ 348 | x64/ 349 | x86/ 350 | [Ww][Ii][Nn]32/ 351 | [Aa][Rr][Mm]/ 352 | [Aa][Rr][Mm]64/ 353 | bld/ 354 | [Bb]in/ 355 | [Oo]bj/ 356 | [Ll]og/ 357 | [Ll]ogs/ 358 | 359 | # Visual Studio 2015/2017 cache/options directory 360 | .vs/ 361 | # Uncomment if you have tasks that create the project's static files in wwwroot 362 | #wwwroot/ 363 | 364 | # Visual Studio 2017 auto generated files 365 | Generated\ Files/ 366 | 367 | # MSTest test Results 368 | [Tt]est[Rr]esult*/ 369 | [Bb]uild[Ll]og.* 370 | 371 | # NUnit 372 | *.VisualState.xml 373 | TestResult.xml 374 | nunit-*.xml 375 | 376 | # Build Results of an ATL Project 377 | [Dd]ebugPS/ 378 | [Rr]eleasePS/ 379 | dlldata.c 380 | 381 | # Benchmark Results 382 | BenchmarkDotNet.Artifacts/ 383 | 384 | # .NET Core 385 | project.lock.json 386 | project.fragment.lock.json 387 | artifacts/ 388 | 389 | # ASP.NET Scaffolding 390 | ScaffoldingReadMe.txt 391 | 392 | # StyleCop 393 | StyleCopReport.xml 394 | 395 | # Files built by Visual Studio 396 | *_i.c 397 | *_p.c 398 | *_h.h 399 | *.ilk 400 | *.meta 401 | *.iobj 402 | *.pdb 403 | *.ipdb 404 | *.pgc 405 | *.pgd 406 | *.rsp 407 | *.sbr 408 | *.tlb 409 | *.tli 410 | *.tlh 411 | *.tmp 412 | *.tmp_proj 413 | *_wpftmp.csproj 414 | *.log 415 | *.tlog 416 | *.vspscc 417 | *.vssscc 418 | .builds 419 | *.pidb 420 | *.svclog 421 | *.scc 422 | 423 | # Chutzpah Test files 424 | _Chutzpah* 425 | 426 | # Visual C++ cache files 427 | ipch/ 428 | *.aps 429 | *.ncb 430 | *.opendb 431 | *.opensdf 432 | *.sdf 433 | *.cachefile 434 | *.VC.db 435 | *.VC.VC.opendb 436 | 437 | # Visual Studio profiler 438 | *.psess 439 | *.vsp 440 | *.vspx 441 | *.sap 442 | 443 | # Visual Studio Trace Files 444 | *.e2e 445 | 446 | # TFS 2012 Local Workspace 447 | $tf/ 448 | 449 | # Guidance Automation Toolkit 450 | *.gpState 451 | 452 | # ReSharper is a .NET coding add-in 453 | _ReSharper*/ 454 | *.[Rr]e[Ss]harper 455 | *.DotSettings.user 456 | 457 | # TeamCity is a build add-in 458 | _TeamCity* 459 | 460 | # DotCover is a Code Coverage Tool 461 | *.dotCover 462 | 463 | # AxoCover is a Code Coverage Tool 464 | .axoCover/* 465 | !.axoCover/settings.json 466 | 467 | # Coverlet is a free, cross platform Code Coverage Tool 468 | coverage*.json 469 | coverage*.xml 470 | coverage*.info 471 | 472 | # Visual Studio code coverage results 473 | *.coverage 474 | *.coveragexml 475 | 476 | # NCrunch 477 | _NCrunch_* 478 | .*crunch*.local.xml 479 | nCrunchTemp_* 480 | 481 | # MightyMoose 482 | *.mm.* 483 | AutoTest.Net/ 484 | 485 | # Web workbench (sass) 486 | .sass-cache/ 487 | 488 | # Installshield output folder 489 | [Ee]xpress/ 490 | 491 | # DocProject is a documentation generator add-in 492 | DocProject/buildhelp/ 493 | DocProject/Help/*.HxT 494 | DocProject/Help/*.HxC 495 | DocProject/Help/*.hhc 496 | DocProject/Help/*.hhk 497 | DocProject/Help/*.hhp 498 | DocProject/Help/Html2 499 | DocProject/Help/html 500 | 501 | # Click-Once directory 502 | publish/ 503 | 504 | # Publish Web Output 505 | *.[Pp]ublish.xml 506 | *.azurePubxml 507 | # Note: Comment the next line if you want to checkin your web deploy settings, 508 | # but database connection strings (with potential passwords) will be unencrypted 509 | *.pubxml 510 | *.publishproj 511 | 512 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 513 | # checkin your Azure Web App publish settings, but sensitive information contained 514 | # in these scripts will be unencrypted 515 | PublishScripts/ 516 | 517 | # NuGet Packages 518 | *.nupkg 519 | # NuGet Symbol Packages 520 | *.snupkg 521 | # The packages folder can be ignored because of Package Restore 522 | **/[Pp]ackages/* 523 | # except build/, which is used as an MSBuild target. 524 | !**/[Pp]ackages/build/ 525 | # Uncomment if necessary however generally it will be regenerated when needed 526 | #!**/[Pp]ackages/repositories.config 527 | # NuGet v3's project.json files produces more ignorable files 528 | *.nuget.props 529 | *.nuget.targets 530 | 531 | # Microsoft Azure Build Output 532 | csx/ 533 | *.build.csdef 534 | 535 | # Microsoft Azure Emulator 536 | ecf/ 537 | rcf/ 538 | 539 | # Windows Store app package directories and files 540 | AppPackages/ 541 | BundleArtifacts/ 542 | Package.StoreAssociation.xml 543 | _pkginfo.txt 544 | *.appx 545 | *.appxbundle 546 | *.appxupload 547 | 548 | # Visual Studio cache files 549 | # files ending in .cache can be ignored 550 | *.[Cc]ache 551 | # but keep track of directories ending in .cache 552 | !?*.[Cc]ache/ 553 | 554 | # Others 555 | ClientBin/ 556 | ~$* 557 | *.dbmdl 558 | *.dbproj.schemaview 559 | *.jfm 560 | *.pfx 561 | *.publishsettings 562 | orleans.codegen.cs 563 | 564 | # Including strong name files can present a security risk 565 | # (https://github.com/github/gitignore/pull/2483#issue-259490424) 566 | #*.snk 567 | 568 | # Since there are multiple workflows, uncomment next line to ignore bower_components 569 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 570 | #bower_components/ 571 | 572 | # RIA/Silverlight projects 573 | Generated_Code/ 574 | 575 | # Backup & report files from converting an old project file 576 | # to a newer Visual Studio version. Backup files are not needed, 577 | # because we have git ;-) 578 | _UpgradeReport_Files/ 579 | Backup*/ 580 | UpgradeLog*.XML 581 | UpgradeLog*.htm 582 | ServiceFabricBackup/ 583 | *.rptproj.bak 584 | 585 | # SQL Server files 586 | *.mdf 587 | *.ldf 588 | *.ndf 589 | 590 | # Business Intelligence projects 591 | *.rdl.data 592 | *.bim.layout 593 | *.bim_*.settings 594 | *.rptproj.rsuser 595 | *- [Bb]ackup.rdl 596 | *- [Bb]ackup ([0-9]).rdl 597 | *- [Bb]ackup ([0-9][0-9]).rdl 598 | 599 | # Microsoft Fakes 600 | FakesAssemblies/ 601 | 602 | # GhostDoc plugin setting file 603 | *.GhostDoc.xml 604 | 605 | # Node.js Tools for Visual Studio 606 | .ntvs_analysis.dat 607 | node_modules/ 608 | 609 | # Visual Studio 6 build log 610 | *.plg 611 | 612 | # Visual Studio 6 workspace options file 613 | *.opt 614 | 615 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 616 | *.vbw 617 | 618 | # Visual Studio 6 auto-generated project file (contains which files were open etc.) 619 | *.vbp 620 | 621 | # Visual Studio 6 workspace and project file (working project files containing files to include in project) 622 | *.dsw 623 | *.dsp 624 | 625 | # Visual Studio 6 technical files 626 | 627 | # Visual Studio LightSwitch build output 628 | **/*.HTMLClient/GeneratedArtifacts 629 | **/*.DesktopClient/GeneratedArtifacts 630 | **/*.DesktopClient/ModelManifest.xml 631 | **/*.Server/GeneratedArtifacts 632 | **/*.Server/ModelManifest.xml 633 | _Pvt_Extensions 634 | 635 | # Paket dependency manager 636 | .paket/paket.exe 637 | paket-files/ 638 | 639 | # FAKE - F# Make 640 | .fake/ 641 | 642 | # CodeRush personal settings 643 | .cr/personal 644 | 645 | # Python Tools for Visual Studio (PTVS) 646 | __pycache__/ 647 | *.pyc 648 | 649 | # Cake - Uncomment if you are using it 650 | # tools/** 651 | # !tools/packages.config 652 | 653 | # Tabs Studio 654 | *.tss 655 | 656 | # Telerik's JustMock configuration file 657 | *.jmconfig 658 | 659 | # BizTalk build output 660 | *.btp.cs 661 | *.btm.cs 662 | *.odx.cs 663 | *.xsd.cs 664 | 665 | # OpenCover UI analysis results 666 | OpenCover/ 667 | 668 | # Azure Stream Analytics local run output 669 | ASALocalRun/ 670 | 671 | # MSBuild Binary and Structured Log 672 | *.binlog 673 | 674 | # NVidia Nsight GPU debugger configuration file 675 | *.nvuser 676 | 677 | # MFractors (Xamarin productivity tool) working folder 678 | .mfractor/ 679 | 680 | # Local History for Visual Studio 681 | .localhistory/ 682 | 683 | # Visual Studio History (VSHistory) files 684 | .vshistory/ 685 | 686 | # BeatPulse healthcheck temp database 687 | healthchecksdb 688 | 689 | # Backup folder for Package Reference Convert tool in Visual Studio 2017 690 | MigrationBackup/ 691 | 692 | # Ionide (cross platform F# VS Code tools) working folder 693 | .ionide/ 694 | 695 | # Fody - auto-generated XML schema 696 | FodyWeavers.xsd 697 | 698 | # VS Code files for those working on multiple tools 699 | *.code-workspace 700 | 701 | # Local History for Visual Studio Code 702 | 703 | # Windows Installer files from build outputs 704 | *.cab 705 | *.msi 706 | *.msix 707 | *.msm 708 | *.msp 709 | 710 | # JetBrains Rider 711 | *.sln.iml 712 | 713 | ### VisualStudio Patch ### 714 | # Additional files built by Visual Studio 715 | 716 | # End of https://www.toptal.com/developers/gitignore/api/c++,clion,cmake,codeblocks,emacs,gcov,sublimetext,vim,visualstudio,visualstudiocode,xcode 717 | 718 | 719 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.26) 2 | 3 | # NOTE: update executable name in .github/workflows/cmake.yml:25 when changing executable name in this file 4 | # for now, the project name is used as the executable name 5 | set(MAIN_PROJECT_NAME "oop") 6 | set(MAIN_EXECUTABLE_NAME "${MAIN_PROJECT_NAME}") 7 | 8 | 9 | project(${MAIN_PROJECT_NAME}) 10 | # set(CMAKE_PROJECT_VERSION_MAJOR 0) 11 | # set(CMAKE_PROJECT_VERSION_MINOR 0) 12 | # set(CMAKE_PROJECT_VERSION_PATCH 1) 13 | 14 | set(CMAKE_CXX_STANDARD 23) 15 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 16 | set(CMAKE_CXX_EXTENSIONS OFF) 17 | 18 | include(cmake/Options.cmake) 19 | include(cmake/CompilerFlags.cmake) 20 | include(cmake/CopyHelper.cmake) 21 | 22 | ############################################################################### 23 | 24 | # external dependencies with FetchContent 25 | # include(FetchContent) 26 | # 27 | # set(FETCHCONTENT_QUIET OFF) 28 | # set(FETCHCONTENT_UPDATES_DISCONNECTED ON) 29 | # 30 | # NOTE: Also update env vars used for caching in 31 | # - .github/actions/configure-cmake/action.yml 32 | # - .github/workflows/cmake.yml 33 | # FetchContent_Declare( 34 | # SomeLib 35 | # GIT_REPOSITORY https://github.com//.git 36 | # GIT_TAG # > 37 | # GIT_SHALLOW 1 # works only with branches or tags, not with arbitrary commit hashes 38 | # ) 39 | # 40 | # FetchContent_MakeAvailable(SomeLib) 41 | 42 | ############################################################################### 43 | 44 | # external dependencies with find_package 45 | 46 | # find_package(Threads REQUIRED) 47 | 48 | ############################################################################### 49 | 50 | # NOTE: update executable name in .github/workflows/cmake.yml:25 when changing name here 51 | add_executable(${MAIN_EXECUTABLE_NAME} 52 | main.cpp 53 | generated/src/Helper.cpp 54 | ) 55 | 56 | # NOTE: Add all defined targets (e.g. executables, libraries, etc. ) 57 | # NOTE: RUN_SANITIZERS is optional, if it's not present it will default to true 58 | set_compiler_flags(RUN_SANITIZERS TRUE TARGET_NAMES ${MAIN_EXECUTABLE_NAME}) 59 | # set_compiler_flags(TARGET_NAMES ${MAIN_EXECUTABLE_NAME} ${FOO} ${BAR}) 60 | # where ${FOO} and ${BAR} represent additional executables or libraries 61 | # you want to compile with the set compiler flags 62 | 63 | ############################################################################### 64 | 65 | # use SYSTEM so cppcheck and clang-tidy do not report warnings from these directories 66 | target_include_directories(${MAIN_EXECUTABLE_NAME} SYSTEM PRIVATE generated/include) 67 | # target_include_directories(${MAIN_EXECUTABLE_NAME} SYSTEM PRIVATE ext//include) 68 | # target_include_directories(${MAIN_EXECUTABLE_NAME} SYSTEM PRIVATE ${_SOURCE_DIR}/include) 69 | # target_link_directories(${MAIN_EXECUTABLE_NAME} PRIVATE ${_BINARY_DIR}/lib) 70 | # target_link_libraries(${MAIN_EXECUTABLE_NAME} ) 71 | 72 | ############################################################################### 73 | 74 | # copy binaries to "bin" folder; these are uploaded as artifacts on each release 75 | # DESTINATION_DIR is set as "bin" in cmake/Options.cmake:6 76 | install(TARGETS ${MAIN_EXECUTABLE_NAME} DESTINATION ${DESTINATION_DIR}) 77 | if(APPLE) 78 | install(FILES launcher.command DESTINATION ${DESTINATION_DIR}) 79 | endif() 80 | 81 | copy_files(FILES tastatura.txt COPY_TO_DESTINATION TARGET_NAME ${MAIN_EXECUTABLE_NAME}) 82 | # copy_files(FILES tastatura.txt config.json DIRECTORY images sounds COPY_TO_DESTINATION TARGET_NAME ${MAIN_EXECUTABLE_NAME}) 83 | # copy_files(DIRECTORY images sounds COPY_TO_DESTINATION TARGET_NAME ${MAIN_EXECUTABLE_NAME}) 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nu primesc notă pentru că nu am pus titlu și descriere 2 | 3 | ### Folosiți template-ul corespunzător grupei voastre! 4 | 5 | | Laborant | Link template | 6 | |-----------|----------------------------------------------| 7 | | Dragoș B | https://github.com/Ionnier/oop-template | 8 | | Tiberiu M | https://github.com/MaximTiberiu/oop-template | 9 | | Marius MC | https://github.com/mcmarius/oop-template | 10 | 11 | ### Important! 12 | 13 | Aveți voie cu cod generat de modele de limbaj la care nu ați contribuit semnificativ doar în folder-ul `generated`. 14 | Codul generat pus "ca să fie"/pe care nu îl înțelegeți se punctează doar pentru puncte bonus, doar în contextul 15 | în care oferă funcționalități ajutătoare și doar dacă are sens. 16 | 17 | O cerință nu se consideră îndeplinită dacă este realizată doar prin cod generat. 18 | 19 | - **Fără cod de umplutură/fără sens!** 20 | - **Fără copy-paste!** 21 | - **Fără variabile globale!** 22 | - **Fără atribute publice!** 23 | - **Pentru T2 și T3, fără date în cod!** Datele vor fi citite din fișier, aveți exemple destule. 24 | 25 | ### Tema 0 26 | 27 | - [ ] Nume proiect (poate fi schimbat ulterior) 28 | - [ ] Scurtă descriere a temei alese, ce v-ați propus să implementați 29 | 30 | ## Tema 1 31 | 32 | #### Cerințe 33 | - [ ] definirea a minim **3-4 clase** folosind compunere cu clasele definite de voi; moștenirile nu se iau în considerare aici 34 | - [ ] constructori de inițializare cu parametri pentru fiecare clasă 35 | - [ ] pentru o aceeași (singură) clasă: constructor de copiere, `operator=` de copiere, destructor 36 | 37 | 38 | - [ ] `operator<<` pentru **toate** clasele pentru afișare (`std::ostream`) folosind compunere de apeluri cu `operator<<` 39 | - [ ] cât mai multe `const` (unde este cazul) și funcții `private` 40 | - [ ] implementarea a minim 3 funcții membru publice pentru funcționalități netriviale specifice temei alese, dintre care cel puțin 1-2 funcții mai complexe 41 | - nu doar citiri/afișări sau adăugat/șters elemente într-un/dintr-un vector 42 | - [ ] scenariu de utilizare **cu sens** a claselor definite: 43 | - crearea de obiecte și apelarea tuturor funcțiilor membru publice în main 44 | - vor fi adăugate în fișierul `tastatura.txt` DOAR exemple de date de intrare de la tastatură (dacă există); dacă aveți nevoie de date din fișiere, creați alte fișiere separat 45 | - [ ] minim 50-55% din codul propriu să fie C++, `.gitattributes` configurat corect 46 | - [ ] tag de `git`: de exemplu `v0.1` 47 | - [ ] serviciu de integrare continuă (CI) cu **toate bifele**; exemplu: GitHub Actions 48 | 49 | ## Tema 2 50 | 51 | #### Cerințe 52 | - [ ] separarea codului din clase în `.h` (sau `.hpp`) și `.cpp` 53 | - [ ] moșteniri: 54 | - minim o clasă de bază și **3 clase derivate** din aceeași ierarhie 55 | - ierarhia trebuie să fie cu bază proprie, nu derivată dintr-o clasă predefinită 56 | - [ ] funcții virtuale (pure) apelate prin pointeri de bază din clasa care conține atributul de tip pointer de bază 57 | - minim o funcție virtuală va fi **specifică temei** (i.e. nu simple citiri/afișări sau preluate din biblioteci i.e. draw/update/render) 58 | - constructori virtuali (clone): sunt necesari, dar nu se consideră funcții specifice temei 59 | - afișare virtuală, interfață non-virtuală 60 | - [ ] apelarea constructorului din clasa de bază din constructori din derivate 61 | - [ ] clasă cu atribut de tip pointer la o clasă de bază cu derivate; aici apelați funcțiile virtuale prin pointer de bază, eventual prin interfața non-virtuală din bază 62 | - [ ] suprascris cc/op= pentru copieri/atribuiri corecte, copy and swap 63 | - [ ] `dynamic_cast`/`std::dynamic_pointer_cast` pentru downcast cu sens 64 | - [ ] smart pointers (recomandat, opțional) 65 | - [ ] excepții 66 | - [ ] ierarhie proprie cu baza `std::exception` sau derivată din `std::exception`; minim **3** clase pentru erori specifice distincte 67 | - clasele de excepții trebuie să trateze categorii de erori distincte (exemplu de erori echivalente: citire fișiere cu diverse extensii) 68 | - [ ] utilizare cu sens: de exemplu, `throw` în constructor (sau funcție care întoarce un obiect), `try`/`catch` în `main` 69 | - această ierarhie va fi complet independentă de ierarhia cu funcții virtuale 70 | - [ ] funcții și atribute `static` 71 | - [ ] STL 72 | - [ ] cât mai multe `const` 73 | - [ ] funcții *de nivel înalt*, de eliminat cât mai mulți getters/setters/funcții low-level 74 | - [ ] minim 75-80% din codul propriu să fie C++ 75 | - [ ] la sfârșit: commit separat cu adăugarea unei noi clase derivate fără a modifica restul codului, **pe lângă cele 3 derivate deja adăugate** din aceeași ierarhie 76 | - noua derivată nu poate fi una existentă care a fost ștearsă și adăugată din nou 77 | - noua derivată va fi integrată în codul existent (adică va fi folosită, nu adăugată doar ca să fie) 78 | - [ ] tag de `git` pe commit cu **toate bifele**: de exemplu `v0.2` 79 | 80 | ## Tema 3 81 | 82 | #### Cerințe 83 | - [ ] 2 șabloane de proiectare (design patterns) 84 | - [ ] o clasă șablon cu sens; minim **2 instanțieri** 85 | - [ ] preferabil și o funcție șablon (template) cu sens; minim 2 instanțieri 86 | - [ ] minim 85% din codul propriu să fie C++ 87 | 88 | - [ ] tag de `git` pe commit cu **toate bifele**: de exemplu `v0.3` sau `v1.0` 89 | 90 | ## Instrucțiuni de compilare 91 | 92 | Proiectul este configurat cu CMake. 93 | 94 | Instrucțiuni pentru terminal: 95 | 96 | 1. Pasul de configurare 97 | ```sh 98 | cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug 99 | # sau ./scripts/cmake.sh configure 100 | ``` 101 | 102 | Sau pe Windows cu GCC: 103 | ```sh 104 | cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug -G Ninja 105 | # sau ./scripts/cmake.sh configure -g Ninja 106 | ``` 107 | 108 | La acest pas putem cere să generăm fișiere de proiect pentru diverse medii de lucru. 109 | 110 | 111 | 2. Pasul de compilare 112 | ```sh 113 | cmake --build build --config Debug --parallel 6 114 | # sau ./scripts/cmake.sh build 115 | ``` 116 | 117 | Cu opțiunea `parallel` specificăm numărul de fișiere compilate în paralel. 118 | 119 | 120 | 3. Pasul de instalare (opțional) 121 | ```sh 122 | cmake --install build --config Debug --prefix install_dir 123 | # sau ./scripts/cmake.sh install 124 | ``` 125 | 126 | Vezi și [`scripts/cmake.sh`](scripts/cmake.sh). 127 | 128 | Observație: folderele `build/` și `install_dir/` sunt adăugate în fișierul `.gitignore` deoarece 129 | conțin fișiere generate și nu ne ajută să le versionăm. 130 | 131 | 132 | ## Resurse 133 | 134 | - adăugați trimiteri către resursele externe care v-au ajutat sau pe care le-ați folosit 135 | -------------------------------------------------------------------------------- /cmake/CompilerFlags.cmake: -------------------------------------------------------------------------------- 1 | include(cmake/CustomStdlibAndSanitizers.cmake) 2 | 3 | # target definitions 4 | 5 | function(set_compiler_flags) 6 | set(multiValueArgs TARGET_NAMES) 7 | set(oneValueArgs RUN_SANITIZERS) 8 | cmake_parse_arguments(PARSE_ARGV 0 ARG "" "${oneValueArgs}" "${multiValueArgs}") 9 | 10 | if(NOT DEFINED ARG_RUN_SANITIZERS) 11 | set(ARG_RUN_SANITIZERS TRUE) 12 | endif() 13 | 14 | # iterate over all specified targets 15 | foreach (TARGET_NAME IN LISTS ARG_TARGET_NAMES) 16 | if(GITHUB_ACTIONS) 17 | message("NOTE: GITHUB_ACTIONS defined") 18 | target_compile_definitions(${TARGET_NAME} PRIVATE GITHUB_ACTIONS) 19 | endif() 20 | 21 | ############################################################################### 22 | 23 | if(PROJECT_WARNINGS_AS_ERRORS) 24 | set_property(TARGET ${TARGET_NAME} PROPERTY COMPILE_WARNING_AS_ERROR ON) 25 | endif() 26 | 27 | # custom compiler flags 28 | message("Compiler: ${CMAKE_CXX_COMPILER_ID} version ${CMAKE_CXX_COMPILER_VERSION}") 29 | if(MSVC) 30 | target_compile_options(${TARGET_NAME} PRIVATE /W4 /permissive- /wd4244 /wd4267 /wd4996 /external:anglebrackets /external:W0 /utf-8 /MP) 31 | else() 32 | target_compile_options(${TARGET_NAME} PRIVATE -Wall -Wextra -pedantic) 33 | endif() 34 | 35 | ############################################################################### 36 | 37 | # sanitizers 38 | if("${ARG_RUN_SANITIZERS}" STREQUAL "TRUE") 39 | set_custom_stdlib_and_sanitizers(${TARGET_NAME} true) 40 | endif () 41 | endforeach () 42 | endfunction() -------------------------------------------------------------------------------- /cmake/CopyHelper.cmake: -------------------------------------------------------------------------------- 1 | # helper function to copy files to build directory and install directory without duplicating file names across commands 2 | function(copy_files) 3 | set(options COPY_TO_DESTINATION) 4 | set(oneValueArgs TARGET_NAME) 5 | set(multiValueArgs FILES DIRECTORY) 6 | cmake_parse_arguments(PARSE_ARGV 0 ARG "${options}" "${oneValueArgs}" "${multiValueArgs}") 7 | 8 | # copy files to build dir 9 | foreach(file ${ARG_FILES}) 10 | add_custom_command( 11 | TARGET ${ARG_TARGET_NAME} POST_BUILD 12 | COMMENT "Copying ${file}..." 13 | COMMAND ${CMAKE_COMMAND} -E copy_if_different 14 | ${CMAKE_SOURCE_DIR}/${file} $) 15 | # ${CMAKE_CURRENT_BINARY_DIR}) 16 | endforeach() 17 | 18 | # copy folders to build dir 19 | foreach(dir ${ARG_DIRECTORY}) 20 | add_custom_command( 21 | TARGET ${ARG_TARGET_NAME} POST_BUILD 22 | COMMENT "Copying directory ${dir}..." 23 | COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different 24 | ${CMAKE_SOURCE_DIR}/${dir} $/${dir}) 25 | # ${CMAKE_CURRENT_BINARY_DIR}/${dir}) 26 | endforeach() 27 | 28 | if(ARG_COPY_TO_DESTINATION) 29 | # copy files and folders to install dir 30 | install(FILES ${ARG_FILES} DESTINATION ${DESTINATION_DIR}) 31 | install(DIRECTORY ${ARG_DIRECTORY} DESTINATION ${DESTINATION_DIR}) 32 | endif() 33 | endfunction() 34 | -------------------------------------------------------------------------------- /cmake/CustomStdlibAndSanitizers.cmake: -------------------------------------------------------------------------------- 1 | include(${CMAKE_CURRENT_LIST_DIR}/DetectLibcpp.cmake) 2 | 3 | function(set_custom_stdlib_and_sanitizers target add_apple_asan) 4 | if(MSVC) 5 | # see https://gitlab.kitware.com/cmake/cmake/-/issues/24922 6 | set_target_properties(${target} PROPERTIES VS_USER_PROPS "${CMAKE_SOURCE_DIR}/disable_modules.props") 7 | target_compile_options(${target} PRIVATE /experimental:module-) 8 | if(USE_ASAN) 9 | target_compile_options(${target} PRIVATE "$<${debug_mode}:/fsanitize=address>") 10 | endif() 11 | return() 12 | endif() 13 | 14 | if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND NOT WIN32) 15 | detect_libcpp() 16 | if(HAS_LIBCPP) 17 | # see also https://stackoverflow.com/a/70382484 18 | target_compile_options(${target} PRIVATE -stdlib=libc++) 19 | target_link_options(${target} PRIVATE -stdlib=libc++) 20 | else() 21 | # fall back to libstdc++ 22 | target_compile_options(${target} PRIVATE -stdlib=libstdc++) 23 | target_link_options(${target} PRIVATE -stdlib=libstdc++) 24 | endif() 25 | endif() 26 | 27 | if(APPLE) 28 | # first check Apple since Apple is also a kind of Unix 29 | if("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang" AND add_apple_asan MATCHES true) 30 | if(USE_ASAN) 31 | target_compile_options(${target} PRIVATE "$<${debug_mode}:-fsanitize=address,undefined>") 32 | target_link_options(${target} PRIVATE "$<${debug_mode}:-fsanitize=address,undefined>") 33 | endif() 34 | endif() 35 | elseif(UNIX) 36 | if(USE_ASAN) 37 | # check leaks on Linux since macOS does not support the leaks sanitizer yet 38 | # leaks sanitizer is enabled by default on Linux, so we do not need to enable it explicitly 39 | target_compile_options(${target} PRIVATE "$<${debug_mode}:-fsanitize=address,undefined>") 40 | target_link_options(${target} PRIVATE "$<${debug_mode}:-fsanitize=address,undefined>") 41 | elseif(USE_MSAN) 42 | # use semi-colons instead of spaces to separate arguments 43 | # it is recommended to quote generator expressions in order to avoid unintentional splitting 44 | target_compile_options(${target} PRIVATE "$<${debug_mode}:-fsanitize=memory,undefined;-fsanitize-recover=memory,undefined;-fsanitize-memory-track-origins>") 45 | target_link_options(${target} PRIVATE "$<${debug_mode}:-fsanitize=memory,undefined;-fsanitize-recover=memory,undefined;-fsanitize-memory-track-origins;-Wl,-rpath,tools/llvm-project/build/lib>") 46 | endif() 47 | endif() 48 | endfunction() 49 | -------------------------------------------------------------------------------- /cmake/DetectLibcpp.cmake: -------------------------------------------------------------------------------- 1 | function(detect_libcpp) 2 | set(OLD_CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS}) 3 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") 4 | set(TEST_STDLIB_SRC [=[ 5 | #include 6 | int main() {} 7 | ]=]) 8 | try_compile(HAS_LIBCPP SOURCE_FROM_CONTENT test_stdlib.cpp ${TEST_STDLIB_SRC}) 9 | set(CMAKE_CXX_FLAGS ${OLD_CMAKE_CXX_FLAGS}) 10 | unset(OLD_CMAKE_CXX_FLAGS) 11 | endfunction() 12 | -------------------------------------------------------------------------------- /cmake/Options.cmake: -------------------------------------------------------------------------------- 1 | option(WARNINGS_AS_ERRORS "Treat warnings as errors" OFF) 2 | option(USE_ASAN "Use Address Sanitizer" OFF) 3 | option(USE_MSAN "Use Memory Sanitizer" OFF) 4 | option(CMAKE_COLOR_DIAGNOSTICS "Enable color diagnostics" ON) 5 | 6 | # update name in .github/workflows/cmake.yml:27 when changing "bin" name here 7 | set(DESTINATION_DIR "bin") 8 | 9 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 10 | set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/install_dir" CACHE PATH "..." FORCE) 11 | endif() 12 | 13 | # disable sanitizers when releasing executables without explicitly requested debug info 14 | # use generator expressions to set flags correctly in both single and multi config generators 15 | set(is_debug "$") 16 | set(is_rel_with_deb "$") 17 | set(debug_mode "$") 18 | -------------------------------------------------------------------------------- /disable_modules.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | false 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /generated/include/Helper.h: -------------------------------------------------------------------------------- 1 | #ifndef OOP_HELPER_H 2 | #define OOP_HELPER_H 3 | 4 | 5 | class Helper { 6 | public: 7 | void help(); 8 | }; 9 | 10 | 11 | #endif //OOP_HELPER_H 12 | -------------------------------------------------------------------------------- /generated/src/Helper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void Helper::help() { 4 | // perform help 5 | } 6 | -------------------------------------------------------------------------------- /launcher.command: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd "$(dirname "${0}")" && ./oop 3 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | int main() { 7 | std::cout << "Hello, world!\n"; 8 | std::array v{}; 9 | int nr; 10 | std::cout << "Introduceți nr: "; 11 | ///////////////////////////////////////////////////////////////////////// 12 | /// Observație: dacă aveți nevoie să citiți date de intrare de la tastatură, 13 | /// dați exemple de date de intrare folosind fișierul tastatura.txt 14 | /// Trebuie să aveți în fișierul tastatura.txt suficiente date de intrare 15 | /// (în formatul impus de voi) astfel încât execuția programului să se încheie. 16 | /// De asemenea, trebuie să adăugați în acest fișier date de intrare 17 | /// pentru cât mai multe ramuri de execuție. 18 | /// Dorim să facem acest lucru pentru a automatiza testarea codului, fără să 19 | /// mai pierdem timp de fiecare dată să introducem de la zero aceleași date de intrare. 20 | /// 21 | /// Pe GitHub Actions (bife), fișierul tastatura.txt este folosit 22 | /// pentru a simula date introduse de la tastatură. 23 | /// Bifele verifică dacă programul are erori de compilare, erori de memorie și memory leaks. 24 | /// 25 | /// Dacă nu puneți în tastatura.txt suficiente date de intrare, îmi rezerv dreptul să vă 26 | /// testez codul cu ce date de intrare am chef și să nu pun notă dacă găsesc vreun bug. 27 | /// Impun această cerință ca să învățați să faceți un demo și să arătați părțile din 28 | /// program care merg (și să le evitați pe cele care nu merg). 29 | /// 30 | ///////////////////////////////////////////////////////////////////////// 31 | std::cin >> nr; 32 | ///////////////////////////////////////////////////////////////////////// 33 | for(int i = 0; i < nr; ++i) { 34 | std::cout << "v[" << i << "] = "; 35 | std::cin >> v[i]; 36 | } 37 | std::cout << "\n\n"; 38 | std::cout << "Am citit de la tastatură " << nr << " elemente:\n"; 39 | for(int i = 0; i < nr; ++i) { 40 | std::cout << "- " << v[i] << "\n"; 41 | } 42 | /////////////////////////////////////////////////////////////////////////// 43 | /// Pentru date citite din fișier, NU folosiți tastatura.txt. Creați-vă voi 44 | /// alt fișier propriu cu ce alt nume doriți. 45 | /// Exemplu: 46 | /// std::ifstream fis("date.txt"); 47 | /// for(int i = 0; i < nr2; ++i) 48 | /// fis >> v2[i]; 49 | /// 50 | /////////////////////////////////////////////////////////////////////////// 51 | /// Exemplu de utilizare cod generat /// 52 | /////////////////////////////////////////////////////////////////////////// 53 | Helper helper; 54 | helper.help(); 55 | /////////////////////////////////////////////////////////////////////////// 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /scripts/build_cppcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | # default values 4 | CPPCHECK_VER=2.14.2 # NOTE: consider updating this value in .github/workflows/cmake.yml:47 when changing this value 5 | CMAKE_BUILD_DIR=build 6 | CMAKE_OPTS=() # example for CLI: -o "-DCMAKE_INSTALL_PREFIX=~/.local/ -DFILESDIR=~/.local/share/Cppcheck" 7 | 8 | while getopts ":b:o:v:" opt; do 9 | case "${opt}" in 10 | b) CMAKE_BUILD_DIR="${OPTARG}" 11 | ;; 12 | o) IFS=" " read -r -a CMAKE_OPTS <<< "${OPTARG}" 13 | ;; 14 | v) CPPCHECK_VER="${OPTARG}" 15 | ;; 16 | *) printf "Unknown option %s; available options: \n\ 17 | -b (build dir)\n\ 18 | -o (cmake opts)\n\ 19 | -v (cppcheck version)\n" "${opt}" 20 | exit 1 21 | ;; 22 | esac 23 | done 24 | 25 | 26 | wget "https://github.com/danmar/cppcheck/archive/${CPPCHECK_VER}.zip" 27 | unzip -q "${CPPCHECK_VER}.zip" 28 | rm "${CPPCHECK_VER}.zip" 29 | mv "cppcheck-${CPPCHECK_VER}" cppcheck 30 | 31 | cd cppcheck || { echo "Eroare cd"; exit 1; } 32 | cmake -S . -B "${CMAKE_BUILD_DIR}" -DEXTERNALS_AS_SYSTEM=ON "${CMAKE_OPTS[@]}" 33 | cmake --build "${CMAKE_BUILD_DIR}" -j6 34 | -------------------------------------------------------------------------------- /scripts/cmake.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | DEFAULT_BUILD_DIR="build" 4 | DEFAULT_BUILD_TYPE="Debug" 5 | DEFAULT_INSTALL_DIR="install_dir" 6 | 7 | configure() { 8 | # cmake -S . -B build -DCMAKE_BUILD_TYPE=Debug 9 | # 10 | BUILD_DIR="${DEFAULT_BUILD_DIR}" 11 | BUILD_TYPE="${DEFAULT_BUILD_TYPE}" 12 | INSTALL_DIR="${DEFAULT_INSTALL_DIR}" 13 | SOURCE_DIR="." 14 | CMAKE_OPTS=() 15 | 16 | while getopts ":b:c:e:g:i:s:" opt; do 17 | case "${opt}" in 18 | b) BUILD_DIR="${OPTARG}" 19 | ;; 20 | c) BUILD_TYPE="${OPTARG}" 21 | ;; 22 | e) IFS=" " read -r -a CMAKE_OPTS <<< "${OPTARG}" 23 | ;; 24 | g) export CMAKE_GENERATOR="${OPTARG}" 25 | ;; 26 | i) INSTALL_DIR="${OPTARG}" 27 | ;; 28 | s) SOURCE_DIR="${OPTARG}" 29 | ;; 30 | *) printf "Unknown option %s; available options: \n\ 31 | -b (build dir)\n\ 32 | -c (CMake config build type)\n\ 33 | -e (extra CMake options e.g. -DCMAKE_EXPORT_COMPILE_COMMANDS=ON)\n\ 34 | -g (generator)\n\ 35 | -i (install dir prefix)\n\ 36 | -s (source dir)\n"\ 37 | "${opt}" 38 | exit 1 39 | ;; 40 | esac 41 | done 42 | 43 | cmake -B "${BUILD_DIR}" \ 44 | -S "${SOURCE_DIR}" \ 45 | -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ 46 | -DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \ 47 | "${CMAKE_OPTS[@]}" 48 | } 49 | 50 | build() { 51 | # cmake --build build --config Debug -j6 52 | # 53 | BUILD_DIR="${DEFAULT_BUILD_DIR}" 54 | BUILD_TYPE="${DEFAULT_BUILD_TYPE}" 55 | NPROC=6 56 | CMAKE_OPTS=() 57 | 58 | while getopts ":b:c:e:j:" opt; do 59 | case "${opt}" in 60 | b) BUILD_DIR="${OPTARG}" 61 | ;; 62 | c) BUILD_TYPE="${OPTARG}" 63 | ;; 64 | e) IFS=" " read -r -a CMAKE_OPTS <<< "${OPTARG}" 65 | ;; 66 | j) NPROC="${OPTARG}" 67 | ;; 68 | *) printf "Unknown option %s; available options: \n\ 69 | -b (build dir)\n\ 70 | -c (CMake config build type)\n\ 71 | -e (extra CMake options)\n\ 72 | -j (number of jobs for parallel build)\n"\ 73 | "${opt}" 74 | exit 1 75 | ;; 76 | esac 77 | done 78 | 79 | cmake --build "${BUILD_DIR}" \ 80 | --config "${BUILD_TYPE}" \ 81 | -j "${NPROC}" \ 82 | "${CMAKE_OPTS[@]}" 83 | } 84 | 85 | install() { 86 | # cmake --install build --config Debug --prefix install_dir 87 | # 88 | BUILD_DIR="${DEFAULT_BUILD_DIR}" 89 | BUILD_TYPE="${DEFAULT_BUILD_TYPE}" 90 | INSTALL_DIR="${DEFAULT_INSTALL_DIR}" 91 | while getopts ":b:c:i:" opt; do 92 | case "${opt}" in 93 | b) BUILD_DIR="${OPTARG}" 94 | ;; 95 | c) BUILD_TYPE="${OPTARG}" 96 | ;; 97 | i) INSTALL_DIR="${OPTARG}" 98 | ;; 99 | *) printf "Unknown option %s; available options: \n\ 100 | -b (build dir)\n\ 101 | -c (CMake config build type)\n\ 102 | -i (install dir prefix)\n"\ 103 | "${opt}" 104 | exit 1 105 | ;; 106 | esac 107 | done 108 | 109 | cmake --install "${BUILD_DIR}" \ 110 | --config "${BUILD_TYPE}" \ 111 | --prefix "${INSTALL_DIR}" 112 | } 113 | 114 | 115 | case "$1" in 116 | configure) 117 | shift 118 | configure "$@" 119 | ;; 120 | build) 121 | shift 122 | build "$@" 123 | ;; 124 | install) 125 | shift 126 | install "$@" 127 | ;; 128 | *) printf "Unknown option %s; available options: \n\ 129 | configure\n\ 130 | build\n\ 131 | install\n" "${opt}" 132 | exit 1 133 | esac 134 | 135 | -------------------------------------------------------------------------------- /scripts/run_cppcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/bash 2 | 3 | cppcheck --enable=all \ 4 | --inline-suppr \ 5 | --project="${BUILD_DIR:-build}"/compile_commands.json \ 6 | -i"${BUILD_DIR:-build}" --suppress="*:${BUILD_DIR:-build}/*" \ 7 | -i"${EXT_DIR:-ext}" --suppress="*:${EXT_DIR:-ext}/*" \ 8 | -i"${GEN_DIR:-generated}" --suppress="*:${GEN_DIR:-generated}/*" \ 9 | --suppress=missingIncludeSystem \ 10 | --suppress=unmatchedSuppression \ 11 | --suppress=useStlAlgorithm \ 12 | --check-level=exhaustive \ 13 | --error-exitcode=1 14 | -------------------------------------------------------------------------------- /tastatura.txt: -------------------------------------------------------------------------------- 1 | 5 2 | 11 22 33 44 55 3 | --------------------------------------------------------------------------------