|
ferencd@0
|
1 This file contains coding guidelines for VMime. You should follow them
|
|
ferencd@0
|
2 if you want to contribute to VMime. The rules below are not guidelines
|
|
ferencd@0
|
3 or recommendations, but strict rules.
|
|
ferencd@0
|
4
|
|
ferencd@0
|
5
|
|
ferencd@0
|
6 1. General rules
|
|
ferencd@0
|
7 1.1. Language
|
|
ferencd@0
|
8 1.2. Unit tests
|
|
ferencd@0
|
9 1.3. Version Control
|
|
ferencd@0
|
10 1.4. ChangeLog
|
|
ferencd@0
|
11 1.5. Warnings
|
|
ferencd@0
|
12 2. Style, indentation and braces
|
|
ferencd@0
|
13 2.1. Indentation
|
|
ferencd@0
|
14 2.2. Brace position
|
|
ferencd@0
|
15 2.3. "switch" statement
|
|
ferencd@0
|
16 2.4. Single instruction
|
|
ferencd@0
|
17 2.5. Line length
|
|
ferencd@0
|
18 2.6. Spaces and parentheses
|
|
ferencd@0
|
19 2.7. End-of-line character
|
|
ferencd@0
|
20 2.8. Short functions
|
|
ferencd@0
|
21 2.9. Limit Variable Scope
|
|
ferencd@0
|
22 3. Naming conventions
|
|
ferencd@0
|
23 3.1. Classes
|
|
ferencd@0
|
24 3.2. Variables/parameters/member variables
|
|
ferencd@0
|
25 3.3. Member variables
|
|
ferencd@0
|
26 3.4. Files
|
|
ferencd@0
|
27 3.5. Namespaces
|
|
ferencd@0
|
28 3.6. Constants
|
|
ferencd@0
|
29 4. Comments
|
|
ferencd@0
|
30 5. Miscellaneous
|
|
ferencd@0
|
31
|
|
ferencd@0
|
32
|
|
ferencd@0
|
33
|
|
ferencd@0
|
34 1. General rules
|
|
ferencd@0
|
35 ================
|
|
ferencd@0
|
36
|
|
ferencd@0
|
37 1.1. Language
|
|
ferencd@0
|
38 -------------
|
|
ferencd@0
|
39
|
|
ferencd@0
|
40 The project language is English. All comments, variable names, class names,
|
|
ferencd@0
|
41 commit messages and so on, must be in English.
|
|
ferencd@0
|
42
|
|
ferencd@0
|
43
|
|
ferencd@0
|
44 1.2. Unit tests
|
|
ferencd@0
|
45 ---------------
|
|
ferencd@0
|
46
|
|
ferencd@0
|
47 Unit tests are very important. For each new class you write, you should also
|
|
ferencd@0
|
48 write a unit test for it. If you write a new method, add a new test case in
|
|
ferencd@0
|
49 the unit test of the class.
|
|
ferencd@0
|
50
|
|
ferencd@0
|
51 When you fix a bug, also add a new test case to ensure the bug will not
|
|
ferencd@0
|
52 happen anymore.
|
|
ferencd@0
|
53
|
|
ferencd@0
|
54
|
|
ferencd@0
|
55 1.3. Version Control
|
|
ferencd@0
|
56 --------------------
|
|
ferencd@0
|
57
|
|
ferencd@0
|
58 Each commit MUST be done with a message ('-m' flag) that briefly describes what
|
|
ferencd@0
|
59 changes have been done.
|
|
ferencd@0
|
60
|
|
ferencd@0
|
61 DO NOT use commit messages like -m "Updated"!
|
|
ferencd@0
|
62
|
|
ferencd@0
|
63
|
|
ferencd@0
|
64 1.4. ChangeLog
|
|
ferencd@0
|
65 --------------
|
|
ferencd@0
|
66
|
|
ferencd@0
|
67 ChangeLog must be updated when a major change has occured. It is not required
|
|
ferencd@0
|
68 (but not forbidden) to report minor bug fixes in the ChangeLog.
|
|
ferencd@0
|
69
|
|
ferencd@0
|
70 Each ChangeLog entry must have an author and a date.
|
|
ferencd@0
|
71
|
|
ferencd@0
|
72
|
|
ferencd@0
|
73 1.5. Warnings
|
|
ferencd@0
|
74 -------------
|
|
ferencd@0
|
75
|
|
ferencd@0
|
76 The code should compile WITHOUT ANY WARNING, even those for unused parameters!
|
|
ferencd@0
|
77
|
|
ferencd@0
|
78
|
|
ferencd@0
|
79
|
|
ferencd@0
|
80 2. Style, indentation and braces
|
|
ferencd@0
|
81 ================================
|
|
ferencd@0
|
82
|
|
ferencd@0
|
83 2.1. Indentation
|
|
ferencd@0
|
84 ----------------
|
|
ferencd@0
|
85
|
|
ferencd@0
|
86 Use TABS (ASCII character #9) and _not_ SPACES. This allow everyone to set tab
|
|
ferencd@0
|
87 width to its preferred settings (eg. 4 or 8 spaces).
|
|
ferencd@0
|
88
|
|
ferencd@0
|
89
|
|
ferencd@0
|
90 2.2. Brace position
|
|
ferencd@0
|
91 -------------------
|
|
ferencd@0
|
92
|
|
ferencd@0
|
93 Open braces should always be at the beginning of the line after the statement
|
|
ferencd@0
|
94 that begins the block. Contents of the brace should be indented by 1 tab.
|
|
ferencd@0
|
95
|
|
ferencd@0
|
96 if (expr)
|
|
ferencd@0
|
97 {
|
|
ferencd@0
|
98 do_something();
|
|
ferencd@0
|
99 do_another_thing();
|
|
ferencd@0
|
100 }
|
|
ferencd@0
|
101 else
|
|
ferencd@0
|
102 {
|
|
ferencd@0
|
103 do_something_else();
|
|
ferencd@0
|
104 }
|
|
ferencd@0
|
105
|
|
ferencd@0
|
106
|
|
ferencd@0
|
107 2.3. "switch" statement
|
|
ferencd@0
|
108 -----------------------
|
|
ferencd@0
|
109
|
|
ferencd@0
|
110 switch (expr)
|
|
ferencd@0
|
111 {
|
|
ferencd@0
|
112 case 0:
|
|
ferencd@0
|
113
|
|
ferencd@0
|
114 something;
|
|
ferencd@0
|
115 break;
|
|
ferencd@0
|
116
|
|
ferencd@0
|
117 case 1:
|
|
ferencd@0
|
118
|
|
ferencd@0
|
119 something_else;
|
|
ferencd@0
|
120 break;
|
|
ferencd@0
|
121
|
|
ferencd@0
|
122 case 2:
|
|
ferencd@0
|
123 {
|
|
ferencd@0
|
124 int var = 42;
|
|
ferencd@0
|
125 another_thing;
|
|
ferencd@0
|
126 break;
|
|
ferencd@0
|
127 }
|
|
ferencd@0
|
128
|
|
ferencd@0
|
129 }
|
|
ferencd@0
|
130
|
|
ferencd@0
|
131
|
|
ferencd@0
|
132 2.4. Single instruction
|
|
ferencd@0
|
133 -----------------------
|
|
ferencd@0
|
134
|
|
ferencd@0
|
135 Omit braces around simple single-statement body:
|
|
ferencd@0
|
136
|
|
ferencd@0
|
137 if (...)
|
|
ferencd@0
|
138 something;
|
|
ferencd@0
|
139
|
|
ferencd@0
|
140 and not:
|
|
ferencd@0
|
141
|
|
ferencd@0
|
142 if (...)
|
|
ferencd@0
|
143 {
|
|
ferencd@0
|
144 something;
|
|
ferencd@0
|
145 }
|
|
ferencd@0
|
146
|
|
ferencd@0
|
147 Except when body spans over multiple lines:
|
|
ferencd@0
|
148
|
|
ferencd@0
|
149 if (...)
|
|
ferencd@0
|
150 {
|
|
ferencd@0
|
151 something_too_long_for(
|
|
ferencd@0
|
152 a_single_line);
|
|
ferencd@0
|
153 }
|
|
ferencd@0
|
154
|
|
ferencd@0
|
155
|
|
ferencd@0
|
156 2.5. Line length
|
|
ferencd@0
|
157 ----------------
|
|
ferencd@0
|
158
|
|
ferencd@0
|
159 Each line of text should not exceed 80 characters.
|
|
ferencd@0
|
160
|
|
ferencd@0
|
161 Exception: if a comment line contains an example command or a literal URL
|
|
ferencd@0
|
162 longer than 100 characters, that line may be longer than 100 characters
|
|
ferencd@0
|
163 for ease of cut and paste.
|
|
ferencd@0
|
164
|
|
ferencd@0
|
165
|
|
ferencd@0
|
166 2.6. Spaces and parentheses
|
|
ferencd@0
|
167 ---------------------------
|
|
ferencd@0
|
168
|
|
ferencd@0
|
169 Put spaces around operators: =, >, <, !=, +, -, /, *, ^, %, ||, &&, &, |:
|
|
ferencd@0
|
170
|
|
ferencd@0
|
171 x = (a * (b + (c - d)))
|
|
ferencd@0
|
172
|
|
ferencd@0
|
173 Do not put spaces around parentheses.
|
|
ferencd@0
|
174
|
|
ferencd@0
|
175 if ((a == b) || (c == d))
|
|
ferencd@0
|
176
|
|
ferencd@0
|
177 Do not put spaces around "->":
|
|
ferencd@0
|
178
|
|
ferencd@0
|
179 object->method()
|
|
ferencd@0
|
180
|
|
ferencd@0
|
181 Do not put spaces inside brackets:
|
|
ferencd@0
|
182
|
|
ferencd@0
|
183 x = array[index] and _NOT_: x = array[ index ]
|
|
ferencd@0
|
184
|
|
ferencd@0
|
185 Do not use space between a function name and parenthesis. No extra spaces
|
|
ferencd@0
|
186 between parameters and arguments, just after commas:
|
|
ferencd@0
|
187
|
|
ferencd@0
|
188 method(arg1, arg2, ...)
|
|
ferencd@0
|
189
|
|
ferencd@0
|
190 Do use a single space before flow control statements:
|
|
ferencd@0
|
191
|
|
ferencd@0
|
192 while (x == y) and _NOT_: while(x==y)
|
|
ferencd@0
|
193
|
|
ferencd@0
|
194
|
|
ferencd@0
|
195 2.7. End-of-line character
|
|
ferencd@0
|
196 --------------------------
|
|
ferencd@0
|
197
|
|
ferencd@0
|
198 Configure your editor to use "\n" (UNIX convention) for end-of-line sequence,
|
|
ferencd@0
|
199 and not "\r\n" (Windows), nor "\n\r", nor any other combination.
|
|
ferencd@0
|
200
|
|
ferencd@0
|
201
|
|
ferencd@0
|
202 2.8. Short functions
|
|
ferencd@0
|
203 --------------------
|
|
ferencd@0
|
204
|
|
ferencd@0
|
205 To the extent that it is feasible, functions should be kept small and focused.
|
|
ferencd@0
|
206 It is, however, recognized that long functions are sometimes appropriate, so no
|
|
ferencd@0
|
207 hard limit is placed on method length. If a function exceeds 40 lines or so,
|
|
ferencd@0
|
208 think about whether it can be broken up without harming the structure of the
|
|
ferencd@0
|
209 program.
|
|
ferencd@0
|
210
|
|
ferencd@0
|
211
|
|
ferencd@0
|
212 2.9. Limit Variable Scope
|
|
ferencd@0
|
213 -------------------------
|
|
ferencd@0
|
214
|
|
ferencd@0
|
215 The scope of local variables should be kept to a minimum. By doing so, you
|
|
ferencd@0
|
216 increase the readability and maintainability of your code and reduce the
|
|
ferencd@0
|
217 likelihood of error. Each variable should be declared in the innermost block
|
|
ferencd@0
|
218 that encloses all uses of the variable.
|
|
ferencd@0
|
219
|
|
ferencd@0
|
220 Local variables should be declared at the point they are first used. Nearly
|
|
ferencd@0
|
221 every local variable declaration should contain an initializer. If you don't
|
|
ferencd@0
|
222 yet have enough information to initialize a variable sensibly, you should
|
|
ferencd@0
|
223 postpone the declaration until you do.
|
|
ferencd@0
|
224
|
|
ferencd@0
|
225
|
|
ferencd@0
|
226
|
|
ferencd@0
|
227 3. Naming conventions
|
|
ferencd@0
|
228 =====================
|
|
ferencd@0
|
229
|
|
ferencd@0
|
230 3.1. Classes
|
|
ferencd@0
|
231 ------------
|
|
ferencd@0
|
232
|
|
ferencd@0
|
233 Classes names are in lower-case. However, each word should start with an
|
|
ferencd@0
|
234 upper-case letter.
|
|
ferencd@0
|
235
|
|
ferencd@0
|
236 Examples: "object", "exampleClass", "anotherExampleClass"...
|
|
ferencd@0
|
237
|
|
ferencd@0
|
238
|
|
ferencd@0
|
239 3.2. Variables/parameters/member variables
|
|
ferencd@0
|
240 ------------------------------------------
|
|
ferencd@0
|
241
|
|
ferencd@0
|
242 Variable names should be enough explicit so that someone reading the code can
|
|
ferencd@0
|
243 instantly understand what the variable contains and is used for.
|
|
ferencd@0
|
244
|
|
ferencd@0
|
245 Variables names are in lower-case.
|
|
ferencd@0
|
246
|
|
ferencd@0
|
247 DO NOT use Hungarian notation.
|
|
ferencd@0
|
248
|
|
ferencd@0
|
249 Examples: "address", "recipientMailbox", ...
|
|
ferencd@0
|
250
|
|
ferencd@0
|
251 Avoid variable names with less than 5 characters, except for loop indices and
|
|
ferencd@0
|
252 iterators.
|
|
ferencd@0
|
253
|
|
ferencd@0
|
254 NOTE: variable names like "it", "jt" and so on are commonly used when iterating
|
|
ferencd@0
|
255 over STL containers.
|
|
ferencd@0
|
256
|
|
ferencd@0
|
257
|
|
ferencd@0
|
258 3.3. Member variables
|
|
ferencd@0
|
259 ---------------------
|
|
ferencd@0
|
260
|
|
ferencd@0
|
261 Use a prefix for class members: "m_" for normal class members, and "sm_" for
|
|
ferencd@0
|
262 static members, if they are not public.
|
|
ferencd@0
|
263
|
|
ferencd@0
|
264 Examples: "m_mailboxList", "sm_instance"...
|
|
ferencd@0
|
265
|
|
ferencd@0
|
266
|
|
ferencd@0
|
267 3.4. Files
|
|
ferencd@0
|
268 ----------
|
|
ferencd@0
|
269
|
|
ferencd@0
|
270 Use ".hpp" for header files, and ".cpp" for implementation files. ".inc" should
|
|
ferencd@0
|
271 be used for implementation files not directly compiled, but included from
|
|
ferencd@0
|
272 other implementation files.
|
|
ferencd@0
|
273
|
|
ferencd@0
|
274 Files have to be named exactly like the class they define. For example, class
|
|
ferencd@0
|
275 "mailboxList" should be declared in "mailboxList.hpp" and implemented in
|
|
ferencd@0
|
276 "mailboxList.cpp".
|
|
ferencd@0
|
277
|
|
ferencd@0
|
278 Both header and implementation files must be placed in 'src/vmime/' directory.
|
|
ferencd@0
|
279
|
|
ferencd@0
|
280
|
|
ferencd@0
|
281 3.5. Namespaces
|
|
ferencd@0
|
282 ---------------
|
|
ferencd@0
|
283
|
|
ferencd@0
|
284 Namespaces are named exactly like variables.
|
|
ferencd@0
|
285
|
|
ferencd@0
|
286
|
|
ferencd@0
|
287 3.6. Constants
|
|
ferencd@0
|
288 --------------
|
|
ferencd@0
|
289
|
|
ferencd@0
|
290 Constants are ALL_CAPS_WITH_UNDERSCORES.
|
|
ferencd@0
|
291
|
|
ferencd@0
|
292
|
|
ferencd@0
|
293
|
|
ferencd@0
|
294 4. Comments
|
|
ferencd@0
|
295 ===========
|
|
ferencd@0
|
296
|
|
ferencd@0
|
297 The // (two slashes) style of comment tags should be used in most situations.
|
|
ferencd@0
|
298 Where ever possible, place comments above the code instead of beside it.
|
|
ferencd@0
|
299
|
|
ferencd@0
|
300 Comments can be placed at the end of a line when one or more spaces follow.
|
|
ferencd@0
|
301 Tabs should NOT be used to indent at the end of a line:
|
|
ferencd@0
|
302
|
|
ferencd@0
|
303 class myClass
|
|
ferencd@0
|
304 {
|
|
ferencd@0
|
305 private:
|
|
ferencd@0
|
306
|
|
ferencd@0
|
307 int m_member1; // first member
|
|
ferencd@0
|
308 int m_secondMember; // second member
|
|
ferencd@0
|
309 };
|
|
ferencd@0
|
310
|
|
ferencd@0
|
311 Note about special comment blocks: Doxygen is used to generate documentation
|
|
ferencd@0
|
312 from annotated C++ sources, so be sure to use available markings to annotate
|
|
ferencd@0
|
313 the purpose of the functions/classes and the meaning of the parameters.
|
|
ferencd@0
|
314
|
|
ferencd@0
|
315
|
|
ferencd@0
|
316 5. Miscellaneous
|
|
ferencd@0
|
317 ================
|
|
ferencd@0
|
318
|
|
ferencd@0
|
319 * No code should be put in header files, only declarations (except for
|
|
ferencd@0
|
320 templates and inline functions).
|
|
ferencd@0
|
321
|
|
ferencd@0
|
322 * Try to avoid public member variables. Write accessors instead (get/set).
|
|
ferencd@0
|
323
|
|
ferencd@0
|
324 * Do NOT use 'using namespace' (and especially not in header files). All
|
|
ferencd@0
|
325 namespaces should be explicitely named.
|
|
ferencd@0
|
326
|
|
ferencd@0
|
327 * Use the 'get' and 'set' prefix for accessors:
|
|
ferencd@0
|
328
|
|
ferencd@0
|
329 Variable: m_foo
|
|
ferencd@0
|
330 Get method: getFoo()
|
|
ferencd@0
|
331 Set method: setFoo()
|
|
ferencd@0
|
332
|
|
ferencd@0
|
333 * No more than one class per file (except for inner classes).
|
|
ferencd@0
|
334
|
|
ferencd@0
|
335 * Put the inclusion for the class's header file as the first inclusion in
|
|
ferencd@0
|
336 the implementation file.
|
|
ferencd@0
|
337
|
|
ferencd@0
|
338 * Put the copyright header at the top of each file.
|
|
ferencd@0
|
339
|
|
ferencd@0
|
340 * Write "unique inclusion #ifdef's" for header files:
|
|
ferencd@0
|
341
|
|
ferencd@0
|
342 #ifndef N1_N2_FILENAME_HPP_INCLUDED
|
|
ferencd@0
|
343 #define N1_N2_FILENAME_HPP_INCLUDED
|
|
ferencd@0
|
344
|
|
ferencd@0
|
345 // ...
|
|
ferencd@0
|
346
|
|
ferencd@0
|
347 #endif // N1_N2_FILENAME_HPP_INCLUDED
|
|
ferencd@0
|
348
|
|
ferencd@0
|
349 where N1 is the top-level namespace, N2 the sub-namespace, and so on.
|
|
ferencd@0
|
350 For example, class "vmime::utility::stringUtils" uses the following
|
|
ferencd@0
|
351 #ifdef name: VMIME_UTILITY_STRINGUTILS_HPP_INCLUDED.
|
|
ferencd@0
|
352
|