DUE TO SPAM, SIGN-UP IS DISABLED. Goto Selfserve wiki signup and request an account.
...
This document described the coding style for the Apache Traffic Server project. The document is still evolving, but all contributors and committers are encourage to read this before contributing patches. And as usual, additions and edits to this document is appreciated, to assure that we all share the same coding style. For major changes to the style, a discussion should be opened on the dev@ mailing before changed here.
Contents
| Table of Contents |
|---|
Overview
Code indentation and formatting was completely standardized prior to open sourcing the Apache Traffic Server code. Command line tool indent did most of the heavy lifting.
...
In most subsystems, header files are named with a P_ or I_ prefix. P_ files should contain any types and definitions that are private to the subsystem, while the public interface should be contained in a I_-prefixed header.
Sample Code
This document relies on code samples which are below to demonstrate most of the rules used on the Apache Traffic Server project.
| Code Block | ||||
|---|---|---|---|---|
| ||||
#include <iostream>
using namespace std;
namespace ts
{
/**
* @brief Demonstrates how to format code
* This class demonstrates to developers how we should structure code
*/
class Counter
{
public:
Counter():_count(0), _totalCount(0) { }
/**
* @brief Increments the count by one or an optional value
* @param delta The amount to increment the count, default is 1
*/
void increment(int delta = 1) {
_count += delta;
}
/**
* @brief Returns the count value
* @return Count value
*/
int getCount() const { // try to use const as much as possible
return _count;
}
private: // try to hide data
void _helpers() { _foo++; }
int _count; /// if there is something special to say
int _totalCount;
protected:
void _anotherHelper() { _foo++; }
int _foo;
};
}
/**
* @brief This is the main function for the program
*/
int
main()
{
ts::Counter x;
if (x.getCount() == 0) {
x.increment();
} else {
// make sure to always use braces for conditionals
}
// increment the counter 10 times
for (int i = 0; i < 10; ++i) {
x.increment();
}
cout << x.getCount() << endl;
}
|
Indentation and Formatting
This style is mostly K&R. Using the GNU indent command line tool as a definition of the K&R style, below is described in detail what options make up the -kr option for the tool and how this style differs. It is also worth noting that most of these formatting rules are mainly defaults from emacs, except for the indentation, so hitting TAB to indent the code in emacs will work well.
Emacs
The corresponding .emacs settings for our style is
| Code Block |
|---|
(c-add-style "trafficserver"
'((inclass . ++)
(defun-block-intro . ++)
(statement-block-intro . ++)
(substatement . ++)
(brace-list-intro . ++)
(statement-case-intro . ++)
(inextern-lang . 0)
))
(setq-default indent-tabs-mode nil)
|
Vim / vi
For .vimrc, this style is
| Code Block |
|---|
set tabstop=2
set softtabstop=2
set shiftwidth=2
set expandtab
set textwidth=120
|
Using indent
There is a .indent.pro file in the top level of the source tree for Traffic Server. This will be used automaticly when invoking indent from the top level directory.
| Code Block |
|---|
# running indent from the top level directory on the file proxy/Main.cc
$ indent proxy/Main.cc
|
Below is a manually way of specifying the options we use.
| Code Block |
|---|
# use indent with the following commands
$ alias indent='indent -nut -nbad -bap -nbbo -nbc -br -bls -ce -ci2 -cli0 -cs -d0 -di2 -nfc1 -nfca -hnl -i2 -ip0 -l120 -lp -npcs -nprs -psl -saf -sai -saw -nsc -nsob -nss'
$ indent foo.cc
|
The -kr option or "common style" is described as:
-nbad -bap -bbo -nbc -br -brs -c33 -cd33 -ncdb -ce -ci4 -cli0
-cp33 -cs -d0 -di1 -nfc1 -nfca -hnl -i4 -ip0 -l75 -lp -npcs
-nprs -npsl -saf -sai -saw -nsc -nsob -ns
The code sample above can be closely formated by using the following options. Because of the number of variations of how code can be structured, indent will give a close and workable solution.
-nbad -bap -nbbo -nbc -br -bls -ce -ci2 -cli0
-cs -d0 -di2 -nfc1 -nfca -hnl -i2 -ip0 -l120 -lp -npcs
-nprs -npsl -saf -sai -saw -nsc -nsob -nss
Below describes each option of K&R and how the modified list of options differ from it. To sum up the major differences, comment structure is ignored mostly to work well with doxygen and indentation is changed from 4 spaces to 2 spaces.
- -nut - No tabs in the source (for the love of god, don't put tabs in source code)
- -nbad - no blank lines after declarations
Code Block char *foo; char *bar; /* no blank line above */ char *baz;
- -bap - blank line after every procedure body
Code Block int foo() { puts("Hi"); } int bar() { puts("Hello"); }
- -nbbo - break long lines after the boolean operators && and || (different from K&R and GNU)
Code Block if (cache_sm.cache_write_vc == NULL && t_state.cache_info.write_lock_state == HttpTransact::CACHE_WL_INIT)
- -nbc - no blank lines after commas
Code Block int a, b, c
- -br - braces on the same line and the conditional
Code Block if (x > 0) { --x; }
- -bls - braces on separate lines for structs and classes (different from K&R, same as GNU)
Code Block struct foo { int x; };
- -c33 & -cd33 - comments to the right of code start at column 33 (removed, only in K&R)
- -ncdb - (removed, only in K&R)
- -ce - if-then-else construct to "cuddle up" to the immediately preceding '}'
Code Block if (x > 0) { --x; } else { cout << "hello world"; }
- -ci2 - continuation indentation of 2 spaces (different then K&R, reduced to 2 spaces)
- -cli0 - number of space3s that case labels should be indented to the right of the switch statement
Code Block switch (i) { case 0: break; default: break; }
- -cp33 - comments on #else and #endif statements on column 33 (removed, only in K&R)
- -cs - space after cast
Code Block foo = (int) bar;
- -di2 - indentation of declarations on separate lines (different then K&R, increased to 2)
Code Block int x, y;
- -nfc1 & -nfca - don't format any comments
- -hnl - prefer to break long lines at the position of the newlines
- -i2 - indent level (different then K&R, decreased from 4 to 2)
- -ip0 - parameter indentation
- -l120 - break long lines at 120 columns
- -lp - indentation for continuation of parameters
Code Block p1 = first_procedure(second_procedure (p2, p3), third_procedure (p4, p5));
- -npcs - no space after function call names
Code Block foo(bar);
- -nprs - no space after parentheses
Code Block foo((x - 1));
- -npsl - don't break procedure type
Code Block int foo(char *s) { }
- -saf - space after each for
Code Block for (int i = 10; i > 0; --i) { // do something }
- -sai - space after each if
- -saw - space after each while
- -nsc - don't but '' at the left of comments *(removed, only in K&R)
- -nsob - don't remove optional blank lines
- -nss - don't put a space before the semicolon
Code Block int x;
Indentation
We have changed from the previous indentation rules, to rely completely on clang-format. The style is mostly the same as it was before, which means:
- 2-space indentation (never tabs)
- 132-character wide lines
- A clang-format based primarily on the Mozilla formatting. But, note that we have our own .clang-format in the top-level of the source tree.
The easiest way to format the code is to simply run
| Code Block |
|---|
$ make clang-format
|
You can also explicitly format one (or several) source files with clang-format directly. Make sure you run it from the top-level directory, which has the necessary .clang-format configuration file. E.g.
| Code Block |
|---|
$ clang-format -i proxy/logging/LogAccessHttp.cc
|
clang-format binary and configuration
You must use the same clang-format binary as everyone else is. This is unfortunate, but is a side effect of how the clang-format team manages their code. You can download the current version, from March 31th 2015. Alternatively, you can build your own version from the clang / llvm source tree, but the tar-ball above includes binaries for both Linux and OS X. You have to copy either of these into somewhere your $PATH will locate, and rename it to just clang format. E.g.
| Code Block |
|---|
$ tar xf clang-format-20150331.tar.bz2
$ sudo mv clang-format/clang-format.linux /usr/local/bin/clang-format |
In addition to the binaries, there is a git script as well as en Emacs mode for clang-format.
Naming conventions
Classes and Structures
...
Example of comment TODO:
| Code Block |
|---|
// TODO handle case for negative config value
|
...
Example of XXX:
| Code Block |
|---|
// XXX Hazardous code! We should find a way to make
// it more secure
|
...
When your case will fall through, please add the no break comment with other more detialed comments at the end of the code block.
Example of no break:
| Code Block |
|---|
switch (*cur) {
case ']' : // address close
n_colon = MAX_COLON - 1;
/* no break */
/* fall through until ... */
case ':' : // track colons, fail if too many.
|
...