]> Creatis software - gdcm.git/blob - DEVELOPPER
* test the checkTabs script.
[gdcm.git] / DEVELOPPER
1 The following comments are intended for core gdcm developpers.
2         
3 * Compiling gdcm:
4   - Checkout the sources to an arbitrary directory noted GDCM (e.g. ~/cvs/gdcm).
5   - Checkout the test images to an arbitrary directory noted GDCMDATA
6     (e.g. ~/cvs/gdcm/gdcmData).
7   - Optionally create a temporary installation directory GDCMINSTALL e.g.
8     mkdir /tmp/gdcminstall
9   - Create a target directory GDCMBIN e.g.
10     mkdir /tmp/gdcmbin
11   - Configure cmake from GDCMBIN:
12     cd GDCMBIN
13     ccmake GDCM
14       * Toggle and adjust the required options and parameters, mainly
15         -- GDCM_DATA_ROOT should be set to GDCMDATA
16         -- CMAKE_INSTALL_PREFIX (equivalent of --prefix of the autotools)
17            should be set to GDCMINSTALL
18         -- CMAKE_BUILD_TYPE set to Debug or Release
19         -- GDCM_DOXYGEN 
20         -- GDCM_VTK When this option is on VTK_DIR might require manual
21            configuration
22         -- GDCM_WRAP_PYTHON
23       * Configure cmake: hit c
24       * Generate the makefiles (or dsw): hit g
25   - Compile gdcm
26     make  
27   - Run the tests manually (optional):
28     Caveat: if you run the tests before installing, you NEED to positionate
29             the environment variable GDCM_DICT_PATH to GDCM/Dicts e.g.
30             export GDCM_DICT_PATH=~/cvs/gdcm/Dicts
31     Assuming your cwd is GDCMBIN, three modes are then available:
32     -- 1/ acces to a by number:
33           ./Test/gdcmCxxTests
34     -- 2/ acces to a test by it's name, by passing it as argument to
35           gdcmCxxTests e.g.
36           ./Test/gdcmCxxTests hashtest
37     -- 3/ launch all the full test suite (again we assume cwd is GDCMBIN):
38           ctest
39           This is equivalent to "make test".
40           Note: ctest supports the argument filtering with regexp and
41                 the verbose mode e.g.
42                    ctest -R print -V
43                 proposes the tests containing "print" in their name and
44                 makes a verbose output. For other options refer to the
45                 documentation at http://www.cmake.org.
46
47 * Sending the result to kitware's dashboard (optional)
48   ctest -D Experimental
49   The results should appear in
50      http://public.kitware.com/dashboard.php?name=public
51      under the name of your machine (uname), but for ease of use you can
52      change the SITE variable in your CMakeCache.txt to something more 
53      accurate such as: GDCM-my_machine_name. The entry will then be within 
54      the "Experimental Builds" entry.
55
56 * Install gdcm (as specified by CMAKE_INSTALL_PREFIX)
57   make install
58   Note: the dictionaries used by gdcm are now located in
59         CMAKE_INSTALL_PREFIX + /share/ (i.e. GDCMINSTALL + /share/ if you
60         followed the above instructions).
61
62 * Python related section.
63   Depending on the cmake flags you used in order to compile gdcm could
64   be wrapped in two ways:
65   - the first python wrappers of gdcm uses Swig (http://www.swig.org). These
66     are the one generated when using autogen.sh --enable-python. 
67     The entry point here is the file gdcmPython/gdcm.i which uses the
68     Swig syntax. As the last lines of this file (the ones starting
69     with the %include directive) only some classes are wrapped for python.
70     In theory only the library interface (basically the classes gdcmHeader
71     and gdcmFile) should be wrapped, but the time being some additional
72     classes are added (just to make sure those classes are Swig compatible:
73     swig is here used as some link checker!?).
74     Since gdcm is written in C++, Swig will produce two different outputs:
75       -- some C based low level wrapper (see gdcmPython/gdcm_wrap.c)
76       -- some Python based object oriented so called "shadow classes" (see
77          file gdcmPython/gdcm.py)
78     We also added the file gdcmPython/__init__.py which is the one that
79     actually gets loaded when one uses the gdcmPython Python package.
80     The file __init__.py loads the Swig generated shadow classes (gdcm.py)
81     but will only re-export the interface of gdcm which corresponds to
82     the lines :
83        gdcmHeader = gdcm.gdcmHeader
84        gdcmDictSet = gdcm.gdcmDictSet
85        gdcmFile = gdcm.gdcmFile
86        [etc.]
87     Hence this whole Swig wrapping process is quite odd since we shall
88     wrap more classes (%include in swig.i) that eventually get exported to
89     the final user by gdcmPython/__init__.py.
90   - the second python wrappers uses the vtk (http://public.kitware.com/VTK/)
91     native wrappers i.e. the binary vtkWrapPython. But it should be noticed
92     that the purpose is here a bit different than the one of the Swig
93     generated Python wrappers. When using vtkWrapPython the goal is to
94     wrap a single vtk class namely vtkGdcmReader as defined in files
95     vtk/vtkGdcmReader.h and vtk/vtkGdcmReader.cxx (and of course those
96     files are hand made vtk oriented wrappers of gdcm).
97     Those wrappers are the one generated when using
98        autogen.sh --enable-python --enable-vtk
99   - In order to understand the difference between both wrappers you should 
100     compare both demo scripts gdcmPython/demo/vtkGdcmDemo.py and
101     gdcmPython/demo/vtkGdcmReader.py. The first one only uses the
102     Swig wrapped classes ("from gdcmPython import gdcmHeader') as opposed
103     to vtkGdcmReader.py which also uses vtkWrapPython wrapped classes
104     ("from gdcmPython.vtkgdcmPython import *").
105     
106 ------------------------------------------------------------------------------
107 gdcm coding style and religious/agnostic beliefs (proposition)
108    
109 * Introduction:
110    The following coding style intends to ease the work of developpers
111    themselves but also of users who will study, maintain, fix, and extend
112    the code. Any bread crumbs that you can drop in the way of explanatory
113    names and comments will go a long way towards helping other readers and
114    developers.
115    Keep in mind that to a large extent the structure of code directly
116    expresses its implementation.
117
118 * Language:
119  - C++ (for the kernel) and Python (for the wrappers).
120  - all the names (variables, members, methods, functions) and comments
121    should be based on English. Documentation, guides, web site and other
122    informations should be in English.
123    Make sure you use correct (basic) English and complete, grammatically
124    correct sentences for comments and documentation.
125
126 * General layout:
127  - Each line of code should take no more than 79 characters. Break the code
128    across multiple lines as necessary. 
129  - Methods and functions should keep a reasonable number of lines when
130    possible (a typical editor displays 50 lines). Avoid code duplication.
131    Always prefer creating a new method or function to duplication.
132    A high indentation level generally suggests the need for a new
133    method or function.
134  - All the code should be properly indented. The appropriate indentation
135    level is three spaces for each level of indentation. DO NOT USE TABS.
136    Set up your editor to insert spaces. Using tabs may look good in your
137    editor but will wreak havoc in others, or in external tools (e.g. side
138    by side diffs).
139  - The declaration of variables within classes, methods, and functions
140    should be one declaration per line. Provide them with default values
141    and don't rely on compilers for default initialization.
142
143 * Naming conventions:
144  - Generalities:
145    In general, names are constructued by using case change to indicate
146    separate words, as in ImageDataSize (standing for "image data size").
147    Underscores are not used. Variable names are chosen carefully with the
148    intention to convey the meaning behind the code. Names are generally
149    spelled out; use of abbreviations is discouraged.
150    [Note: abbreviation are allowable when in common use, and should be in
151     uppercase as in LUT or RGBA.]
152    While this does result in long names, it self-documents the code.
153  - Naming Files:
154    Files should have the same name as the class, with a "gdcm" prepended.
155    Header files are named .h, while implementation files are named either
156    .cxx or .txx, depending on whether they are implementations of templated
157    classes. For example, the class gdcm::Document is declared and defined
158    in the files gdcmDocument.h and gdcmDocument.cxx.
159  - Naming Class Data Members, Methods, and Functions:
160    Class data members are named beginning with a capital letter as in
161    GroupPixel.
162    Global functions and class methods, either static or class members, are
163    named beginning with a capital letter, as in GetImageDataSize().
164  - Naming Local Variables:
165    Local variables begin in lowercase. There is more flexibility in the
166    naming of local variables although they still should convey some
167    semantics.
168
169 * Classes:
170  - Don't use the inline keyword when defining an inline function
171    within a class definition.
172  - Do not repeat the virtual keyword when overriding virtual base methods
173    in declaration of subclasses:
174      class A 
175      {
176         virtual void foo(...);
177      };
178      class B: public A
179      {
180         void foo(...);          // and not: virtual void foo(...);
181      };
182  - The public, protected, private declarations should be at the
183    same indent level as the class. Use
184      class A 
185      {
186      private:
187         void foo(...);
188      public:
189         void bar(...);
190      };
191  - Method and functions devoided of arguments should not use the void
192    notation. Use
193      SomeType Header::GetPixelData()
194    and not
195      SomeType Header::GetPixelData(void).
196
197 * Use of braces:
198  - Braces must be used to delimit the scope of an if, for, while, switch, or
199    other control structure. Braces are placed on a line by themselves, and
200    at the same indentation level as the control structure to which they
201    belong:
202       for (i=0; * i<3; i++)
203       {
204          ...
205       }
206    or when using an if:
207       if ( condition )
208       {
209          ...
210       }
211       else if ( other condition )
212       {
213          ...
214       }
215       else
216       {
217          ....
218       }
219    You can choose to use braces on a line with a code block when
220    the block consists of a single line:
221       if ( condition ) { foo=1; }
222       else if ( condition2 ) { foo=3; }
223       else { return; }
224    or
225       for (i=0; i<3; ++i) {x[i]=0.0;}
226    Methods and functions should follow the same usage of braces:
227       void File::ParsePixelData()
228       {
229          ...
230       }
231
232 * Special layout:
233  - Avoid code mixed with comments on a single line. Instead, prepend the
234    logical blocks of code with the concerned comments.
235  - Use parantheses around conditions e.g. with an if statement: 
236       if ( someLocalVariable == 2 ) { ... }
237  - Add spaces around parantheses, or braces. Use
238       if ( someLocalVariable == 2 ) { ClassMenber += 1; }
239    and not
240       if (someLocalVariable == 2) {ClassMenber += 1;}
241  - Add spaces around each side of the assignement operator, and
242    around binary operators used in boolean expression. Use
243       someLocalVariable = ClassMember * 2;
244       if ( someLocalVariable == 2 || ClassMember == 2 ) ...
245    and not
246       someLocalVariable=ClassMember*2;
247       if ( someLocalVariable==2||ClassMember==2 ) ...
248
249 * Miscelaneous:
250  - Don't use underscores. Don't use tabs. Don't use control characters
251    like ^M. Anyhow, cvs is configured to reject such commits.
252  - Comments should be in C++ style ("// ...", two slashes, per line). Don't
253    use C style comments ("/* ... */").
254  - The last line of a file should terminate with "\n".
255  - Returned arguments of methods and functions should not be wrapped with
256    parantheses. Use 
257       return iter->second;
258    but do not use
259       return ( iter->second );
260
261 * Debugging and Verbose modes:
262    Never use std::cout. Instead use the gdcmDebug class through the
263    global instance dbg. Example:
264       #include "gdcmDebug.h"
265       ...
266       {
267          dbg.Verbose(3, "Local function name: entering.");
268          ...
269       }
270     will send the message to std::cout when dbg.Debug() is called
271     in your main.
272
273 * Documentation:
274    The Doxygen open-source system is used to generate on-line documentation.
275    Doxygen requires the embedding of simple comments in the code which is in
276    turn extracted and formatted into documentation. See
277       http://www.stack.nl/ dimitri/doxygen/
278    for more information about Doxygen.
279  - Documenting a class:
280    Classes should be documented using the class and brief doxygen commands,
281    followed by the detailed class description:
282       /**
283        * \class Header
284        * \brief Header acts as container of Dicom elements of an image.
285        *
286        * Detailed description of the class is provided here
287        * ...
288        */
289    The key here is that the comment starts with /**, each subsequent line has
290    an aligned *, and the comment block terminates with a */.
291  - Documenting class members and inline methods:
292    All the members and the inline methods should be documented within
293    the class declaration as shown in the following example:
294       class Header
295       {
296          /// True when parsing was succefull. False otherwise.
297          bool Readable = false;
298
299          /// \brief The number of lines of the image as interpreted from
300          /// the various elements encountered at header parsing.
301          int NumberOfLines = -1;
302
303          /// Predicate implemented as accessor around \ref Readable.
304          bool IsReadable() { return Readable; }
305       };
306  - Documenting a Method:
307    Methods should be documented using the following comment block style
308    as shown in the following example:
309
310       /**
311        * \brief  Within the Dicom Elements (parsed with the public and private
312        *         dictionaries), look for the element value representation of
313        *         a given tag.
314        * @param  group Group number of the searched tag.
315        * @param  element Element number of the searched tag.
316        * @return Corresponding element value representation when it exists,
317        *         and the string "gdcm::Unfound" otherwise.
318        */
319       std::string Document::GetEntryByNumber(guint16 group, guint16 element)
320       {
321          ...
322       }
323
324 * External includes and C style:
325  - Only the C++ standard library and the STL includes should be used.
326    When including don't use the .h extension (use #include <iostream>
327    instead of #include <iostream.h>).
328  - Don't use the C standard library. Don't include stdio.h, ctype.h...
329    Don't use printf(), sprinf(), FILE*...
330  - Don't use the NULL notation (either as macro, or as const int NULL=0).
331    A pointer that doesn't refer to an object should simply be defined as
332       DataPointer* MyDataPointer = 0;
333
334 * Basic types:
335  - Assume T is a given type. When declaring or defining with the 
336    "pointer to T" notation, the * character must be adjacent to
337    the type and not the variable. That is use
338       T* foo = 0;
339    and not 
340       T *foo = 0;
341  - Always define a typedef for a new type and be consistent in usage.
342    Use
343       typedef Header* HeaderPointer;
344       HeaderPointer MyHeaderPointer;
345  - One notorious counter example for non using C style inclusion concerns
346    exact-width intergers (since there seem to be no equivalent for C++).
347    When using exact-width integers use the typedef names defined by
348    the Basic ISO C99: 7.18 Integer types i.e.
349       int8_t     int16_t     int32_t     int64_t (signed integers)
350    and
351       uint8_t    uint16_t    uint32_t    uint64_t (unsigned integers).
352    Hence do not use declarations like "unsigned int".
353    With g++, accessing those typedef is achieved by the following
354       #include <stdint.h>
355 ------------------------------------------------
356 CVS policy
357 * All the commits should be atomic. They must preserve the compilation
358   in order to prevent checkouts with broken code.
359 * All the commits must correspond to a stade of the code where ctest
360   runs and has no failing subtest. Always run ctest before commiting.
361   Note: * you can start ctest in verbose mode through the command
362              ctest -V >& log
363         * you can start a single test through ctest with
364              ctest -R FailingTestName -V >& log
365 ------------------------------------------------