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