-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Document the new coding style #69
Merged
gilles-peskine-arm
merged 10 commits into
Mbed-TLS:main
from
gilles-peskine-arm:coding-style-202301
Jan 10, 2023
Merged
Changes from 1 commit
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
9fe58c0
Fix indentation and spelling of defined
gilles-peskine-arm daf729c
Switch the "code formatting" section to the new style
gilles-peskine-arm efca62b
Adjust coding style in examples
gilles-peskine-arm 0dd8840
Document enforcement with uncrustify
gilles-peskine-arm 99b4238
Reserve "coding style" to formatting
gilles-peskine-arm 04f8911
Fix copypasta
gilles-peskine-arm bd58768
Cosmetic improvement
gilles-peskine-arm c073596
Document braces more thoroughly
gilles-peskine-arm 3b2a019
Be more specific about unary operators
gilles-peskine-arm cc6d195
Update PSA API links to the new official location
gilles-peskine-arm File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -8,102 +8,101 @@ This document describes Mbed TLS preferences for code formatting, naming convent | |||||
|
||||||
## Code Formatting | ||||||
|
||||||
Mbed TLS source code files use 4 spaces for indentation, **not tabs**, with a preferred maximum line length of 80 characters. | ||||||
### K&R | ||||||
|
||||||
Every code statement should be on its own line. | ||||||
Mbed TLS generally follows the style of *The C Programming Language*, Second Edition, 1988, by Brian Kernighan and Dennis Ritchie (“K&R2”). The main deviations are: | ||||||
|
||||||
**Avoid statements like this:** | ||||||
```c | ||||||
if( a == 1 ) { b = 1; do_function( b ); } | ||||||
if( a == 1 ) do_function( a ); | ||||||
``` | ||||||
* Indentation is 4 spaces (like K&R2, not 5 spaces like K&R1). Do not use tabs. | ||||||
* `case` is indented one level further than `switch`. | ||||||
* The body of `if`, `for` or `while` must be on a separate line and surrounded with braces, even if it's a single statement. | ||||||
|
||||||
### Space placement | ||||||
### Indentation | ||||||
|
||||||
Mbed TLS uses a non-standard space placement throughout the code, where there is no space between a function name and all parentheses are separated by one space from their content: | ||||||
```c | ||||||
if( ( ret = demo_function( a, b, c ) ) != 0 ) | ||||||
``` | ||||||
The same applies to function definitions: | ||||||
```c | ||||||
int demo_function( int a, const unsigned char *value, size_t len ) | ||||||
``` | ||||||
There are a few exceptions to this rule. This includes the preprocessor directive `defined` and casts, as well as arguments for function-like macros: | ||||||
```c | ||||||
#if defined(MBEDTLS_HAVE_TIME) | ||||||
timestamp = (uint32_t) time( NULL ); | ||||||
``` | ||||||
Mbed TLS source code files use 4 spaces for indentation, **not tabs**, with a preferred maximum line length of 80 characters. | ||||||
|
||||||
### Braces placement and block declaration | ||||||
`case` is indented one level further than `switch`. | ||||||
|
||||||
Braces (curly brackets) should be located on a line by themselves at the indentation level of the original block: | ||||||
```c | ||||||
if( val >= 1 ) | ||||||
{ | ||||||
if( val == 1 ) | ||||||
{ | ||||||
/* code block here */ | ||||||
} | ||||||
else | ||||||
{ | ||||||
/* alternate code block */ | ||||||
} | ||||||
} | ||||||
``` | ||||||
In case a block is only single source code line, the braces can be omitted if the block initiator is only a single line: | ||||||
```c | ||||||
if( val >= 1 ) | ||||||
a = 2; | ||||||
switch (x) { | ||||||
case 0: | ||||||
zero(); | ||||||
break; | ||||||
... | ||||||
} | ||||||
``` | ||||||
But not if it is a multi-line initiator: | ||||||
|
||||||
Labels are indented at the same level as the enclosing block. | ||||||
```c | ||||||
if( val >= 1 && | ||||||
this_big_statement_deserved_its_own_line == another_big_part ) | ||||||
{ | ||||||
a = 2; | ||||||
int f() | ||||||
{ | ||||||
...code... | ||||||
if (ret != 0) { | ||||||
goto exit; | ||||||
} | ||||||
...code... | ||||||
exit: | ||||||
...cleanup... | ||||||
return ret; | ||||||
} | ||||||
``` | ||||||
|
||||||
### Related lines: Multi-line formatting and indentation | ||||||
Every code statement should be on its own line, except in `for` loop headers. | ||||||
|
||||||
Multiple related source code lines should be formatted to be easily readable: | ||||||
```c | ||||||
#define GET_UINT32_LE( n, b, i ) \ | ||||||
{ \ | ||||||
(n) = ( (uint32_t) (b)[(i) ] ) \ | ||||||
| ( (uint32_t) (b)[(i) + 1] << 8 ) \ | ||||||
| ( (uint32_t) (b)[(i) + 2] << 16 ) \ | ||||||
| ( (uint32_t) (b)[(i) + 3] << 24 ); \ | ||||||
} | ||||||
### Space placement | ||||||
|
||||||
if( my_super_var == second_super_var && | ||||||
this_check_will_do != the_other_value ) | ||||||
Put a space in the following places: | ||||||
|
||||||
do_function( ctx, this_is_a_value, value_b, | ||||||
the_special_var ); | ||||||
* Around binary operators: `(x + y) * z` | ||||||
* After a comma: `f(x, y)` | ||||||
* Before the asterisk in a pointer type: `int *p` | ||||||
* Between `if`, `switch`, `while`, `for` and the opening parenthesis: `if (f(x))` | ||||||
* Outside curly braces: `do { ... } while (!done)`, `struct mystruct s = { 0 }` | ||||||
* Inside the curly braces around initializers: `int a[] = { 1, 2, 3 };` | ||||||
|
||||||
void this_is_a_function( context_struct *ctx, size_t length, | ||||||
unsigned char *result ); | ||||||
``` | ||||||
Do not put a space in the following places: | ||||||
|
||||||
### Extra parentheses for `return` and `sizeof` | ||||||
* After the function or macro name in a function or macro call: `f(x, y)` | ||||||
* Inside parentheses: `if (f(sizeof(int), (int) y))` | ||||||
* Inside square brackets: `a[i + 1]` | ||||||
* Before a comma: `f(x, y)` | ||||||
* After a unary operator: `if (!condition)`, `++x` | ||||||
* Before a unary operator: `x++` | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
* Between an array and the following opening bracket: `int a[2]; a[i]` | ||||||
mpg marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
* Around field access symbols: `s.a`, `p->a` | ||||||
* After the asterisk in a pointer type: `int *p` | ||||||
* Between the asterisks double pointers types or derefences: `char **p`, `x + **p` | ||||||
|
||||||
Within Mbed TLS return statements use parentheses to contain their value: | ||||||
### Use of parentheses | ||||||
|
||||||
`sizeof` expressions always use parentheses even when it is not necessary (when taking the size of an object): | ||||||
```c | ||||||
return( 0 ); | ||||||
memset(buf, 0, sizeof(buf)); | ||||||
``` | ||||||
Similarly, sizeof expressions always use parentheses even when it is not necessary (when taking the size of an object): | ||||||
|
||||||
### Braces placement and block declaration | ||||||
|
||||||
Braces are mandatory in control statements such as `if`, `while`, `for`, even when the content is a simple statement. | ||||||
Opening braces (curly brackets) are on the same line as the control statement. | ||||||
|
||||||
Closing braces are aligned with the control statement or opening brace. They are generally alone on their line, except when followed by `else` or by the `while` of a `do ... while` statement. | ||||||
|
||||||
```c | ||||||
memset( buf, 0, sizeof( buf ) ); | ||||||
do { | ||||||
x += f(); | ||||||
if (x == 0) { | ||||||
continue; | ||||||
} | ||||||
x += g(); | ||||||
} while (condition); | ||||||
mpg marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
``` | ||||||
|
||||||
### Formatting of lists | ||||||
|
||||||
When a function or macro call doesn't fit on a single line, put one argument per line or a sensible grouping per line. For example, in the snippet below, `input_buffer` and `input_size` are on a line of their own even though the call could fit on two lines instead of three if they were separated: | ||||||
```c | ||||||
function_with_a_very_long_name( parameter1, parameter2, | ||||||
input_buffer, input_size, | ||||||
output_buffer, output_size ); | ||||||
function_with_a_very_long_name(parameter1, parameter2, | ||||||
input_buffer, input_size, | ||||||
output_buffer, output_size); | ||||||
``` | ||||||
|
||||||
Lists of items other than function arguments should generally have one item per line. Exceptions: | ||||||
|
@@ -113,8 +112,7 @@ Lists of items other than function arguments should generally have one item per | |||||
|
||||||
In lists of items such array initializers and enum definitions, do include the optional comma after the last element. This simplifies merging, reordering, etc. | ||||||
```c | ||||||
typedef enum foo | ||||||
{ | ||||||
typedef enum foo { | ||||||
FOO_1, | ||||||
FOO_2, // <- do put a comma here | ||||||
} | ||||||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.