Prex Coding Standard
Version 1.0.1 2009/10/01
/*
* Prex Coding Standard
*
* Based on the CSRG's KNF (Kernel Normal Form) and FreeBSD's style guide
*
* @(#)style 1.14 (Berkeley) 4/28/95
*/
/*
* 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.
*/
/* Don't use C-99 style "// ..." comments. */
/* Don't use DOS '\r\n' line feeds. */
/*
* Attempt to wrap lines longer than 80 characters appropriately.
* Comments should not be enclosed in large boxes drawn with asterisks
* or other characters.
*/
/*
* The copyright header should be a multi-line comment, with the first
* line of the comment having a dash after the star like so:
*/
/*-
* Copyright (c) 1984-2025 John Q. Public
* All rights reserved.
*
* Long, boring license goes here, but redacted for brevity
*/
/* After any copyright header, there is a blank line. */
/*
* Kernel include files come first.
*/
#include <sys/types.h> /* Non-local includes in brackets. */
/*
* Then there's a blank line, followed by the /usr include files.
*/
#include <stdio.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. */
/*
* The names of ``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
* #define and the macro name. If the macro encapsulates a compound
* statement, enclose it in a do loop, so that it can safely be used
* in 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.
*/
#define MACRO(x, y) \
do { \
variable = (x) + (y); \
(y) += 2; \
} while (0)
/* Enum types are capitalized. */
enum enumtype {
ONE,
TWO
} et;
/*
* In declarations, do not put any whitespace between asterisks and
* adjacent tokens, except for tokens that are identifiers related to
* types. (These identifiers are the names of basic types, type
* qualifiers, and typedef-names other than the one being declared.)
* Separate these identi- fiers from asterisks using a single space.
*/
/*
* When declaring variables in structures, 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 only if it suffices to align at least 90% of the
* member names. Names following extremely long types should be
* separated by a single space.
*
* 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.
*/
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 */
/*
* Prototypes should not have variable names associated with the types.
* Prototypes may have an extra space after a tab to enable function
* names to line up:
*/
static char *function(int, const char *);
static void usage(void);
/* 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;
/*
* 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.
*/
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 != '\0')
err("illegal number -- %s", optarg);
break;
case '?':
default:
usage();
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
/*
* Use a space after keywords (if, while, for, return, switch).
* No braces are required for control statements with only a
* single statement, unless it's a long statement.
*
* Forever loops are done with for's, not while's.
*/
for (p = buf; *p != '\0'; ++p)
; /* Do nothing */
for (;;)
stmt;
/*
* Parts of a for loop may be left empty. Don't put
* declarations inside blocks.
*/
for (; cnt < 15; cnt++) {
stmt1;
stmt2;
}
/*
* Indentation is an 8 character tab. If you have to wrap a
* long statement, put the operator at the end of the line.
*/
while (cnt < 20 && this_variable_name_is_too_long &&
ep != NULL)
z = a + really + long + statment + that + needs +
two + lines + gets + indented + properly +
on + the + second + and + subsequent + lines;
/* Do not add whitespace at the end of a line, */
/*
* Closing and opening braces go on the same line as the else.
* Don't add braces that aren't necessary except in cases where
* there are ambiguity or readability issues.
*/
if (test) {
/*
* I have a long comment here.
*/
stmt;
} else if (bar) {
stmt;
stmt;
} else
stmt;
/*
* No spaces after function names. Commas have a space after them.
* No spaces after `(' or `[' or preceding `]' or `)' characters.
*/
error = function(a1, a2);
if (error != 0)
exit(error);
/*
* Unary operators don't require spaces, binary operators do.
* Don't excessively use parenthesis, but they should be used if
* 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 0 on success, and other value on failure.
* Avoid obvious comments such as "Exit 0 on success."
*/
exit(0);
}
/*
* The function type should be on a line by itself preceding the
* function. The opening brace of the function body should be on a
* line by itself.
*/
static char *
function(int a1, int a2, float fl, int a4)
{
/*
* When declaring variables in functions declare them sorted
* by size; multiple ones per line are okay.
*
* DO NOT use function calls in initializers.
*/
struct foo three, *four;
double five;
int *six, seven;
char *nine, ten, eleven, twelve;
/*
* Casts and sizeof's are not followed by a space. 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, i.e. use:
*
* (p = f()) == NULL
* not:
* !(p = f())
*
* 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 any pointer type.
*
* Values in return statements should NOT be enclosed in
* parentheses.
*/
if ((four = malloc(sizeof(struct foo))) == NULL)
err(1, NULL);
if ((six = (int *)overflow()) == NULL)
errx(1, "Number overflowed.");
return eight;
}
static void
usage()
{
/* Insert an empty line if the function has no local variables. */
/*
* Use printf, not fputs/puts/putchar/whatever, it's faster
* and usually cleaner, not to mention avoiding 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. 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 ('|') separates either/or
* options/arguments, and multiple options/arguments which are
* specified together are placed in a single set of braces.
*
* "usage: f [-ade] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\n"
* "usage: f [-a | -b] [-c [-de] [-n number]]\n"
*/
(void)fprintf(stderr, "usage: f [-ab]\n");
exit(1);
}