eedd038914
documented by example. Since most of this file is documented by example, it is confusing. Make things a little less confusing.
606 lines
17 KiB
Groff
606 lines
17 KiB
Groff
.\" Copyright (c) 1995 FreeBSD Inc.
|
|
.\" All rights reserved.
|
|
.\"
|
|
.\" Redistribution and use in source and binary forms, with or without
|
|
.\" modification, are permitted provided that the following conditions
|
|
.\" are met:
|
|
.\" 1. Redistributions of source code must retain the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer.
|
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
|
.\" notice, this list of conditions and the following disclaimer in the
|
|
.\" documentation and/or other materials provided with the distribution.
|
|
.\"
|
|
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
|
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
.\" ARE DISCLAIMED. IN NO EVENT SHALL [your name] OR CONTRIBUTORS BE LIABLE
|
|
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|
.\" SUCH DAMAGE.
|
|
.\"
|
|
.\"
|
|
.Dd December 14, 1995
|
|
.Dt STYLE 9
|
|
.Os
|
|
.Sh NAME
|
|
.Nm style
|
|
.Nd "kernel source file style guide"
|
|
.Sh DESCRIPTION
|
|
This file specifies the preferred style for kernel source files in the
|
|
.Fx
|
|
source tree. It is also a guide for preferred userland code style.
|
|
.Bd -literal
|
|
/*
|
|
* Style guide for FreeBSD. Based on the CSRG's KNF (Kernel Normal Form).
|
|
*
|
|
* @(#)style 1.14 (Berkeley) 4/28/95
|
|
* $FreeBSD$
|
|
*/
|
|
|
|
/*
|
|
* VERY important single-line comments look like this.
|
|
*/
|
|
|
|
/* Most single-line comments look like this. */
|
|
|
|
/*
|
|
* Multi-line comments look like this. Make them real sentences. Fill
|
|
* them so they look like real paragraphs.
|
|
*/
|
|
.Ed
|
|
.Pp
|
|
After any copyright header, there is a blank line, and the
|
|
.Va rcsid
|
|
for source files.
|
|
Version control system ID tags should only exist once in a file
|
|
(unlike this one).
|
|
Non-C/C++ source files follow the example above, while C/C++ source files
|
|
follow the one below.
|
|
All VCS (version control system) revision identification from files obtained
|
|
from elsewhere should be maintained, including, where applicable, multiple IDs
|
|
showing a file's history.
|
|
In general, keep the IDs intact, including any `$'s.
|
|
There is no reason to add "From" in front of foreign VCS IDs.
|
|
Most
|
|
.No non- Ns Fx
|
|
VCS IDs should be indented by a tab if in a comment.
|
|
.Bd -literal
|
|
#include <sys/cdefs.h>
|
|
__RCSID("@(#)style 1.14 (Berkeley) 4/28/95");
|
|
__FBSDID("$FreeBSD$");
|
|
.Ed
|
|
.Pp
|
|
Leave another blank line before the header files.
|
|
.Pp
|
|
Kernel include files (i.e. sys/*.h) come first; normally, include
|
|
<sys/types.h>
|
|
OR <sys/param.h>, but not both. <sys/types.h> includes <sys/cdefs.h>,
|
|
and it's okay to depend on that.
|
|
.Bd -literal
|
|
#include <sys/types.h> /* Non-local includes in angle brackets. */
|
|
.Ed
|
|
.Pp
|
|
For a network program, put the network include files next.
|
|
.Bd -literal
|
|
#include <net/if.h>
|
|
#include <net/if_dl.h>
|
|
#include <net/route.h>
|
|
#include <netinet/in.h>
|
|
#include <protocols/rwhod.h>
|
|
.Ed
|
|
.Pp
|
|
Leave a blank line before the next group, the /usr include files,
|
|
which should be sorted alphabetically by name.
|
|
.Bd -literal
|
|
#include <stdio.h>
|
|
.Ed
|
|
.Pp
|
|
Global pathnames are defined in /usr/include/paths.h. Pathnames local
|
|
to the program go in pathnames.h in the local directory.
|
|
.Bd -literal
|
|
#include <paths.h>
|
|
.Ed
|
|
.Pp
|
|
Leave another blank line before the user include files.
|
|
.Bd -literal
|
|
#include "pathnames.h" /* Local includes in double quotes. */
|
|
.Ed
|
|
.Pp
|
|
Do not #define or declare names in the implementation namespace except
|
|
for implementing application interfaces.
|
|
.Pp
|
|
The names of
|
|
.Dq unsafe
|
|
macros (ones that have side effects), and the names of macros for
|
|
manifest constants, are all in uppercase.
|
|
The expansions of expression-like macros are either a single token
|
|
or have outer parentheses.
|
|
Put a single tab character between the
|
|
.Ql #define
|
|
and the macro name.
|
|
If a macro is an inline expansion of a function, the function name is
|
|
all in lowercase and the macro has the same name all in uppercase.
|
|
.\" XXX the above conflicts with ANSI style where the names are the
|
|
.\" same and you #undef the macro (if any) to get the function.
|
|
.\" It is not followed for MALLOC(), and not very common if inline
|
|
.\" functions are used.
|
|
If a
|
|
macro needs more than a single line, use braces
|
|
.Sq ( \&{
|
|
and
|
|
.Sq \&} ) .
|
|
Right-justify the
|
|
backslashes; it makes it easier to read.
|
|
If the macro encapsulates a compound statement, enclose it in a
|
|
.Dq Li do
|
|
loop,
|
|
so that it can safely be used in
|
|
.Dq Li if
|
|
statements.
|
|
Any final statement-terminating semicolon should be
|
|
supplied by the macro invocation rather than the macro, to make parsing easier
|
|
for pretty-printers and editors.
|
|
.Bd -literal
|
|
#define MACRO(x, y) do { \e
|
|
variable = (x) + (y); \e
|
|
(y) += 2; \e
|
|
} while(0)
|
|
.Ed
|
|
.Pp
|
|
Enumeration values are all uppercase.
|
|
.Bd -literal
|
|
enum enumtype { ONE, TWO } et;
|
|
.Ed
|
|
.Pp
|
|
When declaring variables in structures, declare them sorted by use, then
|
|
by size, and then by alphabetical order. The first category normally
|
|
doesn't apply, but there are exceptions. Each one gets its own line.
|
|
Try to make the structure
|
|
readable by aligning the member names using either one or two tabs
|
|
depending upon your judgment.
|
|
You should use one tab if it suffices to align most of the member names.
|
|
Names following extremely long types
|
|
should be separated by a single space.
|
|
.Pp
|
|
Major structures should be declared at the top of the file in which they
|
|
are used, or in separate header files if they are used in multiple
|
|
source files. Use of the structures should be by separate declarations
|
|
and should be "extern" if they are declared in a header file.
|
|
.Bd -literal
|
|
struct foo {
|
|
struct foo *next; /* List of active foo. */
|
|
struct mumble amumble; /* Comment for mumble. */
|
|
int bar; /* Try to align the comments. */
|
|
struct verylongtypename *baz; /* Won't fit in 2 tabs. */
|
|
};
|
|
struct foo *foohead; /* Head of global foo list. */
|
|
.Ed
|
|
.Pp
|
|
Use
|
|
.Xr queue 3
|
|
macros rather than rolling your own lists, whenever possible. Thus,
|
|
the previous example would be better written:
|
|
.Bd -literal
|
|
#include <sys/queue.h>
|
|
struct foo {
|
|
LIST_ENTRY(foo) link; /* Use queue macros for foo lists. */
|
|
struct mumble amumble; /* Comment for mumble. */
|
|
int bar; /* Try to align the comments. */
|
|
struct verylongtypename *baz; /* Won't fit in 2 tabs. */
|
|
};
|
|
LIST_HEAD(, foo) foohead; /* Head of global foo list. */
|
|
.Ed
|
|
.Pp
|
|
Avoid using typedefs for structure types. This makes it impossible
|
|
for applications to use pointers to such a structure opaquely, which
|
|
is both possible and beneficial when using an ordinary struct tag.
|
|
When convention requires a typedef, make its name match the struct
|
|
tag. Avoid typedefs ending in
|
|
.Dq Li \&_t ,
|
|
except as specified in Standard C or by
|
|
.Tn POSIX .
|
|
.Bd -literal
|
|
/* Make the structure name match the typedef. */
|
|
typedef struct bar {
|
|
int level;
|
|
} BAR;
|
|
.Ed
|
|
.Pp
|
|
All functions are prototyped somewhere.
|
|
.Pp
|
|
Function prototypes for private functions (i.e. functions not used
|
|
elsewhere) go at the top of the first source module. Functions
|
|
local to one source module should be declared
|
|
.Ql static .
|
|
.Pp
|
|
Functions used from other parts of the kernel are prototyped in the
|
|
relevant include file.
|
|
.Pp
|
|
Functions that are used locally in more than one module go into a
|
|
separate header file, e.g.\&
|
|
.Pa extern.h .
|
|
.Pp
|
|
Only use the __P macro from the include file <sys/cdefs.h> if the source
|
|
file in general is (to be) compilable with a K&R Old Testament compiler.
|
|
Use of the __P macro in new code is discouraged, although modifications
|
|
to existing files should be consistent with that file's conventions.
|
|
.Pp
|
|
In general code can be considered
|
|
.Dq new code
|
|
when it makes up about 50% or more of the file[s] involved. This is enough
|
|
to break precedents in the existing code and use the current style guidelines.
|
|
.Pp
|
|
The kernel has a name associated with parameter types, e.g., in the kernel
|
|
use:
|
|
.Bd -literal
|
|
void function(int fd);
|
|
.Ed
|
|
.Pp
|
|
In header files visible to userland applications, prototypes that are
|
|
visible must use either
|
|
.Dq protected
|
|
names (ones beginning with an underscore) or no names with the types.
|
|
It is preferable to use protected names.
|
|
E.g., use:
|
|
.Bd -literal
|
|
void function(int);
|
|
.Ed
|
|
.Pp
|
|
or:
|
|
.Bd -literal
|
|
void function(int _fd);
|
|
.Ed
|
|
.Pp
|
|
Prototypes may have an extra space after a tab to enable function names
|
|
to line up:
|
|
.Bd -literal
|
|
static char *function(int _arg, const char *_arg2, struct foo *_arg3,
|
|
struct bar *_arg4);
|
|
static void usage(void);
|
|
|
|
/*
|
|
* All major routines should have a comment briefly describing what
|
|
* they do. The comment before the "main" routine should describe
|
|
* what the program does.
|
|
*/
|
|
int
|
|
main(int argc, char *argv[])
|
|
{
|
|
long num;
|
|
int ch;
|
|
char *ep;
|
|
|
|
.Ed
|
|
.Pp
|
|
For consistency, getopt should be used to parse options. Options
|
|
should be sorted in the getopt call and the switch statement, unless
|
|
parts of the switch cascade. Elements in a switch statement that
|
|
cascade should have a FALLTHROUGH comment. Numerical arguments
|
|
should be checked for accuracy. Code that cannot be reached should
|
|
have a NOTREACHED comment.
|
|
.Bd -literal
|
|
while ((ch = getopt(argc, argv, "abn:")) != -1)
|
|
switch (ch) { /* Indent the switch. */
|
|
case 'a': /* Don't indent the case. */
|
|
aflag = 1;
|
|
/* FALLTHROUGH */
|
|
case 'b':
|
|
bflag = 1;
|
|
break;
|
|
case 'n':
|
|
num = strtol(optarg, &ep, 10);
|
|
if (num <= 0 || *ep != '\e0') {
|
|
warnx("illegal number, -n argument -- %s",
|
|
optarg);
|
|
usage();
|
|
}
|
|
break;
|
|
case '?':
|
|
default:
|
|
usage();
|
|
/* NOTREACHED */
|
|
}
|
|
argc -= optind;
|
|
argv += optind;
|
|
|
|
.Ed
|
|
.Pp
|
|
Space after keywords (if, while, for, return, switch). No braces are
|
|
used for control statements with zero or only a single statement unless that
|
|
statement is more than a single line in which case they are permitted.
|
|
Forever loops are done with for's, not while's.
|
|
.Bd -literal
|
|
for (p = buf; *p != '\e0'; ++p)
|
|
; /* nothing */
|
|
for (;;)
|
|
stmt;
|
|
for (;;) {
|
|
z = a + really + long + statement + that + needs +
|
|
two lines + gets + indented + four + spaces +
|
|
on + the + second + and + subsequent + lines;
|
|
}
|
|
for (;;) {
|
|
if (cond)
|
|
stmt;
|
|
}
|
|
if (val != NULL)
|
|
val = realloc(val, newsize);
|
|
.Ed
|
|
.Pp
|
|
Parts of a for loop may be left empty. Don't put declarations
|
|
inside blocks unless the routine is unusually complicated.
|
|
.Bd -literal
|
|
for (; cnt < 15; cnt++) {
|
|
stmt1;
|
|
stmt2;
|
|
}
|
|
.Ed
|
|
.Pp
|
|
Indentation is an 8 character tab.
|
|
Second level indents are four spaces.
|
|
If you have to wrap a long statement, put the operator at the end of the
|
|
line.
|
|
.Bd -literal
|
|
while (cnt < 20 && this_variable_name_is_too_long_for_its_own_good &&
|
|
ep != NULL)
|
|
z = a + really + long + statement + that + needs +
|
|
two lines + gets + indented + four + spaces +
|
|
on + the + second + and + subsequent + lines;
|
|
.Ed
|
|
.Pp
|
|
Do not add whitespace at the end of a line, and only use tabs
|
|
followed by spaces
|
|
to form the indentation. Do not use more spaces than a tab will produce
|
|
and do not use spaces in front of tabs.
|
|
.Pp
|
|
Closing and opening braces go on the same line as the else.
|
|
Braces that aren't necessary may be left out.
|
|
.Bd -literal
|
|
if (test)
|
|
stmt;
|
|
else if (bar) {
|
|
stmt;
|
|
stmt;
|
|
} else
|
|
stmt;
|
|
.Ed
|
|
.Pp
|
|
No spaces after function names. Commas have a space after them. No spaces
|
|
after
|
|
.Sq \&(
|
|
or
|
|
.Sq \&[
|
|
or preceding
|
|
.Sq \&]
|
|
or
|
|
.Sq \&)
|
|
characters.
|
|
.Bd -literal
|
|
error = function(a1, a2);
|
|
if (error != 0)
|
|
exit(error);
|
|
.Ed
|
|
.Pp
|
|
Unary operators don't require spaces, binary operators do. Don't
|
|
use parentheses unless they're required for precedence or unless the
|
|
statement is confusing without them. Remember that other people may
|
|
confuse easier than you. Do YOU understand the following?
|
|
.Bd -literal
|
|
a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1;
|
|
k = !(l & FLAGS);
|
|
.Ed
|
|
.Pp
|
|
Exits should be 0 on success, or according to the predefined
|
|
values in
|
|
.Xr sysexits 3 .
|
|
.Bd -literal
|
|
exit(EX_OK); /*
|
|
* Avoid obvious comments such as
|
|
* "Exit 0 on success."
|
|
*/
|
|
}
|
|
.Ed
|
|
.Pp
|
|
The function type should be on a line by itself
|
|
preceding the function.
|
|
.Bd -literal
|
|
static char *
|
|
function(int a1, int a2, float fl, int a4)
|
|
{
|
|
.Ed
|
|
.Pp
|
|
When declaring variables in functions declare them sorted by size,
|
|
then in alphabetical order; multiple ones per line are okay.
|
|
If a line overflows reuse the type keyword.
|
|
.Pp
|
|
Be careful to not obfuscate the code by initializing variables in
|
|
the declarations. Use this feature only thoughtfully.
|
|
DO NOT use function calls in initializers.
|
|
.Bd -literal
|
|
struct foo one, *two;
|
|
double three;
|
|
int *four, five;
|
|
char *six, seven, eight, nine, ten, eleven, twelve;
|
|
|
|
four = myfunction();
|
|
.Ed
|
|
.Pp
|
|
Do not declare functions inside other functions; ANSI C says that
|
|
such declarations have file scope regardless of the nesting of the
|
|
declaration. Hiding file declarations in what appears to be a local
|
|
scope is undesirable and will elicit complaints from a good compiler.
|
|
.Pp
|
|
Casts and sizeof's are not followed by a space. Note that
|
|
.Xr indent 1
|
|
does not understand this rule.
|
|
.Pp
|
|
NULL is the preferred null pointer constant. Use NULL instead of
|
|
(type *)0 or (type *)NULL in contexts where the compiler knows the
|
|
type, e.g., in assignments. Use (type *)NULL in other contexts,
|
|
in particular for all function args. (Casting is essential for
|
|
variadic args and is necessary for other args if the function prototype
|
|
might not be in scope.)
|
|
Test pointers
|
|
against NULL, e.g., use:
|
|
.Bd -literal
|
|
(p = f()) == NULL
|
|
.Ed
|
|
.Pp
|
|
not:
|
|
.Bd -literal
|
|
!(p = f())
|
|
.Ed
|
|
.Pp
|
|
Don't use '!' for tests unless it's a boolean, e.g. use
|
|
.Bd -literal
|
|
if (*p == '\e0')
|
|
.Ed
|
|
.Pp
|
|
not
|
|
.Bd -literal
|
|
if (!*p)
|
|
.Ed
|
|
.Pp
|
|
Routines returning void * should not have their return values cast
|
|
to any pointer type.
|
|
.Pp
|
|
Values in return statements should be enclosed in parentheses.
|
|
.Pp
|
|
Use
|
|
.Xr err 3
|
|
or
|
|
.Xr warn 3 ,
|
|
don't roll your own.
|
|
.Bd -literal
|
|
if ((four = malloc(sizeof(struct foo))) == NULL)
|
|
err(1, (char *)NULL);
|
|
if ((six = (int *)overflow()) == NULL)
|
|
errx(1, "number overflowed");
|
|
return (eight);
|
|
}
|
|
.Ed
|
|
.Pp
|
|
Old-style function declarations look like this:
|
|
.Bd -literal
|
|
static char *
|
|
function(a1, a2, fl, a4)
|
|
int a1, a2; /* Declare ints, too, don't default them. */
|
|
float fl; /* Beware double vs. float prototype differences. */
|
|
int a4; /* List in order declared. */
|
|
{
|
|
.Ed
|
|
.Pp
|
|
Use ANSI function declarations unless you explicitly need K&R compatibility.
|
|
Long parameter lists are wrapped with a normal four space indent.
|
|
.Pp
|
|
Variable numbers of arguments should look like this.
|
|
.Bd -literal
|
|
#include <stdarg.h>
|
|
|
|
void
|
|
vaf(const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
|
|
va_start(ap, fmt);
|
|
STUFF;
|
|
va_end(ap);
|
|
/* No return needed for void functions. */
|
|
}
|
|
|
|
static void
|
|
usage()
|
|
{
|
|
/* Insert an empty line if the function has no local variables. */
|
|
.Ed
|
|
.Pp
|
|
Use
|
|
.Xr printf 3 ,
|
|
not fputs/puts/putchar/whatever; it's faster and usually cleaner, not
|
|
to mention avoiding stupid bugs.
|
|
.Pp
|
|
Usage statements should look like the manual pages synopsis.
|
|
The usage statement should be structured in the following order:
|
|
.Pp
|
|
.Bl -enum
|
|
.It
|
|
Options without operands come first,
|
|
in alphabetical order,
|
|
inside a single set of brackets
|
|
.Sq ( \&[
|
|
and
|
|
.Sq \&] ) .
|
|
.It
|
|
Options with operands come next,
|
|
also in alphabetical order,
|
|
with each option and its argument inside its own pair of brackets.
|
|
.It
|
|
Required arguments
|
|
(if any)
|
|
are next,
|
|
listed in the order they should be specified in the command line.
|
|
.It
|
|
Finally,
|
|
any optional arguments should be listed,
|
|
listed in the order they should be specified,
|
|
and all inside brackets.
|
|
.El
|
|
.Pp
|
|
A bar
|
|
.Pq Sq \&|
|
|
separates either-or options/arguments,
|
|
and multiple options/arguments which are specified together are
|
|
placed in a single set of brackets.
|
|
.Pp
|
|
.Bd -ragged -offset 4n
|
|
"usage: f [-aDde] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\en"
|
|
"usage: f [-a | -b] [-c [-dEe] [-n number]]\en"
|
|
.Ed
|
|
.Bd -literal
|
|
(void)fprintf(stderr, "usage: f [-ab]\en");
|
|
exit(EX_USAGE);
|
|
}
|
|
.Ed
|
|
.Pp
|
|
Note that the manual page options description should list the options in
|
|
pure alphabetical order.
|
|
That is, without regard to whether an option takes arguments or not.
|
|
The alphabetical ordering should take into account the case ordering
|
|
shown above.
|
|
.Pp
|
|
New core kernel code should be reasonably compliant with the style guides.
|
|
The guidelines for third-party maintained modules and device drivers are more
|
|
relaxed but at a minimum should be internally consistent with their style.
|
|
.Pp
|
|
Stylistic changes (including whitespace changes) are hard on the source
|
|
repository and are to be avoided without good reason. Code that is
|
|
approximately
|
|
.Fx
|
|
KNF
|
|
.Xr style 9
|
|
compliant in the repository must not diverge from compliance.
|
|
.Pp
|
|
Whenever possible, code should be run through a code checker
|
|
(e.g.,
|
|
.Xr lint 1
|
|
or
|
|
"gcc -Wall") and produce minimal warnings.
|
|
.Sh SEE ALSO
|
|
.Xr indent 1 ,
|
|
.Xr lint 1 ,
|
|
.Xr err 3 ,
|
|
.Xr sysexits 3 ,
|
|
.Xr warn 3
|
|
.Sh HISTORY
|
|
This man page is largely based on the src/admin/style/style file from
|
|
the
|
|
.Bx 4.4 Lite2
|
|
release, with occasional updates to reflect the current practice and
|
|
desire of the
|
|
.Fx
|
|
project.
|