summaryrefslogtreecommitdiff
path: root/CODING_STYLE.md
blob: 4fe97ed79d3e812b13bee85f0a8fc3e094e96b4a (plain)
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

- Indentation in tabs, 8 characters wide, spaces after the tabs where
  vertical alignment is required (see below)

**Note: this file uses spaces due to markdown rendering issues for tabs.
  Code must be implemented using tabs.**

- Max line width 80ch, do not break up printed strings though

- Break up long lines at logical groupings, one line for each logical group

```c
int a = somelongname() +
        someotherlongname();

if (a < 0 &&
    (b > 20 & d < 10) &&
    d != 0.0)


somelongfunctioncall(arg1,
                     arg2,
                     arg3);
```

- Function declarations: return type on separate line, {} on separate line,
  arguments broken up as above.

```c
static inline int
foobar(int a, int b)
{

}

void
somenamethatiswaytoolong(int a,
                         int b,
                         int c)
{
}
```

- `/* comments only */`, no `// comments`

- `variable_name`, not `VariableName` or `variableName`. same for functions.

- no typedefs of structs, enums, unions

- if it generates a compiler warning, it needs to be fixed
- if it generates a static checker warning, it needs to be fixed or
  commented

- declare variables at the top, try to keep them as local as possible.
  Exception: if the same variable is re-used in multiple blocks, declare it
  at the top.
  Exception: basic loop variables, e.g. for (int i = 0; ...)

```c
int a;
int c;

if (foo) {
        int b;

        c = get_value();
        usevalue(c);
}

if (bar) {
        c = get_value();
        useit(c);
}
```

- do not mix function invocations and variable definitions.

  wrong:

```c
{
        int a = foo();
        int b = 7;
}
```

  right:
```c
{
        int a;
        int b = 7;

        a = foo();
}
```

  There are exceptions here, e.g. `tp_libinput_context()`,
  `litest_current_device()`

- if/else: { on the same line, no curly braces if both blocks are a single
  statement. If either if or else block are multiple statements, both must
  have curly braces.

```c
if (foo) {
        blah();
        bar();
} else {
        a = 10;
}
```

- public functions MUST be doxygen-commented, use doxygen's `@foo` rather than
  `\foo` notation

- `#include "config.h"` comes first, followed by system headers, followed by
  external library headers, followed by internal headers.
  sort alphabetically where it makes sense (specifically system headers)

```c
#include "config.h"

#include <stdio.h>
#include <string.h>

#include <libevdev/libevdev.h>

#include "libinput-private.h"
```

- goto jumps only to the end of the function, and only for good reasons
  (usually cleanup). goto never jumps backwards

- Use stdbool.h's bool for booleans within the library (instead of `int`).
  Exception: the public API uses int, not bool.