xref: /aosp_15_r20/external/tpm2-tss/doc/coding_standard_c.md (revision 758e9fba6fc9adbf15340f70c73baee7b168b1c9)
1# Coding Standard
2The coding standard followed in this code base is similar in most ways to the
3style followed by the Linux kernel. Naturally there are exceptions. Most
4notably is the indentation (more on this later). Above all else we ask
5that when modifying the code that you follow the most important rule:
6check the surrounding code and imitate its style [1].
7
8## C Standard and Compiler Stuff
9Code should hold as close to the C99 standard as possible with the exception
10that GCC specific extensions are generally accepted. The code must compile
11without warnings for the primary target compiler when all warnings are
12enabled. If a warning is unavoidable, the offending line must be documented
13with an explanation of why said code can not be modified to appease the
14compiler [2].
15
16It is worth noting however that this code base has yet to run into a compiler
17warning that wasn't the authors fault. It is likely that if you do find
18yourself disabling `-Werror` you're probably doing something wrong.
19
20## Comments
21There are two acceptable commenting styles: block, line.  Block comments
22are used to document a largeish block of code, typically a function. Sometimes
23block comments are useful with a function to document a loop or a particularly
24tricky part of an algorithm. Line comments are typically a single sentence on a
25single line. They provide some brief explanation of a line or two of code.
26
27NOTE: Comments are most useful to convey the purpose, parameters and results
28from functions and objects in a system. Excessive use of comments within a
29function is indicative of two things: over documentation and code that needs
30to be refactored. To combat the first case let's say that it's safe to assume
31that your code will be read by competent C programmers. The second case can be
32tricky and there's no rule of thumb. Follow your instincts and keep in mind
33that excessive line comments are a sort of "code smell" that may mean your
34code would benefit from some restructuring.
35
36### Examples
37```c
38/*
39 * This block comment could apply to some function and describe its inner
40 * workings.  Notice these sentences have traditional capitalization and
41 * punctuation... that's because it has to be read in a way completely
42 * unlike the Post-It style content of next-line and line comments.
43 */
44```
45```c
46// This is *not* an acceptable block comment.
47// Don't do this.
48// Please.
49```
50```c
51/* This is a line comment */
52```
53
54## Whitespace
55All indentation must be spaces, not tabs. Lines are indented in multiples of
564 spaces. Each line of code and documentation will end with a non-whitespace
57character. There must *not* be any whitespace between the last line of code
58or documentation in a file and the end of the file.
59
60## Naming Variables, Functions and Other Stuff
61Names should clearly convey the purpose of whatever is being named. While the
62data type of a variable conveys some information, this alone is insufficient.
63Multiple word names are descriptive and most easily read if words are
64separated with the underscore character, "_".
65
66Variable and function names must be lowercase. Words in each name must be
67separated by an underscore character: "_". Macros and constants (anything
68declared with \#define) must be in all-caps, again with words separated by
69underscores.
70
71Objects created using the GObject system follow the GObject naming convention
72with individual words in object names as upper case characters.
73
74### Exceptions
75Exceptions to these rules are made for compliance with the TCG
76specifications. All function names, parameters, and other data types must
77be implemented faithfully to the specification and so may violate the naming
78conventions defined here.
79
80### Examples
81```c
82unsigned int table_index = find_index(jacket_table, “color”, COLOR_RED);
83```
84```c
85int last_item = 0;
86while (!last_item) {
87     /* ... */
88}
89```
90```c
91int char_found = is_alpha (c);
92```
93
94Single letter variable names should be avoided.  Exceptions are:
95* "i", "j", and "k" are loop counters or temporary array indexes
96* "m" and "n" are row and column indexes for multidimensional arrays
97* "c" and "s" are temporary/parameter characters or strings
98* "r", "g", "b", and "a" are red, green, blue, and alpha levels, but only when
99* they are used together
100* "x", "y", and "z" are coordinate values
101
102Abbreviated words in variable names should be avoided.  Exceptions are:
103* "char" = character
104* "col" = column.  Typically there is also "row" so it is not confused with color
105* "cnt" = count
106* "pos" = position
107* "rem" = remainder
108* "ctx" = context
109
110Function names should follow the naming conventions of variables and clearly
111describe not only what the function does, but also the nature of what it
112returns (if anything). Functions that return boolean integers should be named
113to reflect the true condition even if they are created to detect false
114conditions. Functions should never be hidden in conditional statements, with
115the exception of loops where it makes the code more simple.
116```c
117bool is_number_prime = is_prime(i);
118```
119```c
120if (is_number_prime) {
121    /* ... */
122}
123```
124```c
125while (!labeled_correctly(sample[i])) {
126    /* ... */
127}
128```
129
130A function that is exported for use in multiple source files should be
131prefixed with the source file (or object module) name where it is defined.
132For example, the file list.c may contain the implementation of a dynamic
133list ADT including an exported method for creating a list instance and an
134internal (static) method for overflow checking. The first function might be
135named "list_create", and the second, "is_overflowed".
136
137The use of the static keyword when defining functions is a useful way to scope
138the visibility of the function to the same translation unit. A negative side
139effect of this is preventing the testing of the function through the unit
140testing harness. Generally we accept exposing symbols to get better test
141coverage.
142
143## Files
144Typically every header file has the same base filename as an associated source
145file. Exceptions to this rule are generally limited to modules that will
146expose a separate set symbols to external consumers. In this case the internal
147version of the header should be suffixed with '-priv'.
148
149Files names are formatted in the same way as described above with the
150exception of hyphens "-" separating words.
151
152The body of each header file must be surrounded by an include guard (aka
153"header guard"). These guards shall be given the same name as the file in
154which they reside. Their names shall be all caps, with words separated by
155the underscore character "_".
156
157Header files should never define functions or variables.
158
159Header files should only \#include what is necessary to allow a file that
160includes it to compile.  Associated source files will always \#include the
161header of the same name, but should \#include files whose resources are used
162within the source even if they are already included in that header. This
163provides a complete context for readers of the source file... i.e., they
164don't have to search through headers to determine where a resource came from.
165
166Files included by all source files must conform to the following format and
167order. Each entry in the list below defines a contiguous block of `include`
168directives separated by a blank line:
169* System headers - These are headers provided by the core c libraries
170(typically from libc).
171* External dependencies - These are headers installed on the platform defining
172interfaces to external libraries.
173* Standard TSS2 headers - These are headers that define the public TSS2 types
174and interfaces. They are all located under $(srcdir)/include/* and will be
175installed as part of the `install` build target. These *must* be included
176using the quoted include variant (using `"` instead of the angle brackets).
177* Internal headers - These are headers defining the interfaces to code modules
178that are internal to the project.
179
180Headers in each block must listed in alphabetical order.
181
182### Example
183header: `example-module.h`
184```
185/*
186 * BSD license block
187 */
188#ifndef EXAMPLE_MODULE_H
189#define EXAMPLE_MODULE_H
190
191#include <stdint.h>
192#include <sys/types.h>
193
194#include "tss2/tss2_tpm2_types.h"
195
196#include "internal-module.h"
197
198/*
199 * preprocess or directives and declarations using stuff from included headers
200 */
201
202#endif /* EXAMPLE_MODULE_H */
203```
204
205implementation: `example-module.c`
206```
207/*
208 * BSD license block
209 */
210#include <inttypes.h>
211#include <stdint.h>
212
213#include <foo/bar.h>
214
215#include "tss2/tss2_tcti.h"
216#include "tss2/tss2_tpm2_types.h"
217
218#include "example-module.h"
219#include "internal-module.h"
220
221/*
222 * Implementation / code using headers listed above.
223 */
224```
225
226## Types
227Types shall be selected for their use case. Variables should only be of a
228signed type if something should ever be negative. A common, incorrect use, is
229to declare loop counters as int instead of unsigned, or to use an int to hold
230the size of some object.
231
232## Formatting
233Always use space characters, 4 spaces per level of indentation.
234
235Conditional statements (such as if, else, while, for, switch, etc) must place
236the opening brace on the same line after the end of the control flow statement.
237The closing brace should be placed at the same column position as the beginning
238of the associated control flow statement on a line by itself.
239
240Function definitions specify the return type on a line, followed by the
241function name followed by the first parameter. Each additional parameter is
242listed on a separate line aligned with the line above. The opening brace
243defning the functions scope must be on the following line at column position 0.
244
245A space must separate a control flow statement or function and the opening
246parenthesis.
247
248Line length should not exceed 80 characters and should be split on the nearest
249whitespace or delimiter character. When splitting lines with
250
251### Example
252```c
253if (some_int > 0) {
254    statement1;
255    statement2;
256}
257```
258```c
259void
260some_function (short_t       arg_1,
261               longer_name_t arg_2)
262{
263    statement1;
264    statement2;
265}
266```
267```c
268some_long_variable_name =
269    some_long_function_name (lots_of_parameters_1, lots_of_parameters_2);
270```
271```c
272some_long_variable_name = some_long_function_name (lots_of_parameters_1,
273                                                   lots_of_parameters_2,
274                                                   lots_of_parameters_3);
275```
276These formatting conditions are contrary to Kernighan and Ritchie's "one true brace style" [3].
277
278## References
2791. GNOME C Coding Style : https://developer.gnome.org/programming-guidelines/stable/c-coding-style.html.en
2802. Alan Bridger, Mick Brooks, and Jim Pisano, C Coding Standards, 2001, http://www.alma.nrao.edu/development/computing/docs/joint/0009/2001-02-28.pdf
2813. Brian Kernighan, Dennis Ritchie, The C Programing Language, 1988
282