Preferred date format for documenttaion
[geeqie.git] / CODING.md
1 # Coding and Documentation Style
2
3 [Error Logging](#error-logging)  
4 [GPL header](#gpl-header)  
5 [Git change log](#git-change-log)  
6 [Source Code Style](#source-code-style)  
7 [Shell Script Style](#shell-script-style)  
8 [External Software Tools](#external-software-tools)  
9 [Geeqie Software Tools](#geeqie-software-tools)  
10 [Documentation](#documentation)  
11 [Documentation - C code](#c-code)  
12 [Documentation - Script files](#script-files)  
13 [Documentation - Markdown](#markdown)  
14 [Doxygen](#doxygen)  
15
16 ---
17
18 ## Error Logging
19
20 ### DEBUG_0()
21
22 Use `DEBUG_0()` only for temporary debugging i.e. not in code in the repository.
23 The user will then not see irrelevant debug output when the default
24 `debug level = 0` is used.
25
26 ### log_printf()
27
28 If the first word of the message is "error" or "warning" (case insensitive) the message will be color-coded appropriately.
29
30 - Note that these messages are output in the idle loop.
31
32 ### print_term()
33
34 `print_term(gboolean err, const gchar *text_utf8)`
35
36 - If `err` is TRUE output is to STDERR, otherwise to STDOUT
37
38 ### DEBUG_NAME(widget)
39
40 For use with the [GTKInspector](https://wiki.gnome.org/action/show/Projects/GTK/Inspector?action=show&redirect=Projects%2FGTK%2B%2FInspector) to provide a visual indication of where objects are declared.
41
42 Sample command line call:  
43 `GTK_DEBUG=interactive src/geeqie`
44
45 ---
46
47 ## GPL header
48
49 Include a header in every file, like this:  
50
51 ```c
52 /*
53  * Copyright (C) <year> The Geeqie Team
54  *
55  * Author: Author1  
56  * Author: Author2  
57  *  
58  * This program is free software; you can redistribute it and/or modify
59  * it under the terms of the GNU General Public License as published by
60  * the Free Software Foundation; either version 2 of the License, or
61  * (at your option) any later version.
62  *
63  * This program is distributed in the hope that it will be useful,
64  * but WITHOUT ANY WARRANTY; without even the implied warranty of
65  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
66  * GNU General Public License for more details.
67  *
68  * You should have received a copy of the GNU General Public License along
69  * with this program; if not, write to the Free Software Foundation, Inc.,
70  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
71  *
72  *
73  * Optional description of purpose of file.
74  *
75 */  
76 ```
77
78 ---
79
80 ## git change-log
81
82 If referencing a Geeqie GitHub issue, include the issue number in the summary line and a hyperlink to the GitHub issue webpage in the message body. Start with a short summary in the first line (without a dot at the end) followed by a empty line.
83
84 Use whole sentences beginning with Capital letter. For each modification use a new line. Or you can write the theme, colon and then every change on new line, begin with "- ".
85
86 See also [A Note About Git Commit Messages](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html)
87
88 Example:
89
90 ```text
91 I did some bugfixes
92
93 There was the bug that something was wrong. I fixed it.
94
95 Library:
96 - the interface was modified
97 - new functions were added`
98 ```
99
100 Also please use your full name and a working e-mail address as author for any contribution.
101
102 ---
103
104 ## Source Code Style
105
106 Indentation: tabs at 4 spaces
107
108 Names:
109
110 - of variables & functions: small\_letters  
111 - of defines: CAPITAL\_LETTERS
112
113 Try to use explicit variable and function names.  
114 Try not to use macros.  
115 Use **either** "struct foo" OR "foo"; never both
116
117 Conditions, cycles:  
118
119 ```c
120 if (<cond>)
121     {
122     <command>;
123     ...
124     <command>;
125     }
126 else
127     {
128     <command>;
129     ...
130     <command>;
131     }
132
133 if (<cond_very_very_very_very_very_very_very_very_very_long> &&
134 <cond2very_very_very_very_very_very_very_very_very_long>)
135 <the_only_command>;
136
137 switch (<var>)
138     {
139     case 0:
140         <command>;
141         <command>;
142         break;
143     case 1:
144         <command>; break;
145     }
146
147 for (i = 0; i <= 10; i++)
148     {
149     <command>;
150     ...
151     <command>;
152     }
153 ```
154
155 Functions:
156
157 ```c
158 gint bar(<var_def>, <var_def>, <var_def>)
159 {
160     <command>;
161     ...
162     <command>;
163
164     return 0; // i.e. SUCCESS; if error, you must return minus <err_no> @FIXME
165 }
166
167 void bar2(void)
168 {
169     <command>;
170     ...
171     <command>;
172 }
173 ```
174
175 Pragma: (Indentation 2 spaces)
176
177 ```c
178 #ifdef ENABLE_NLS
179 #  undef _
180 #  define _(String) (String)
181 #endif /* ENABLE_NLS */
182 ```
183
184 Headers:
185
186 ```c
187 #ifndef _FILENAME_H
188 ```
189
190 Use spaces around every operator (except `.`, `->`, `++` and `--`).  
191 Unary operator `*` and `&` are missing the space from right, (and also unary `-`).
192
193 As you can see above, parentheses are closed to inside, i.e. ` (blah blah) `  
194 In `function(<var>)` there is no space before the `(`.  
195 You *may* use more tabs/spaces than you *ought to* (according to this CodingStyle), if it makes your code nicer in being vertically indented.  
196 Variables declarations should be followed by a blank line and should always be at the start of the block.  
197
198 Use glib types when possible (ie. gint and gchar instead of int and char).  
199 Use glib functions when possible (i.e. `g_ascii_isspace()` instead of `isspace()`).  
200 Check if used functions are not deprecated.  
201 Use UNUSED() for unused function parameters.
202
203 ---
204
205 ## Shell Script Style
206
207 Use `/bin/sh` as the interpreter directive.  
208 Ensure the script is POSIX compliant.  
209 Use `printf` rather than `echo` except for plain text.  
210 There are several versions of `mktemp`. Using the following definition helps portability (note that `template` is not optional):
211
212 ```sh
213 mktemp [-d] [-q] template ...
214 ```
215
216 and use for example this style:
217
218 ```sh
219 mktemp  "${TMPDIR:-/tmp}/geeqie.XXXXXXXXXX"
220 ```
221
222 ---
223 ## External Software Tools
224
225 ### astyle
226
227 There is no code format program that exactly matches the above style, but if you are writing new code the following command line program formats code to a fairly close level:
228
229 ```sh
230 astyle --options=<options file>
231 ```
232
233 Where the options file might contain:
234
235 ```text
236 style=vtk
237 indent=force-tab
238 pad-oper
239 pad-header
240 unpad-paren
241 align-pointer=name
242 align-reference=name
243 ```
244
245 ### cppcheck
246
247 A lint-style program may be used, e.g.
248
249 ```sh
250 cppcheck --language=c --library=gtk --enable=all --force  -USA_SIGINFO -UZD_EXPORT -Ugettext_noop -DG_KEY_FILE_DESKTOP_GROUP --template=gcc -I .. --quiet --suppressions-list=<suppressions file>
251 ```
252
253 Where the suppressions file might contain:
254
255 ```text
256 missingIncludeSystem
257 variableScope
258 unusedFunction
259 unmatchedSuppression
260 ```
261
262 ### markdownlint
263
264 Markdown documents may be validated with e.g. [markdownlint](https://github.com/markdownlint/markdownlint).
265
266 ```sh
267 mdl --style <style file>`
268 ```
269
270 Where the style file might contain:
271
272 ```text
273 all
274 rule 'MD007', :indent => 4
275 rule 'MD009', :br_spaces => 2
276 rule 'MD010', :code_blocks => true
277 exclude_rule 'MD013'
278 ```
279
280 ### shellcheck
281
282 Shell scripts may also be validated, e.g.
283
284 ```sh
285 shellcheck --enable=add-default-case,avoid-nullary-conditions,check-unassigned-uppercase,deprecate-which,quote-safe-variables
286 ```
287
288 ### shfmt
289
290 Shell scripts may formatted to some extent with [shfmt](https://github.com/mvdan/sh). At the time of writing it does not format `if`, `for` or `while` statements in the style used by Geeqie.  
291 However the following script can be used to achieve that:
292
293 ```sh
294 #!/bin/sh
295
296 shfmt -s -p -ci -sr -fn | awk '
297     {if ($0 ~ /; then/)
298         {
299         match($0, /^\t*/);
300         printf('%s\n', substr($0, 0, length($0) - 6));
301         printf('%s, substr("\t\t\t\t\t\t\t\t\t\t", 1, RLENGTH))
302         print("then")
303         }
304     else if ($0 ~ /; do/)
305         {
306         match($0, /^\t*/);
307         printf('%s\n', substr($0, 0, length($0) - 4));
308         printf('%s', substr("\t\t\t\t\t\t\t\t\t\t", 1, RLENGTH))
309         print("do")
310         }
311     else
312         {
313         print
314         }
315     }'
316 ```
317
318 ### xmllint
319
320 The .xml Help files may be validated with e.g. `xmllint`.
321
322 ---
323
324 ## Geeqie Software Tools
325
326 See the shell scripts section in the Doxygen documentation (`File List`, `detail level 3`, except the `src` sublist).
327
328 ---
329
330 ## Documentation
331
332 Use American, rather than British English, spelling. This will facilitate consistent
333 text searches. User text may be translated via the en_GB.po file.
334
335 To avoid confusion between American and British date formats, use ISO format (YYYY-MM-DD) where possible.
336
337 To document the code use the following rules to allow extraction with Doxygen.  
338 Not all comments have to be Doxygen comments.
339
340 ### C code
341
342 - Use C comments in plain C files and use C++ comments in C++ files for one line comments.
343 - Use `/**` (note the two asterisks) to start comments to be extracted by Doxygen and start every following line with ` *` as shown below.
344 - Use `@` to indicate Doxygen keywords/commands (see below).
345 - Use the `@deprecated` command to indicate the function is subject to be deleted or to a  complete rewrite.
346
347 To document functions or big structures:
348
349 ```c
350 /**
351  * @brief This is a short description of the function.
352  *
353  * This function does ...
354  *
355  * @param x1 This is the first parameter named x1
356  * @param y1 This is the second parameter named y1
357  * @return What the function returns
358  *    You can extend that return description (or anything else) by indenting the
359  *    following lines until the next empty line or the next keyword/command.
360  * @see Cross reference
361  */
362 ```
363
364 To document members of a structure that have to be documented (use it at least
365 for big structures) use the `/**<` format:  
366
367 ```c
368 gint counter; /**< This counter counts images */
369
370 ```
371
372 Document TODO or FIXME comments as:  
373
374 ```c
375 /**  
376 * @todo
377 ```
378
379 or
380
381 ```c
382 /**  
383 * @FIXME
384 ```
385
386 ### Script files
387
388 Script files such as .sh, .pl, and .awk should have the file relevant file extension or be symlinked as so.
389
390 Doxygen comments should start each line with `##`, and each file should contain:
391
392 ```sh
393 ## @file
394 ## @brief <one line description>
395 ## <contents description>
396 ##
397 ```
398
399 ### Markdown
400
401 For a newline use two spaces (a backslash is not interpreted correctly by Doxygen).
402
403 ## Doxygen
404
405 For further documentation about Doxygen see the [Doxygen Manual](https://www.doxygen.nl/index.html).  
406 For the possible commands you may use, see [Doxygen Special Commands](https://www.doxygen.nl/manual/commands.html).
407
408 The file `./scripts/doxygen-help.sh` may be used to integrate access to the Doxygen files into a code editor.
409
410 The following environment variables may be set to personalize the Doxygen output:
411
412 ```sh
413 DOCDIR=<output folder>
414 SRCDIR=<the top level directory of the project>
415 PROJECT=
416 VERSION=
417 PLANTUML_JAR_PATH=
418 INLINE_SOURCES=<YES|NO>
419 STRIP_CODE_COMMENTS=<YES|NO>
420 ```
421
422 Ref: [INLINE\_SOURCES](https://www.doxygen.nl/manual/config.html#cfg_inline_sources)  
423 Ref: [STRIP\_CODE\_COMMENTS](https://www.doxygen.nl/manual/config.html#cfg_strip_code_comments)
424
425 For shell scripts to be documented, the file `doxygen-bash.sed` must be in the `$PATH` environment variable.  
426 It can be download from here:
427
428 ```sh
429 wget https://raw.githubusercontent.com/Anvil/bash-doxygen/master/doxygen-bash.sed
430 chmod +x doxygen-bash.sed
431 ```
432
433 To include diagrams in the Doxygen output, the following are required to be installed. The installation process will vary between distributions:
434
435 [The PlantUML jar](https://plantuml.com/download)
436
437 ```sh
438 sudo apt install default-jre
439 sudo apt install texlive-font-utils
440 ```
441
442 ---
443
444 But in case just think about that the documentation is for other developers not
445 for the end user. So keep the focus.