| 1 |
INTRODUCTION |
|---|
| 2 |
--------------------------------------------------------------------- |
|---|
| 3 |
Here will you find coding standards to the project. Requirements are |
|---|
| 4 |
listed in their respective files and can be considered an adendum to |
|---|
| 5 |
this document. |
|---|
| 6 |
|
|---|
| 7 |
|
|---|
| 8 |
CODING STYLE |
|---|
| 9 |
--------------------------------------------------------------------- |
|---|
| 10 |
See linux/Documentation/CodingStyle. |
|---|
| 11 |
|
|---|
| 12 |
Some highlights: |
|---|
| 13 |
|
|---|
| 14 |
- Outside of comments and documentation, never |
|---|
| 15 |
use spaces. Identation is done using tabs only. |
|---|
| 16 |
|
|---|
| 17 |
- Do not use tabs to align text documentation. Changing tab |
|---|
| 18 |
width should not interfere with the layout/alignment of code, |
|---|
| 19 |
only indentation. |
|---|
| 20 |
|
|---|
| 21 |
- functions are declared like this: |
|---|
| 22 |
char *function(const char *test) |
|---|
| 23 |
{ |
|---|
| 24 |
|
|---|
| 25 |
} |
|---|
| 26 |
|
|---|
| 27 |
- if you use brackets INSIDE a function put them on the same line |
|---|
| 28 |
|
|---|
| 29 |
Wrong: |
|---|
| 30 |
if (condition) |
|---|
| 31 |
{ |
|---|
| 32 |
do_something; |
|---|
| 33 |
} |
|---|
| 34 |
|
|---|
| 35 |
Right: |
|---|
| 36 |
if (condition) { |
|---|
| 37 |
do_something; |
|---|
| 38 |
} |
|---|
| 39 |
|
|---|
| 40 |
- Do not put actions in the same line of conditions: |
|---|
| 41 |
|
|---|
| 42 |
Wrong: |
|---|
| 43 |
if (condition) do_this; |
|---|
| 44 |
|
|---|
| 45 |
Right: |
|---|
| 46 |
if (condition) |
|---|
| 47 |
do_this; |
|---|
| 48 |
|
|---|
| 49 |
- Variables are always in lower case (like tmp_buf) |
|---|
| 50 |
- New defined types are capitalized (like OSyncEngine) |
|---|
| 51 |
- Never use typedefs just to hide pointers |
|---|
| 52 |
|
|---|
| 53 |
- External APIs, used for integration between components may |
|---|
| 54 |
look like this: |
|---|
| 55 |
|
|---|
| 56 |
osync_engine_init() |
|---|
| 57 |
|
|---|
| 58 |
- Always add the osync_ prefix to your functions |
|---|
| 59 |
|
|---|
| 60 |
- Do not return function calls, like "return do_something();", |
|---|
| 61 |
instead, use a auxiliar variable (rationale: easy trace). |
|---|
| 62 |
|
|---|
| 63 |
- When doing error checking, use goto to help creating a single |
|---|
| 64 |
return point. Do not abuse goto usage though... never goto up, |
|---|
| 65 |
never create more than one label and do not "gotoo far". |
|---|
| 66 |
|
|---|
| 67 |
|
|---|
| 68 |
CODE DOCUMENTATION |
|---|
| 69 |
--------------------------------------------------------------------- |
|---|
| 70 |
|
|---|
| 71 |
* Add FIXME, TODO and XXX comments appropriately. |
|---|
| 72 |
|
|---|
| 73 |
* Doxygen |
|---|
| 74 |
|
|---|
| 75 |
* Add simple READMEs and pictures as needed, but concentrate |
|---|
| 76 |
on doxygen. |
|---|
| 77 |
|
|---|
| 78 |
CODE INSTRUMENTATION |
|---|
| 79 |
----------------------------------------------------------------- |
|---|
| 80 |
|
|---|
| 81 |
Always: |
|---|
| 82 |
* Use const; |
|---|
| 83 |
* Use static for internal functions; |
|---|
| 84 |
* Use safe glib functions where possible; |
|---|
| 85 |
* Check validity of all received parameters; |
|---|
| 86 |
* Use assert() while developing; |
|---|
| 87 |
* Do not use alloca() or other non-recommended functions; |
|---|
| 88 |
* Check for return errors even from malloc() and other |
|---|
| 89 |
standard system calls; |
|---|
| 90 |
|
|---|
| 91 |
Regularly: |
|---|
| 92 |
* Use valgrind to profile you application and find memleaks |
|---|
| 93 |
|
|---|
| 94 |
About header files: |
|---|
| 95 |
* Source code has to be split into modules, which are defined as |
|---|
| 96 |
a collection of implementation files (.c) with an interface |
|---|
| 97 |
exported through a header file (.h). |
|---|
| 98 |
* The inclusion (#include) of headers must reflect the dependencies |
|---|
| 99 |
between modules in the implementation. The most important |
|---|
| 100 |
implications from this statement are: |
|---|
| 101 |
|
|---|
| 102 |
. implementation files (.c) *must* include *all* headers it |
|---|
| 103 |
directly depends; |
|---|
| 104 |
. implementation files (.c) *must not* include headers it |
|---|
| 105 |
doesn't directly depend; |
|---|
| 106 |
. headers should include headers only when needing a |
|---|
| 107 |
definition or declaration; |
|---|
| 108 |
. headers should never include other headers just to create a |
|---|
| 109 |
"single point of inclusion". |
|---|
| 110 |
|
|---|
| 111 |
These rules may sound obvious, but they're actually hard to |
|---|
| 112 |
follow. |
|---|
| 113 |
|
|---|
| 114 |
|
|---|
| 115 |
COMMITS AND CHANGELOGS |
|---|
| 116 |
--------------------------------------------------------------------- |
|---|
| 117 |
Descriptive and small. |
|---|
| 118 |
|
|---|
| 119 |
General rules: |
|---|
| 120 |
- *Always* do a svn diff and a svn status before a commit and |
|---|
| 121 |
document the diff(s) in the changelogs; |
|---|
| 122 |
- What matters is not what but why; |
|---|
| 123 |
- Several commits are usually better than a big one; |
|---|
| 124 |
- Do not commit unrelated modifications at once unless they're |
|---|
| 125 |
really trivial; |
|---|
| 126 |
- Commit ASAP. |
|---|
| 127 |
|
|---|
| 128 |
BUILD-SYSTEM |
|---|
| 129 |
--------------------------------------------------------------------- |
|---|
| 130 |
Standard instructions: |
|---|
| 131 |
|
|---|
| 132 |
Code should compile with no warnings, using the following GCC |
|---|
| 133 |
options: |
|---|
| 134 |
|
|---|
| 135 |
-Wall |
|---|
| 136 |
-Werror |
|---|
| 137 |
|
|---|
| 138 |
Recomended but not mandatory (for now): |
|---|
| 139 |
-W |
|---|
| 140 |
-Wmissing-declarations |
|---|
| 141 |
-Wmissing-prototypes |
|---|
| 142 |
-Wredundant-decls |
|---|
| 143 |
-Wshadow |
|---|
| 144 |
-Wbad-function-cast |
|---|
| 145 |
-Wcast-qual |
|---|
| 146 |
-std=iso9899:1990 |
|---|
| 147 |
|
|---|
| 148 |
LOGS and TRACES |
|---|
| 149 |
--------------------------------------------------------------------- |
|---|
| 150 |
There are two types of logs that must be handled by almost all |
|---|
| 151 |
applications: |
|---|
| 152 |
|
|---|
| 153 |
* HIGH-LEVEL LOGS: these are standard, high-level logs usually |
|---|
| 154 |
enabled by default. Useful to advanced users, support-centers and |
|---|
| 155 |
alike. Should include basic information, including but not limited |
|---|
| 156 |
to: |
|---|
| 157 |
- start/end of application |
|---|
| 158 |
- errors |
|---|
| 159 |
- complex operations |
|---|
| 160 |
|
|---|
| 161 |
The requirements document specifies if logs are needed or not. |
|---|
| 162 |
|
|---|
| 163 |
* TRACES: traces are a particular kind of log used to debug the |
|---|
| 164 |
application. They're used mostly by black-box testers to submit |
|---|
| 165 |
failure reports. |
|---|
| 166 |
|
|---|
| 167 |
Traces should be enabled in a per-application basis using an |
|---|
| 168 |
envinronment variable or at compile time, to be yet defined. |
|---|
| 169 |
|
|---|
| 170 |
UNIT TESTS |
|---|
| 171 |
----------------------------------------------------------------- |
|---|
| 172 |
|
|---|
| 173 |
* All code should be written together with unit-tests. The tool |
|---|
| 174 |
used to implement the tests is "check", available on |
|---|
| 175 |
http://check.sourceforge.net/. |
|---|
| 176 |
|
|---|
| 177 |
The build-system infra-structure provides a configure option to |
|---|
| 178 |
allow check usage. |
|---|
| 179 |
|
|---|
| 180 |
The tests must be implemented inside a sub-directory called test |
|---|
| 181 |
with the following modules: |
|---|
| 182 |
|
|---|
| 183 |
check_<component name> --> the test-manager |
|---|
| 184 |
check_<unit name> --> implements tests for interfaces |
|---|
| 185 |
exported by unit |
|---|
| 186 |
check_<...> |
|---|
| 187 |
|
|---|
| 188 |
Just to remember, an unit, or module, is a collection of |
|---|
| 189 |
souce-code files (.c) with an interface exported through |
|---|
| 190 |
a header file (.h). |
|---|
| 191 |
|
|---|
| 192 |
All interfaces exported by units must be tested (that is, |
|---|
| 193 |
all non-static functions). The tests should implement at |
|---|
| 194 |
least the following test cases: |
|---|
| 195 |
|
|---|
| 196 |
- standard usage |
|---|
| 197 |
- upper and bottom limits of buffers and variables as |
|---|
| 198 |
needed |
|---|
| 199 |
- error conditions |
|---|
| 200 |
- critical paths |
|---|
| 201 |
|
|---|
| 202 |
Use incremental tests, that is, test functions before using them in |
|---|
| 203 |
other test-cases (for example, if you need to call function A to |
|---|
| 204 |
prepare the environment to test function B, test function A first). |
|---|
| 205 |
|
|---|
| 206 |
Try to write the test-case before the unit or function itself. |
|---|
| 207 |
|
|---|
| 208 |
If the test needs an external entity to work (for example, it needs |
|---|
| 209 |
a device connected on a specific port), put the test inside a |
|---|
| 210 |
condition for an environemnt variable and document it in a README |
|---|
| 211 |
file. |
|---|