Last active
January 22, 2024 03:10
-
-
Save chawyehsu/f6fcd3912ecbdb778f5a62984f7c0d89 to your computer and use it in GitHub Desktop.
NetBSD C language source coding style (Kernel Normal Form - KNF) /usr/share/misc/style
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* $NetBSD: style,v 1.75 2023/08/07 18:01:42 riastradh Exp $ */ | |
/* | |
* The revision control tag appears first, with a blank line after it. | |
* Copyright text appears after the revision control tag. | |
*/ | |
/* | |
* The NetBSD source code style guide. | |
* (Previously known as KNF - Kernel Normal Form). | |
* | |
* from: @(#)style 1.12 (Berkeley) 3/18/94 | |
*/ | |
/* | |
* An indent(1) profile approximating the style outlined in | |
* this document lives in /usr/share/misc/indent.pro. It is a | |
* useful tool to assist in converting code to KNF, but indent(1) | |
* output generated using this profile must not be considered to | |
* be an authoritative reference. | |
*/ | |
/* | |
* Source code revision control identifiers appear after any copyright | |
* text. Use the appropriate macros from <sys/cdefs.h>. Usually only one | |
* source file per program contains a __COPYRIGHT() section. | |
* Historic Berkeley code may also have an __SCCSID() section. | |
* Only one instance of each of these macros can occur in each file. | |
* Don't use newlines in the identifiers. | |
*/ | |
#include <sys/cdefs.h> | |
__COPYRIGHT("@(#) Copyright (c) 2008\ | |
The NetBSD Foundation, inc. All rights reserved."); | |
__RCSID("$NetBSD: style,v 1.75 2023/08/07 18:01:42 riastradh Exp $"); | |
/* | |
* 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. | |
*/ | |
/* | |
* Attempt to wrap lines longer than 80 characters appropriately. | |
* Refer to the examples below for more information. | |
*/ | |
/* | |
* EXAMPLE HEADER FILE: | |
* | |
* A header file should protect itself against multiple inclusion. | |
* E.g, <sys/socket.h> would contain something like: | |
*/ | |
#ifndef _SYS_SOCKET_H_ | |
#define _SYS_SOCKET_H_ | |
/* | |
* Include other header files only as necessary, mainly for type | |
* definitions or macros that are necessary to use in this header file. | |
* | |
* Avoid relying on transitive inclusions. | |
* | |
* Avoid header files dependencies just for struct and union types that | |
* are used in pointer types, which don't require type defintions. | |
* Instead, use forward declarations of the struct or union tag. | |
*/ | |
#include <sys/foobar.h> | |
/* | |
* Forward declarations for struct and union tags that don't need | |
* definitions go next. | |
*/ | |
struct dirent; | |
/* | |
* Define public structs and unions, only if they are user-allocated or | |
* otherwise exposed to users for a good reason; otherwise keep them | |
* private to .c files or `_impl.h' or `_private.h' files. | |
* | |
* Do not create a typedef like `typedef struct example example_t;' or | |
* `typedef struct example *example_t;'. Use `struct example' or | |
* `struct example *' in the public API; that way, other header files | |
* which declare functions or define struct or union types that involve | |
* only pointers to `struct example' need not pull in unnecessary | |
* header files. | |
*/ | |
struct example { | |
struct data *p; | |
int x; | |
char y; | |
}; | |
/* | |
* Use typedefs judiciously. | |
* | |
* Function or function pointer types: | |
*/ | |
typedef void sighandler_t(int); | |
/* | |
* Aliases for arithmetic types: | |
*/ | |
typedef uint16_t nlink_t; | |
/* | |
* Types that might be defined differently in some contexts, like | |
* uint8_t on one port, a pointer to a struct on another port, and an | |
* in-line struct larger than a pointer on a third port: | |
*/ | |
typedef uint8_t foo_t; /* Hypothetical leg26 definition */ | |
typedef struct foo *foo_t; /* Hypothetical i786 definition */ | |
typedef struct { /* Hypothetical risc72 definition */ | |
uint32_t p; | |
uint32_t q; | |
uint8_t t; | |
} foo_t; | |
/* | |
* For opaque data structures that are always represented by a pointer | |
* when stored in other data structures or passed to functions, don't | |
* use a type `foo_t' with `typedef void *foo_t'. Use `struct foo *' | |
* with no public definition for `struct foo', so the compiler can | |
* detect type errors, and other header files can use `struct foo *' | |
* without creating header file dependencies. | |
*/ | |
/* | |
* extern declarations must only appear in header files, not in .c | |
* files, so the same declaration is used by the .c file defining it | |
* and the .c file using it, giving the compiler the opportunity to | |
* detect type errors. | |
* | |
* extern function declarations should not use the extern keyword, | |
* which is unnecessary. | |
* | |
* Exception: A subroutine written in assembly in an adjacent .S file, | |
* which is used only in one .c file, may be declared in the .c file. | |
*/ | |
extern int frotz; | |
int frobnicate(const char *, struct dirent *, foobar_t); | |
/* | |
* Contents of #include file go between the #ifndef and the #endif at the end. | |
*/ | |
#endif /* !_SYS_SOCKET_H_ */ | |
/* | |
* END OF EXAMPLE HEADER FILE. | |
*/ | |
/* | |
* If a header file requires structures, defines, typedefs, etc. from | |
* another header file it should include that header file and not depend | |
* on the including file for that header including both. If there are | |
* exceptions to this for specific headers it should be clearly documented | |
* in the headers and, if appropriate, the documentation. Nothing in this | |
* rule should suggest relaxation of the multiple inclusion rule and the | |
* application programmer should be free to include both regardless. | |
*/ | |
/* | |
* Kernel include files come first. | |
*/ | |
#include <sys/param.h> /* <sys/param.h> first, */ | |
#include <sys/types.h> /* <sys/types.h> next, */ | |
#include <sys/ioctl.h> /* and then the rest, */ | |
#include <sys/socket.h> /* sorted lexicographically. */ | |
#include <sys/stat.h> | |
#include <sys/wait.h> /* Non-local includes in brackets. */ | |
/* | |
* If it's a network program, put the network include files next. | |
* Group the include files by subdirectory. | |
*/ | |
#include <net/if.h> | |
#include <net/if_dl.h> | |
#include <net/route.h> | |
#include <netinet/in.h> | |
#include <protocols/rwhod.h> | |
/* | |
* Then there's a blank line, followed by the /usr include files. | |
* The /usr include files should be sorted lexicographically! | |
*/ | |
#include <assert.h> | |
#include <errno.h> | |
#include <inttypes.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
/* | |
* Global pathnames are defined in /usr/include/paths.h. Pathnames local | |
* to the program go in pathnames.h in the local directory. | |
*/ | |
#include <paths.h> | |
/* Then, there's a blank line, and the user include files. */ | |
#include "pathnames.h" /* Local includes in double quotes. */ | |
/* | |
* Declarations for file-static functions go at the top of the file. | |
* Don't associate a name with the parameter types. I.e. use: | |
* void function(int); | |
* Use your discretion on indenting between the return type and the name, and | |
* how to wrap a prototype too long for a single line. In the latter case, | |
* lining up under the initial left parenthesis may be more readable. | |
* In any case, consistency is important! | |
*/ | |
static char *function(int, int, float, int); | |
static int dirinfo(const char *, struct stat *, struct dirent *, | |
struct statfs *, int *, char **[]); | |
static void usage(void) __dead; /* declare functions that don't return dead */ | |
/* | |
* Macros are capitalized, parenthesized, and should avoid side-effects. | |
* Spacing before and after the macro name may be any whitespace, though | |
* use of TABs should be consistent through a file. | |
* 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 is an expression, wrap the expression in parentheses. | |
* If the macro is more than a single statement, use ``do { ... } while (0)'' | |
* or ``do { ... } while (false)'', so that a trailing semicolon works. | |
* Right-justify the backslashes; it makes it easier to read. | |
*/ | |
#define MACRO(v, w, x, y) \ | |
do { \ | |
v = (x) + (y); \ | |
w = (y) + 2; \ | |
} while (0) | |
#define DOUBLE(x) ((x) * 2) | |
/* Enum constants are capitalized. No comma on the last element. */ | |
enum enumtype { | |
ONE, | |
TWO | |
}; | |
/* | |
* Sometimes we want a macro to be conditionally defined for debugging | |
* and expand to nothing (but still as statement) when we are not debugging: | |
*/ | |
#ifdef FOO_DEBUG | |
# define DPRINTF(...) printf(__VA_ARGS__) | |
#else | |
# define DPRINTF(...) __nothing | |
#endif | |
/* | |
* When declaring variables in structures, declare them organized by use in | |
* a manner to attempt to minimize memory wastage because of compiler alignment | |
* issues, then by size, and then by alphabetical order. E.g, don't use | |
* ``int a; char *b; int c; char *d''; use ``int a; int b; char *c; char *d''. | |
* Each variable gets its own type and line, although an exception can be made | |
* when declaring bitfields (to clarify that it's part of the one bitfield). | |
* Note that the use of bitfields in general is discouraged. | |
* | |
* 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. | |
* | |
* It may be useful to use a meaningful prefix for each member name. | |
* E.g, for ``struct softc'' the prefix could be ``sc_''. | |
* | |
* Don't create typedef aliases for struct or union types. That way, | |
* other header files can use pointer types to them without the header | |
* file defining the typedef. | |
*/ | |
struct foo { | |
struct foo *next; /* List of active foo */ | |
struct mumble amumble; /* Comment for mumble */ | |
int bar; | |
unsigned int baz:1, /* Bitfield; line up entries if desired */ | |
fuz:5, | |
zap:2; | |
uint8_t flag; | |
}; | |
struct foo *foohead; /* Head of global foo list */ | |
/* C99 uintN_t is preferred over u_intN_t. */ | |
uint32_t zero; | |
/* | |
* 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; | |
/* | |
* At the start of main(), call setprogname() to set the program | |
* name. This does nothing on NetBSD, but increases portability | |
* to other systems. | |
*/ | |
setprogname(argv[0]); | |
/* | |
* 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. For the | |
* sorting order, see the usage() example below. Don't forget | |
* to add option descriptions to the usage and the manpage. | |
* 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. | |
*/ | |
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': | |
errno = 0; | |
num = strtol(optarg, &ep, 10); | |
if (num <= 0 || *ep != '\0' || (errno == ERANGE && | |
(num == LONG_MAX || num == LONG_MIN)) ) { | |
errx(1, "illegal number -- %s", optarg); | |
} | |
break; | |
case '?': | |
default: | |
usage(); | |
/* NOTREACHED */ | |
} | |
} | |
argc -= optind; | |
argv += optind; | |
/* | |
* Space after keywords (while, for, return, switch). | |
* | |
* Braces around single-line bodies are optional; use discretion. | |
* | |
* Use narrow scopes for loop variables where possible. | |
*/ | |
for (char *p = buf; *p != '\0'; ++p) | |
continue; /* Explicit no-op */ | |
/* | |
* Forever loops are done with for's, not while's. | |
*/ | |
for (;;) | |
stmt; | |
/* | |
* Parts of a for loop may be left empty. Don't put declarations | |
* inside blocks unless the routine is unusually complicated. | |
*/ | |
for (; cnt < 15; cnt++) { | |
stmt1; | |
stmt2; | |
} | |
/* Second level indents are four spaces. */ | |
while (cnt < 20) { | |
z = a + really + long + statement + that + needs + two + lines + | |
gets + indented + four + spaces + on + the + second + | |
and + subsequent + lines; | |
} | |
/* | |
* Closing and opening braces go on the same line as the else. | |
*/ | |
if (test) { | |
/* | |
* I have a long comment here. | |
*/ | |
#ifdef zorro | |
z = 1; | |
#else | |
b = 3; | |
#endif | |
} else if (bar) { | |
stmt; | |
stmt; | |
} else { | |
stmt; | |
} | |
/* No spaces after function names. */ | |
if ((result = function(a1, a2, a3, a4)) == NULL) | |
exit(EXIT_FAILURE); | |
/* | |
* Unary operators don't require spaces, binary operators do. | |
* Don't excessively use parentheses, but they should be used if a | |
* statement is really confusing without them, such as: | |
* a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1; | |
*/ | |
a = ((b->c[0] + ~d == (e || f)) || (g && h)) ? i : (j >> 1); | |
k = !(l & FLAGS); | |
/* | |
* Exits should be EXIT_SUCCESS on success, and EXIT_FAILURE on | |
* failure. Don't denote all the possible exit points, using the | |
* integers 1 through 127. Avoid obvious comments such as "Exit | |
* 0 on success.". Since main is a function that returns an int, | |
* prefer returning from it, than calling exit. | |
*/ | |
return EXIT_SUCCESS; | |
} | |
/* | |
* The function type must be declared on a line by itself | |
* preceding the function. | |
*/ | |
static char * | |
function(int a1, int a2, float fl, int a4) | |
{ | |
/* | |
* When declaring variables in functions, multiple variables per line | |
* are okay. If a line overflows reuse the type keyword. | |
* | |
* Function prototypes and external data declarations should go in a | |
* suitable include file. | |
* | |
* Avoid initializing variables in the declarations; move | |
* declarations next to their first use, and initialize | |
* opportunistically. This avoids over-initialization and | |
* accidental bugs caused by declaration reordering. | |
*/ | |
struct foo three, *four; | |
double five; | |
int *six, seven; | |
char *eight, *nine, ten, eleven, twelve, thirteen; | |
char fourteen, fifteen, sixteen; | |
/* | |
* Casts and sizeof's are not followed by a space. | |
* | |
* We parenthesize sizeof expressions to clarify their precedence: | |
* | |
* sizeof(e) + 4 | |
* not: | |
* sizeof e + 4 | |
* | |
* We don't put a space before the parenthesis so that it looks like | |
* a function call. We always parenthesize the sizeof expression for | |
* consistency. | |
* | |
* On the other hand, we don't parenthesize the return statement | |
* because there is never a precedence ambiguity situation (it is | |
* a single statement). | |
* | |
* NULL is any pointer type, and doesn't need to be cast, so use | |
* NULL instead of (struct foo *)0 or (struct foo *)NULL. Also, | |
* test pointers against NULL because it indicates the type of the | |
* expression to the user. I.e. use: | |
* | |
* (p = f()) == NULL | |
* not: | |
* !(p = f()) | |
* | |
* The notable exception here is variadic functions. Since our | |
* code is designed to compile and work on different environments | |
* where we don't have control over the NULL definition (on NetBSD | |
* it is defined as ((void *)0), but on other systems it can be | |
* defined as (0) and both definitions are valid), it | |
* it advised to cast NULL to a pointer on variadic functions, | |
* because on machines where sizeof(pointer) != sizeof(int) and in | |
* the absence of a prototype in scope, passing an un-casted NULL, | |
* will result in passing an int on the stack instead of a pointer. | |
* | |
* Don't use `!' for tests unless it's a boolean. | |
* E.g. use "if (*p == '\0')", not "if (!*p)". | |
* | |
* Routines returning ``void *'' should not have their return | |
* values cast to more specific pointer types. | |
* | |
* Prefer sizeof(*var) over sizeof(type) because if type changes, | |
* the change needs to be done in one place. | |
* | |
* Use err/warn(3), don't roll your own! | |
* | |
* Prefer EXIT_FAILURE instead of random error codes. | |
*/ | |
if ((four = malloc(sizeof(*four))) == NULL) | |
err(EXIT_FAILURE, NULL); | |
if ((six = (int *)overflow()) == NULL) | |
errx(EXIT_FAILURE, "Number overflowed."); | |
/* No parentheses are needed around the return value. */ | |
return eight; | |
} | |
/* | |
* Place the opening brace of a function body in column 1. | |
* As per the wrapped prototypes, use your discretion on how to format | |
* the subsequent lines. | |
*/ | |
static int | |
dirinfo(const char *p, struct stat *sb, struct dirent *de, struct statfs *sf, | |
int *rargc, char **rargv[]) | |
{ /* Insert an empty line if the function has no local variables. */ | |
/* | |
* In system libraries, catch obviously invalid function arguments | |
* using _DIAGASSERT(3). | |
*/ | |
_DIAGASSERT(p != NULL); | |
_DIAGASSERT(filedesc != -1); | |
/* Prefer checking syscalls against -1 instead of < 0 */ | |
if (stat(p, sb) == -1) | |
err(EXIT_FAILURE, "Unable to stat %s", p); | |
/* | |
* To printf quantities that might be larger than "long", | |
* cast quantities to intmax_t or uintmax_t and use %j. | |
*/ | |
(void)printf("The size of %s is %jd (%#ju)\n", p, | |
(intmax_t)sb->st_size, (uintmax_t)sb->st_size); | |
/* | |
* To printf quantities of known bit-width, include <inttypes.h> and | |
* use the corresponding defines (generally only done within NetBSD | |
* for quantities that exceed 32-bits). | |
*/ | |
(void)printf("%s uses %" PRId64 " blocks and has flags %#" PRIx32 "\n", | |
p, sb->st_blocks, sb->st_flags); | |
/* | |
* There are similar constants that should be used with the *scanf(3) | |
* family of functions: SCN?MAX, SCN?64, etc. | |
*/ | |
} | |
/* | |
* Functions that support variable numbers of arguments should look like this. | |
* (With the #include <stdarg.h> appearing at the top of the file with the | |
* other include files.) | |
*/ | |
#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(void) | |
{ | |
/* | |
* Use printf(3), not fputs/puts/putchar/whatever, it's faster and | |
* usually cleaner, not to mention avoiding stupid bugs. | |
* Use snprintf(3) or strlcpy(3)/strlcat(3) instead of sprintf(3); | |
* again to avoid stupid bugs. | |
* | |
* Usage statements should look like the manual pages. | |
* Options w/o operands come first, in alphabetical order | |
* inside a single set of braces, upper case before lower case | |
* (AaBbCc...). Next are options with operands, in the same | |
* order, each in braces. Then required arguments in the | |
* order they are specified, followed by optional arguments in | |
* the order they are specified. A bar (`|') separates | |
* either/or options/arguments, and multiple options/arguments | |
* which are specified together are placed in a single set of | |
* braces. | |
* | |
* Use getprogname() instead of hardcoding the program name. | |
* | |
* "usage: f [-aDde] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\n" | |
* "usage: f [-a | -b] [-c [-de] [-n number]]\n" | |
*/ | |
(void)fprintf(stderr, "usage: %s [-ab]\n", getprogname()); | |
exit(EXIT_FAILURE); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment