blob: fd1984d303eba89c968ac8b0d33fa7db5dfbf116 [file] [log] [blame]
Paul Beesley07f0a312019-05-16 13:33:18 +01001Coding Style
2============
3
4The following sections outline the |TF-A| coding style for *C* code. The style
5is based on the `Linux kernel coding style`_, with a few modifications.
6
7The style should not be considered *set in stone*. Feel free to provide feedback
8and suggestions.
9
10.. note::
11 You will almost certainly find code in the |TF-A| repository that does not
12 follow the style. The intent is for all code to do so eventually.
13
14File Encoding
15-------------
16
17The source code must use the **UTF-8** character encoding. Comments and
18documentation may use non-ASCII characters when required (e.g. Greek letters
19used for units) but code itself is still limited to ASCII characters.
20
21Newlines must be in **Unix** style, which means that only the Line Feed (``LF``)
22character is used to break a line and reset to the first column.
23
24Language
25--------
26
27The primary language for comments and naming must be International English. In
28cases where there is a conflict between the American English and British English
29spellings of a word, the American English spelling is used.
30
31Exceptions are made when referring directly to something that does not use
32international style, such as the name of a company. In these cases the existing
33name should be used as-is.
34
35C Language Standard
36-------------------
37
38The C language mode used for TF-A is *GNU99*. This is the "GNU dialect of ISO
39C99", which implies the *ISO C99* standard with GNU extensions.
40
41Both GCC and Clang compiler toolchains have support for *GNU99* mode, though
42Clang does lack support for a small number of GNU extensions. These
43missing extensions are rarely used, however, and should not pose a problem.
44
45MISRA Compliance
46----------------
47
48TF-A attempts to comply with the `MISRA C:2012 Guidelines`_. Coverity
49Static Analysis is used to regularly generate a report of current MISRA defects
50and to prevent the addition of new ones.
51
52It is not possible for the project to follow all MISRA guidelines. We maintain
53`a spreadsheet`_ that lists all rules and directives and whether we aim to
54comply with them or not. A rationale is given for each deviation.
55
56.. note::
57 Enforcing a rule does not mean that the codebase is free of defects
58 of that rule, only that they would ideally be removed.
59
60.. note::
61 Third-party libraries are not considered in our MISRA analysis and we do not
62 intend to modify them to make them MISRA compliant.
63
64Indentation
65-----------
66
67Use **tabs** for indentation. The use of spaces for indentation is forbidden
68except in the case where a term is being indented to a boundary that cannot be
69achieved using tabs alone.
70
71Tab spacing should be set to **8 characters**.
72
73Trailing whitespace is not allowed and must be trimmed.
74
75Spacing
76-------
77
78Single spacing should be used around most operators, including:
79
80- Arithmetic operators (``+``, ``-``, ``/``, ``*``)
81- Assignment operators (``=``, ``+=``, etc)
82- Boolean operators (``&&``, ``||``)
83- Comparison operators (``<``, ``>``, ``==``, etc)
84
85A space should also be used to separate parentheses and braces when they are not
86already separated by a newline, such as for the ``if`` statement in the
87following example:
88
89.. code:: c
90
91 int function_foo(bool bar)
92 {
93 if (bar) {
94 function_baz();
95 }
96 }
97
98Note that there is no space between the name of a function and the following
99parentheses.
100
101Control statements (``if``, ``for``, ``switch``, ``while``, etc) must be
102separated from the following open paranthesis by a single space. The previous
103example illustrates this for an ``if`` statement.
104
105Line Length
106-----------
107
108Line length *should* be at most **80 characters**. This limit does not include
109non-printing characters such as the line feed.
110
111This rule is a *should*, not a must, and it is acceptable to exceed the limit
112**slightly** where the readability of the code would otherwise be significantly
113reduced. Use your judgement in these cases.
114
115Blank Lines
116-----------
117
118Functions are usually separated by a single blank line. In certain cases it is
119acceptable to use additional blank lines for clarity, if required.
120
121The file must end with a single newline character. Many editors have the option
122to insert this automatically and to trim multiple blank lines at the end of the
123file.
124
125Braces
126------
127
128Opening Brace Placement
129^^^^^^^^^^^^^^^^^^^^^^^
130
131Braces follow the **Kernighan and Ritchie (K&R)** style, where the opening brace
132is **not** placed on a new line.
133
134Example for a ``while`` loop:
135
136.. code:: c
137
138 while (condition) {
139 foo();
140 bar();
141 }
142
143This style applies to all blocks except for functions which, following the Linux
144style, **do** place the opening brace on a new line.
145
146Example for a function:
147
148.. code:: c
149
150 int my_function(void)
151 {
152 int a;
153
154 a = 1;
155 return a;
156 }
157
158Conditional Statement Bodies
159^^^^^^^^^^^^^^^^^^^^^^^^^^^^
160
161Where conditional statements (such as ``if``, ``for``, ``while`` and ``do``) are
162used, braces must be placed around the statements that form the body of the
163conditional. This is the case regardless of the number of statements in the
164body.
165
166.. note::
167 This is a notable departure from the Linux coding style that has been
168 adopted to follow MISRA guidelines more closely and to help prevent errors.
169
170For example, use the following style:
171
172.. code:: c
173
174 if (condition) {
175 foo++;
176 }
177
178instead of omitting the optional braces around a single statement:
179
180.. code:: c
181
182 /* This is violating MISRA C 2012: Rule 15.6 */
183 if (condition)
184 foo++;
185
186The reason for this is to prevent accidental changes to control flow when
187modifying the body of the conditional. For example, at a quick glance it is easy
188to think that the value of ``bar`` is only incremented if ``condition``
189evaluates to ``true`` but this is not the case - ``bar`` will always be
190incremented regardless of the condition evaluation. If the developer forgets to
191add braces around the conditional body when adding the ``bar++;`` statement then
192the program execution will not proceed as intended.
193
194.. code:: c
195
196 /* This is violating MISRA C 2012: Rule 15.6 */
197 if (condition)
198 foo++;
199 bar++;
200
201Naming
202------
203
204Functions
205^^^^^^^^^
206
207Use lowercase for function names, separating multiple words with an underscore
208character (``_``). This is sometimes referred to as *Snake Case*. An example is
209given below:
210
211.. code:: c
212
213 void bl2_arch_setup(void)
214 {
215 ...
216 }
217
218Local Variables and Parameters
219^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
220
221Local variables and function parameters use the same format as function names:
222lowercase with underscore separation between multiple words. An example is
223given below:
224
225.. code:: c
226
227 static void set_scr_el3_from_rm(uint32_t type,
228 uint32_t interrupt_type_flags,
229 uint32_t security_state)
230 {
231 uint32_t flag, bit_pos;
232
233 ...
234
235 }
236
237Preprocessor Macros
238^^^^^^^^^^^^^^^^^^^
239
240Identifiers that are defined using preprocessor macros are written in all
241uppercase text.
242
243.. code:: c
244
245 #define BUFFER_SIZE_BYTES 64
246
247Function Attributes
248-------------------
249
250Place any function attributes after the function type and before the function
251name.
252
253.. code:: c
254
255 void __init plat_arm_interconnect_init(void);
256
257Alignment
258---------
259
260Alignment should be performed primarily with tabs, adding spaces if required to
261achieve a granularity that is smaller than the tab size. For example, with a tab
262size of eight columns it would be necessary to use one tab character and two
263spaces to indent text by ten columns.
264
265Switch Statement Alignment
266^^^^^^^^^^^^^^^^^^^^^^^^^^
267
268When using ``switch`` statements, align each ``case`` statement with the
269``switch`` so that they are in the same column.
270
271.. code:: c
272
273 switch (condition) {
274 case A:
275 foo();
276 case B:
277 bar();
278 default:
279 baz();
280 }
281
282Pointer Alignment
283^^^^^^^^^^^^^^^^^
284
285The reference and dereference operators (ampersand and *pointer star*) must be
286aligned with the name of the object on which they are operating, as opposed to
287the type of the object.
288
289.. code:: c
290
291 uint8_t *foo;
292
293 foo = &bar;
294
295
296Comments
297--------
298
299The general rule for comments is that the double-slash style of comment (``//``)
300is not allowed. Examples of the allowed comment formats are shown below:
301
302.. code:: c
303
304 /*
305 * This example illustrates the first allowed style for multi-line comments.
306 *
307 * Blank lines within multi-lines are allowed when they add clarity or when
308 * they separate multiple contexts.
309 *
310 */
311
312.. code:: c
313
314 /**************************************************************************
315 * This is the second allowed style for multi-line comments.
316 *
317 * In this style, the first and last lines use asterisks that run the full
318 * width of the comment at its widest point.
319 *
320 * This style can be used for additional emphasis.
321 *
322 *************************************************************************/
323
324.. code:: c
325
326 /* Single line comments can use this format */
327
328.. code:: c
329
330 /***************************************************************************
331 * This alternative single-line comment style can also be used for emphasis.
332 **************************************************************************/
333
334Headers and inclusion
335---------------------
336
337Header guards
338^^^^^^^^^^^^^
339
340For a header file called "some_driver.h" the style used by |TF-A| is:
341
342.. code:: c
343
344 #ifndef SOME_DRIVER_H
345 #define SOME_DRIVER_H
346
347 <header content>
348
349 #endif /* SOME_DRIVER_H */
350
351Include statement ordering
352^^^^^^^^^^^^^^^^^^^^^^^^^^
353
354All header files that are included by a source file must use the following,
355grouped ordering. This is to improve readability (by making it easier to quickly
356read through the list of headers) and maintainability.
357
358#. *System* includes: Header files from the standard *C* library, such as
359 ``stddef.h`` and ``string.h``.
360
361#. *Project* includes: Header files under the ``include/`` directory within
362 |TF-A| are *project* includes.
363
364#. *Platform* includes: Header files relating to a single, specific platform,
365 and which are located under the ``plat/<platform_name>`` directory within
366 |TF-A|, are *platform* includes.
367
368Within each group, ``#include`` statements must be in alphabetical order,
369taking both the file and directory names into account.
370
371Groups must be separated by a single blank line for clarity.
372
373The example below illustrates the ordering rules using some contrived header
374file names; this type of name reuse should be otherwise avoided.
375
376.. code:: c
377
378 #include <string.h>
379
380 #include <a_dir/example/a_header.h>
381 #include <a_dir/example/b_header.h>
382 #include <a_dir/test/a_header.h>
383 #include <b_dir/example/a_header.h>
384
385 #include "a_header.h"
386
387Include statement variants
388^^^^^^^^^^^^^^^^^^^^^^^^^^
389
390Two variants of the ``#include`` directive are acceptable in the |TF-A|
391codebase. Correct use of the two styles improves readability by suggesting the
392location of the included header and reducing ambiguity in cases where generic
393and platform-specific headers share a name.
394
395For header files that are in the same directory as the source file that is
396including them, use the ``"..."`` variant.
397
398For header files that are **not** in the same directory as the source file that
399is including them, use the ``<...>`` variant.
400
401Example (bl1_fwu.c):
402
403.. code:: c
404
405 #include <assert.h>
406 #include <errno.h>
407 #include <string.h>
408
409 #include "bl1_private.h"
410
411Typedefs
412--------
413
414Avoid anonymous typedefs of structs/enums in headers
415^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
416
417For example, the following definition:
418
419.. code:: c
420
421 typedef struct {
422 int arg1;
423 int arg2;
424 } my_struct_t;
425
426
427is better written as:
428
429.. code:: c
430
431 struct my_struct {
432 int arg1;
433 int arg2;
434 };
435
436This allows function declarations in other header files that depend on the
437struct/enum to forward declare the struct/enum instead of including the
438entire header:
439
440.. code:: c
441
442 struct my_struct;
443 void my_func(struct my_struct *arg);
444
445instead of:
446
447.. code:: c
448
449 #include <my_struct.h>
450 void my_func(my_struct_t *arg);
451
452Some TF definitions use both a struct/enum name **and** a typedef name. This
453is discouraged for new definitions as it makes it difficult for TF to comply
454with MISRA rule 8.3, which states that "All declarations of an object or
455function shall use the same names and type qualifiers".
456
457The Linux coding standards also discourage new typedefs and checkpatch emits
458a warning for this.
459
460Existing typedefs will be retained for compatibility.
461
462--------------
463
464*Copyright (c) 2020, Arm Limited. All rights reserved.*
465
466.. _`Linux kernel coding style`: https://www.kernel.org/doc/html/latest/process/coding-style.html
467.. _`MISRA C:2012 Guidelines`: https://www.misra.org.uk/Activities/MISRAC/tabid/160/Default.aspx
468.. _`a spreadsheet`: https://developer.trustedfirmware.org/file/download/lamajxif3w7c4mpjeoo5/PHID-FILE-fp7c7acszn6vliqomyhn/MISRA-and-TF-Analysis-v1.3.ods