]> Creatis software - bbtkGEditor.git/blob - doc/UserDoxygen/CodingStyle.html
Feature #1771 Add licence terms for all files.
[bbtkGEditor.git] / doc / UserDoxygen / CodingStyle.html
1 <!--
2 # ---------------------------------------------------------------------
3 #
4 # Copyright (c) CREATIS (Centre de Recherche en Acquisition et Traitement de l'Image 
5 #                        pour la Santé)
6 # Authors : Eduardo Davila, Frederic Cervenansky, Claire Mouton
7 #
8 #  This software is governed by the CeCILL-B license under French law and 
9 #  abiding by the rules of distribution of free software. You can  use, 
10 #  modify and/ or redistribute the software under the terms of the CeCILL-B 
11 #  license as circulated by CEA, CNRS and INRIA at the following URL 
12 #  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
13 #  or in the file LICENSE.txt.
14 #
15 #  As a counterpart to the access to the source code and  rights to copy,
16 #  modify and redistribute granted by the license, users are provided only
17 #  with a limited warranty  and the software's author,  the holder of the
18 #  economic rights,  and the successive licensors  have only  limited
19 #  liability. 
20 #
21 #  The fact that you are presently reading this means that you have had
22 #  knowledge of the CeCILL-B license and that you accept its terms.
23 # ------------------------------------------------------------------------  
24 -->
25
26 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
27 <html><head>
28    <meta http-equiv="Content-Type"
29    content="text/html;charset=iso-8859-1"><title>bbtk Developpers</title></head>
30
31 <body>
32
33 <!--#######################################################################-->
34 <h1>bbtk coding style (and other religious/agnostic beliefs)</h1>
35 <hr size="1"><address style=""></address>
36
37 <pre>* Introduction:
38    The following coding style intends to ease the work of developpers
39    themselves but also of users who will study, maintain, fix, and extend
40    the code. Any bread crumbs that you can drop in the way of explanatory
41    names and comments will go a long way towards helping other readers and
42    developers.
43    Keep in mind that to a large extent the structure of code directly
44    expresses its implementation.
45                                                                                 
46 * Language:
47  - C++ (for the kernel) and Python (for the wrappers).
48  - all the names (variables, members, methods, functions) and comments
49    should be based on English. Documentation, guides, web site and other
50    informations should be in English.
51    Make sure you use correct (basic) English and complete, grammatically
52    correct sentences for comments and documentation.
53                                                                                 
54 * General layout:
55  - Each line of code should take no more than 79 characters. Break the code
56    across multiple lines as necessary.
57  - Methods and functions should keep a reasonable number of lines when
58    possible (a typical editor displays 50 lines). Avoid code duplication.
59    Always prefer creating a new method or function to duplication.
60    A high indentation level generally suggests the need for a new
61    method or function.
62  - All the code should be properly indented. The appropriate indentation
63    level is TWO spaces for each level of indentation. DO NOT USE TABS.
64    Set up your editor to insert spaces. Using tabs may look good in your
65    editor but will wreak havoc in others, or in external tools (e.g. side
66    by side diffs).
67  - The declaration of variables within classes, methods, and functions
68    should be one declaration per line. Provide them with default values
69    and don't rely on compilers for default initialization.
70                                                                                 
71 * Naming conventions:
72  - Generalities:
73    In general, names are constructed by using case change to indicate
74    separate words, as in ImageDataSize (standing for "image data size").
75    Underscores are not used. Variable names are choosen carefully with the
76    intention to convey the meaning behind the code. Names are generally
77    spelled out; use of abbreviations is discouraged.
78    [Note: abbreviation are allowable when in common use, and should be in
79     uppercase as in LUT or RGBA.]
80    While this does result in long names, it self-documents the code.
81  - Naming Files:
82    Files should have the same name as the class, with a "bbtk" prepended.
83    Header files are named .h, while implementation files are named either
84    .cxx or .txx, depending on whether they are implementations of templated
85    classes. For example, the class bbtk::BlackBox is declared and defined
86    in the files bbtkBlackBox.h and bbtkBlackBox.cxx.
87  - Naming Class Data Members, Methods, and Functions:
88    Class data members (aka Attributes) are named beginning with a lower case 'm'
89    (m as 'member'!) followed by capital letter as in mGroupPixel, in order not
90    be confused with methods names.
91    Global functions and class methods, either static or class members, are
92    named beginning with a capital letter, as in GetImageDataSize().
93  - Naming Local Variables:
94    Local variables begin in lowercase. There is more flexibility in the
95    naming of local variables although they still should convey some
96    semantics.
97  - Naming function parameters:
98    Function parameters begin in lowercase. There is more flexibility in the
99    naming of function parameters although they still should convey some
100    semantics.
101                                                                                  
102 * Classes:
103  - Don't use the inline keyword when defining an inline function
104    within a class definition.
105    (Any method defined within a .h file is ipso facto considered as 'inline'.
106    Dont write useless stuff!)
107  - As stated in the "Naming conventions" section, class data members
108    named beginning with a lower case 'm' followed by capital letter 
109    as in mGroupPixel.
110    But the parameter names of method should be named with a lowercase
111    letter (in order to distinguish at a glance data members, from parameters
112    and also to avoid potential collisions with data members):
113       void A::SetGroupPixel( int groupPixel )
114       {
115          mGroupPixel = groupPixel;
116       }
117  - Don't use trailing ';' in inline function definition.
118    use :
119    void A::SetGroupPixel( int groupPixel ){mGroupPixel = groupPixel;}
120      NOT
121    void A::SetGroupPixel( int groupPixel ){mGroupPixel = groupPixel;};
122  - Do not repeat the 'virtual' keyword when overriding virtual base methods
123    in declaration of subclasses:
124      class A
125      {
126         virtual void foo(...);
127      };
128      class B : public bbtk::A
129      {
130         void foo(...);          // and NOT: virtual void foo(...);
131      };
132      
133     (when the keyword 'virtual' is used at the parent level, it's propagated 
134      for all the child classes)
135
136  - In declaration of subclasses, always preprend the class name with 'bbtk::'
137    in order not to confuse Umbrello ( OpenSource UML diagram generator)
138      class A
139      {
140         ...
141      };
142      class B : public bbtk::A // and NOT: class B: public A
143      {
144         ...   
145      };    
146  - The public, protected, private declarations should be at the
147    same indent level as the class. Use :
148      class A
149      {
150      public:
151         void bar(...);
152      protected:
153         void foo(...);  
154      private:
155         void pff(...);
156      };
157      
158  - The Data members should be declared at the end of the class declaration :
159      class A
160      {
161      public:
162         void bar(...);
163      protected:
164         void foo(...);
165      private:
166         void pff(...);
167
168      // --- Data members
169      
170      public:
171         int mPublicCounter;
172      protected:
173         int mProtectedCounter;
174      private:
175         int mPrivateCounter;     
176      }; 
177  
178  - Method and functions devoided of arguments should not use the void
179    notation. Use :
180      SomeType Header::GetPixelData()
181    and not
182      SomeType Header::GetPixelData(void)
183                                                                                 
184 * Use of braces:
185  - Braces must be used to delimit the scope of an if, for, while, switch, or
186    other control structure. Braces are placed on a line by themselves, and
187    at the same indentation level as the control structure to which they
188    belong:
189       for (i=0; * i&lt;3; i++)
190       {
191          ...
192       }
193    and NOT :
194       for (i=0; * i&lt;3; i++) {
195          ...
196       }   
197    or when using an if:
198       if ( condition )
199       {
200          ...
201       }
202       else if ( other condition )
203       {
204          ...
205       }
206       else
207       {
208         ....
209       }
210     and NOT :
211       if ( condition ) {
212          ...
213       } else if ( other condition ) {
214          ...
215       } else {
216          ....
217       }    
218    You can choose to use braces on a line with a code block when
219    the block consists of a single line:
220       if ( condition ) { foo=1; }
221       else if ( condition2 ) { foo=3; }
222       else { return; }
223    or
224       for (i=0; i&lt;3; ++i) {x[i]=0.0;}
225    Methods and functions should follow the same usage of braces:
226       void File::ParsePixelData()
227       {
228          ...
229       }
230
231 * Special layout:
232  - Avoid code mixed with comments on a single line. Instead, prepend the
233    logical blocks of code with the concerned comments.
234  - Use parentheses around conditions e.g. with an if statement:
235       if ( someLocalVariable == 2 ) { ... }
236  - Add spaces around parentheses, or braces. Use
237       if ( someLocalVariable == 2 ) { mClassMember += 1; }
238    and not
239       if (someLocalVariable == 2) {mClassMember += 1;}
240  - Add spaces around each side of the assignement operator, and
241    around binary operators used in boolean expression. Use
242       someLocalVariable = mClassMember * 2;
243       if ( someLocalVariable == 2 || mClassMember == 2 ) ...
244    and not
245       someLocalVariable=mClassMember*2;
246       if ( someLocalVariable==2||mClassMember==2 ) ...
247                                                                                 
248 * Miscelaneous:
249  - Don't use underscores. Don't use tabs. Don't use control characters
250    like ^M. Anyhow, cvs is configured to reject such commits.
251  - Comments should be in C++ style ("// ...", two slashes, per line). Don't
252    use C style comments ("/* ... */").
253  - The last line of a file should terminate with "\n".
254  - Returned arguments of methods and functions should not be wrapped with
255    parentheses. Use
256       return iter-&gt;second;
257    but do not use
258       return ( iter-&gt;second );
259                                                                                 
260 * Debugging and Verbose modes:
261    Never use std::cout. Instead use the bbtkMessage, bbtkDebugMessage, bbtkWarning or bbtkError macros and their variants. Example:
262       #include "bbtkMessageManager.h"
263       ...
264       {
265          bbtkDebugMessageInc("MyClass",9,"Local function name: entering.");
266          ...
267          bbtkDecTab("MyClass",9);
268       }
269     will send the message to std::cout when the Debug messages are compiled 
270     and the Message Level for the category of messages "MyClass" is greater than 9.
271                                                                                 
272 * Documentation:
273    The Doxygen open-source system is used to generate on-line documentation.
274    Doxygen requires the embedding of simple comments in the code which is in
275    turn extracted and formatted into documentation. See :
276       http://www.stack.nl/~dimitri/doxygen/
277    for more information about Doxygen.
278  - Documenting a class:
279    Classes should be documented using the class and brief doxygen commands,
280    followed by the detailed class description:
281       /**
282        * \class Header
283        * \brief Header acts as container of Dicom elements of an image.
284        *
285        * Detailed description of the class is provided here
286        * ...
287        */
288    The key here is that the comment starts with /**, each subsequent line has
289    an aligned *, and the comment block terminates with a */.
290  - Documenting class members and inline methods:
291    All the members and the inline methods should be documented within
292    the class declaration ( .h file) as shown in the following example:
293       class Header
294       {
295          /// True when parsing was successfull. False otherwise.
296          bool mReadable = false;
297                                                                                 
298          /// \brief The number of lines of the image as interpreted from
299          ///        the various elements encountered at header parsing.
300          int mNumberOfLines = -1;
301                                                                                 
302          /// Predicate implemented as accessor around \ref mReadable.
303          bool IsReadable() { return mReadable; }
304       };
305  - Documenting a Method:
306    Methods should be documented using the following comment block style
307    as shown in the following example:
308                                                                                 
309       /**
310        * \brief  Within the Dicom Elements (parsed with the public and private
311        *         dictionaries), look for the element value representation of
312        *         a given tag.
313        * @param  group  Group number of the searched tag.
314        * @param  elem Element number of the searched tag.
315        * @return Corresponding element value representation when it exists,
316        *         and the string "bbtk::Unfound" otherwise.
317        */
318       std::string Document::GetEntryByNumber(guint16 group, guint16 elem)
319       {
320          ...
321       }
322                                                                                 
323 * External includes and C style:
324  - Only the C++ standard library and the STL includes should be used.
325    When including don't use the .h extension (use #include <iostream>
326    instead of #include <iostream.h>).
327    Note: include the stl header AFTER the bbtk ones (otherwise pragma
328          warnings won't work).
329  - Don't use the C standard library. Don't include stdio.h, ctype.h...
330    Don't use printf(), sprinf(), FILE*...
331  - Don't use the NULL notation (neither as macro, nor as const int NULL=0).
332    A pointer that doesn't refer to an object should simply be defined as
333       DataPointer *myDataPointer = 0;
334                                                                                 
335 * Basic types:
336  - Assume T is a given type. When declaring or defining with the
337    "pointer to T" notation, the * character must be adjacent to
338    the variable and not the type. That is use
339       T *foo = 0;
340    and not
341       T* foo = 0;
342    nor
343       T * foo = 0;
344  - Assume T is a given type. When declaring or defining with the
345    "reference to T" notation, the &amp; character must be adjacent to
346    the variable and not the type. That is use :
347       T &amp;foo = 0;
348    and not
349       T&amp; foo = 0;
350
351    (Doxygen will not have any longer to correct)
352
353  - Always define a typedef for a new type and be consistent in usage.
354    Use :
355       typedef Header *HeaderPointer;
356       HeaderPointer myHeaderPointer;
357       
358  - One notorious counter example for non using C style inclusion concerns
359    exact-width integers (since there seem to be no equivalent for C++).
360    When using exact-width integers use the typedef names defined by
361    the Basic ISO C99: 7.18 Integer types i.e.
362       int8_t     int16_t     int32_t     int64_t (signed integers)
363    and
364       uint8_t    uint16_t    uint32_t    uint64_t (unsigned integers).
365    Conversion table is then:
366     unsigned char       -&gt; uint8_t;
367     unsigned short      -&gt; uint16_t;
368     unsigned int        -&gt; uint32_t;
369     unsigned long       -&gt; uint32_t;
370     unsigned long long  -&gt; uint64_t;
371     (signed) char       -&gt; int8_t;
372     short               -&gt; int16_t;
373     int                 -&gt; int32_t;
374     long                -&gt; int32_t;
375     long long           -&gt; int64_t;
376    Hence do not use declarations like "unsigned int".
377    With g++, accessing those typedef is achieved by the following
378       #include &lt; stdint.h &gt;
379 </iostream.h></iostream></pre>
380
381
382 <!--#######################################################################-->
383 <hr size="1"><address style=""></address>
384
385 </body></html>