xref: /freebsd/share/man/man9/style.9 (revision ce834215a70ff69e7e222827437116eee2f9ac6f)
1.\" Copyright (c) 1995 FreeBSD Inc.
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL [your name] OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\"	$Id: style.9,v 1.17 1997/04/09 19:03:14 mpp Exp $
26.\"
27.Dd December 14, 1995
28.Dt STYLE 9
29.Os FreeBSD
30.Sh NAME
31.Nm style
32.Nd "Kernel source file style guide"
33.Sh DESCRIPTION
34This file specifies the preferred style for kernel source files in the
35.Tn FreeBSD
36source tree.  It is also a guide for preferred user land code style.
37.Bd -literal -offset 0i
38/*
39 * Style guide for the FreeBSD KNF (Kernel Normal Form).
40 */
41
42/*
43 * VERY important single-line comments look like this.
44 */
45
46/* Most single-line comments look like this. */
47
48/*
49 * Multi-line comments look like this.  Make them real sentences.  Fill
50 * them so they look like real paragraphs.
51 */
52.Ed
53.Pp
54Kernel include files come first; normally, you'll need <sys/types.h>
55OR <sys/param.h>, but not both!  <sys/types.h> includes <sys/cdefs.h>,
56and it's okay to depend on that.
57.Bd -literal -offset 0i
58#include <sys/types.h>		/* Non-local includes in brackets. */
59.Ed
60.Pp
61If it's a network program, put the network include files next.
62.Bd -literal -offset 0i
63#include <net/if.h>
64#include <net/if_dl.h>
65#include <net/route.h>
66#include <netinet/in.h>
67#include <protocols/rwhod.h>
68.Ed
69.Pp
70Then there's a blank line, followed by the /usr include files.
71The /usr include files should be sorted!
72.Bd -literal -offset 0i
73#include <stdio.h>
74.Ed
75.Pp
76Global pathnames are defined in /usr/include/paths.h.  Pathnames local
77to the program go in pathnames.h in the local directory.
78.Bd -literal -offset 0i
79#include <paths.h>
80.Ed
81.Pp
82Then, there's a blank line, and the user include files.
83.Bd -literal -offset 0i
84#include "pathnames.h"		/* Local includes in double quotes. */
85.Ed
86.Pp
87Macros are capitalized, parenthesized, and should avoid side-effects.
88If they are an inline expansion of a function, the function is defined
89all in lowercase, the macro has the same name all in uppercase. If the
90macro needs more than a single line, use braces.  Right-justify the
91backslashes, it makes it easier to read.
92.Bd -literal -offset 0i
93#define	MACRO(x, y) {							\e
94	variable = (x) + (y);						\e
95	(y) += 2;							\e
96}
97.Ed
98.Pp
99Enum types are capitalized.
100.Bd -literal -offset 0i
101enum enumtype { ONE, TWO } et;
102.Ed
103.Pp
104When declaring variables in structures, declare them sorted by use, then
105by size, and then by alphabetical order.  The first category normally
106doesn't apply, but there are exceptions.  Each one gets its own line.
107Put a tab after the first word, i.e. use
108.Ql int^Ix;
109and
110.Ql struct^Ifoo *x; .
111.Pp
112Major structures should be declared at the top of the file in which they
113are used, or in separate header files, if they are used in multiple
114source files.  Use of the structures should be by separate declarations
115and should be "extern" if they are declared in a header file.
116.Bd -literal -offset 0i
117struct foo {
118	struct	foo *next;	/* List of active foo */
119	struct	mumble amumble;	/* Comment for mumble */
120	int	bar;
121};
122struct foo *foohead;		/* Head of global foo list */
123
124/* Make the structure name match the typedef. */
125typedef struct _bar {
126	int	level;
127} BAR;
128.Ed
129.Pp
130All functions are prototyped somewhere.
131.Pp
132Function prototypes for private functions (i.e. functions not used
133elsewhere) go at the top of the first source module.  Functions
134local to one source module should be declared
135.Ql static .
136.Pp
137Functions used from other parts of the kernel are prototyped in the
138relevant include file.
139.Pp
140Functions that are used locally in more than one module go into a
141separate header file, e.g.
142.Pa extern.h .
143.Pp
144Only use the __P macro from the include file <sys/cdefs.h> if the source
145file in general is (to be) compilable with a K&R Old testament compiler.
146Use of the __P macro in new code is discouraged, although modifications
147to existing files should be consistent with that file's conventions.
148.Pp
149In general code can be considered
150.Dq new code
151when it makes up about 50% or more of the file[s] involved.  This is enough
152to break precedents in the existing code and use the current style guidelines.
153.Pp
154The kernel has a name associated with parameter types, e.g., in the kernel
155use:
156.Bd -literal -offset 0i
157void	function(int fd);
158.Ed
159.Pp
160In header files visible to user land applications, prototypes that are
161visible must use either protected names or no names with the types.  It
162is preferable to use protected names.
163e.g., use:
164.Bd -literal -offset 0i
165void	function(int);
166.Ed
167.Pp
168or:
169.Bd -literal -offset 0i
170void	function(int _fd);
171.Ed
172.Pp
173Prototypes may have an extra space after a tab to enable function names
174to line up:
175.Bd -literal -offset 0i
176static char	*function(int _arg, const char *_arg2, struct foo *_arg3,
177			  struct bar *_arg4);
178static void	 usage(void);
179
180/*
181 * All major routines should have a comment briefly describing what
182 * they do.  The comment before the "main" routine should describe
183 * what the program does.
184 */
185int
186main(int argc, char *argv[])
187{
188	long num;
189	int ch;
190	char *ep;
191
192.Ed
193.Pp
194For consistency, getopt should be used to parse options.  Options
195should be sorted in the getopt call and the switch statement, unless
196parts of the switch cascade.  Elements in a switch statement that
197cascade should have a FALLTHROUGH comment.  Numerical arguments
198should be checked for accuracy.  Code that cannot be reached should
199have a NOTREACHED comment.
200.Bd -literal -offset 0i
201	while ((ch = getopt(argc, argv, "abn")) != -1)
202		switch (ch) {		/* Indent the switch. */
203		case 'a':		/* Don't indent the case. */
204			aflag = 1;
205			/* FALLTHROUGH */
206		case 'b':
207			bflag = 1;
208			break;
209		case 'n':
210			num = strtol(optarg, &ep, 10);
211			if (num <= 0 || *ep != '\e0')
212				err("illegal number -- %s", optarg);
213			break;
214		case '?':
215		default:
216			usage();
217			/* NOTREACHED */
218		}
219	argc -= optind;
220	argv += optind;
221
222.Ed
223.Pp
224Space after keywords (if, while, for, return, switch).  No braces are
225used for control statements with zero or only a single statement.
226Forever loops are done with for's, not while's.
227.Bd -literal -offset 0i
228	for (p = buf; *p != '\e0'; ++p)
229		;	/* nothing */
230	for (;;)
231		stmt;
232	if (val != NULL)
233		val = realloc(val, newsize);
234.Ed
235.Pp
236Parts of a for loop may be left empty.  Don't put declarations
237inside blocks unless the routine is unusually complicated.
238.Bd -literal -offset 0i
239	for (; cnt < 15; cnt++) {
240		stmt1;
241		stmt2;
242	}
243.Ed
244.Pp
245Indentation is an 8 character tab.
246Second level indents are four spaces.
247.Bd -literal -offset 0i
248	while (cnt < 20)
249		z = a + really + long + statement + that + needs +
250		    two lines + gets + indented + four + spaces +
251		    on + the + second + and + subsequent + lines.
252.Ed
253.Pp
254Do not add whitespace at the end of a line, and only use tabs then spaces
255to form the indentation.  Do not use more spaces than a tab will produce
256and do not use spaces in front of tabs.
257.Pp
258Closing and opening braces go on the same line as the else.
259Don't add braces that aren't necessary.
260.Bd -literal -offset 0i
261	if (test)
262		stmt;
263	else if (bar) {
264		stmt;
265		stmt;
266	} else
267		stmt;
268.Ed
269.Pp
270No spaces after function names.  Commas have a space after them.  No spaces
271after
272.Sq \&(
273or
274.Sq \&[
275or preceding
276.Sq \&]
277or
278.Sq \&)
279characters.
280.Bd -literal -offset 0i
281	if (error = function(a1, a2))
282		exit(error);
283.Ed
284.Pp
285Unary operators don't require spaces, binary operators do. Don't
286use parenthesis unless they're required for precedence, or the
287statement is really confusing without them.
288.Bd -literal -offset 0i
289	a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1;
290	k = !(l & FLAGS);
291.Ed
292.Pp
293Exits should be 0 on success, or according to the predefined
294values in
295.Xr sysexits 3 .
296.Bd -literal -offset 0i
297	exit(EX_OK);	/*
298			 * Avoid obvious comments such as
299			 * "Exit 0 on success."
300			 */
301}
302.Ed
303.Pp
304The function type should be on a line by itself
305preceding the function.
306.Bd -literal -offset 0i
307static char *
308function(int a1, int a2, float fl, int a4)
309{
310.Ed
311.Pp
312When declaring variables in functions declare them sorted by size,
313then in alphabetical order; multiple ones per line are okay.
314Declaring functions inside functions is not recommendable, since their
315linkage scope is always global.  If a line overflows reuse the type
316keyword.
317.Pp
318Be careful to not obfuscate the code by initializing variables in
319the declarations.  Use this feature only thoughtfully.
320DO NOT use function calls in initializers!
321.Bd -literal -offset 0i
322	struct foo one, *two;
323	double three;
324	int *four, five;
325	char *six, seven, eight, nine, ten, eleven, twelve;
326
327	four = myfunction();
328.Ed
329.Pp
330Do not declare functions inside other functions; ANSI C says that
331such declarations have file scope regardless of the nesting of the
332declaration.  Hiding file declarations in what appears to be a local
333scope is undesirable and will elicit complaints from a good compiler.
334.Pp
335Casts and sizeof's are not followed by a space.  Note that
336.Xr indent 1
337does not understand this rule.
338.Pp
339NULL is the preferred null pointer constant.  Use NULL instead of
340(type *)0 or (type *)NULL in contexts where the compiler knows the
341type, e.g., in assignments.  Use (type *)NULL in other contexts,
342in particular for all function args.  (Casting is essential for
343varadic args and is necessary for other args if the function prototype
344might not be in scope.)
345Test pointers
346against NULL, e.g., use:
347.Bd -literal -offset 0i
348(p = f()) == NULL
349.Ed
350.Pp
351not:
352.Bd -literal -offset 0i
353!(p = f())
354.Ed
355.Pp
356Don't use '!' for tests unless it's a boolean, e.g. use
357.Bd -literal -offset 0i
358if (*p == '\e0')
359.Ed
360.Pp
361not
362.Bd -literal -offset 0i
363if (!*p)
364.Ed
365.Pp
366Routines returning void * should not have their return values cast
367to any pointer type.
368.Pp
369Use
370.Xr err 3
371or
372.Xr warn 3 ,
373don't roll your own!
374.Bd -literal -offset 0i
375	if ((four = malloc(sizeof(struct foo))) == NULL)
376		err(1, (char *)NULL);
377	if ((six = (int *)overflow()) == NULL)
378		errx(1, "Number overflowed.");
379	return (eight);
380}
381.Ed
382.Pp
383Old-style function declarations look like this:
384.Bd -literal -offset 0i
385static char *
386function(a1, a2, fl, a4)
387	int a1, a2;	/* Declare ints, too, don't default them. */
388	float fl;	/* Beware double vs. float prototype differences. */
389	int a4;		/* List in order declared. */
390{
391.Ed
392.Pp
393Use ANSI function declarations unless you explicitly need K&R compatability.
394.Pp
395Variable numbers of arguments should look like this.
396.Bd -literal -offset 0i
397#include <stdarg.h>
398
399void
400vaf(const char *fmt, ...)
401{
402	va_list ap;
403
404	va_start(ap, fmt);
405	STUFF;
406	va_end(ap);
407	/* No return needed for void functions. */
408}
409
410static void
411usage()
412{
413	/* Insert an empty line if the function has no local variables. */
414.Ed
415.Pp
416Use
417.Xr printf 3 ,
418not fputs/puts/putchar/whatever, it's faster and usually cleaner, not
419to mention avoiding stupid bugs.
420.Pp
421Usage statements should look like the manual pages.  Options w/o
422operands come first, in alphabetical order inside a single set of
423braces.  Followed by options with operands, in alphabetical order,
424each in braces.  Followed by required arguments in the order they
425are specified, followed by optional arguments in the order they
426are specified.  A bar
427.Pq Sq \&|
428separates either/or options/arguments,
429and multiple options/arguments which are specified together are
430placed in a single set of braces.
431.Pp
432.Bd -ragged -offset 0.3i
433"usage: f [-ade] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\en"
434"usage: f [-a | -b] [-c [-de] [-n number]]\en"
435.Ed
436.Bd -literal -offset 0i
437	(void)fprintf(stderr, "usage: f [-ab]\en");
438	exit(1);
439}
440.Ed
441.Pp
442New core kernel code should be reasonably compliant with the style guides.
443The guidelines for third-party maintained modules and device drivers are more
444relaxed but at a minimum should be internally consistant with their style.
445.Pp
446Stylistic changes (including whitespace changes) are hard on the source
447repository and are to be avoided without good reason.  Code that is
448approximately KNF compliant in the repository must not diverge from
449compliance.
450.Sh SEE ALSO
451.Xr indent 1 ,
452.Xr err 3 ,
453.Xr sysexits 3 ,
454.Xr warn 3
455.Sh HISTORY
456This man page is largely based on the src/admin/style/style file from
457the
458.Tn BSD
4594.4-Lite2 release, with updates to reflect the current practice and
460desire of the
461.Tn FreeBSD
462project.
463