summaryrefslogtreecommitdiff
path: root/share/man/man9/style.9
diff options
context:
space:
mode:
authorTodd C. Miller <millert@cvs.openbsd.org>1999-08-19 08:12:12 +0000
committerTodd C. Miller <millert@cvs.openbsd.org>1999-08-19 08:12:12 +0000
commit31bef4da8b16646d3365f7fdeefa43b5e79f4b82 (patch)
tree0108937563aeeffc0a57b0ad43aaadf7302691d5 /share/man/man9/style.9
parentd6e3aa3875f277e063cd9238f2decc060491b3a1 (diff)
From FreeBSD with changes from /usr/share/misc/style
Diffstat (limited to 'share/man/man9/style.9')
-rw-r--r--share/man/man9/style.9527
1 files changed, 527 insertions, 0 deletions
diff --git a/share/man/man9/style.9 b/share/man/man9/style.9
new file mode 100644
index 00000000000..1ee279dc50a
--- /dev/null
+++ b/share/man/man9/style.9
@@ -0,0 +1,527 @@
+.\" 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.
+.\"
+.\" $OpenBSD: style.9,v 1.1 1999/08/19 08:12:11 millert Exp $
+.\"
+.Dd August 19, 1999
+.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
+.Tn OpenBSD
+source tree. It is also a guide for preferred user land code style.
+These guidelines should be followed for for all new code.
+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.
+.Bd -literal -offset 0i
+/*
+ * Style guide for the OpenBSD KNF (Kernel Normal Form).
+ */
+
+/*
+ * 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
+Kernel include files (i.e. sys/*.h) come first; normally, you'll need
+<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 -offset 0i
+#include <sys/types.h> /* Non-local includes in brackets. */
+.Ed
+.Pp
+If it's a network program, put the network include files next.
+.Bd -literal -offset 0i
+#include <net/if.h>
+#include <net/if_dl.h>
+#include <net/route.h>
+#include <netinet/in.h>
+#include <protocols/rwhod.h>
+.Ed
+.Pp
+Then there's a blank line, followed by the /usr include files.
+The /usr include files should be sorted!
+.Bd -literal -offset 0i
+#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 -offset 0i
+#include <paths.h>
+.Ed
+.Pp
+Then, there's a blank line, and the user include files.
+.Bd -literal -offset 0i
+#include "pathnames.h" /* Local includes in double quotes. */
+.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. In, user land,
+functions local to one source module should be declared
+.Ql static .
+This should not be done in kernel land since it makes it impossible
+to use the kernel debugger.
+.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
+When declaring a prototype, use the __P macro from the include file
+<sys/cdefs.h>. Only the kernel has a name associated with the types,
+i.e. in the kernel use:
+.Bd -literal -offset 0i
+void function __P((int a));
+.Ed
+in user land use:
+.Bd -literal -offset 0i
+void function __P((int));
+.Ed
+.Pp
+Prototypes may have an extra space after a tab to enable function names
+to line up:
+.Bd -literal -offset 0i
+static char *function __P((int, const char *));
+static void usage __P((void));
+.Ed
+.Pp
+Macros are capitalized, parenthesized, and should avoid side-effects.
+If they are an inline expansion of a function, the function is defined
+all in lowercase, the macro has the same name all in uppercase. If the
+macro needs more than a single line, use braces. 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 -offset 0i
+#define MACRO(x, y) do { \e
+ variable = (x) + (y); \e
+ (y) += 2; \e
+} while (0)
+.Ed
+.Pp
+Enumeration values are all uppercase.
+.Bd -literal -offset 0i
+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.
+Put a tab after the first word, i.e. use
+.Ql int^Ix;
+and
+.Ql struct^Ifoo *x; .
+.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 -offset 0i
+struct foo {
+ struct foo *next; /* List of active foo */
+ struct mumble amumble; /* Comment for mumble */
+ int bar;
+};
+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 -offset 0i
+#include <sys/queue.h>
+struct foo {
+ LIST_ENTRY(foo) link; /* Queue macro glue for foo lists */
+ struct mumble amumble; /* Comment for mumble */
+ int bar;
+};
+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 -offset 0i
+/* Make the structure name match the typedef. */
+typedef struct _bar {
+ int level;
+} BAR;
+.Ed
+.Pp
+.Bd -literal -offset 0i
+/*
+ * 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 -offset 0i
+ 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 -offset 0i
+ 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;
+ }
+.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 -offset 0i
+ for (; cnt < 15; cnt++) {
+ stmt1;
+ stmt2;
+ }
+.Ed
+.Pp
+Indentation is an 8 character tab.
+Second level indents are four spaces.
+.Bd -literal -offset 0i
+ while (cnt < 20)
+ 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, unless they cause
+a compiler warning.
+.Bd -literal -offset 0i
+ 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 -offset 0i
+ if (error = function(a1, a2))
+ exit(error);
+.Ed
+.Pp
+Unary operators don't require spaces, binary operators do. Don't
+use parentheses unless they're required for precedence, the statement
+is confusing without them, or the compiler generates a waring without
+them. Remember that other people may be confused more easily than you.
+Do YOU understand the following?
+.Bd -literal -offset 0i
+ 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 -offset 0i
+ 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 -offset 0i
+static char *
+function(a1, a2, fl, a4)
+ int a1, a2, a4; /* Declare ints, too, don't default them. */
+ float fl; /* List in order declared, as much as possible. */
+{
+.Ed
+.Pp
+When declaring variables in functions declare them sorted by size,
+then in alphabetical order; multiple ones per line are okay. Old
+style function declarations can go on the same line. ANSI style
+function declarations should go in the include file "extern.h".
+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 -offset 0i
+ 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 -offset 0i
+(p = f()) == NULL
+.Ed
+.Pp
+not:
+.Bd -literal -offset 0i
+!(p = f())
+.Ed
+.Pp
+Don't use '!' for tests unless it's a boolean, e.g. use
+.Bd -literal -offset 0i
+if (*p == '\e0')
+.Ed
+.Pp
+not
+.Bd -literal -offset 0i
+if (!*p)
+.Ed
+.Pp
+Routines returning void * should not have their return values cast
+to any pointer type.
+.Pp
+Use
+.Xr err 3
+or
+.Xr warn 3 ,
+don't roll your own!
+.Bd -literal -offset 0i
+ if ((four = malloc(sizeof(struct foo))) == NULL)
+ err(1, (char *)NULL);
+ if ((six = (int *)overflow()) == NULL)
+ errx(1, "Number overflowed.");
+ return (eight);
+}
+.Ed
+.Pp
+Don't use ANSI function declarations unless you absolutely have to,
+i.e. you're declaring functions with variable numbers of arguments.
+.Pp
+ANSI function declarations look like this:
+.Bd -literal -offset 0i
+void
+function(int a1, int a2)
+{
+ ...
+}
+.Ed
+.Pp
+Variable numbers of arguments should look like this:
+.Bd -literal -offset 0i
+#if __STDC__
+#include <stdarg.h>
+#else
+#include <varargs.h>
+#endif
+
+void
+#if __STDC__
+vaf(const char *fmt, ...)
+#else
+vaf(fmt, va_alist)
+ char *fmt;
+ va_dcl
+#endif
+{
+ va_list ap;
+#if __STDC__
+ va_start(ap, fmt);
+#else
+ va_start(ap);
+#endif
+
+ STUFF;
+
+ va_end(ap);
+
+ /* No return needed for void functions. */
+}
+
+static void
+usage()
+{
+ extern char *__progname; /* from crt0.o */
+.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. Options w/o
+operands come first, in alphabetical order inside a single set of
+braces, followed by options with operands, in alphabetical order,
+each in braces, followed by required arguments in the order they
+are specified, followed by optional arguments in the order they
+are specified. A bar
+.Pq Sq \&|
+separates either-or options/arguments,
+and multiple options/arguments which are specified together are
+placed in a single set of braces.
+.Pp
+.Bd -ragged -offset 0.3i
+"usage: f [-ade] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\en"
+"usage: f [-a | -b] [-c [-de] [-n number]]\en"
+.Ed
+.Pp
+The
+.Li __progname
+string, should be used instead of hard-coding the program name.
+.Bd -literal -offset 0i
+ (void)fprintf(stderr, "usage: %s [-ab]\en", __progname);
+ exit(1);
+}
+.Ed
+.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 KNF compliant in the repository must not diverge from
+compliance.
+.Pp
+Whenever possible, code should be run through a code checker
+(e.g., "gcc -Wall" or lint(1)) and produce minimal warnings.
+
+.Sh SEE ALSO
+.Xr indent 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
+.Tn BSD
+4.4-Lite2 release, with updates to reflect the current practice and
+desire of the
+.Tn OpenBSD
+project.