Mercurial > molko
comparison STYLE.md @ 13:c188e9603faf
misc: add basic documentation files
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 07 Jan 2020 21:34:03 +0100 |
parents | |
children | 98e091b9251e |
comparison
equal
deleted
inserted
replaced
12:29b479760c05 | 13:c188e9603faf |
---|---|
1 Molko's Adventure CODING STYLE | |
2 ============================== | |
3 | |
4 File content | |
5 ============ | |
6 | |
7 - Use UTF-8 charset, | |
8 - Use Unix line endings, | |
9 - Never write two consecutives blank lines. | |
10 | |
11 Indent | |
12 ====== | |
13 | |
14 Use tabs to indent and spaces for alignment. Tabs are meant and designed for | |
15 indenting code and have the advantage of being configurable. On the other hand | |
16 to keep code clean, you must align content with spaces only *within* a line. | |
17 | |
18 Note: we recommend 8 columns to avoid high number of indentations. | |
19 | |
20 Example (show whitespace in your editor) | |
21 | |
22 ```cpp | |
23 class foo { | |
24 public: | |
25 enum type { | |
26 dummy_value, // dummy comment | |
27 other_value // other comment | |
28 }; | |
29 | |
30 void long_function_name(very_long_type x1, | |
31 very_long_type x2) | |
32 { | |
33 const map<string, string> m{ | |
34 { "hostname", "127.0.0.1" }, | |
35 { "port", "6667" } | |
36 }; | |
37 } | |
38 }; | |
39 ``` | |
40 | |
41 As a rule of thumb, tabs must always be all length. | |
42 | |
43 Example of incorrect usage: | |
44 | |
45 ```cpp | |
46 { "hostname", "127.0.0.1" }, | |
47 { "port", "6667" } | |
48 ``` | |
49 | |
50 This example will not align correctly if tabstops are not set to 8. | |
51 | |
52 C | |
53 = | |
54 | |
55 Style | |
56 ----- | |
57 | |
58 - Do not exceed 80 columns. | |
59 | |
60 ### Braces | |
61 | |
62 Braces follow the K&R style, they are never placed on their own lines except for | |
63 function definitions. | |
64 | |
65 Do not put braces for single line statements. | |
66 | |
67 ```c | |
68 if (condition) { | |
69 apply(); | |
70 add(); | |
71 } else | |
72 ok(); | |
73 | |
74 if (condition) | |
75 validate(); | |
76 | |
77 if (foo) | |
78 state = long + conditional + that + requires + several + lines + | |
79 to + complete; | |
80 ``` | |
81 | |
82 Functions require braces on their own lines. | |
83 | |
84 ```c | |
85 void | |
86 function() | |
87 { | |
88 } | |
89 ``` | |
90 | |
91 Note: the type of a function is broken into its own line. | |
92 | |
93 ### Spaces | |
94 | |
95 Each reserved keyword (e.g. `if`, `for`, `while`) requires a single space before | |
96 its argument. | |
97 | |
98 Normal function calls do not require it. | |
99 | |
100 ```c | |
101 if (foo) | |
102 destroy(sizeof (int)); | |
103 ``` | |
104 | |
105 ### Pointers | |
106 | |
107 Pointers are always next variable name. | |
108 | |
109 ```c | |
110 void | |
111 cleanup(struct owner *owner); | |
112 ``` | |
113 | |
114 ### Typedefs | |
115 | |
116 Do not use typedef for non-opaque objects. It is allowed for function pointers. | |
117 | |
118 ```c | |
119 struct pack { | |
120 int x; | |
121 int y; | |
122 }; | |
123 | |
124 typedef void (*logger)(const char *line); | |
125 ``` | |
126 | |
127 Note: do never add `_t` suffix to typedef's. | |
128 | |
129 ### Naming | |
130 | |
131 - English names, | |
132 - No hungarian notation, | |
133 | |
134 Almost everything is in `underscore_case` except macros and enumeration | |
135 constants. | |
136 | |
137 ```c | |
138 #if defined(FOO) | |
139 # include <foo.hpp> | |
140 #endif | |
141 | |
142 #define MAJOR 1 | |
143 #define MINOR 0 | |
144 #define PATCH 0 | |
145 | |
146 enum color { | |
147 COLOR_RED, | |
148 COLOR_GREEN, | |
149 COLOR_BLUE | |
150 }; | |
151 | |
152 void | |
153 add_widget(const struct widget *widget_to_add); | |
154 ``` | |
155 | |
156 ### Header guards | |
157 | |
158 Do not use `#pragma once`. | |
159 | |
160 Header guards are usually named `PROJECT_COMPONENT_FILENAME_H`. | |
161 | |
162 ```c | |
163 #ifndef FOO_COMMON_UTIL_H | |
164 #define FOO_COMMON_UTIL_H | |
165 | |
166 #endif /* !FOO_COMMON_UTIL_HPP */ | |
167 ``` | |
168 | |
169 ### Enums | |
170 | |
171 Enumerations constants are always defined in separate line to allow commenting | |
172 them as doxygen. | |
173 | |
174 Note: enumeration constants are prefixed with its name. | |
175 | |
176 ```c | |
177 enum color { | |
178 COLOR_RED, | |
179 COLOR_GREEN, | |
180 COLOR_BLUE | |
181 }; | |
182 ``` | |
183 | |
184 ### Switch | |
185 | |
186 In a switch case statement, you **must** not declare variables and not indent | |
187 cases. | |
188 | |
189 ```c | |
190 switch (variable) { | |
191 case foo: | |
192 do_some_stuff(); | |
193 break; | |
194 default: | |
195 break; | |
196 } | |
197 ``` | |
198 | |
199 ### Files | |
200 | |
201 - Use `.c` and `.h` as file extensions, | |
202 - Filenames are all lowercase. | |
203 | |
204 ### Comments | |
205 | |
206 Avoid useless comments in source files. Comment complex things or why it is done | |
207 like this. However any public function in the .h **must** be documented as | |
208 doxygen without exception. | |
209 | |
210 ```c | |
211 /* | |
212 * Multi line comments look like | |
213 * this. | |
214 */ | |
215 | |
216 // Short comment | |
217 ``` | |
218 | |
219 Use `#if 0` to comment blocks of code. | |
220 | |
221 ```c | |
222 #if 0 | |
223 broken_stuff(); | |
224 #endif | |
225 ``` | |
226 | |
227 ### Includes | |
228 | |
229 The includes should always come in the following order. | |
230 | |
231 1. System headers (POSIX mostly) | |
232 2. C header | |
233 3. Third party libraries | |
234 4. Application headers in "" | |
235 | |
236 ```c | |
237 #include <sys/types.h> | |
238 #include <sys/stat.h> | |
239 #include <string.h> | |
240 | |
241 #include <libircclient.h> | |
242 | |
243 #include "foo.h" | |
244 ``` | |
245 | |
246 Programming | |
247 ----------- | |
248 | |
249 ### C Standard | |
250 | |
251 Use C99 standard without extensions. | |
252 | |
253 ### Assertions | |
254 | |
255 Use the `assert` macro from the assert.h header file to verify programming | |
256 errors. | |
257 | |
258 For example, you may use `assert` to verify that the developer access the data | |
259 between the bounds of an array: | |
260 | |
261 ```c | |
262 int | |
263 get(struct data *data, unsigned index) | |
264 { | |
265 assert(index < data->length); | |
266 | |
267 return data->buffer[index]; | |
268 } | |
269 ``` | |
270 | |
271 The `assert` macro is not meant to check that a function succeeded, this code | |
272 must not be written that way: | |
273 | |
274 ```c | |
275 assert(listen(10)); | |
276 ``` | |
277 | |
278 ### Return | |
279 | |
280 The preferred style is to return early in case of errors. That makes the code | |
281 more linear and not highly indented. | |
282 | |
283 This code is preferred: | |
284 | |
285 ```c | |
286 if (a_condition_is_not_valid) | |
287 return false; | |
288 if (an_other_condition) | |
289 return false; | |
290 | |
291 start(); | |
292 save(); | |
293 | |
294 return true; | |
295 ``` | |
296 | |
297 Additional rules: | |
298 | |
299 - Do never put parentheses between the returned value, | |
300 - Do not put a else branch after a return. | |
301 | |
302 Shell | |
303 ===== | |
304 | |
305 Write POSIX shell only with no bash, zsh or any extension. | |
306 | |
307 Style | |
308 ----- | |
309 | |
310 - Try to keep lines shorter than 80 columns | |
311 | |
312 Functions | |
313 --------- | |
314 | |
315 Don't use `function` keyword, just keep the function name. | |
316 | |
317 ```sh | |
318 usage() | |
319 { | |
320 } | |
321 ``` | |
322 | |
323 It's usually recommended to prefix functions names with the program name to | |
324 avoid collisions with global commands. | |
325 | |
326 ```sh | |
327 foo_clean() | |
328 { | |
329 } | |
330 | |
331 foo_process() | |
332 { | |
333 } | |
334 ``` | |
335 | |
336 Options | |
337 ------- | |
338 | |
339 For options, use `getopts` and prefer short options to long unless necessary. | |
340 Also set OPTERR=0 to avoid printing errors and do it yourself for UX | |
341 consistency. | |
342 | |
343 ```sh | |
344 OPTERR=0 | |
345 while getopts "v" arg; do | |
346 case $arg in | |
347 v) | |
348 verbose=1 | |
349 ;; | |
350 esac | |
351 done | |
352 ``` | |
353 | |
354 Naming | |
355 ------ | |
356 | |
357 Use `UPPERCASE` variables for global variables and `lowercase` for temporary or | |
358 local variables. | |
359 | |
360 Markdown | |
361 ======== | |
362 | |
363 Headers | |
364 ------- | |
365 | |
366 For 1st and 2nd level headers, use `===` and `---` delimiters and underline the | |
367 whole title. Otherwise use `###`. | |
368 | |
369 ```markdown | |
370 Top level title | |
371 =============== | |
372 | |
373 Sub title | |
374 --------- | |
375 | |
376 ### Header 3 | |
377 | |
378 #### Header 4 | |
379 | |
380 ##### Header 5 | |
381 | |
382 ###### Header 6 | |
383 ``` | |
384 | |
385 Lists | |
386 ----- | |
387 | |
388 Use hyphens for unordered lists for consistency, do not indent top level lists, | |
389 then indent by two spaces each level | |
390 | |
391 ```markdown | |
392 - unordered list 1 | |
393 - unordered list 2 | |
394 - sub unordered item | |
395 | |
396 1. unordered list 1 | |
397 2. unordered list 2 | |
398 2.1. sub unordered item | |
399 ``` | |
400 | |
401 Code blocks | |
402 ----------- | |
403 | |
404 You can use three backticks and the language specifier or just indent a block by | |
405 for leading spaces if you don't need syntax. | |
406 | |
407 ```cpp | |
408 std::cout << "hello world" << std::endl; | |
409 ``` | |
410 | |
411 And without syntax: | |
412 | |
413 ```markdown | |
414 This is simple code block. | |
415 ``` | |
416 | |
417 Tables | |
418 ------ | |
419 | |
420 Tables are supported and formatted as following: | |
421 | |
422 ```markdown | |
423 | header 1 | header 2 | | |
424 |----------|----------| | |
425 | item 1 | item 2 | | |
426 ``` | |
427 | |
428 Alerts | |
429 ------ | |
430 | |
431 It's possible to prefix a paragraph by one of the following topic, it renders a | |
432 different block depending on the output format: | |
433 | |
434 - Note: | |
435 - Warning: | |
436 - Danger: | |
437 | |
438 Then, if the paragraph is too long, indent the text correctly. | |
439 | |
440 ```markdown | |
441 Note: this is an information block that is too long to fit between the limits so | |
442 it is split and indented. | |
443 ``` |