Introduction

The below is shamlessly taken from OpenBSD's style(9) (and modified).

Description

This document describes the required coding style for all sources in the overall project.

Comments

All comments are to be the form:

/* this is a comment
 */

With multi-line comments as such:

/* this is a multi-line comment
 * look at it in its shiny glory
 */

Includes

If the file is in the systems search path such as stdio.h then we will use <>'s:

#include <stdio.h>

Any file that we create and include, we will use "'s:

#include "ourFile.h"

Also, all pathing will be relative to maintain a self contained environment.

The order of the includes will be (from /usr/include) sys, blank line, net, netinet, protocols (if a network program), a blank line, then the file that don't require a directory specified (eg stdio.h), a blank line, the includes from /usr/local/include ordered by first ones that require a directory to be specified, then not, then a blank line, and then our local files.

Function Proto-types

All functions are prototyped somewhere.

Private function (ie functions not used elsewhere) are prototyped at the top of the source file which they reside. These functions should also be declared as 'static'. Functions that are used in multiple files go into a separte header file. Other functions will go into the header file of the source file.

The __P macro is forbidden.

Prototypes will not have variable names associated with the types:

	void	function(int):
not:
	void	function(int a);

Prototypes should be formated such that the function names line up:

	static char	*function(int, const char*);
	static void	usage(void);

There should be no space between the function name and the argument list.

Functions

Function names will be simple, and descriptive (ie keep acronyms to a minimum). The first word will be all lowercase with each subsequent work having the first letter uppercase, the rest lowercase.

All functions will have a comment above them that describes the function as such:

	/***
	 * Function Name: function
	 *
	 * Description:
	 *   The function does...
	 *
	 * Parameter(s):
	 *   param1 - is...
	 *
	 * Return Value(s):
	 *   None||On Success/Failure...
	 */

Macros

Macros are capitalized adn parenthesized, and should avoid side-effects*. If they are an inline expansion of a function, the macro has the same name as the function, but in all uppercase. If the macro needs more than a single line, use braces. Righ-justify the backslashes, as the resulting definition is earier to read. If the macro encapulates a compund statement, enclose it in a ``do'' loop, so that it can safely be used in ``if'' statements. Any final statement-terminating semicolon will 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)

Variable Declaration

Enumeration values are all uppercase.

	enum enumtype { ONE, TWO } et;

When declaring variables in structures, declare them sorted by use, then by size (largest to smallest), 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 ie use `int^Ix;' and `struct^Ifoo *x;'.

Major structures will 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 seperate 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;
	};
	struct foo *foohead;		/* head of global foo list */

Use queue(3)** macros rather than rolling your own lists, whenever possible. Thus the previous example would be better written:

	#include 
	struct	foo {
		LIST_ENTRY(foo)	link;		/* queue macro glue for foo lists */
		struct	mumble a mumble;	/* comment for mumble */
		int	bar;
	};
	LIST_HEAD(, foo) foohead;		/* head of global foo list */

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 ``_t'', except as specified in Standard C or by POSIX. Don't use the same name for a struct tag and a typedef, as this makes the code unusable from C++.

	/* Make the structure name match the typedef
	 */
	typedef struct	_bar {
		int	level;
	} BAR;

General Coding

For consistency, getopt(3)** will be used to parse options. Options will be sorted in the getopt(3)** 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 must be checked for accuracy. Code that cannot be reached will have a NOTREACHED comment.

	while ((ch = getopt(argc, argv, "abn:")) != -1) {
		switch (ch) {		/* indent the switch *
			case 'a':	/* and the case */
				aflag = 1;
				/* FALLTHROUGH */
			case 'b':
				bflag = 1;
				break;
			case 'n':
				num = strtol(optarg, &ep, 10);
				if (num <= 0 || *ep != '\0') {
					warnx("illegal number, -n argument -- %s", optarg);
					usage();
				}
				break;
			case '?':
			default:
				usage();
				/* NOTREACHED */
		}
		argc -= optind;
		argv += optind;
	}

Use a space after keywords (if, while, for, return, switch). Braces are required for control statements even if they have only a single statement, but braces are not required for control statements that have no statements, eg:

	/* required */
	for (i = 0; i < limit; i++) {
		stmt;
	}

	/* not required */
	for (i = 0; i < limit; i++) ;

Forever loops are done withe while:

	while (1) {
	}

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;
	}

All indentation will be done with tabs. No spaces are permitted to be used as a tab. This is to ensure that everyone gets their preferred representation (this can be set in any programmers editor) and the code stays lined up regardless of editor.

Do not add whitespace at the end of a line.

Opening braces will be on the same line as the statement that the block is associated with and closing braces go on the line after the last statement in the block indented according to the the statement that started the block as in the example directly above.

Do not use spaces after function names. Commas have a space after them. Do not use spaces after `(' or `[' preceding `]' or `)' characters.

	if ((error = function(a1, a2))) {
		exit(error);
	}

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 warning without them. remember that other people may be confused more easily than you. Do YOU understand the following?

	a = b->c[0] + ~d == (e || f) || g && h ? i : j >> 1;
	k = !(l & FLAGS);

Exists will be 0 on success, or non-zero for errors.

	exit(0);	/* avoid obvious comments such as
			 * "Exit 0 on success
			 */

The function type is on the same line as the function name, etc.

	static char * function(int a1, int a2, float f1, int a4) {

When declaring variables in functions, declare them sorted by size (largest to smallest), then in alphabetical order; multiple ones per line are okay. If a line overflows, reuse the type keyword.

Do not obfuscate the code by initializing variables in the declarations. use this feature only thoughtfully. DO NOT use function calls in initalizers!

	struct foo one, *two;
	double three;
	int *four, five;
	char *six, seven, eight, nine, ten, eleven, twelve;

	four = myFunction();

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, such as ``gcc -Wtraditional''.

Casts and sizeof() calls are not followed by a space. Note that indent(1) does not understand this rule.

Use of the ``register'' specifier is not permitted. Optimizing compilers such as gcc can generally do a better job of choosing which variables to place in registers to improve code performance.

longjmp() and vfork() will not be used.

Global flags set inside signal handlers should be of type ``volatile sig_atomic_t'' if possible. This guarantees that the variables may be accessed as an atomic entity, even when a signal has been delivered. Global variables of other types (such as sturctures) are not guaranteed to have consistent values when accessed via a signal handler.

NULL is the preferred null pointer constant. Use NULL instead of (type *)0 or (type *)NULL in all cases except for arguments to variadic functions where the compiler does not know the type. Test pointers against NULL, ie use:

	(p = f()) == NULL
not:
	!(p = f())

Don't use `!' for tests unless it's a boolean, ie use:

	if (*p == '\0')
not:
	if (!*p)

Routines returning void * should not have their return values cast to any pointer type.

Use err(3) or warn(3), don't roll your own!

	if ((four = malloc(sizeof(struct foo))) == NULL) {
		err(1, (char *)NULL);
	}
	if ((six = (int *)overflow()) == NULL) {
		errx(1, "Number overflowed.");
	}
	return (eight);

Long parameter lists are wrapped with a single indent.

Usage statements should look like the manual pages. Options without 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 optinos/arguments, and multiple options/arguments which are specified together are placed in a single set of braces.

If numbers are used as options, they should be placed first, as shown in the example below. Uppercase leters take precedence over lowercase. That is, with no regard to whether an option takes an argument.

	"usage: f [-12aDde] [-b b_arg] [-m m_arg] req1 req2 [opt1 [opt2]]\n"
	"usage: f [-a | -b] [-c [-de] [-n number]]\n"

The __progname string, should be used instead of hard-coding the program name.

	(void)fprintf(stderr, "usage: %s [-ab]\n", __progname);
	exit(1);

Whenever possible, code should be run through a code checker (eg ``gcc -Wall -W -Wtraditional -Wpointer-arith -Wbad-function-cast ...'', lint(1) or split) and produce minial (preferably no) warnings.


*  We will not be using GNU extensions in this project.
** I still need to check for the cross-platform avalability of this.

The 'Verse is a fan project. It is not authorized by Fox, Universal Pictures, Mutant Enemy or anyone involved with Firefly/Serenity. No copyright infringment or challenge of ownership is made or intended.
© Copyright 2006 The 'Verse Project. All rights reserved.

Hosted by:
ourproject.org Logo