Coding Style

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.

This document will describe the indentation, formatting, doxygen comments, class naming, and naming conventions to use.

2.2 Prefix and Directory Structure changes

In the v2.2 release of Apache Traffic Server, we made some changes to prefixes, and directory structure. Some of this work is still undergoing, see this page for additional details. The most important part of these changes is the semantics of the prefix name spaces:

Public APIs (ts/ts.h, ts/experimental.h etc.)

The prefix to use for these include files and underlying code in e.g. InkAPI.cc is one of

In addition, none of these methods, struct names or definitions should be used in the core itself, other than the actual API implementations (InkAPI.cc etc.).

Internal code

For all other code that's internal, the prefix should be one of

No new code / functionality should be added using the ink/INK prefix. Long term, we will migrate these into the ats/ATS prefix. Adhering to these rules is important, the goal is to be able to easily distinguish public from private APIs. In the past, we've had several cases where public APIs were used in the private code implementation, and this is a bad idea for both performance and functionality.

Header files

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.

#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

(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

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.

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

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

Naming conventions

Classes and Structures

Methods

Member Variables

Comments

TODO comments

Example of comment TODO:

  // TODO handle case for negative config value

Notice the format:

XXX comments

Example of XXX:

  // XXX Hazardous code! We should find a way to make
  //     it more secure

Notice the format: