Coding Conventions

These are style guidelines for code in libavg. They're not there to railroad anyone - the main reason for their existence is that uniform code is a lot easier to read and understand. If in doubt, look at existing code and use common sense.

(There are some places in the source code where the coding conventions aren't followed. Patches to fix this are welcome.)

General Guidelines

  • The language for all identifiers and comments is English.
  • Every file must start with the GNU LGPL license and copyright statement.
  • If significant contributions to the code were added by someone other than the copyright holder, a contributor line should mention this below the copyright statement.
  • Tab characters (except in makefiles) are not allowed.
  • Indent is by 4 characters.
  • Maximum line length is 90 characters. Lines broken by this rule are indented by 8 characters.
  • Reference documentation is in Sphinx format under libavg/sphinxdoc. Code without documentation is not accepted.

C++ Code

Files

  • Each c++ class should have its own interface (.h) and implementation file.
  • The filenames used are the exactly the classnames. Filenames for tests are all lowercase.
  • Exception 1: Small structs (<10 lines or so) can be in the same file as a full class if that makes sense semantically.
  • Exception 2: Classes that are only used by one other class can be defined entirely in the cpp file of that class. (This is the case for tests.)

Includes

Includes are ordered. Those files 'closest' to the including file come first, those furthest away last. This means that the first file included by an implementation file will be the corresponding header file. Then come headers in the same directory, other libavg headers and headers from outside of libavg - in that order.

Every header file has an include guard of the form:

1#ifndef _Classname_H_
2#define _Classname_H_
3...
4#endif

Naming

  • Class names are CamelCase.
  • Variable names are mixedCase and always start with a lower-case letter: pos, imagePos.
  • Member variables are prefixed by an m_: m_Pos, m_pBmp.
  • Statics are prefixed by an s_: s_BlobCount.
  • Some types have prefixes: p for pointers, b for bools, s for stl strings, h for handles: pBmp.
  • Everything is declared in the avg namespace.
  • Constants are all UPPERCASE.
  • Function names are verbs and capitalized like this: getImage(), open(), createNode(). (never distance() or size() - those are nouns)
  • Template parameters are all UPPERCASE.

Indentation, Braces, etc.

  • Each code line only contains one statement.
  • Each variable declaration is on a separate line.
  • Braces are used like this for code blocks (if, for, while...):
1if (bFoo) {
2...
3} else {
4...
5}

If the part before the opening brace is wrapped, the brace is moved to a separate line. if (and for, while etc.) statements always have at least 3 lines and always include opening and closing braces.

  • Braces for functions and class definitions look like this:
1Telephone::Telephone(string sPhoneNumber)
2{
3...
4}
  • Nothing that actually does something is placed inside an if statement. In particular, checking for errors is done in a separate statement:
1int err = m_pCamera->ReadQuadlet(advOffset+0x48, &imageDataFormat);
2if (err != CAM_SUCCESS) {
3...
4}

or better:

1int err = m_pCamera->ReadQuadlet(advOffset+0x48, &imageDataFormat);
2checkCMUError(err, 
3        "Unable to read firewire camera IMAGE_DATA_FORMAT register.");

Indentation generally shows the flow of control at runtime, not compile time. Thus, #ifdefs have no impact on indentation:

 1    bool bOk;
 2
 3#ifdef AVG_ENABLE_RPI
 4    m_xDisplay = (EGLNativeDisplayType)getBCMDisplay(pSDLWMInfo);
 5    m_Display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
 6#else
 7    m_xDisplay = (EGLNativeDisplayType)getX11Display(pSDLWMInfo);
 8    m_Display = eglGetDisplay(m_xDisplay);
 9#endif
10    checkEGLError(m_Display == EGL_NO_DISPLAY, "No EGL display available");

Nested preprocessor directives, however, have their own indentation hierarchy:

1#ifdef AVG_ENABLE_RPI
2    #include "BCMDisplay.h" 
3#else
4    #include "X11Display.h" 
5#endif

Indentation is ignored if the scope of the indentation would be the complete file. This is the case for include guards and namespace avg {} declarations.

Class Declaration Order

  • Class members are declared in the order public, protected, private.
  • All member variables are private.
  • Constructors and destructors are declared first, then other methods, then member variables.

Error Reporting

Errors are reported using asserts, exceptions and (seldom) error return codes:

  • asserts are used when an inconsistent state is detected that has its cause in a bug in libavg itself.
  • Exceptions are used for all other errors, including errors that are caused by the user of the library (i.e. python code).
  • Error return codes are only used in speed-critical situations.

Python Code

(Guidelines based loosely on http://www.python.org/dev/peps/pep-0008/)

Files

  • File (and thus module) names are all lowercase without underscores.
  • File encoding is UTF-8.
  • The first two lines of every file look like this:
1#!/usr/bin/env python
2# -*- coding: utf-8 -*-

Naming

  • protected methods are prefixed by an underscore:
1def _callFromSubClass(self):
  • private methods are prefixed by two underscores:
1def __internalUseOnly(self):
  • Class names are CamelCase.
  • Variable names are mixedCase.
  • Global variables are prefixed with g_: g_GameState.
  • Function names are mixedCase as well. Use verbs for function names: getIllumination().

Blank Lines and Whitespace

  • Top-level functions and class definitions are separated with two blank lines.
  • Method definitions inside a class are separated by a single blank line.
  • Examples for correct whitespace formatting:
1bar[1]
2foo(2)
3dict['key'] = 'flup'
4foo(bar[1], {baz: 4})
5
6if x == 4:
7    print x, y

Compound Statements

  • No more than one statement per line.
  • Always separate an if statement from its body by a line break:
1if bork:
2    fizz()

Imports

  • Imports are at the top of a file, directly after copyright and (possibly) docstrings.
  • Imports are grouped in the following order:
    1. Standard library imports
    2. Third party imports
    3. Local application/library imports

Shaders

Apply the C++ guidelines. In addition, there are prefixes for the different types of shader variables:

  • u_: Uniform variable, Passed from CPU code to a shader.
  • a_: Per-vertex attribute - Part of a vertex array and input to a vertex shader.
  • v_: Varying variable: Output from a vertex shader, input to a fragment shader.