1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215
|
OpenVPN 3 Linux coding style guide
==================================
The OpenVPN 3 Linux project uses a coding style which aims to be closer
to the OpenVPN 2.x project. But there are several cases where the coding
style needs to be extended, due to the natural difference between C and
C++.
In addition, the OpenVPN 3 Core Library is loosely based on the GNU style,
which is often quite different. This coding style is isolated to the
openvpn3-core directory and should not be used in OpenVPN 3 Linux at all.
Basic guideline
---------------
The coding style is mostly based on the Allman/BSD coding style, but with
a few minor tweaks.
- Spaces only. NO tabs.
- Indenting is 4 spaces.
- Line length less than 78 chars as much as possible.
- Ensure readability, don't be worried adding spaces and blank lines.
- Using the C++11 mandatory. Do not use newer features if not available
or functional with compilers only supporting C++11.
- Use C++11 features and constructs over older C++ and C standards.
Naming conventions
------------------
Main goal: Readability. It should be quick and easy to separate even
quite similar names based on the writing style.
### Classes
Class names is based on camel case where multiple following capital letters
are allowed, like `OpenVPNexampleClass`. Another example is
`ExampleClass`.
### Class method names
Public methods should always start with a a capital letter. Otherwise,
similar camel case style can be used, like: `ExampleMethod()`.
Private and protected methods should always be lower case. To separate
words, use underscore/underbar (`_`), like: `example_method()`
### Function names
Functions are always defined outside a class, and pure functions should
be using lower-case names only. Static functions which are only available
inside the single source file can carry a separate identified to make it
clear this is a scope local function.
### Variables and variable names
Variable names should normally be lower case only and longer explanatory
names are better. So instead if `int i` it is preferred `int counter`.
Private members may have an underscore (`_`) after the name, like:
`int private_variable_`
Variables being assigned with a value or being compared should always have
spaces between the name, the operator and the value.
```cpp
int i = 0;
bool equal = (4 == i);
```
Member (variable) access
------------------------
Member variables should in classes normally only be accessed via getter
and setter methods. For struct, where members are public by default,
direct access is fine.
Namespaces
----------
Namespaces may be used, but the `openvpn` namespace is reserved for the
OpenVPN 3 Core library (files under `openvpn3-core/`). Nesting namespaces
can be done, but no indenting is needed when declaring the namespace chain.
Anything defined inside the namespace must be indented.
The closing bracket of the namespace clearly must declare which namespace
is being closed.
```cpp
namespace NS1
{
namespace NS2
{
namespace NS3
{
int some_variable; // This is accessed as NS1::NS2::NS3::some_variable
} // namespace NS3
} // namespace NS2
} // namespace NS1
```
Class declarations
------------------
```cpp
/**
* Simple explanation in doxygen style clarifying what
* this class provides
*/
class ExampleWidget : public ParentClassOne,
public ParentClassTwo
{
public:
/**
* (Optional) constructor documentation
* explaining arguments and what it constructs
*/
ExampleWidget(std::string name)
: ParentClassOne(name),
ParentClassTwo()
{
}
/**
* Doxygen formatted documentation for the
* method
*
* @param arg std::string provides an argument....
*
*/
void ExampleMethod(std::string arg)
{
}
/**
* Similar documentation, this documentation is kept
* at the main declaration in the class and not
* at the method implementation if this is split up
*
* @param arg1 int containing the first argument
* @param arg2 int containing the second argument
*
* @return Explain what this method returns
*/
int Sum(int arg1, int arg2);
/**
* (similar to above, simplifying here to avoid duplication)
* Arguments are aligned as the example below
*/
bool CompareValues(SomeClass obj_a, SomeClass obj_b,
SomeOtherClass obj_other);
private:
int val1 = 0; ///< Doxygen comment describing a single member
void do_some_magic()
{
// Magic happens here
}
}
int ExampleWidget::sum(int arg1, arg2)
{
// Do something clever with arg1 and arg2
do_some_magic();
}
```
Classes are separated with minimum 2 blank lines. Methods as well as
public/protected/private sections are separated with 2 blank lines.
Keywords
--------
C++ keywords, like `if`, `for`, `while` and related ones will always carry
a space before any brackets. Curly braces are mandatory for all loop and
conditional statements.
```cpp
for (const auto& j : some_list)
{
std::cout << j << std::endl;
}
while (!done)
{
// do something
}
if (4 == variable)
{
}
```
Also note that the left side of a comparison operator should be the one
least likely to be modifiable. This avoids errors like:
```cpp
if (i = 3) // BAD BAD BAD
{
// This is incorrect and some compilers might accept it
// without warning of assignment operation
}
```
For-loops
---------
For-loops should use C++ iterators as much as possible, wherever it makes
sense. The variable used to contain the iterated value should be declared
as `const auto&`.
|