Coding Style for the Xen Hypervisor
===================================

The Xen coding style described below is the coding style used by the
Xen hypervisor itself (xen/*) as well as various associated low-level
libraries (e.g. tools/libxc/*).

An exception is made for files which are imported from an external
source. In these cases the prevailing coding style of the upstream
source is generally used (commonly the Linux coding style).

Other parts of the code base may use other coding styles, sometimes
explicitly (e.g. tools/libxl/CODING_STYLE) but often implicitly (Linux
coding style is fairly common). In general you should copy the style
of the surrounding code. If you are unsure please ask.

SPDX
----

New files should start with a single-line SPDX comment to express the
license, e.g.:

/* SPDX-License-Identifier: GPL-2.0-only */

See LICENSES/ for a list of licenses and SPDX tags currently used.

MISRA C
-------

The Xen Hypervisor follows some MISRA C coding rules. See
docs/misra/rules.rst for details.

Indentation
-----------

Indenting uses spaces, not tabs - in contrast to Linux.  An indent
level consists of four spaces.  Code within blocks is indented by one
extra indent level.  The enclosing braces of a block are indented the
same as the code _outside_ the block.  e.g.

void fun(void)
{
    /* One level of indent. */

    {
        /* A second level of indent. */
    }
}

Due to the behavior of GNU diffutils "diff -p", labels should be
indented by at least one blank.  Non-case labels inside switch() bodies
are preferred to be indented the same as the block's case labels.

White space
-----------

Space characters are used to spread out logical statements, such as in
the condition of an if or while.  Spaces are placed between the
keyword and the brackets surrounding the condition, between the
brackets and the condition itself, and around binary operators (except
the structure access operators, '.' and '->'). e.g.

if ( (wibble & wombat) == 42 )
{
    ...

There should be no trailing white space at the end of lines (including
after the opening /* of a comment block).

Line Length
-----------

Lines should be less than 80 characters in length.  Long lines should
be split at sensible places and the trailing portions indented.

User visible strings (e.g., printk() messages) should not be split so
they can searched for more easily.

Bracing
-------

Braces ('{' and '}') are usually placed on a line of their own, except
for
- the do/while loop
- the opening brace in definitions of enum, struct, and union
- the opening brace in initializers
- compound literals
This is unlike the Linux coding style and unlike K&R.  do/while loops
are one exception. e.g.:

if ( condition )
{
    /* Do stuff. */
}
else
{
    /* Other stuff. */
}

while ( condition )
{
    /* Do stuff. */
}

do {
    /* Do stuff. */
} while ( condition );

etc.

Braces should be omitted for blocks with a single statement. e.g.,

if ( condition )
    single_statement();

Types
-----

Use basic C types and C standard mandated typedef-s where possible (and
with preference in this order).  This in particular means to avoid u8,
u16, etc despite those types continuing to exist in our code base.
Fixed width types should only be used when a fixed width quantity is
meant (which for example may be a value read from or to be written to a
register).

Especially with pointer types, whenever the pointed to object is not
(supposed to be) modified, qualify the pointed to type with "const".

Comments
--------

Only C style /* ... */ comments are to be used.  C++ style // comments
should not be used.  Multi-word comments should begin with a capital
letter.  Comments containing a single sentence may end with a full
stop; comments containing several sentences must have a full stop
after each sentence.

Multi-line comment blocks should start and end with comment markers on
separate lines and each line should begin with a leading '*'.

/*
 * Example, multi-line comment block.
 *
 * Note beginning and end markers on separate lines and leading '*'.
 */

Naming convention for files and command line options
----------------------------------------------------

'-' should be used to separate words in commandline options and filenames.
E.g. timer-works.

Note that some of the options and filenames are using '_'. This is now
deprecated.

Header inclusion guards
-----------------------

Unless otherwise specified, all header files should include proper
guards to prevent multiple inclusions. The following naming conventions
apply:

- Guard names are derived from directory path underneath xen/ and the
  actual file name.  Path components are separated by double
  underscores.  Alphabetic characters are converted to upper case.  Non-
  alphanumeric characters are replaced by single underscores.
- Certain directory components are omitted, to keep identifier length
  bounded:
  - the top level include/,
  - architecture-specific private files' arch/,
  - any architecture's arch/<arch>/include/asm/ collapses to
    ASM__<ARCH>__.

For example:

- Xen headers: XEN__<filename>_H
  - include/xen/something.h -> XEN__SOMETHING_H

- asm-generic headers: ASM_GENERIC__<filename>_H
  - include/asm-generic/something.h -> ASM_GENERIC__SOMETHING_H

- arch-specific headers: ASM__<architecture>__<subdir>__<filename>_H
  - arch/x86/include/asm/something.h -> ASM__X86__SOMETHING_H

- Private headers: <dir>__<filename>_H
  - arch/arm/arm64/lib/something.h -> ARM__ARM64__LIB__SOMETHING_H
  - arch/x86/lib/something.h -> X86__LIB__SOMETHING_H
  - common/something.h -> COMMON__SOMETHING_H

Note that this requires some discipline on the naming of future new
sub-directories: There shouldn't be any other asm/ one anywhere, for
example.  Nor should any new ports be named the same as top-level
(within xen/) directories.  Which may in turn require some care if any
new top-level directories were to be added.  Rule of thumb: Whenever
adding a new subdirectory, check the rules to prevent any potential
collisions.

Emacs local variables
---------------------

A comment block containing local variables for emacs is permitted at
the end of files.  It should be:

/*
 * Local variables:
 * mode: C
 * c-file-style: "BSD"
 * c-basic-offset: 4
 * indent-tabs-mode: nil
 * End:
 */
