1# Coding style 2 3- Indentation in tabs, 8 characters wide, spaces after the tabs where 4 vertical alignment is required (see below) 5 6**Note: this file uses spaces due to markdown rendering issues for tabs. 7 Code must be implemented using tabs.** 8 9- Max line width 80ch, do not break up printed strings though 10 11- Break up long lines at logical groupings, one line for each logical group 12 13```c 14int a = somelongname() + 15 someotherlongname(); 16 17if (a < 0 && 18 (b > 20 & d < 10) && 19 d != 0.0) 20 21 22somelongfunctioncall(arg1, 23 arg2, 24 arg3); 25``` 26 27- Function declarations: return type on separate line, {} on separate line, 28 arguments broken up as above. 29 30```c 31static inline int 32foobar(int a, int b) 33{ 34 35} 36 37void 38somenamethatiswaytoolong(int a, 39 int b, 40 int c) 41{ 42} 43``` 44 45- `/* comments only */`, no `// comments` 46 47- `variable_name`, not `VariableName` or `variableName`. same for functions. 48 49- no typedefs of structs, enums, unions 50 51- if it generates a compiler warning, it needs to be fixed 52- if it generates a static checker warning, it needs to be fixed or 53 commented 54 55- declare variables when they are used first and try to keep them as local as possible. 56 Exception: basic loop variables, e.g. for (int i = 0; ...) should always be 57 declared inside the loop even where multiple loops exist 58 59```c 60int a; 61 62if (foo) { 63 int b = 10; 64 65 a = get_value(); 66 usevalue(a, b); 67} 68 69if (bar) { 70 a = get_value(); 71 useit(a); 72} 73 74int c = a * 100; 75useit(c); 76``` 77 78- avoid uninitialized variables where possible, declare them late instead. 79 Note that most of libinput predates this style, try to stick with the code 80 around you if in doubt. 81 82 wrong: 83 84```c 85 int *a; 86 int b = 7; 87 88 ... some code ... 89 90 a = zalloc(32); 91``` 92 93 right: 94 95```c 96 int b = 7; 97 ... some code ... 98 99 int *a = zalloc(32); 100``` 101 102- avoid calling non-obvious functions inside declaration blocks for multiple 103 variables. 104 105 bad: 106 107```c 108{ 109 int a = 7; 110 int b = some_complicated_function(); 111 int *c = zalloc(32); 112} 113``` 114 115 better: 116```c 117{ 118 int a = 7; 119 int *c = zalloc(32); 120 121 int b = some_complicated_function(); 122} 123``` 124 125 There is a bit of gut-feeling involved with this, but the goal is to make 126 the variable values immediately recognizable. 127 128- Where statements are near-identical and repeated, try to keep them 129 identical: 130 131 bad: 132```c 133int a = get_some_value(x++); 134do_something(a); 135a = get_some_value(x++); 136do_something(a); 137a = get_some_value(x++); 138do_something(a); 139``` 140 better: 141 142```c 143int a; 144a = = get_some_value(x++); 145do_something(a); 146a = get_some_value(x++); 147do_something(a); 148a = get_some_value(x++); 149do_something(a); 150``` 151 152- if/else: { on the same line, no curly braces if both blocks are a single 153 statement. If either if or else block are multiple statements, both must 154 have curly braces. 155 156```c 157if (foo) { 158 blah(); 159 bar(); 160} else { 161 a = 10; 162} 163``` 164 165- public functions MUST be doxygen-commented, use doxygen's `@foo` rather than 166 `\foo` notation 167 168- `#include "config.h"` comes first, followed by system headers, followed by 169 external library headers, followed by internal headers. 170 sort alphabetically where it makes sense (specifically system headers) 171 172```c 173#include "config.h" 174 175#include <stdio.h> 176#include <string.h> 177 178#include <libevdev/libevdev.h> 179 180#include "libinput-private.h" 181``` 182 183- goto jumps only to the end of the function, and only for good reasons 184 (usually cleanup). goto never jumps backwards 185 186- Use stdbool.h's bool for booleans within the library (instead of `int`). 187 Exception: the public API uses int, not bool. 188 189# Git commit message requirements 190 191Our CI will check the commit messages for a few requirements. Below is the 192list of what we expect from a git commit. 193 194## Commit message content 195 196A [good commit message](http://who-t.blogspot.com/2009/12/on-commit-messages.html) needs to 197answer three questions: 198 199- Why is it necessary? It may fix a bug, it may add a feature, it may 200 improve performance, reliabilty, stability, or just be a change for the 201 sake of correctness. 202- How does it address the issue? For short obvious patches this part can be 203 omitted, but it should be a high level description of what the approach 204 was. 205- What effects does the patch have? (In addition to the obvious ones, this 206 may include benchmarks, side effects, etc.) 207 208These three questions establish the context for the actual code changes, put 209reviewers and others into the frame of mind to look at the diff and check if 210the approach chosen was correct. A good commit message also helps 211maintainers to decide if a given patch is suitable for stable branches or 212inclusion in a distribution. 213 214## Commit message format 215 216The canonical git commit message format is: 217 218``` 219one line as the subject line with a high-level note 220 221full explanation of the patch follows after an empty line. This explanation 222can be multiple paragraphs and is largely free-form. Markdown is not 223supported. 224 225You can include extra data where required like: 226- benchmark one says 10s 227- benchmark two says 12s 228``` 229 230The subject line is the first thing everyone sees about this commit, so make 231sure it's on point. 232 233## Commit message technical requirements 234 235- The commit message should use present tense (not past tense). Do write 236 "change foo to bar", not "changed foo to bar". 237- The text width of the commit should be 78 chars or less, especially the 238 subject line. 239- The author must be the name you usually identify as and email address. We do 240 not accept the default `@users.noreply` gitlab addresses. 241 ``` 242 git config --global user.name Your Name 243 git config --global user.email your@email 244 ``` 245