XMMS2 Coding Style

Erik Massop edited this page Nov 4, 2017 · 1 revision

This document describes the coding style to be used when working on code that is maintained as part of the XMMS2 codebase. This includes everything in the main tree: the daemon, libraries, some plugins and clients. It does not apply to third party XMMS2 clients.

Consider this as an informational guide - it is here simply to provide a common style that all XMMS2 developers and contributors can refer to, and rely on. A lot of this is from http://lxr.linux.no/source/Documentation/CodingStyle The sections below apply to C, as well as other languages, unless otherwise indicated. For python style please read PEP 8.

Indentation

  • Single tabs (\t)
  • Tabs are usually equivalent to 8 characters in length. However, XMMS2 code should be written with a tab-width of 4 characters. (This affects the line length, as discussed in the next section) Note that tabs should not be substituted with 4 real spaces (soft tabs); use an actual tab character. (some editors, such as vim, may do this, depending on settings )
  • "The whole idea behind indentation is to clearly define where a block of control starts and ends." 1 Always indent when needed - that is, after if, do, while statements, function declarations (void foo (bar)), and so on.
  • Tabs are only used for indentation of code blocks, everything should be tab-width agnostic (indented with spaces instead of tabs if needed). (see point below)
  • When defining an argument list over multiple lines, the lines should be indented with the same number of tabs as the first line, then supplemented with spaces such that the argument lines up under the opening brace of the argument list. For example:

[tab][tab][tab]foo_function (arg1, [tab][tab][tab]              arg2, [tab][tab][tab]              arg3)

NOT:

[tab][tab][tab]foo_function (arg1, [tab][tab][tab][tab][tab]    arg2, [tab][tab][tab][tab][tab]    arg3)

(see Emacs C style adapted from LDP, or SmartTabs plugin for vim)

Arguments

Arguments to code constructs and functions should always have a space between the construct or function name and the open parenthesis. The same goes for functions that take no arguments:

call_foo (arg1, arg2); call_bar ();

NOT:

call_foo(arg1, arg2); call_bar();

Variable declarations

  • Variables should only be declared in beginning of blocks.
  • Don't declare variables of different types on same line.

/* Don't: */ int i, *p; /* Do: */ int i; int *p;

Breaking long lines and strings

  • Lines should not be longer than 80 characters (columns) long. (Note that this assumes 4-character long tab widths for indents)
  • "Statements longer than 80 columns will be broken into sensible chunks. Descendants are always substantially shorter than the parent and are placed substantially to the right. The same applies to function headers with a long argument list. Long strings are as well broken into shorter strings." 2
  • See section above for example how to indent the continuation lines with spaces instead of tabs for the part that is indented more than the first line in multi line statements.

Placing Braces

  • An opening brace must be last on the relevant line. 3
  • An exception to the above guideline is for function declarations, where the opening brace is at the beginning of the next line. 4
  • "Note that the closing brace is empty on a line of its own, _except_ in the cases where it is followed by a continuation of the same statement, ie a "while" in a do-statement or an "else" in an if-statement [...]" 5
  • Braces shall always be used, even if the block is a one-liner.
  • These guidelines do not apply to certain languages, e.g. Python

Naming

  • Use descriptive names for global variables and functions.
  • Local variables should be short and to the point.
  • Public functions should be named xmms(c)_module_action
    • Examples: xmms_frobnozzle_activate, xmms_frobnoozle_shutdown
  • Public getters/setters should be named xmms(c)_module_attribute_get(_type)
    • Examples: xmms_frobnozzle_speed_get, xmms_frobnozzle_config_set_str
  • (add thing about xmms_something_do and xmms_something_do_full, where first is just a shortcut for second with the arguments for the default usecase already filled in)

Functions

  • "Functions should be short and sweet, and do just one thing. They should fit on one or two screenfuls of text (the ISO/ANSI screen size is 80x24, as we all know), and do one thing and do that well." 6 (Functional cohesion)
  • For complex functions, break the code up into helper functions, or inline code if performance-critical. 7
  • Try to keep the number of local variables in a function around 7 (plus or minus two or three). If more variables are needed, think about splitting the code into multiple functions. 8

Centralised exiting of functions

  • Functions should generally have a single exit (return) point.

Trailing whitespace

  • Avoid trailing whitespace.

Vim users put this in your .gvimrc:

highlight WhitespaceEOL ctermbg=red guibg=red match WhitespaceEOL /\s\+$/

Commenting and Documentation

  • Comments should explain what the code is doing, not how. The how should be more or less obvious from the way the code is written.
  • Generally try to avoid putting comments in a function body - put comments at the head of the function instead (explaining what the function does)
  • C code should use C89-style comments only:

 /* this is a C89 comment */  // This is a C99/C++ comment, not a C89 comment

  • Code is generally documented using Doxygen. Please learn how to use this tool, if you want to contribute code to XMMS2.
  • Doxygen comments should be in the following form. Imperative tense should be used (i.e. "Activate frobnozzle gadget" NOT "Activates frobnozzle gadget"). The first sentence should be short and just give an extremely brief description. Detailed description should be in the following sentences. The comment text should start on the next line AFTER "/**". There should be an empty line between the description and params/return value. The "*" on the continued lines should be lined up with the FIRST asterisk in "/**"

/**  * Activate frobnozzle gadget.  * Initialize and set the gadgets state to active, allowing it to process  * frobnozzle data.  *  * @param gadget gadget to activate  * @return status true if successfully activated  */ gboolean frobnozzle_gadget_activate (gadget_t *gadget) {  /* ... */ }

  • Python code, on the other hand, is documented using Pydoc and is rather easy to learn.

Macros, Enums, Inline functions and RTL

  • Names of macros defining constants and labels in enums should be capitalized. 9
  • Macro names should be capitalised.
Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.