index.md - sites - public wiki contents of suckless.org
HTML git clone git://git.suckless.org/sites
DIR Log
DIR Files
DIR Refs
---
index.md (4924B)
---
1 Style
2 =====
3 Note that the following are guidelines and the most important aspect of style
4 is consistency. Strive to keep your style consistent with the project on which
5 you are working. It is up to the project maintainer to take some liberty in the
6 style **guidelines**.
7
8
9 Recommended Reading
10 -------------------
11 The following contain good information, some of which is repeated below, some
12 of which is contradicted below.
13
14 * <https://man.openbsd.org/style>
15 * <http://doc.cat-v.org/bell_labs/pikestyle>
16 * <https://www.kernel.org/doc/Documentation/process/coding-style.rst>
17
18
19 File Layout
20 -----------
21 * Comment with LICENSE and possibly short explanation of file/tool.
22 * Headers
23 * Macros
24 * Types
25 * Function declarations:
26 * Include variable names.
27 * For short files these can be left out.
28 * Group/order in logical manner.
29 * Global variables.
30 * Function definitions in same order as declarations.
31 * `main`
32
33
34 C Features
35 ----------
36 * Use C99 without extensions (ISO/IEC 9899:1999).
37 * Use POSIX.1-2008:
38 * When using gcc define `_POSIX_C_SOURCE 200809L`.
39 * Alternatively define `_XOPEN_SOURCE 700`.
40 * Do not mix declarations and code.
41 * Do not use for loop initial declarations.
42 * Use `/* */` for comments, not `//`.
43 * Variadic macros are acceptable, but remember:
44 * `__VA_ARGS__` not a named parameter.
45 * Arg list cannot be empty.
46
47
48 Blocks
49 ------
50 * All variable declarations at top of block.
51 * `{` on same line preceded by single space (except functions).
52 * `}` on own line unless continuing statement (`if else`, `do while`, ...).
53
54 Use block for single statement if inner statement needs a block.
55
56 for (;;) {
57 if (foo) {
58 bar;
59 baz;
60 }
61 }
62
63 Use block if another branch of the same statement needs a block:
64
65 if (foo) {
66 bar;
67 } else {
68 baz;
69 qux;
70 }
71
72
73 Leading Whitespace
74 ------------------
75 Use tabs for indentation and spaces for alignment. This ensures everything will
76 line up independent of tab size. This means:
77
78 * No tabs except beginning of line.
79 * Use spaces - not tabs - for multiline macros as the indentation level is 0,
80 where the `#define` began.
81
82
83 Functions
84 ---------
85 * Return type and modifiers on own line.
86 * Function name and argument list on next line. This allows to grep for function
87 names simply using `grep ^functionname(`.
88 * Opening `{` on own line (function definitions are a special case of blocks as
89 they cannot be nested).
90 * Functions not used outside translation unit should be declared and defined
91 `static`.
92
93 Example:
94
95 static void
96 usage(void)
97 {
98 eprintf("usage: %s [file ...]\n", argv0);
99 }
100
101
102 Variables
103 ---------
104 * Global variables not used outside translation unit should be declared `static`.
105 * In declaration of pointers the `*` is adjacent to variable name, not type.
106
107
108 Keywords
109 --------
110 * Use a space after `if`, `for`, `while`, `switch` (they are not function calls).
111 * Do not use a space after the opening `(` and before the closing `)`.
112 * Preferably use `()` with `sizeof`.
113 * Do not use a space with `sizeof()`.
114
115
116 Switch
117 ------
118 * Do not indent cases another level.
119 * Comment cases that FALLTHROUGH.
120
121 Example:
122
123 switch (value) {
124 case 0: /* FALLTHROUGH */
125 case 1:
126 case 2:
127 break;
128 default:
129 break;
130 }
131
132
133 Headers
134 -------
135 * Place system/libc headers first in alphabetical order.
136 * If headers must be included in a specific order add a comment to explain.
137 * Place local headers after an empty line.
138 * When writing and using local headers.
139 * Try to avoid cyclic header inclusion dependencies.
140 * Instead ensure they are included where and when they are needed.
141 * Read <https://talks.golang.org/2012/splash.article#TOC_5.>
142 * Read <http://plan9.io/sys/doc/comp.html>
143
144
145 User Defined Types
146 ------------------
147 * Do not use `type_t` naming (it is reserved for POSIX and less readable).
148 * Typedef opaque structs.
149 * Do not typedef builtin types.
150 * Use `CamelCase` for typedef'd types.
151
152
153 Line Length
154 -----------
155 * Keep lines to reasonable length (max 79 characters).
156
157
158 Tests and Boolean Values
159 ------------------------
160 * Do not use C99 `bool` types (stick to integer types).
161 * Otherwise use compound assignment and tests unless the line grows too long:
162
163 if (!(p = malloc(sizeof(*p))))
164 hcf();
165
166
167 Handling Errors
168 ---------------
169 * When functions `return -1` for error test against `0` not `-1`:
170
171 if (func() < 0)
172 hcf();
173
174 * Use `goto` to unwind and cleanup when necessary instead of multiple nested
175 levels.
176 * `return` or `exit` early on failures instead of multiple nested levels.
177 * Unreachable code should have a NOTREACHED comment.
178 * Think long and hard on whether or not you should cleanup on fatal errors.
179 For simple "one-shot" programs (not daemons) it can be OK to not free memory.
180 It is advised to cleanup temporary files however.
181
182
183 Enums and #define
184 -----------------
185 Use enums for values that are grouped semantically and #define otherwise:
186
187 #define MAXSZ 4096
188 #define MAGIC1 0xdeadbeef
189
190 enum {
191 DIRECTION_X,
192 DIRECTION_Y,
193 DIRECTION_Z
194 };