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