diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..cb1c4f6 --- /dev/null +++ b/.clang-format @@ -0,0 +1,121 @@ +--- +Language: Cpp +# BasedOnStyle: Mozilla +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignConsecutiveMacros: true +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: true +BinPackArguments: true +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + AfterExternBlock: false + BeforeCatch: true + BeforeElse: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: false +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 120 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: true +ConstructorInitializerAllOnOneLineOrOnePerLine: true +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 2 +Cpp11BracedListStyle: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH + - TEST_GROUP + - TEST_GROUP_BASE + - TEST_BASE +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 3 + - Regex: '.*' + Priority: 1 +IncludeIsMainRegex: '(Test)?$' +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 4 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: true +ObjCSpaceBeforeProtocolList: false +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +RawStringFormats: + - Delimiters: ['pb', 'proto'] + Language: TextProto + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: true +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: Leave +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: c++20 +TabWidth: 4 +TypenameMacros: ['TEST'] +UseTab: Never +... + diff --git a/.coderabbit.yaml b/.coderabbit.yaml new file mode 100644 index 0000000..49d494c --- /dev/null +++ b/.coderabbit.yaml @@ -0,0 +1,17 @@ +# yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json +language: "en-GB" +early_access: false +reviews: + profile: "chill" + request_changes_workflow: false + high_level_summary: true + poem: false + review_status: true + collapse_walkthrough: false + changed_files_summary: false + estimate_code_review_effort: false + auto_review: + enabled: true + drafts: false +chat: + auto_reply: true \ No newline at end of file diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 0000000..240f8a6 --- /dev/null +++ b/.codespellrc @@ -0,0 +1,2 @@ +[codespell] +skip = ./libraries,./tests/googletest,./resources,./icons \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..376f68c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + allow: + - dependency-type: "all" + ignore: + - dependency-name: "*" + update-types: ["version-update:semver-patch"] \ No newline at end of file diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 481150d..41f7839 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -8,33 +8,36 @@ jobs: runs-on: ubuntu-latest container: - image: docker://jgeudens/qt-linux:6.4.1_build_1 + image: docker://jgeudens/qt-linux:6.8.3_build_1 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6.0.0 + - name: Configure safe directory for git + run: git config --global --add safe.directory ${GITHUB_WORKSPACE} + - name: Update Modules and Build run: bash scripts/build_linux.sh - name: Deploy run: bash scripts/deploy_linux.sh - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v5.0.0 with: name: modbussim-linux path: ModbusSim*.AppImage windows: - runs-on: windows-2019 + runs-on: windows-2022 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v6.0.0 - name: Install Qt installer - run: pip3 install aqtinstall + run: pip3 install aqtinstall==3.3.0 # Cache go build cache, used to speedup go test - name: Qt Build Cache - uses: actions/cache@v3 + uses: actions/cache@v5.0.0 id: cache with: path: ${{ github.workspace }}\Qt @@ -44,8 +47,8 @@ jobs: shell: cmd run: scripts\full_build_and_deploy_windows.bat '${{ steps.cache.outputs.cache-hit }}' ${{ github.workspace }}\Qt - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v5.0.0 with: - name: modbussim-windows + name: modbusscope-windows path: | - release\bin\win\ModbusSim.zip + ModbusSim.zip diff --git a/.gitignore b/.gitignore index 1f5730a..e3f4d3e 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ *.so.* *.dll *.dylib +.cache # Qt-es object_script.*.Release @@ -30,8 +31,6 @@ qrc_*.cpp ui_*.h *.qmlc *.jsc -Makefile* -*build-* *.qm *.prl @@ -54,4 +53,13 @@ compile_commands.json # QtCreator local machine specific files for imported projects *creator.user* -src/util/version.h +# docs +_build +build/ +venv +*docs/doxygen/html +*docs/doxygen/doxygen.log + +.vscode/ + +coverage/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 27728ae..7ab228d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,15 +8,14 @@ project(modbussim set(CMAKE_POSITION_INDEPENDENT_CODE ON) -set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) -set(CMAKE_AUTOUIC ON) -set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) # Find the QtCore library -find_package(QT NAMES Qt6 Qt5 COMPONENTS Core REQUIRED) +find_package(QT NAMES Qt6 COMPONENTS Core REQUIRED) find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core REQUIRED) message(STATUS "Using Qt${QT_VERSION_MAJOR} version ${Qt${QT_VERSION_MAJOR}Core_VERSION}") @@ -30,6 +29,8 @@ find_package(Qt${QT_VERSION_MAJOR} COMPONENTS REQUIRED ) +qt_standard_project_setup() + set(QT_LIB Qt::Widgets Qt::Xml @@ -42,6 +43,13 @@ include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/testslave ) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Werror") +if (MINGW) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj") +endif() + SET(APP_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/mainwindow.cpp @@ -91,3 +99,4 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") elseif(WIN32) # not required endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") + diff --git a/scripts/deploy_windows.bat b/scripts/deploy_windows.bat index 0db4f27..f0405bb 100644 --- a/scripts/deploy_windows.bat +++ b/scripts/deploy_windows.bat @@ -21,7 +21,10 @@ cd .. 7z a ModbusSim.zip ".\%DEPLOY_DIR%\*" IF ERRORLEVEL 1 GOTO errorHandling +cd ..\..\.. +move release\bin\win\ModbusSim.zip ModbusSim.zip + EXIT :errorHandling -EXIT /B 1 \ No newline at end of file +EXIT /B 1 diff --git a/scripts/setup_windows.bat b/scripts/setup_windows.bat index 94d99eb..e3cce37 100644 --- a/scripts/setup_windows.bat +++ b/scripts/setup_windows.bat @@ -9,7 +9,7 @@ echo QT_INSTALL_DIR: %QT_INSTALL_DIR% echo CACHE_HIT: %CACHE_HIT% REM Set configuration -set QT=6.4.1 +set QT=6.8.3 set QT_MODULES=qtserialbus qtserialport set QT_HOST=windows set QT_TARGET=desktop @@ -28,10 +28,11 @@ REM Install Qt aqt install-qt --outputdir %QT_INSTALL_DIR% %QT_HOST% %QT_TARGET% %QT% %QT_ARCH% -m %QT_MODULES% REM Install Tools -aqt install-tool --outputdir %QT_INSTALL_DIR% %QT_HOST% %QT_TARGET% tools_mingw90 qt.tools.win64_mingw900 +REM Qt 6.8.x uses mingw 13.1.0 (GCC 13.1.0) (https://wiki.qt.io/MinGW) +aqt install-tool --outputdir %QT_INSTALL_DIR% %QT_HOST% %QT_TARGET% tools_mingw1310 aqt install-tool --outputdir %QT_INSTALL_DIR% %QT_HOST% %QT_TARGET% tools_cmake aqt install-tool --outputdir %QT_INSTALL_DIR% %QT_HOST% %QT_TARGET% tools_ninja -aqt install-tool --outputdir %QT_INSTALL_DIR% %QT_HOST% %QT_TARGET% tools_openssl_x64 +aqt install-tool --outputdir %QT_INSTALL_DIR% %QT_HOST% %QT_TARGET% tools_opensslv3_x64 :cache_hit @@ -41,7 +42,7 @@ dir %QT_INSTALL_DIR%\Tools REM Set env variables with path set "PATH=%QT_INSTALL_DIR%\%QT%\%QT_ARCH_PATH%\bin;%PATH%" -set "PATH=%QT_INSTALL_DIR%\Tools\mingw1120_64\bin;%PATH%" +set "PATH=%QT_INSTALL_DIR%\Tools\mingw1310_64\bin;%PATH%" set "PATH=%QT_INSTALL_DIR%\Tools\CMake_64\bin;%PATH%" set "PATH=%QT_INSTALL_DIR%\Tools\Ninja;%PATH%" @@ -50,4 +51,4 @@ set "QML_IMPORT_PATH=%QT_INSTALL_DIR%\%QT%\%QT_ARCH_PATH%\qml\" set "QML2_IMPORT_PATH=%QT_INSTALL_DIR%\%QT%\%QT_ARCH_PATH%\qml\" set "CMAKE_PREFIX_PATH=%QT_INSTALL_DIR%\%QT%\%QT_ARCH_PATH%\lib\cmake\Qt6" -set "OPENSSL_DIR=%QT_INSTALL_DIR%\Tools\OpenSSL\Win_x64\bin" +set "OPENSSL_DIR=%QT_INSTALL_DIR%\Tools\OpenSSLv3\Win_x64\bin" diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 57d3131..912ba0a 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -37,12 +37,12 @@ MainWindow::MainWindow(QWidget *parent) : _exceptionGroup.addButton(_pUi->chkGatewayPathUnavailable, QModbusPdu::GatewayPathUnavailable); connect(&_exceptionGroup, QOverload::of(&QButtonGroup::idToggled), this, - [=](int id, bool checked){ - if (checked) - { - _pSlaveModbus->setException(static_cast(id)); - } - }); + [=, this](int id, bool checked) { + if (checked) + { + _pSlaveModbus->setException(static_cast(id)); + } + }); /** Handle error recurrence group **/ _bErrorOnce = true; @@ -50,19 +50,17 @@ MainWindow::MainWindow(QWidget *parent) : _errorRecurrenceGroup.addButton(_pUi->optErrorPersistent, false); connect(&_errorRecurrenceGroup, QOverload::of(&QButtonGroup::idClicked), this, - [=](int id){ - _bErrorOnce = static_cast(id); - }); + [=, this](int id) { _bErrorOnce = static_cast(id); }); connect(_pSlaveModbus, &TestSlaveModbus::requestProcessed, this, &MainWindow::handleRequestProcessed); /** Auto increment **/ _bAutoInc = false; - connect(_pUi->checkAutoIncrement, &QCheckBox::stateChanged, this, - [=](int state){ - _bAutoInc = (state == Qt::Checked); - _pIncGraph->setState(_bAutoInc); - }); + + connect(_pUi->checkAutoIncrement, &QCheckBox::checkStateChanged, this, [this](Qt::CheckState state) { + _bAutoInc = state; + _pIncGraph->setState(_bAutoInc); + }); /** Setup registerView **/ _pUi->tblRegData->setModel(_pRegisterDataModel); diff --git a/src/registerdatamodel.cpp b/src/registerdatamodel.cpp index 472d562..c14a663 100644 --- a/src/registerdatamodel.cpp +++ b/src/registerdatamodel.cpp @@ -42,7 +42,7 @@ int RegisterDataModel::columnCount(const QModelIndex & /*parent*/) const QVariant RegisterDataModel::data(const QModelIndex &index, int role) const { - const int registerAddress = index.row() * _cRegistersPerRow + index.column(); + const uint registerAddress = index.row() * _cRegistersPerRow + index.column(); if (role == Qt::ToolTipRole) { if (registerAddress < _pTestSlaveData->size()) @@ -84,7 +84,7 @@ Qt::ItemFlags RegisterDataModel::flags(const QModelIndex & index) const Qt::ItemFlags flags = Qt::NoItemFlags; - const int registerAddress = index.row() * _cRegistersPerRow + index.column(); + const uint registerAddress = index.row() * _cRegistersPerRow + index.column(); if (registerAddress < _pTestSlaveData->size()) {