*nix Documentation Project
·  Home
 +   man pages
·  Linux HOWTOs
·  FreeBSD Tips
·  *niX Forums

  man pages->OpenBSD man pages -> style (9)              
Title
Content
Arch
Section
 

STYLE(9)

Contents


NAME    [Toc]    [Back]

     style - Kernel source file style guide (KNF)

DESCRIPTION    [Toc]    [Back]

     This file specifies the preferred style  for  kernel  source
files in the
     OpenBSD  source tree.  It is also a guide for preferred user
land code
     style.  These guidelines should  be  followed  for  all  new
code.  In general,
  code  can  be  considered ``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.

           /*
            *  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.
            */

     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.

           #include  <sys/types.h>   /*  Non-local  includes   in
brackets. */

     If  it's  a  network  program, put the network include files
next.

           #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!

           #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. */

     All functions are prototyped somewhere.

     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 `static'.
This should not
     be done in kernel land since it makes it impossible  to  use
the kernel debugger.


     Functions used from other parts of the kernel are prototyped
in the relevant
 include file.

     Functions that are used locally in more than one  module  go
into a separate
 header file, e.g., extern.h.

     Use  of the __P macro has been deprecated.  It is allowed in
code imported
     from other sources but should not be used in native  OpenBSD
code.  Prototypes
  should  not  have  variable names associated with the
types; i.e.,

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

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

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

     Use __dead from <sys/cdefs.h> for functions that  don't  return, i.e.,

           __dead void     abort(void);

     In  header files, put function prototypes within __BEGIN_DECLS /
     __END_DECLS matching pairs.  This makes the header file  usable from C++.

     Macros  are  capitalized and 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,
  as the resulting definition is easier to read.  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)

     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,  i.e.,  use
`int^Ix;' and
     `struct^Ifoo *x;'.

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

     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;

           /*
            * 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(3) should be used to parse  options.
Options
     should 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
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 != ' ') {
                                   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).
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, not while.

           for (p = buf; *p != ' '; ++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;
           }

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

     Indentation is an 8 character tab.  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;

     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.

     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.

           if (test)
                   stmt;
           else if (bar) {
                   stmt;
                   stmt;
           } else
                   stmt;

     Do not use spaces after function names.  Commas have a space
after them.
     Do not use spaces after `(' or `[' 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);

     Exits should be 0 on success, or non-zero for errors.

           exit(0);        /*
                            * Avoid obvious comments such as
                            * "Exit 0 on success."
                            */
           }

     The  function  type  should be on a line by itself preceding
the function.

           static char *
           function(int a1, int a2, float fl, 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.  Old style function declarations should be  avoided.  ANSI style
     function  declarations  should go in an include file such as
``extern.h''.
     If a line overflows, reuse the type keyword.

     Be careful not to obfuscate the code by  initializing  variables in the
     declarations.   Use  this feature only thoughtfully.  DO NOT
use function
     calls in initializers!

           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 discouraged in new
code.  Optimizing
     compilers such as gcc can  generally  do  a  better  job  of
choosing which
     variables to place in registers to improve code performance.
The exception
 to this is in functions containing assembly code  where
the
     ``register''  specifier  is required for proper code generation in the absence
 of compiler optimization.

     When using longjmp() or vfork() in  a  program,  the  -W  or
-Wall flag should
     be  used to verify that the compiler does not generate warnings such as

           warning:  variable  `foo'  might   be   clobbered   by
`longjmp' or `vfork'.

     If  any  warnings  of  this  type  occur, you must apply the
``volatile'' typequalifier
 to the variable in question.  Failure to do so may
result in
     improper code generation when optimization is enabled.  Note
that for
     pointers, the location  of  ``volatile''  specifies  if  the
type-qualifier
     applies  to  the  pointer, or the thing being pointed to.  A
volatile pointer
 is declared with ``volatile'' to the right of the  ``*''.
Example:

           char *volatile foo;

     says that ``foo'' is volatile, but ``*foo'' is not.  To make
``*foo''
     volatile use the syntax

           volatile char *foo;

     If both the pointer and the thing pointed  to  are  volatile
use

           volatile char *volatile foo;

     ``const'' is also a type-qualifier and the same rules apply.
The description
 of a read-only hardware register might look  something like:

           const volatile char *reg;

     Global  flags  set  inside signal handlers should be of type
``volatile
     sig_atomic_t'' if possible.  This guarantees that the  variable may be accessed
  as an atomic entity, even when a signal has been delivered.  Global
 variables of other types (such  as  structures)  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  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, i.e., use:

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

     Don't use `!' for tests unless it's a boolean, i.e., use

           if (*p == ' ')
     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);
           }

     Old-style function declarations look like this:

           static char *
           function(a1, a2, fl, a4)
                   int  a1,  a2;      /* Declare ints, too, don't
default them. */
                   float fl;       /*  Beware  double  vs.  float
prototype differences. */
                   int a4;         /* List in order declared. */
           {
                   ...
           }

     Use  ANSI  function  declarations unless you explicitly need
K&R compatibility.
  Long parameter lists are wrapped with  a  normal  four
space indent.

     Variable numbers of arguments should look like this:

           #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)
           {
                   extern char *__progname;        /* from crt0.o
*/

     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 options/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 letters take precedence over
lowercase.
     Note that the options list in manual pages should be  purely
alphabetical.
     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]]0
           "usage: f [-a | -b] [-c [-de] [-n number]]0

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

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

     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.

     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.


     Whenever possible, code should be run through a code checker
(e.g., ``gcc
     -Wall  -W  -Wtraditional -Wpointer-arith -Wbad-function-cast
...'', lint(1)
     or lclint from the ports tree) and produce minimal warnings.

FILES    [Toc]    [Back]

     /usr/share/misc/license.template    Example  license for new
code.

SEE ALSO    [Toc]    [Back]

      
      
     indent(1), err(3), queue(3), warn(3)

HISTORY    [Toc]    [Back]

     This man page is largely based on the  src/admin/style/style
file from the
     BSD  4.4-Lite2  release, with updates to reflect the current
practice and
     desire of the OpenBSD project.

OpenBSD     3.6                           June      18,      2001
[ Back ]
 Similar pages
Name OS Title
style FreeBSD kernel source file style guide
style.Makefile FreeBSD FreeBSD Makefile file style guide
perlstyle IRIX Perl style guide
perlstyle OpenBSD Perl style guide
perlmodstyle OpenBSD Perl module style guide
urandom Tru64 Kernel random number source devices
random Linux kernel random number source devices
random Tru64 Kernel random number source devices
elfdump IRIX dumps selected parts of a 32-bit or a 64-bit ELF object file/archive and displays them in ELF style
ctags Tru64 Makes a tags file for source file objects.
Copyright © 2004-2005 DeniX Solutions SRL
newsletter delivery service