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