276 lines
7.9 KiB
Markdown
276 lines
7.9 KiB
Markdown
This document specifies the coding style for Broker. The style is based on
|
|
[CAF's][caf-style] and [VAST's][vast-style] style guidelines.
|
|
|
|
Git Workflow
|
|
============
|
|
|
|
Broker's git workflow follows [Zeek's development process][zeek-dev-proc]. In a
|
|
nutshell, this means:
|
|
|
|
- The `master` branch reflects the latest state of development and should
|
|
always compile.
|
|
|
|
- For new features and non-trivial fixes, use *topic branches* that branch off
|
|
`master` with a naming convention of `topic/description` or
|
|
`topic/your-name/description`. After completing work in a topic branch, check
|
|
the following steps to prepare for a merge back into `master`:
|
|
|
|
+ Squash your commits into a single one if necessary
|
|
+ Create a pull request to `master` on the [Broker github][broker-github]
|
|
+ Ask a maintainer to review your work
|
|
+ Address the feedback articulated during the review
|
|
+ A maintainer will merge the topic branch into `master` after it passes the
|
|
code review
|
|
|
|
Commit Messages
|
|
---------------
|
|
|
|
When writing commit messages, use the following style:
|
|
|
|
- The first line succinctly summarizes the changes in no more than 50
|
|
characters. It is capitalized and written in and imperative present tense:
|
|
e.g., "Fix bug" as opposed to "Fixes bug" or "Fixed bug".
|
|
|
|
- The first line does not contain a dot at the end. (Think of it as the header
|
|
of the following description.)
|
|
|
|
- The second line is empty.
|
|
|
|
- Optional long descriptions as full sentences begin on the third line,
|
|
indented at 72 characters per line.
|
|
|
|
Coding Style
|
|
============
|
|
|
|
General
|
|
-------
|
|
|
|
- Use 2 spaces per indentation level.
|
|
|
|
- No tabs, ever.
|
|
|
|
- No C-style casts, ever.
|
|
|
|
- 80 characters max per line.
|
|
|
|
- Minimize vertical whitespace within functions. Use comments to separate
|
|
logical code blocks.
|
|
|
|
- Namespaces and access modifiers (e.g., `public`) do not increase the
|
|
indentation level.
|
|
|
|
- The `const` keyword preceeds the type, e.g., `const T&` as opposed to
|
|
`T const&`.
|
|
|
|
- `*` and `&` bind to the *type*, e.g., `const T& arg`.
|
|
|
|
- Always use `auto` to declare a variable unless you cannot initialize it
|
|
immediately or if you actually want a type conversion. In the latter case,
|
|
provide a comment why this conversion is necessary.
|
|
|
|
- Never use unwrapped, manual resource management such as `new` and `delete`.
|
|
|
|
- Never use `typedef`; always write `using T = X` in favor of `typedef X T`.
|
|
|
|
- Keywords are always followed by a whitespace: `if (...)`, `template <...>`,
|
|
`while (...)`, etc.
|
|
|
|
- Leave a whitespace after `!` to make negations easily recognizable.
|
|
|
|
```cpp
|
|
if (! sunny())
|
|
stay_home()
|
|
```
|
|
|
|
- Opening braces belong onto the same line:
|
|
|
|
```cpp
|
|
struct foo {
|
|
void f() {
|
|
}
|
|
};
|
|
```
|
|
|
|
- Do not use the `inline` keyword unless to avoid duplicate symbols. The
|
|
compiler does a better job at figuring out what functions should be inlined.
|
|
|
|
Header
|
|
------
|
|
|
|
- Header filenames end in `.hh`, implementation filenames in `.cc` and files for
|
|
unit tests end in `.test.cc`.
|
|
|
|
- All header files should use `#pragma once` to prevent multiple inclusion.
|
|
|
|
- Don't use `#include` when a forward declarations suffices. It can make sense
|
|
to outsource forward declarations into a separate file per module. The file
|
|
name should be `<MODULE>/fwd.h`.
|
|
|
|
- Include order is from low-level to high-level headers, e.g.,
|
|
|
|
```cpp
|
|
#include <sys/types.h>
|
|
|
|
#include <memory>
|
|
|
|
#include <3rd/party.hpp>
|
|
|
|
#include "broker/endpoint.hh"
|
|
```
|
|
|
|
Within each section the order should be alphabetical. Broker includes should
|
|
always be in double quotes and relative to the source directory, whereas
|
|
system-wide includes in angle brackets.
|
|
|
|
- As in the standard library, the order of parameters when declaring a function
|
|
is: inputs, then outputs. API coherence and symmetry trumps this rule, e.g.,
|
|
when the first argument of related functions model the same concept.
|
|
|
|
Classes
|
|
-------
|
|
|
|
- Use the order `public`, `proctected`, `private` for functions and members in
|
|
classes.
|
|
|
|
- Mark single-argument constructors as `explicit` to avoid implicit
|
|
conversions.
|
|
|
|
- The order of member functions within a class is: constructors, operators,
|
|
mutating members, accessors.
|
|
|
|
- Friends first: put friend declaration immediate after opening the class.
|
|
|
|
- Use structs for state-less classes or when the API is the struct's state.
|
|
|
|
- Prefer types with value semantics over reference semantics.
|
|
|
|
- Use the [rule of zero or rule of
|
|
five](http://en.cppreference.com/w/cpp/language/rule_of_three).
|
|
|
|
- When providing a move constructor and move-assignment operator, declare them
|
|
as `noexcept`.
|
|
|
|
Naming
|
|
------
|
|
|
|
- Class names, constants, and function names are lowercase with underscores.
|
|
|
|
- Template parameter types should be written in CamelCase.
|
|
|
|
- Types and variables should be nouns, while functions performing an action
|
|
should be "command" verbs. Getter and setter functions should be nouns. We do
|
|
not use an explicit `get_` or `set_` prefix. Classes used to implement
|
|
metaprogramming functions also should use verbs, e.g., `remove_const`.
|
|
|
|
- All library macros should start with `BROKER_` to avoid potential clashes
|
|
with external libraries.
|
|
|
|
- Names of (i) classes/structs, (ii) functions, and (iii) enums should be
|
|
lower case and delimited by underscores.
|
|
|
|
- Put non-API implementation into namespace `detail`.
|
|
|
|
- Member variables have an underscore (`_`) as suffix, unless they constitute
|
|
the public interface. Getters and setters use the same member name without
|
|
the suffix.
|
|
|
|
- Put static non-const variables in an anonymous namespace.
|
|
|
|
Breaking Statements
|
|
-------------------
|
|
|
|
- Break constructor initializers after the comma, use two spaces for
|
|
indentation, and place each initializer on its own line (unless you don't
|
|
need to break at all):
|
|
|
|
```cpp
|
|
my_class::my_class()
|
|
: my_base_class{some_function()},
|
|
greeting_{"Hello there! This is my_class!"},
|
|
some_bool_flag_{false} {
|
|
// ok
|
|
}
|
|
other_class::other_class() : name_{"tommy"}, buddy_{"michael"} {
|
|
// ok
|
|
}
|
|
```
|
|
|
|
- Break function arguments after the comma for both declaration and invocation:
|
|
|
|
```cpp
|
|
a_rather_long_return_type f(std::string const& x,
|
|
std::string const& y) {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
- Break before binary and ternary operators:
|
|
|
|
```cpp
|
|
if (today_is_a_sunny_day()
|
|
&& it_is_not_too_hot_to_go_swimming()) {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
Template Metaprogramming
|
|
------------------------
|
|
|
|
- Use the `typename` keyword only to access dependent types. For general
|
|
template parameters, use `class` instead:
|
|
|
|
```cpp
|
|
template <class T>
|
|
auto f(typename T::type dependent) {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
- Use `T` for generic, unconstrained template parameters and `x` for generic
|
|
function arguments. Suffix both with `s` for template parameter packs:
|
|
|
|
```cpp
|
|
template <class T, class... Ts>
|
|
auto f(T x, Ts... xs) {
|
|
// ...
|
|
}
|
|
```
|
|
|
|
- Break `using name = ...` statements always directly after `=` if they do not
|
|
fit in one line.
|
|
|
|
- Use one level of indentation per "open" template and place the closing `>`,
|
|
`>::type` or `>::value` on its own line. For example:
|
|
```cpp
|
|
using optional_result_type =
|
|
typename std::conditional<
|
|
std::is_same<result_type, void>::value,
|
|
bool,
|
|
optional<result_type>
|
|
>::type;
|
|
```
|
|
|
|
- When dealing with "ordinary" templates, use indentation based on the position
|
|
of the last opening `<`:
|
|
```cpp
|
|
using type = quite_a_long_template_which_needs_a_break<std::string,
|
|
double>;
|
|
```
|
|
|
|
Comments
|
|
--------
|
|
|
|
- Doxygen comments start with `///`.
|
|
|
|
- Use Markdown instead of Doxygen formatters.
|
|
|
|
- Use `@cmd` rather than `\cmd`.
|
|
|
|
- Use `//` or `/*` and `*/` to define basic comments that should not be
|
|
swallowed by Doxygen.
|
|
|
|
[caf-style]: https://github.com/actor-framework/actor-framework/blob/master/CONTRIBUTING.md
|
|
[vast-style]: https://github.com/mavam/vast/blob/master/CONTRIBUTING.md
|
|
[zeek-dev-proc]: https://www.zeek.org/development/howtos/process.html
|
|
[broker-github]: https://github.com/zeek/broker
|