1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
|
# Contributing Guidelines
This document outlines the conventions to follow when contributing to this project.
## Commit Policy
### Run Tests Before Committing
Before preparing or proposing a commit, you **must** run the entire local test suite and ensure that all tests pass. This is a critical step to prevent regressions and maintain the stability of the codebase.
Refer to the "Testing" section in `HOWTO.md` for instructions on how to build and run the tests.
### Format Code Before Committing
All code **must** be formatted using `clang-format` before committing. This ensures a consistent coding style across the entire codebase.
To format your code, run the following command from the project root:
```bash
clang-format -i $(git ls-files | grep -E '\.(h|cc)$' | grep -vE '^(assets|archive|third_party)/')
```
Refer to the `.clang-format` file in the project root for the specific style rules.
### Ensure Newline at End of File
All source files (`.h`, `.cc`, `.cpp`, etc.) must end with a newline character. This prevents "No newline at end of file" errors from linters and ensures consistent file handling.
### Source File Headers
Every source file (`.h`, `.cc`) must begin with a concise 3-line comment header describing its purpose.
Example:
```cpp
// This file is part of the 64k demo project.
// It implements the core audio synthesis engine.
// This is not a user-facing header, but an internal one.
```
### Function and method comments
Functions and methods, especially if they are internal non user-facing,
should at least have a 1-line comment describing what they do or their
how/when they should be called. Except if they are just 1-line function
or very very short, obvious ones.
### '#endif' directive
The closing #endif directive must recall the corresponding opening #ifdef
clause they are closing
Example:
```cpp
#ifdef MY_TAG
...some code
#endif /* MY TAG */
```
We must also prefer '#if defined(MY_QUITE_LONG_TAG)' over '#ifdef MY_QUITE_LONG_TAG'
especially if there's a risk of having later something like:
```cpp
#if defined(MY_TAG_1) && !defined(MY_TAG_2)
```
### use and abuse 'const' directives
Especially for local variable, use 'const' qualification as much as
possible.
As an example, don't use:
```cpp
StructA variable_name = StructA(...);
```
but prefer instead:
```cpp
const StructA variable_name = StructA(...);
```
if variable_name is not mutated afterward.
Also: pass parameter as "const ref" as much as possible
(```const Struct& param``` instead of pointers or non-const refs)
### put spaces around code and operators (cosmetics)
Don't compact the code to much horizontally, and prefer adding extra
spaces around code and operators.
Example:
```cpp
const bool v = my_variable && (my_function() / 3. > (1. / x));
const y = function_call(3, x, 2.);
for (int x = 0; x < 24; ++x) { ... }
```
instead of
```cpp
const bool v=my_variable&&my_function()/3.>(1./x);
const y = function_call(3,x,2);
for(int x=0;x<24;++x){ ... }
```
### prefer prefixed incrementation over suffixed
Use pre-incrementation:
```cpp
++x
```
instead of post-incrementation:
```cpp
x++
```
### use extra () for boolean operations
Even if they are not strictly needed due to operator precedence rules,
prefer adding extra ()'s around tests for clarity, with parcimony.
|