Skip to content

Commit d1d300b

Browse files
authored
[REACTOS] Add CODING_STYLE.md (reactos#7753)
JIRA issue: CORE-20011 - Add CODING_STYLE.md at the root directory. - This CODING_STYLE.md is generated from HTML text of https://reactos.org/wiki/Coding_Style
1 parent 115cf65 commit d1d300b

File tree

1 file changed

+356
-0
lines changed

1 file changed

+356
-0
lines changed

CODING_STYLE.md

Lines changed: 356 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,356 @@
1+
# Coding Style
2+
3+
This article describes general coding style guidelines, which should be used for new ReactOS code. These guidelines apply exclusively to C and C++ source files. The Members of ReactOS agreed on this document in the October 2013 meeting.
4+
5+
As much existing ReactOS code as possible should be converted to this style unless there are reasons against doing this (like if the code is going to be rewritten from scratch in the near future). See [Notes on reformatting existing code](#notes-on-reformatting-existing-code) for more details.
6+
7+
Code synchronized with other sources (like Wine) must not be rewritten. [3rd Party Files.txt](https://github.com/reactos/reactos/blob/master/media/doc/3rd%20Party%20Files.txt) and [WINESYNC.txt](https://github.com/reactos/reactos/blob/master/media/doc/WINESYNC.txt) files can be used for tracking synchronized files.
8+
9+
## File Structure
10+
11+
1. Every ReactOS source code file should include a file header like this:
12+
13+
```
14+
/*
15+
* PROJECT: ReactOS Kernel
16+
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
17+
* PURPOSE: Does cool things like Memory Management
18+
* COPYRIGHT: Copyright 2017 Arno Nymous <[email protected]>
19+
* Copyright 2017 Mike Blablabla <[email protected]>
20+
*/
21+
```
22+
23+
Please use SPDX license identifiers available at https://spdx.org/licenses.
24+
This makes our source file parseable by licensing tools!
25+
26+
You should add yourself to the `COPYRIGHT` section of a file if you did a major contribution to it and could take responsibility for the whole file or a part of it. Not more than 3 people shall be in that list for each file.
27+
28+
`FILE` line of the old header should be removed.
29+
30+
2. [Doxygen](https://doxygen.reactos.org/) documentation generator is used for ReactOS codebase, so use a proper header for functions, see [API Documentation](https://reactos.org/wiki/Documentation_Guidelines#API_Documentation) for details.
31+
32+
## Indentation and line width
33+
34+
1. Line width must be at most **100 characters**.
35+
2. Do not add a space or tab at the end of any line.
36+
3. Indent with **4 spaces**, don't use tabs!
37+
4. Indent both a case label and the case statement of a switch statement.
38+
39+
**Right:**
40+
```c
41+
switch (Condition)
42+
{
43+
case 1:
44+
DoSomething();
45+
break;
46+
47+
case 2:
48+
{
49+
DoMany();
50+
ManyMore();
51+
OtherThings();
52+
break;
53+
}
54+
}
55+
```
56+
57+
**Wrong:**
58+
```c
59+
switch(Condition)
60+
{
61+
case 1:
62+
DoSomething();
63+
break;
64+
case 2:
65+
DoMany();
66+
ManyMore();
67+
OtherThings();
68+
break;
69+
}
70+
```
71+
72+
5. When a function call does not fit onto a line, align arguments like this:
73+
```c
74+
FunctionCall(arg1,
75+
arg2,
76+
arg3);
77+
```
78+
79+
6. Function headers should have this format (preserving the order as in the example):
80+
```c
81+
static // scope identifier
82+
CODE_SEG("PAGE") // section placement
83+
// other attributes
84+
BOOLEAN // return type
85+
FASTCALL // calling convention
86+
IsOdd(
87+
_In_ UINT32 Number);
88+
```
89+
90+
## Spacing
91+
92+
1. Do not use spaces around unary operators.
93+
**Right:** `i++;`
94+
**Wrong:** `i ++;`
95+
96+
2. Place spaces around binary and ternary operators.
97+
**Right:** `a = b + c;`
98+
**Wrong:** `a=b+c;`
99+
100+
3. Do not place spaces before comma and semicolon.
101+
102+
**Right:**
103+
```c
104+
for (int i = 0; i < 5; i++)
105+
DoSomething();
106+
107+
func1(a, b);
108+
```
109+
110+
**Wrong:**
111+
```c
112+
for (int i = 0; i < 5 ; i++)
113+
DoSomething();
114+
115+
func1(a , b) ;
116+
```
117+
118+
4. Place spaces between control statements and their parentheses.
119+
120+
**Right:**
121+
```c
122+
if (Condition)
123+
DoSomething();
124+
```
125+
126+
**Wrong:**
127+
```c
128+
if(Condition)
129+
DoSomething();
130+
```
131+
132+
5. Do not place spaces between a function and its parentheses, or between a parenthesis and its content.
133+
134+
**Right:**
135+
```c
136+
func(a, b);
137+
```
138+
139+
**Wrong:**
140+
```c
141+
func (a, b);
142+
func( a, b );
143+
```
144+
145+
## Line breaking
146+
147+
1. Each statement should get its own line.
148+
149+
**Right:**
150+
```c
151+
x++;
152+
y++;
153+
154+
if (Condition)
155+
DoSomething();
156+
```
157+
158+
**Wrong:**
159+
```c
160+
x++; y++;
161+
162+
if (Condition) DoSomething();
163+
```
164+
165+
## Braces
166+
167+
1. Always put braces (`{` and `}`) on their own lines.
168+
2. One-line control clauses may use braces, but this is not a requirement. An exception are one-line control clauses including additional comments.
169+
170+
**Right:**
171+
```c
172+
if (Condition)
173+
DoSomething();
174+
175+
if (Condition)
176+
{
177+
DoSomething();
178+
}
179+
180+
if (Condition)
181+
{
182+
// This is a comment
183+
DoSomething();
184+
}
185+
186+
if (A_Very || (Very && Long || Condition) &&
187+
On_Many && Lines)
188+
{
189+
DoSomething();
190+
}
191+
192+
if (Condition)
193+
DoSomething();
194+
else
195+
DoSomethingElse();
196+
197+
if (Condition)
198+
{
199+
DoSomething();
200+
}
201+
else
202+
{
203+
DoSomethingElse();
204+
YetAnother();
205+
}
206+
```
207+
208+
**Wrong:**
209+
```c
210+
if (Condition) {
211+
DoSomething();
212+
}
213+
214+
if (Condition)
215+
// This is a comment
216+
DoSomething();
217+
218+
if (A_Very || (Very && Long || Condition) &&
219+
On_Many && Lines)
220+
DoSomething();
221+
222+
if (Condition)
223+
DoSomething();
224+
else {
225+
DoSomethingElse();
226+
YetAnother();
227+
}
228+
```
229+
230+
## Control structures
231+
232+
1. Don't use inverse logic in control clauses.
233+
**Right:** `if (i == 1)`
234+
**Wrong:** `if (1 == i)`
235+
236+
2. Avoid too many levels of cascaded control structures. Prefer a "linear style" over a "tree style". Use `goto` when it helps to make the code cleaner (e.g. for cleanup paths).
237+
238+
**Right:**
239+
```c
240+
if (!func1())
241+
return;
242+
243+
i = func2();
244+
if (i == 0)
245+
return;
246+
247+
j = func3();
248+
if (j == 1)
249+
return;
250+
...
251+
```
252+
253+
**Wrong:**
254+
```c
255+
if (func1())
256+
{
257+
i = func2();
258+
if (func2())
259+
{
260+
j = func3();
261+
if (func3())
262+
{
263+
...
264+
}
265+
}
266+
}
267+
```
268+
269+
## Naming
270+
271+
1. Capitalize names of variables and functions. Hungarian Notation may be used when developing for Win32, but it is not required. If you don't use it, the first letter of a name must be a capital too (no lowerCamelCase). Do not use underscores as separators either.
272+
273+
**Right:**
274+
```c
275+
PLIST_ENTRY FirstEntry;
276+
VOID NTAPI IopDeleteIoCompletion(PVOID ObjectBody);
277+
PWSTR pwszTest;
278+
```
279+
280+
**Wrong:**
281+
```c
282+
PLIST_ENTRY first_entry;
283+
VOID NTAPI iop_delete_io_completion(PVOID objectBody);
284+
PWSTR pwsztest;
285+
```
286+
287+
2. Avoid abbreviating function and variable names, use descriptive verbs where possible.
288+
289+
3. Precede boolean values with meaningful verbs like "is" and "did" if possible and if it fits the usage.
290+
291+
**Right:**
292+
```c
293+
BOOLEAN IsValid;
294+
BOOLEAN DidSendData;
295+
```
296+
297+
**Wrong:**
298+
```c
299+
BOOLEAN Valid;
300+
BOOLEAN SentData;
301+
```
302+
303+
## Commenting
304+
305+
1. Avoid line-wasting comments, which could fit into a single line.
306+
307+
**Right:**
308+
```c
309+
// This is a one-line comment
310+
311+
/* This is a C-style comment */
312+
313+
// This is a comment over multiple lines.
314+
// We don't define any strict rules for it.
315+
```
316+
317+
**Wrong:**
318+
```c
319+
//
320+
// This comment wastes two lines
321+
//
322+
```
323+
324+
## Null, false and 0
325+
326+
1. The null pointer should be written as `NULL`. In the rare case that your environment recommends a different null pointer (e.g. C++11 `nullptr`), you may use this one of course. Just don't use the value `0`.
327+
328+
2. Win32/NT Boolean values should be written as `TRUE` and `FALSE`. In the rare case that you use C/C++ `bool` variables, you should write them as `true` and `false`.
329+
330+
3. When you need to terminate ANSI or OEM string, or check for its terminator, use `ANSI_NULL`. If the string is Unicode or Wide string, use `UNICODE_NULL`.
331+
332+
## Notes on reformatting existing code
333+
334+
- Never totally reformat a file and put a code change into it. Do this in separate commits.
335+
- If a commit only consists of formatting changes, say this clearly in the commit message by preceding it with *[FORMATTING]*.
336+
337+
## Other points
338+
339+
- Do not use `LARGE_INTEGER`/`ULARGE_INTEGER` unless needed for using APIs. Use `INT64`/`UINT64` instead
340+
- Use `#pragma once` instead of guard defines in headers
341+
- Don't specify a calling convention for a function unless required (usually for APIs or exported symbols)
342+
343+
## Using an automatic code style tool
344+
345+
TO BE ADDED BY User:Zefklop
346+
347+
## Points deliberately left out
348+
349+
Additional ideas were suggested during the discussion of this document, but a consensus couldn't be reached on them. Therefore we refrain from enforcing any rules on these points:
350+
351+
- TO BE ADDED BY User:Hbelusca
352+
353+
## See also
354+
355+
- [Kernel Coding Style](https://reactos.org/wiki/Kernel_Coding_Style)
356+
- [GNU Indent](https://reactos.org/wiki/GNU_Indent)

0 commit comments

Comments
 (0)