fixed "remaining" column in WebUI
[qBittorrent.git] / CODING_GUIDELINES.md
blobd17888a3b646763d2ba3f77f3139589497a4f3b2
1 All new code must follow the following coding guidelines.  
2 If you make changes in a file that still uses another coding style, make sure that you follow these guidelines for your changes instead.  
3 **Note 1:** I will not take your head if you forget and use another style. However, most probably the request will be delayed until you fix your coding style.  
4 **Note 2:** You can use the `uncrustify` program/tool to clean up any source file. Use it with the `uncrustify.cfg` configuration file found in the root folder.  
5 **Note 3:** There is also a style for QtCreator but it doesn't cover all cases. In QtCreator `Tools->Options...->C++->Code Style->Import...` and choose the `codingStyleQtCreator.xml` file found in the root folder.  
7 ### 1. Curly braces ###
8 #### a. Function blocks, class/struct definitions, namespaces ####
9 ```c++
10 int myFunction(int a)
12     //code
15 void myFunction() {} // empty body
17 MyClass::MyClass(int *parent)
18     : m_parent(parent)
20     //initialize
23 int MyClass::myMethod(int a)
25     //code
28 class MyOtherClass
30 public:
31     //code
32     
33 protected:
34     //code
35     
36 private:
37     //code
40 namespace Name
42     //code
45 // Lambdas
46 [](int arg1, int arg2) -> bool { return arg1 < arg2; }
48 [this](int arg)
50     this->acc += arg;
52 ```
54 #### b. Other code blocks ####
55 ```c++
56 if (condition) {
57     //code
60 for (int a = 0; a < b; ++b) {
61     //code
64 switch (a) {
65 case 1:
66     //blah
67 case 2:
68     //blah
69 default:
70     //blah
72 ```
74 #### c. Blocks in switch's case labels ####
75 ```c++
76 switch (var) {
77 case 1: {
78         //declare local variables
79         //code
80     }
81     break;
82 case 2: {
83         //declare local variables
84         //code
85     }
86     break;
87 default:
88     //code
90 ```
92 #### d. Brace enclosed initializers ####
93 Unlike single-line functions, you must not insert spaces between the brackets and concluded expressions.<br/>
94 But you must insert a space between the variable name and initializer.
95 ```c++
96 Class obj {}; // empty
97 Class obj {expr};
98 Class obj {expr1, /*...,*/ exprN};
99 QVariantMap map {{"key1", 5}, {"key2", 10}};
102 ### 2. If blocks ###
103 #### a. Multiple tests ####
104 ```c++
105 if (condition) {
106     //code
108 else if (condition) {
109     //code
111 else {
112     //code
115 The `else if`/`else` must be on their own lines.
117 #### b. Single statement if blocks ####
118 **Most** single statement if blocks should look like this:
119 ```c++
120 if (condition)
121     a = a + b;
124 One acceptable exception to this **can be** `return`, `break` or `continue` statements, provided that the test condition isn't very long. However you can choose to use the first rule instead.
125 ```c++
126 a = myFunction();
127 b = a * 1500;
129 if (b > 0) return;
130 c = 100 / b;
133 #### c. Using curly braces for single statement if blocks ####
135 However, there are cases where curly braces for single statement if blocks **should** be used.
136 * If some branch needs braces then all others should use them. Unless you have multiple `else if` in a row and the one needing the braces is only for a very small sub-block of code.
137 * Another exception would be when we have nested if blocks or generally multiple levels of code that affect code readability.
139 Generally it will depend on the particular piece of code and would be determined on how readable that piece of code is. **If in doubt** always use braces if one of the above exceptions applies.
141 ### 3. Indentation ###
142 4 spaces.
144 ### 4. File encoding and line endings. ###
146 UTF-8 and Unix-like line ending (LF). Unless some platform specific files need other encodings/line endings.
148 ### 5. Initialization lists. ###
149 Initialization lists should be vertical. This will allow for more easily readable diffs. The initialization colon should be indented and in its own line along with first argument. The rest of the arguments should be indented too and have the comma prepended.
150 ```c++
151 myClass::myClass(int a, int b, int c, int d)
152     : m_a(a)
153     , m_b(b)
154     , m_c(c)
155     , m_d(d)
157     //code
161 ### 6. Enums. ###
162 Enums should be vertical. This will allow for more easily readable diffs. The members should be indented.
163 ```c++
164 enum Days
166     Monday,
167     Tuesday,
168     Wednesday,
169     Thursday,
170     Friday,
171     Saturday,
172     Sunday
176 ### 7. Names. ###
177 All names should be camelCased.
179 #### a. Type names and namespaces ####
180 Type names and namespaces start with Upper case letter (except POD types).
181 ```c++
182 class ClassName {};
184 struct StructName {};
186 enum EnumName {};
188 typedef QList<ClassName> SomeList;
190 namespace NamespaceName
195 #### b. Variable names ####
196 Variable names start with lower case letter.
197 ```c++
198 int myVar;
201 #### c. Private member variable names ####
202 Private member variable names start with lower case letter and should have ```m_``` prefix.
203 ```c++
204 class MyClass
206     int m_myVar;
210 ### 8. Header inclusion order. ###
211 The headers should be placed in the following order:
212  1. Module header (in .cpp)
213  2. System/Qt/Boost etc. headers (splitted in subcategories if you have many).
214  3. Application headers, starting from *Base* headers.
216 The headers should be ordered alphabetically within each group (subgroup).<br/>
217 <br/>
218 Example:
219 ```c++
220 // examplewidget.cpp
222 #include "examplewidget.h"
224 #include <cmath>
225 #include <cstdio>
227 #include <QDateTime>
228 #include <QList>
229 #include <QString>
230 #include <QUrl>
232 #include <libtorrent/version.hpp>
234 #include "base/bittorrent/session.h"
235 #include "base/bittorrent/infohash.h"
236 #include "base/utils/fs.h"
237 #include "base/utils/misc.h"
238 #include "base/utils/string.h"
239 #include "ui_examplewidget.h"
243 ### 9. Misc. ###
245 * Line breaks for long lines with operation:
247 ```c++
248 a += "b"
249   + "c"
250   + "d";
253 * **auto** keyword
255 We allow the use of the **auto** keyword only where it is strictly necessary 
256 (for example, to declare a lambda object, etc.), or where it **enhances** the readability of the code.
257 Declarations for which one can gather enough information about the object interface (type) from its name 
258 or the usage pattern (an iterator or a loop variable are good examples of clear patterns) 
259 or the right part of the expression nicely fit here.<br/>
260 <br/>
261 When weighing whether to use an auto-typed variable please think about potential reviewers of your code, 
262 who will read it as a plain diff (on github.com, for instance). Please make sure that such reviewers can 
263 understand the code completely and without excessive effort.<br/>
264 <br/>
265 Some valid use cases:
266 ```c++
267 template <typename List>
268 void doSomethingWithList(const List &list)
270     foreach (const auto &item, list) {
271         // we don't know item type here so we use 'auto' keyword
272         // do something with item
273     }
276 for (auto it = container.begin(), end = container.end(); it != end; ++it) {
277     // we don't need to know the exact iterator type,
278     // because all iterators have the same interface
281 auto spinBox = static_cast<QSpinBox*>(sender());
282 // we know the variable type based on the right-hand expression
285 * Space around operations eg `a = b + c` or `a=b+c`:
287 Before and after the assignment and other binary (and ternary) operators there should be a space.<br/>
288 There should not be a space between increment/decrement and its operand.<br/>
289 Some valid use cases:
290 ```c++
291 a += 20;
292 a = (b <= MAX_B ? b : MAX_B);
293 ++a;
294 b--;
296 for (int a = 0; a < b; ++b) {
297     // code
301 * private/public/protected must not be indented
303 * Preprocessor commands must go at line start
305 * Method definitions aren't allowed in header files
307 ### 10. Not covered above ###
308 If something isn't covered above, just follow the same style the file you are editing has. If that particular detail isn't present in the file you are editing, then use whatever the rest of the project uses.