blob: 1922fa9c4792598b6e8f12e86f9290e63aed0ce2 [file] [log] [blame]
Radek Krejci71f20292015-06-11 11:55:55 +02001# libyang Coding Style
2
3This file describes the coding style used in most C files in the libyang
Radek Krejcifb111892015-06-16 10:33:52 +02004library.
Radek Krejci71f20292015-06-11 11:55:55 +02005
6## Basics
7
8- Use space instead of tabs for indentations.
9
10- There is no strict limit for the line length, However, try to keep lines in a
Radek Krejcifb111892015-06-16 10:33:52 +020011reasonable length (120 characters).
Radek Krejci71f20292015-06-11 11:55:55 +020012
13- Avoid trailing spaces on lines.
14
15- Put one blank line between function definitions.
16
17- Don't mix declarations and code within a block. Similarly, don't use
18 declarations in iteration statements.
19
20## Naming
21
22Use underscores to separate words in an identifier: `multi_word_name`.
23
24Use lowercase for most names. Use uppercase for macros, macro parameters and
25members of enumerations.
26
27Do not use names that begin with `_`. If you need a name for "internal use
28only", use `__` as a suffix instead of a prefix.
29
30## Comments
31
32Avoid `//` comments. Use `/* ... */` comments, write block comments with the
33leading asterisk on each line. You may put the `/*` and `*/` on the same line as
34comment text if you prefer.
35
36```c
37/*
38 * comment text
39 */
40```
41
42## Functions
43
44Put the return type, function name, and the braces that surround the function's
45code on separate lines, all starting in column 0.
46
47```c
48static int
49foo(int arg)
50{
51 ...
52}
53```
54
55When you need to put the function parameters on multiple lines, start new line
56at column after the opening parenthesis from the initial line.
57
58```c
59static int
60my_function(struct my_struct *p1, struct another_struct *p2,
61 int size)
62{
63 ...
64}
65```
66
67In the absence of good reasons for another order, the following parameter order
68is preferred. One notable exception is that data parameters and their
69corresponding size parameters should be paired.
70
711. The primary object being manipulated, if any (equivalent to the "this"
72 pointer in C++).
732. Input-only parameters.
743. Input/output parameters.
754. Output-only parameters.
765. Status parameter.
77
78Functions that destroy an instance of a dynamically-allocated type should accept
79and ignore a null pointer argument. Code that calls such a function (including
80the C standard library function `free()`) should omit a null-pointer check. We
81find that this usually makes code easier to read.
82
83### Function Prototypes
84
85Put the return type and function name on the same line in a function prototype:
86
87```c
88static const struct int foo(int arg);
89```
90
91## Statements
92
93- Indent each level of code with 4 spaces.
94- Put single space between `if`, `while`, `for`, etc. statements and the
95 expression that follow them. On the other hand, function calls has no space
96 between the function name and opening parenthesis.
97- Opening code block brace is kept at the same line with the `if`, `while`,
98 `for` or `switch` statements.
99
100```c
101if (a) {
102 x = exp(a);
103} else {
104 return 1;
105}
106```
107
108- Start switch's cases at the same column as the switch.
109
110```c
111switch (conn->state) {
112case 0:
113 return "data found";
114case 1:
115 return "data not found";
116default:
117 return "unknown error";
118}
119```
120
121- Do not put gratuitous parentheses around the expression in a return statement,
122that is, write `return 0;` and not `return(0);`
123
124## Types
125
126Use typedefs sparingly. Code is clearer if the actual type is visible at the
127point of declaration. Do not, in general, declare a typedef for a struct, union,
128or enum. Do not declare a typedef for a pointer type, because this can be very
129confusing to the reader.
130
131Use the `int<N>_t` and `uint<N>_t` types from `<stdint.h>` for exact-width
132integer types. Use the `PRId<N>`, `PRIu<N>`, and `PRIx<N>` macros from
133`<inttypes.h>` for formatting them with `printf()` and related functions.
134
135Pointer declarators bind to the variable name, not the type name. Write
136`int *x`, not `int* x` and definitely not `int * x`.
137
138## Expresions
139
140Put one space on each side of infix binary and ternary operators:
141
142```c
143* / % + - << >> < <= > >= == != & ^ | && || ?: = += -= *= /= %= &= ^= |= <<= >>=
144```
145
146Do not put any white space around postfix, prefix, or grouping operators with
147one exception - `sizeof`, see the note below.
148
149```c
150() [] -> . ! ~ ++ -- + - * &
151```
152
153The "sizeof" operator is unique among C operators in that it accepts two very
154different kinds of operands: an expression or a type. In general, prefer to
155specify an expression
156```c
157int *x = calloc(1, sizeof *x);
158```
159When the operand of sizeof is an expression, there is no need to parenthesize
160that operand, and please don't. There is an exception to this rule when you need
161to work with partially compatible structures:
162
163```c
164struct a_s {
165 uint8_t type;
166}
167
168struct b_s {
169 uint8_t type;
170 char *str;
171}
172
173struct c_s {
174 uint8_t type;
175 uint8_t *u8;
176}
177...
178struct a_s *a;
179
180switch (type) {
181case 1:
182 a = (struct a_s *)calloc(1, sizeof(struct b_s));
183 break;
184case 2:
185 a = (struct a_s *)calloc(1, sizeof(struct c_s));
186 break;
187 ...
188```