-
Notifications
You must be signed in to change notification settings - Fork 2
/
STYLE
131 lines (107 loc) · 4.46 KB
/
STYLE
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
Code style
==========
In general, FreeBSD style(9) should be followed unless it is irrelevant
(e.g., $FreeBSD$ tags).
Functions with external linkage are declared like this:
/**
* module_func(arg1, arg2):
* Description of what the function does, referring to arguments as
* ${arg1} or suchlike.
*/
int module_func(void *, int);
The identical comment appears in the C file where the function is defined.
Static functions may have the the above form of comment, or simply a
/* Brief description of what the function does. */
line before the function.
In general, functions should return (int)(-1) or NULL to indicate error.
Errors should be printed via warnp (if errno is relevant) or warn0 (if errno
is not relevant) when they are first detected and also at higher levels where
useful. As an exception to this, malloc failures (i.e., errno = ENOMEM) can
result in failure being passed back up the call chain without being printed
immediately. (Naturally, other errors can be passed back where a function
definition so specifies; e.g., ENOENT in cases where a file not existing is
not erronous.)
The first statement in main(), after variable declarations, should be
"WARNP_INIT;" in order to set the program name used for printing warnings.
In general, functions should be structured with one return statement per
status, e.g., one return() for success and one return() for failure. Errors
should be handled by using goto to enter the error return path, e.g.,
int
foo(int bar)
{
if (something fails)
goto err0;
/* ... */
if (something else fails)
goto err1;
/* ... */
if (yet another operation fails)
goto err2;
/* Success! */
return (0);
err2:
/* Clean up something. */
err1:
/* Clean up something else. */
err0:
/* Failure! */
return (-1);
}
As an exception to the above, if there is only one way for the function to
fail, the idioms
return (baz(bar));
and
int rc;
rc = baz(bar);
/* ... cleanup code here ... */
return (rc);
are allowed; furthermore, in cases such as foo_free(), the idiom
if (we shouldn't do anything)
return;
is preferred over
if (we shouldn't do anything)
goto done;
at the start of a function.
Headers should be included in the following groups, with a blank line after
each (non-empty) group:
1. <sys/*.h>, with <sys/types.h> first followed by others alphabetically.
2. <net/*.h>, in alphabetical order.
3. <*.h>, in alphabetical order.
4. header files from /lib/, in alphabetical order.
5. header files from the program being built, in alphabetical order.
6. header files (usually just one) defining the interface for this C file.
If size_t is needed, <stddef.h> should be included to provide it unless
<stdio.h>, <stdlib.h>, <string.h>, or <unistd.h> is already required.
If the C99 integer types (uint8_t, int64_t, etc.) are required, <stdint.h>
should be included to provide them unless <inttypes.h> is already required.
When a struct is referenced, the idiom
/* Opaque types. */
struct foo;
struct bar * bar_from_foo(struct foo *);
is preferable to
#include "foo.h" /* needed for struct foo */
struct bar * bar_from_foo(struct foo *);
unless there is some reason why the internal layout of struct foo is needed
(e.g., if struct bar contains a struct foo rather than a struct foo *). Such
struct declarations should be sorted alphabetically.
The file foo.c should only export symbols of the following forms:
foo_* -- most symbols should be of this form.
FOO_* / BAR_FOO_*
-- allowed in cases where FOO or BAR_FOO is idiomatic (e.g.,
MD5, HMAC_SHA256).
foo() / defoo() / unfoo()
-- where "foo" is a verb and this improves code clarity.
Functions named foo_free should return void, and foo_free(NULL) should have
no effect.
If static variables need to be initialized to 0 (or NULL) then they should be
explicitly declared that way; implicit initialization should not be used.
In non-trivial code, comments should be included which describe in English
what is being done by the surrounding code with sufficient detail that if the
code were removed, it could be replaced based on reading the comments without
requiring any significant creativity.
Comments and documentation should be written in en-GB-oed; i.e., with
the 'u' included in words such as "honour", "colour", and "neighbour",
and the ending '-ize' in words such as "organize" and "realize". The
Oxford (aka. serial) comma should be used in lists. Quotation marks
should be placed logically, i.e., not including punctuation marks which
do not form a logical part of the quoted text.