361 lines
8.4 KiB
Plaintext
361 lines
8.4 KiB
Plaintext
This file contains coding guidelines for VMime. You should follow them
|
|
if you want to contribute to VMime. The rules below are not guidelines
|
|
or recommendations, but strict rules.
|
|
|
|
|
|
1. General rules
|
|
1.1. Language
|
|
1.2. Unit tests
|
|
1.3. Version Control
|
|
1.4. Warnings
|
|
2. Style, indentation and braces
|
|
2.1. Indentation
|
|
2.2. Brace position
|
|
2.3. "switch" statement
|
|
2.4. Single instruction
|
|
2.5. Line length
|
|
2.6. Spaces and parentheses
|
|
2.7. End-of-line character
|
|
2.8. Short functions
|
|
2.9. Limit Variable Scope
|
|
3. Naming conventions
|
|
3.1. Classes
|
|
3.2. Variables/parameters/member variables
|
|
3.3. Member variables
|
|
3.4. Files
|
|
3.5. Namespaces
|
|
3.6. Constants
|
|
4. Comments
|
|
5. Miscellaneous
|
|
|
|
|
|
|
|
1. General rules
|
|
================
|
|
|
|
1.1. Language
|
|
-------------
|
|
|
|
The project language is English. All comments, variable names, class names,
|
|
commit messages and so on, must be in English.
|
|
|
|
|
|
1.2. Unit tests
|
|
---------------
|
|
|
|
Unit tests are very important. For each new class you write, you should also
|
|
write a unit test for it. If you write a new method, add a new test case in
|
|
the unit test of the class.
|
|
|
|
When you fix a bug, also add a new test case to ensure the bug will not
|
|
happen anymore.
|
|
|
|
|
|
1.3. Version Control
|
|
--------------------
|
|
|
|
Each commit MUST be done with a message ('-m' flag) that briefly describes what
|
|
changes have been done.
|
|
|
|
DO NOT use commit messages like -m "Updated"!
|
|
|
|
|
|
1.4. Warnings
|
|
-------------
|
|
|
|
The code should compile WITHOUT ANY WARNING, even those for unused parameters!
|
|
|
|
|
|
|
|
2. Style, indentation and braces
|
|
================================
|
|
|
|
2.1. Indentation
|
|
----------------
|
|
|
|
Use TABS (ASCII character #9) and _not_ SPACES. This allow everyone to set tab
|
|
width to its preferred settings (eg. 4 or 8 spaces).
|
|
|
|
|
|
2.2. Brace position
|
|
-------------------
|
|
|
|
Open braces should always be at the end of the line of the statement that
|
|
begins the block. Contents of the brace should be indented by 1 tab.
|
|
|
|
if (expr) {
|
|
|
|
do_something();
|
|
do_another_thing();
|
|
|
|
} else {
|
|
|
|
do_something_else();
|
|
}
|
|
|
|
In a function, the opening brace must always be followed by an empty line:
|
|
|
|
void header::appendField(const shared_ptr <headerField>& field) {
|
|
|
|
m_fields.push_back(field);
|
|
}
|
|
|
|
A function with few arguments:
|
|
|
|
bool header::hasField(const string& fieldName) const {
|
|
|
|
...
|
|
}
|
|
|
|
A function with more arguments:
|
|
|
|
void header::parseImpl(
|
|
const parsingContext& ctx,
|
|
const string& buffer,
|
|
const size_t position,
|
|
const size_t end,
|
|
size_t* newPosition
|
|
) {
|
|
|
|
...
|
|
}
|
|
|
|
|
|
2.3. "switch" statement
|
|
-----------------------
|
|
|
|
switch (expr) {
|
|
|
|
case 0:
|
|
|
|
something;
|
|
break;
|
|
|
|
case 1:
|
|
|
|
something_else;
|
|
break;
|
|
|
|
case 2: {
|
|
|
|
int var = 42;
|
|
another_thing;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
2.4. Single instruction
|
|
-----------------------
|
|
|
|
Don't omit braces around simple single-statement body:
|
|
|
|
if (...) {
|
|
something;
|
|
}
|
|
|
|
and not:
|
|
|
|
if (...)
|
|
something;
|
|
|
|
|
|
2.5. Line length
|
|
----------------
|
|
|
|
If possible, each line of text should not exceed 100 characters, except if
|
|
manual line wrapping breaks code clarity.
|
|
|
|
Exception: if a comment line contains an example command or a literal URL
|
|
longer than 100 characters, that line may be longer than 100 characters
|
|
for ease of cut and paste.
|
|
|
|
|
|
2.6. Spaces and parentheses
|
|
---------------------------
|
|
|
|
Put spaces around operators: =, >, <, !=, +, -, /, *, ^, %, ||, &&, &, |:
|
|
|
|
x = (a * (b + (c - d)))
|
|
|
|
Do not put spaces around parentheses.
|
|
|
|
if ((a == b) || (c == d))
|
|
|
|
Do not put spaces around "->":
|
|
|
|
object->method()
|
|
|
|
Do not put spaces inside brackets:
|
|
|
|
x = array[index] and _NOT_: x = array[ index ]
|
|
|
|
Do not use space between a function name and parenthesis. No extra spaces
|
|
between parameters and arguments, just after commas:
|
|
|
|
method(arg1, arg2, ...)
|
|
|
|
Do use a single space before flow control statements:
|
|
|
|
while (x == y) and _NOT_: while(x==y)
|
|
|
|
|
|
2.7. End-of-line character
|
|
--------------------------
|
|
|
|
Configure your editor to use "\n" (UNIX convention) for end-of-line sequence,
|
|
and not "\r\n" (Windows), nor "\n\r", nor any other combination.
|
|
|
|
|
|
2.8. Short functions
|
|
--------------------
|
|
|
|
To the extent that it is feasible, functions should be kept small and focused.
|
|
It is, however, recognized that long functions are sometimes appropriate, so no
|
|
hard limit is placed on method length. If a function exceeds 40 lines or so,
|
|
think about whether it can be broken up without harming the structure of the
|
|
program.
|
|
|
|
|
|
2.9. Limit Variable Scope
|
|
-------------------------
|
|
|
|
The scope of local variables should be kept to a minimum. By doing so, you
|
|
increase the readability and maintainability of your code and reduce the
|
|
likelihood of error. Each variable should be declared in the innermost block
|
|
that encloses all uses of the variable.
|
|
|
|
Local variables should be declared at the point they are first used. Nearly
|
|
every local variable declaration should contain an initializer. If you don't
|
|
yet have enough information to initialize a variable sensibly, you should
|
|
postpone the declaration until you do.
|
|
|
|
|
|
|
|
3. Naming conventions
|
|
=====================
|
|
|
|
3.1. Classes
|
|
------------
|
|
|
|
Classes names are in lower-case. However, each word should start with an
|
|
upper-case letter.
|
|
|
|
Examples: "object", "exampleClass", "anotherExampleClass"...
|
|
|
|
|
|
3.2. Variables/parameters/member variables
|
|
------------------------------------------
|
|
|
|
Variable names should be enough explicit so that someone reading the code can
|
|
instantly understand what the variable contains and is used for.
|
|
|
|
Variables names are in lower-case.
|
|
|
|
DO NOT use Hungarian notation.
|
|
|
|
Examples: "address", "recipientMailbox", ...
|
|
|
|
Avoid variable names with less than 5 characters, except for loop indices and
|
|
iterators.
|
|
|
|
NOTE: variable names like "it", "jt" and so on are commonly used when iterating
|
|
over STL containers.
|
|
|
|
|
|
3.3. Member variables
|
|
---------------------
|
|
|
|
Use a prefix for class members: "m_" for normal class members, and "sm_" for
|
|
static members, if they are not public.
|
|
|
|
Examples: "m_mailboxList", "sm_instance"...
|
|
|
|
|
|
3.4. Files
|
|
----------
|
|
|
|
Use ".hpp" for header files, and ".cpp" for implementation files. ".inc" should
|
|
be used for implementation files not directly compiled, but included from
|
|
other implementation files.
|
|
|
|
Files have to be named exactly like the class they define. For example, class
|
|
"mailboxList" should be declared in "mailboxList.hpp" and implemented in
|
|
"mailboxList.cpp".
|
|
|
|
Both header and implementation files must be placed in 'src/vmime/' directory.
|
|
|
|
|
|
3.5. Namespaces
|
|
---------------
|
|
|
|
Namespaces are named exactly like variables.
|
|
|
|
|
|
3.6. Constants
|
|
--------------
|
|
|
|
Constants are ALL_CAPS_WITH_UNDERSCORES.
|
|
|
|
|
|
|
|
4. Comments
|
|
===========
|
|
|
|
The // (two slashes) style of comment tags should be used in most situations.
|
|
Where ever possible, place comments above the code instead of beside it.
|
|
|
|
Comments can be placed at the end of a line when one or more spaces follow.
|
|
Tabs should NOT be used to indent at the end of a line:
|
|
|
|
class myClass {
|
|
|
|
private:
|
|
|
|
int m_member1; // first member
|
|
int m_secondMember; // second member
|
|
};
|
|
|
|
Note about special comment blocks: Doxygen is used to generate documentation
|
|
from annotated C++ sources, so be sure to use available markings to annotate
|
|
the purpose of the functions/classes and the meaning of the parameters.
|
|
|
|
|
|
5. Miscellaneous
|
|
================
|
|
|
|
* No code should be put in header files, only declarations (except for
|
|
templates and inline functions).
|
|
|
|
* Try to avoid public member variables. Write accessors instead (get/set).
|
|
|
|
* Do NOT use 'using namespace' (and especially not in header files). All
|
|
namespaces should be explicitely named.
|
|
|
|
* Use the 'get' and 'set' prefix for accessors:
|
|
|
|
Variable: m_foo
|
|
Get method: getFoo()
|
|
Set method: setFoo()
|
|
|
|
* No more than one class per file (except for inner classes).
|
|
|
|
* Put the #include for the class's header file first in the implementation
|
|
file.
|
|
|
|
* Put the copyright header at the top of each file.
|
|
|
|
* Write "unique inclusion #ifdef's" for header files:
|
|
|
|
#ifndef N1_N2_FILENAME_HPP_INCLUDED
|
|
#define N1_N2_FILENAME_HPP_INCLUDED
|
|
|
|
// ...
|
|
|
|
#endif // N1_N2_FILENAME_HPP_INCLUDED
|
|
|
|
where N1 is the top-level namespace, N2 the sub-namespace, and so on.
|
|
For example, class "vmime::utility::stringUtils" uses the following
|
|
#ifdef name: VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED.
|
|
|