Enforce coding style using clang-tidy (#3603)

Added scripts/clang-tidy.py
Updated doc to tell about clang-tidy
Added checks for clang-tidy are defined below
* cppcoreguidelines-pro-type-cstyle-cast
* misc-const-correctness
* misc-unused-parameters
* modernize-loop-convert
* modernize-use-auto
* modernize-use-nullptr
* readability-braces-around-statements
* readability-identifier-naming
* readability-make-member-function-const
* performance-for-range-copy
* performance-enum-size
* performance-move-const-arg
* performance-no-automatic-move
* performance-noexcept-destructor
* performance-noexcept-move-constructor
* performance-noexcept-swap
* performance-unnecessary-copy-initialization
* performance-unnecessary-value-param
* performance-use-std-move
* performance-move-constructor-init
This commit is contained in:
Premade 2026-05-22 21:46:02 +05:00 committed by GitHub
parent 1e6782de48
commit dc76ccf59e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
11 changed files with 652 additions and 113 deletions

46
.clang-tidy Normal file
View file

@ -0,0 +1,46 @@
---
Checks: >
-*,
cppcoreguidelines-pro-type-cstyle-cast,
misc-const-correctness,
misc-unused-parameters,
modernize-loop-convert,
modernize-use-auto,
modernize-use-nullptr,
readability-braces-around-statements,
readability-identifier-naming,
readability-make-member-function-const,
performance-for-range-copy,
performance-enum-size,
performance-move-const-arg,
performance-no-automatic-move,
performance-noexcept-destructor,
performance-noexcept-move-constructor,
performance-noexcept-swap,
performance-unnecessary-copy-initialization,
performance-unnecessary-value-param,
performance-use-std-move,
performance-move-constructor-init
HeaderFilterRegex: 'src/(?!.*autogen).*'
WarningsAsErrors: '*'
CheckOptions:
- key: readability-identifier-naming.VariableCase
value: camelBack
- key: readability-identifier-naming.FunctionCase
value: camelBack
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.MemberCase
value: camelBack
- key: misc-const-correctness.TransformValues
value: 'true'
# required because using "-fix" puts "const" after the typename instead of before
- key: misc-const-correctness.TransformValues
value: 'false'
- key: misc-const-correctness.TransformReferences
value: 'false'
- key: misc-const-correctness.TransformPointersAsValues
value: 'false'
- key: misc-const-correctness.TransformPointersAsPointers
value: 'false'
...

View file

@ -31,7 +31,7 @@ jobs:
clang-format:
needs: changes
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
if: ${{ needs.changes.outputs.clang-format == 'true' }}
steps:
- name: Checkout repository
@ -43,17 +43,63 @@ jobs:
- name: Uninstall old conflicting packages
run: sudo apt purge --assume-yes --auto-remove llvm python3-lldb-14 llvm-14
- name: Install automatic LLVM 16
run: wget https://apt.llvm.org/llvm.sh -O /tmp/llvm-install.sh; chmod +x /tmp/llvm-install.sh; sudo /tmp/llvm-install.sh 16
- name: Install automatic LLVM 20
run: wget https://apt.llvm.org/llvm.sh -O /tmp/llvm-install.sh; chmod +x /tmp/llvm-install.sh; sudo /tmp/llvm-install.sh 20
- name: Install clang-format-16
run: sudo apt --assume-yes install clang-format-16
- name: Install clang-format-20
run: sudo apt --assume-yes install clang-format-20
- name: Install gitpython
run: sudo pip install gitpython
- name: Run clang-format
run: |
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-16 160
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-20 200
clang-format --version
python scripts/clang-format.py --check --verbose
clang-tidy:
needs: changes
# if: ${{ needs.changes.outputs.code == 'true' }}
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
submodules: recursive
- name: Install Build Dependencies
run: |
sudo apt update
sudo apt install -y \
build-essential cmake ninja-build meson \
qt6-base-dev qt6-tools-dev \
qt6-tools-dev-tools libqt6svg6-dev libqt6core5compat6-dev \
libqt6svgwidgets6 qt6-l10n-tools \
libgl1-mesa-dev libglu1-mesa-dev
- name: Install automatic LLVM 20
run: wget https://apt.llvm.org/llvm.sh -O /tmp/llvm-install.sh; chmod +x /tmp/llvm-install.sh; sudo /tmp/llvm-install.sh 20
- name: Install clang-tidy-20
run: |
sudo apt --assume-yes install clang-tidy-20
- name: CMake Configuration
run: |
cmake -S . -B build \
-G Ninja \
-DCMAKE_BUILD_TYPE=Release \
-DCUTTER_QT=6 \
-DCMAKE_EXPORT_COMPILE_COMMANDS=ON
- name: Run autogen
run: |
cmake --build build --target Cutter_autogen
- name: Run Clang-Tidy
run: |
sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-20 200
sudo update-alternatives --install /usr/bin/run-clang-tidy run-clang-tidy /usr/bin/run-clang-tidy-20 200
clang-tidy -version
python3 scripts/clang-tidy.py

View file

@ -1,30 +1,59 @@
# Do not edit this file! Automatically generated using scripts/udate_clang_format.sh and scripts/_clang_format
# See update_clang_format.sh for more information.
# generated using clang-format version 8.0.0-3~ubuntu16.04.1 (tags/RELEASE_800/final)
# generated using clang-format version 15.0.4 (https://github.com/ssciwr/clang-format-wheel 0bdee69eb2db136302efab015caaf616d33f5430)
---
Language: Cpp
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignEscapedNewlines: Right
AlignOperands: false
AlignOperands: DontAlign
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortEnumsOnASingleLine: true
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
BraceWrapping:
AfterCaseLabel: false
AfterClass: true
AfterControlStatement: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: true
AfterNamespace: false
@ -34,11 +63,14 @@ BraceWrapping:
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: NonAssignment
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Custom
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
@ -49,16 +81,23 @@ BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 100
CommentPragmas: '^!|^:'
QualifierAlignment: Leave
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 8
Cpp11BracedListStyle: false
DeriveLineEnding: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
PackConstructorInitializers: NextLine
BasedOnStyle: ''
ConstructorInitializerAllOnOneLineOrOnePerLine: false
AllowAllConstructorInitializersOnNextLine: true
FixNamespaceComments: false
ForEachMacros:
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
@ -67,61 +106,118 @@ ForEachMacros:
- QBENCHMARK
- QBENCHMARK_ONCE
- CutterRzListForeach
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^"([^"]*)"'
Priority: 1
SortPriority: 0
CaseSensitive: false
- Regex: '^<[Qq]'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 3
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseLabels: false
IndentCaseBlocks: false
IndentGotoLabels: true
IndentPPDirectives: AfterHash
IndentExternBlock: AfterExternBlock
IndentRequiresClause: true
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertBraces: true
InsertTrailingCommas: None
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
LambdaBodyIndentation: Signature
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PenaltyIndentedWhitespace: 0
PointerAlignment: Right
PPIndentWidth: -1
ReferenceAlignment: Pointer
ReflowComments: true
SortIncludes: false
RemoveBracesLLVM: false
RequiresClausePosition: OwnLine
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceAroundPointerQualifiers: Default
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInAngles: Never
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
StatementMacros:
SpaceBeforeSquareBrackets: false
BitFieldColonSpacing: Both
Standard: Latest
StatementAttributeLikeMacros:
- emit
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseCRLF: false
UseTab: Never
WhitespaceSensitiveMacros:
- STRINGIZE
- PP_STRINGIZE
- BOOST_PP_STRINGIZE
- NS_SWIFT_NAME
- CF_SWIFT_NAME
...

View file

@ -20,7 +20,7 @@
# -- Project information -----------------------------------------------------
project = 'Cutter'
copyright = '2020, The Cutter Developers'
copyright = '2026, The Cutter Developers'
author = 'The Cutter Developers'
# The short X.Y version

View file

@ -51,6 +51,9 @@ so your widget refreshes its output when Rizin seek is modified
Coding Style
------------
clang-format
~~~~~~~~~~~~
In general, we follow a slightly customized version of `the official Qt guidelines <https://wiki.qt.io/Qt_Coding_Style>`__
to format the code. Before sending a pull request, you will need to use `clang-format <https://clang.llvm.org/docs/ClangFormat.html>`__ (version 8 or newer)
to format the code. The command line for formatting the code according
@ -60,12 +63,226 @@ to the style is:
clang-format -style=file -i src/filename.cpp
If your changes were done on many files across the codebase, you can use this oneliner to tun ``clang-format`` on the entire 'src' directory:
If your changes were done on many files across the codebase, you can use this oneliner to run ``clang-format`` on the entire ``src`` directory:
.. code:: bash
find ./src -regex '.*\.\(cpp\|h\)' -exec clang-format -style=file -i {} \;
clang-tidy
~~~~~~~~~~
Beyond formatting, we use `clang-tidy <https://clang.llvm.org/extra/clang-tidy/>`__ (version 13 or newer) to catch potential style violations.
To run ``clang-tidy``, first configure your build to generate ``compile_commands.json`` and run the autogen tools:
.. code:: bash
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release -DCUTTER_QT=6 -DCUTTER_USE_BUNDLED_RIZIN=ON -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake --build build --target Cutter_autogen
Run ``clang-tidy`` on modified files relative to the latest commit
.. code:: bash
git diff -U0 --no-color HEAD~1 | clang-tidy-diff.py -p1 -path build/
Similar to ``clang-format``, If your changes were done on many files across the codebase, you can use this oneliner to run ``clang-tidy`` on the entire 'src' directory. The following command excludes third-party and auto generated files:
.. code:: bash
run-clang-tidy -p build ".*src/(?!(themes|bindings|fonts|img|translations|Cutter_autogen)).*\.(cpp|h)$"
``clang-tidy`` can also attempt to fix style violations using the ``-fix`` flag. However these may not always be perfect. Make sure to verify the fixes before opening a pull request:
.. code:: bash
git diff -U0 --no-color HEAD~1 | clang-tidy-diff.py -fix -p1 -path build/
Python scripts
~~~~~~~~~~~~~~
If you don't want to run manual commands, cutter also provides scripts for running ``clang-format`` and ``clang-tidy`` in the ``scripts`` directory
.. code:: bash
python scripts/clang-format.py -h
usage: clang-format.py [-h] [-C CLANG_FORMAT] [-c] [-v] [-f FILE] [-d DIFF]
Clang format the cutter project
options:
-h, --help show this help message and exit
-C, --clang-format CLANG_FORMAT
path of clang-format
-c, --check enable the check mode
-v, --verbose use verbose output
-f, --file FILE formats (or checks) only the given file
-d, --diff DIFF format all modified file related to branch
.. code:: bash
usage: clang-tidy.py [-h] [-T RUN_CLANG_TIDY] [-p BUILD_PATH] [-j JOBS] [-r REGEX] [-i] [-q]
clang-tidy regex wrapper
options:
-h, --help show this help message and exit
-T, --run-clang-tidy RUN_CLANG_TIDY
Path of run-clang-tidy binary
-p, --build-path BUILD_PATH
Path to the build directory
-j, --jobs JOBS Number of parallel execution jobs
-r, --regex REGEX Regex pattern for filtering files
-i, --fix Apply fixes automatically
-q, --quiet Suppress configuration logs
Below are some of the low level coding conventions that we follow
Variables
~~~~~~~~~
Variable names start with a lowercase letter with each consecutive word starting with an uppercase letter. (**camelBack** case)
.. code:: cpp
int Height // Wrong
string name_of_widget // Wrong
int height; // Correct
string nameOfWidget // Correct
Avoid meaningless variable names
.. code:: cpp
int a, b; // Wrong
string c; // Wrong
int height, width; // Correct
string nameOfThis; // Correct
Object obj; // Also Correct
Only first letter of an acronym is uppercase
.. code:: cpp
CutterJsonWigdet cutterJSONWidget; // Wrong
CutterJsonWigdet cutterJsonWigdet; // Correct
Variable names don't use leading/trailing underscores, including prefixes like m\_
.. code:: cpp
class Example {
private:
int index_; // Wrong
int m_index; // Wrong
int index; // Correct
};
Global variables follow the same naming conventions
Anonymous Namespace
~~~~~~~~~~~~~~~~~~~
Global entities (variables, functions, structs...) private to a source file (internal linkage) are defined in an anonymous namespace
.. code:: cpp
namespace {
int globalCounter = 0;
bool doSomething() {
...
return true;
}
};
Functions
~~~~~~~~~
Function names follow the same naming convention as `variables`_. (**camelBack** casing)
.. code:: cpp
void do_something() {} // Wrong
void DoSomething() {} // Wrong
void doSomething() {} // Correct
Unused parameters inside a function are omitted in the definition either by commenting out the parameter name or not writing the name at all.
Avoid using ``Q_UNUSED``
.. code:: cpp
// Bad
void doSomething(int one, int two) {
Q_UNUSED(one)
...
}
// Good
void doSomething(int /*one*/, int two) {
...
}
// Good
void doSomething(int, int two) {
...
}
Avoid the use of automatic name based connections. See `Connecting Qt Signals`_.
Classes
~~~~~~~~
First letter of each word is uppercased. (**CamelCase**)
.. code:: cpp
class memory_dock_widget; // Wrong
class memoryDockWidget; // Wrong
class MemoryDockWidget; // Correct
Only first letter of an acronym is uppercase
.. code:: cpp
class CutterJSONWidget // Wrong
class CutterJsonWidget // Correct
Member variables follow the same naming conventions defined in `variables`_ that means no leading/trailing underscores or m\_ prefixes
Casting
~~~~~~~
Avoid the use of C style casts, prefer C++ casts (``static_cast``, ``const_cast`` ...)
Use ``qobject_cast`` for ``QObjects``
Smart Pointers
~~~~~~~~~~~~~~
Prefer the use of C++ smart pointers (``unique_ptr``, ``shared_ptr``...)
.. code:: cpp
RegisterProfileDialog *ui; // Bad
std::unique_ptr<Ui::RegisterProfileDialog> ui; // Good
Braces
~~~~~~
In contrast to the official guidelines of Qt, in Cutter we always use curly braces in conditional statements, even if the body of a conditional statement contains only one line.
.. code:: cpp
@ -88,51 +305,6 @@ In contrast to the official guidelines of Qt, in Cutter we always use curly brac
qDebug("%i", i);
}
Includes
~~~~~~~~
Strive to include only **required** definitions inside header files.
This will avoid triggering additional unnecessary compilations.
If you only need to know that a class exists but don't need the prototype,
you can declare the class like this:
.. code:: cpp
class MyClassThatExists;
/** ... **/
private:
MyClassThatExists *classInstance;
And then include the class header inside your .cpp so you can use that class.
If you need something in the source file (.cpp) that is not a class member,
then add the include in the source file.
The includes must be ordered from local to global. That is, first include
any local header file (with double quotes like `#include "common/Helpers.h"`.
Then, after an empty newline, include Qt definitions like
`#include <QShortcut>`.
Finally, include the standard C++ headers you need.
Includes must be sorted by alphabetical order.
Docstrings
~~~~~~~~~~
Our API reference is generated using Doxygen, so when it comes to
function documentation, please use the following format:
.. code:: cpp
/**
* @brief Add a new param to the accumulator
*/
virtual void accumulate(RefreshDeferrerParams params) =0;
Loops
~~~~~
@ -140,10 +312,41 @@ We use the C++11 foreach loop style, which means any “foreach” loop should
look like:
.. code:: cpp
for (QJsonValue value : importsArray) {
doSomething(value);
// Good - If a copy of each element is required
for (auto import : importsArray) {
doSomething(import);
}
// Good - If copy is not required
for (auto &import : importsArray) {
doSomething(import);
}
// Good - If no modification is required
for (const auto &import : importsArray) {
doSomething(import);
}
auto
~~~~
Prefer the use of ``auto`` keyword when working with the following:
.. code:: cpp
// Iterators
auto it = myMap.find(key);
for (const auto &import : importsArray) { ... }
// Lambdas
auto multiply = [](int a, int b) -> int { return a * b; };
// Casting
auto myFloat = static_cast<float>(myInt);
// Initializing using new
auto *item = new QListWidgetItem(text);
nullptr
~~~~~~~
@ -154,7 +357,10 @@ Example:
.. code:: cpp
QObject *object = nullptr;
std::unique_ptr<QObject> obj = nullptr;
// Note that this is just an example, unique_ptr constructor initializes the internal pointer to nullptr by default
Connecting Qt Signals
~~~~~~~~~~~~~~~~~~~~~
@ -191,13 +397,82 @@ Don't use the older macro based syntax or automatic name based connections.
connect(sender, &SomeObject::signal, [this](){ this->foo(getBar()); }); // BAD
Includes
~~~~~~~~
Strive to include only **required** definitions inside header files.
This will avoid triggering additional unnecessary compilations.
If you only need to know that a class exists but don't need the prototype,
you can declare the class like this:
.. code:: cpp
class MyClassThatExists;
/** ... **/
private:
std::unqiue_ptr<MyClassThatExists> classInstance;
And then include the class header inside your .cpp so you can use that class.
If you need something in the source file (.cpp) that is not a class member,
then add the include in the source file.
The includes must be ordered from local to global. That is, first include
any local header file (with double quotes like `#include "common/Helpers.h"`.
Then, after an empty newline, include Qt definitions like
`#include <QShortcut>`.
Finally, include the standard C++ headers you need.
Includes must be sorted by alphabetical order.
This is automatically handled by running ``clang-format``
Docstrings
~~~~~~~~~~
Our API reference is generated using Doxygen, so when it comes to
function documentation, please use the following format:
.. code:: cpp
/**
* @brief Add new parameters to the accumulator
* @param params The parameters to add
* @return True if the parameters were added, false otherwise
*/
bool accumulate(RefreshDeferrerParams params) { ... };
Documenting every function is generally not required. Only document those functions whose purpose is not immediately understandable just by looking at the function name.
.. code:: cpp
// No need for docs
int getCount() const;
// Should provide docs
bool syncRemote();
It is preferred for classes to have documentation just above the definition, explaining their purpose.
.. code:: cpp
/**
* @brief A short description about SomeDialog
*/
class SomeDialog {
...
};
General Coding Advices
----------------------
Functions Documentation
~~~~~~~~~~~~~~~~~~~~~~~
You can find the class documentation in the API Reference menu item.
You can find the class documentation in the `API Reference <https://cutter.re/docs/api.html>`__ menu item.
Updating the Git Submodules
~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -239,6 +514,6 @@ In order to update one submodule individually, use the following code:
Useful Resources (Qt Development)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* `Signals & Slots <https://doc.qt.io/qt-5/signalsandslots.html>`__
* `Model/View Programming <https://doc.qt.io/qt-5/model-view-programming.html>`__ - read this if you are going to work with a list or table-like widgets
* `QAction <https://doc.qt.io/qt-5/qaction.html#details>`__
* `Signals & Slots <https://doc.qt.io/qt-6/signalsandslots.html>`__
* `Model/View Programming <https://doc.qt.io/qt-6/model-view-programming.html>`__ - read this if you are going to work with a list or table-like widgets
* `QAction <https://doc.qt.io/qt-6/qaction.html#details>`__

View file

@ -79,10 +79,10 @@ AllowShortFunctionsOnASingleLine: Inline
# separate categories with an empty line. It does not specify the order within
# the categories. Since the SortInclude feature of clang-format does not
# re-order includes separated by empty lines, the feature is not used.
SortIncludes: false
SortIncludes: true
# macros for which the opening brace stays attached.
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE, CutterRzListForeach ]
# Break constructor initializers before the colon and after the commas.
BreakConstructorInitializers: BeforeColon
@ -92,3 +92,28 @@ BreakConstructorInitializers: BeforeColon
# Align the assignment operators of consecutive lines
AlignConsecutiveAssignments: false
# Sort headers in the following groups in alphabetical order
# Each group is seperated by an empty line
# 1- Main header
# 2- Local headers starting with ""
# 3- Qt headers starting with <Q...> or <q...>
# 4- Standard C++ headers or any others
IncludeBlocks: Regroup
IncludeCategories:
- Regex: '^"([^"]*)"'
Priority: 1
- Regex: '^<[Qq]'
Priority: 2
- Regex: '.*'
Priority: 3
# Insert braces after conditional statements/loops even if they
# contain a single statement
InsertBraces: true
# Insert space in empty braces
SpaceInEmptyBlock: false
# Removes the spaces around ->
StatementAttributeLikeMacros: [emit]

51
scripts/clang-tidy.py Normal file
View file

@ -0,0 +1,51 @@
#!/usr/bin/env python3
import argparse
import subprocess
import sys
DEFAULT_REGEX = r".*src/(?!(themes|bindings|fonts|img|translations|Cutter_autogen)).*\.(cpp|h)$"
def run_tidy(args):
cmd = [args.run_clang_tidy, "-p", args.build_path]
if args.jobs:
cmd.append(f"-j {args.jobs}")
if args.fix:
cmd.append("-fix")
if args.quiet:
cmd.append("-quiet")
cmd.append(f"'{args.regex}'")
print(f"Executing: {' '.join(cmd)}")
result = subprocess.run(" ".join(cmd), shell=True)
sys.exit(result.returncode)
def main():
parser = argparse.ArgumentParser(description="clang-tidy regex wrapper")
parser.add_argument("-T", "--run-clang-tidy",
default="run-clang-tidy",
help="Path of run-clang-tidy binary")
parser.add_argument("-p", "--build-path", default="build",
help="Path to the build directory")
parser.add_argument("-j", "--jobs", type=int, default=0,
help="Number of parallel execution jobs")
parser.add_argument("-r", "--regex", default=DEFAULT_REGEX,
help="Regex pattern for filtering files")
parser.add_argument("-i", "--fix", action="store_true", help="Apply fixes automatically")
parser.add_argument("-q", "--quiet", action="store_true", default=False, help="Suppress configuration logs")
args = parser.parse_args()
run_tidy(args)
if __name__ == "__main__":
main()

View file

@ -5,9 +5,9 @@ set -euo pipefail
cd $(dirname "${BASH_SOURCE[0]}")
# Do not replace with newer without dicussing! Intentionally using older clang-format-version.
tool=clang-format-8
tool=clang-format-15
# Using full config dumped with older clang format should produce more consistent result when some
# people have slightly newer clang-format. 8 chosen because it is newest version available in Ubuntu 16.04 official repository.
# people have slightly newer clang-format. 15 chosen because it is newest version available in Ubuntu 22.04 official repository.
output_file=../_clang-format

View file

@ -4974,29 +4974,27 @@ QString CutterCore::getVersionInformation()
{
const char *name;
const char *(*callback)();
} vcs[] = {
{ "rz_arch", &rz_arch_version },
{ "rz_lib", &rz_lib_version },
{ "rz_egg", &rz_egg_version },
{ "rz_bin", &rz_bin_version },
{ "rz_cons", &rz_cons_version },
{ "rz_flag", &rz_flag_version },
{ "rz_core", &rz_core_version },
{ "rz_crypto", &rz_crypto_version },
{ "rz_debug", &rz_debug_version },
{ "rz_hash", &rz_hash_version },
{ "rz_io", &rz_io_version },
} vcs[] = { { "rz_arch", &rz_arch_version },
{ "rz_lib", &rz_lib_version },
{ "rz_egg", &rz_egg_version },
{ "rz_bin", &rz_bin_version },
{ "rz_cons", &rz_cons_version },
{ "rz_flag", &rz_flag_version },
{ "rz_core", &rz_core_version },
{ "rz_crypto", &rz_crypto_version },
{ "rz_debug", &rz_debug_version },
{ "rz_hash", &rz_hash_version },
{ "rz_io", &rz_io_version },
#if !USE_LIB_MAGIC
{ "rz_magic", &rz_magic_version },
{ "rz_magic", &rz_magic_version },
#endif
{ "rz_reg", &rz_reg_version },
{ "rz_sign", &rz_sign_version },
{ "rz_search", &rz_search_version },
{ "rz_syscall", &rz_syscall_version },
{ "rz_util", &rz_util_version },
/* ... */
{ nullptr, nullptr }
};
{ "rz_reg", &rz_reg_version },
{ "rz_sign", &rz_sign_version },
{ "rz_search", &rz_search_version },
{ "rz_syscall", &rz_syscall_version },
{ "rz_util", &rz_util_version },
/* ... */
{ nullptr, nullptr } };
versionInfo.append(getRizinVersionReadable());
versionInfo.append("\n");
for (i = 0; vcs[i].name; i++) {

View file

@ -28,9 +28,10 @@ void ColorThemeComboBox::updateFromConfig(bool interfaceThemeChanged)
}
}
QString curTheme = interfaceThemeChanged ? Config()->getLastThemeOf(
Configuration::cutterInterfaceThemesList()[curInterfaceThemeIndex])
: Config()->getColorTheme();
QString curTheme = interfaceThemeChanged
? Config()->getLastThemeOf(
Configuration::cutterInterfaceThemesList()[curInterfaceThemeIndex])
: Config()->getColorTheme();
const int index = findText(curTheme);
setCurrentIndex(index == -1 ? 0 : index);

View file

@ -253,9 +253,10 @@ void HexdumpWidget::updateParseWindow(RVA start_address, int size)
tempConfig.set("asm.arch", arch).set("asm.bits", bits).set("cfg.bigendian", bigEndian);
ui->hexDisasTextEdit->setPlainText(
selectedCommand != "" ? Core()->cmdRawAt(
QString("%1 @! %2").arg(selectedCommand).arg(size), start_address)
: "");
selectedCommand != ""
? Core()->cmdRawAt(QString("%1 @! %2").arg(selectedCommand).arg(size),
start_address)
: "");
} else {
// Fill the information tab hashes and entropy
RzHashSize digestSize = 0;