Code Formatting Conventions for tla
Regular code formatting practices within a program's source code are
invaluable. Regular formatting aids both the readability of the
code and its maintainability. Code which is regularly formatted is
easier to process with tools not specifically aware of C syntax
(such as grep
) or which may be only partially aware of C syntax
(such as an Emacs mode for editting C programs). In general,
regular formatting is key to being able to manipulate source code
work as a whole rather merely as a lose collection of separate
modules.
Code formatted according to the conventions for tla
has the
following properties (more to be added later):
Contents:
Files and Modular Structure
Formatting Comments
Line Width
Structure, Enum, and Union Declarations
Indenting and Curly Braces
Spaces and Operators
Spaces and Parentheses
{Files and Modular Structure}
tla
source code is divided into conceptual "modules", each
comprised of a single .c
file and a matching .h
file.
The .c
file contains the definitions exported by the module. The
.h
file contains the declarations for these exported entities.
Each .h
file is independently includable. In other words, for
any file foo.h
, this C program compiles without error:
#include "foo.h"
The .h
files are cumulatively includable. In other words,
a program may include any set of tla
header files, in any order.
There are two templates included in the tla
source file: one for
.h
files and one for .c
files. All modules should be formatted consistently
with these templates.
{Formatting Comments}
Most comments are formatted in the style:
/* This is a short comment. */ /* * This is a short comment about code which preceedes it. */ /* Multi-line comments are written in this style. * Every line begins with blanks and a `*' character, * aligned as in this example. */
{Line Width}
No line in a source file should be longer than 90 characters (91 if a 0-width line terminator character is included). (Two 90-character-wide listing can comfortably sit side by side, mostly filling many computer displays and landscape-orientation printed pages.)
C expressions should be placed entirely on one line if they will fit. (This makes expressions-as-a-whole easier to manipulate. It also allows more of a program to fit on one screen or page at a time.)
The text in comment lines, following the initial *
character,
should be no longer than 79 characters. It should be formatted
for an 80-column display on which it is preferable to not display
characters in the rightmost column.
Each parameter in a function prototype should appear on its own line and the function name should be in column 0, as in this example:
int main (int argc, char * argv[])
This helps allow function prototypes to be "cut and paste" into
contexts where they must be displayed in relatively few columns.
The general 90-character width limit for most tla
code is too
wide for function prototypes.
Similarly, structure, enum, and union declarations should be formated for as narrow a display as they can be comfortably displayed on.
{Structure, Enum, and Union Declarations}
The curly braces in top level declarations should be column 0, followed immediately by a newline.
The curly braces in nested declarations should be indented to the
same column as the struct
, enum
, or union
keyword and
immediately followed by a newline.
No such declarations may part of a typedef
.
Struct/enum/union declarations may not be part of a variable declaration.
Each field specifier should specify exactly one field.
Correct:
struct point { int x; int y; }; struct point a_point;
So wrong:
struct point { int x, y; } a_point;
{Indenting and Curly Braces}
All curly braces should be on a line by themselves with the exception of right braces which are part of a type or field declaration.
Conditional and loop bodies should be indented two columns.
The contents of a compound statement should be indented two columns.
Most labels should be outdented two spaces except for labels in the outermost compound expression of a function definition; those labels should be outdented one space.
{Spaces and Operators}
All binary operators except for ->
and .
must be surrounded
by a single space character.
The operators ->
and .
must never be next to a space character.
Sometimes programmers omit spaces to create a visual reminder of operator precedence. They should use parentheses instead:
Ok:
h_sq = (a * a) + (b * b);
Uh...no:
h_sq = a*a + b*b;
These rules make it easier to distinguish unary and binary operator both visually and in search patterns. The rules make parenthesis-oriented editor navigation commands more useful.
{Spaces and Parentheses}
Every left parenthesis character ((
) which immediately follows
a function name or binary operator should be preceeded by a space.
There is almost no circumstance under which a left parenthesis is followed by a space.
Yes:
time_t foo (struct stat * sb) { return bar (sb, baz (2 * (sb->st_mtime + offset))); }
NO!:
time_t foo( struct stat * sb ) { return bar( sb, baz( 2*(sb->st_mtime + offset) ) ); }
Consistent application of any such spacing rules would make it easier to write search patterns to find function prototypes and calls. Any consistent rule would help readability.
This particular rule to follow function names in prototypes or calls
by a space is easier to read when small fonts are used in which the
left parenthesis character is hard to distinguish from the digit 1
or
the letter "lower-case 'l'".
The rule to not follow a left parenthesis by spaces interacts will with editor commands which optimize for positioning the cursor immediately to the right of a left parenthesis. (Such commands are very valuable for navigating C programs.)
Copyright
Copyright (C) 2004 Tom Lord
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
See the file COPYING
for further information about
the copyright and warranty status of this work.