]> git.proxmox.com Git - ceph.git/blob - ceph/src/pmdk/CODING_STYLE.md
import ceph 16.2.7
[ceph.git] / ceph / src / pmdk / CODING_STYLE.md
1 # C Style and Coding Standards for Persistent Memory Development Kit
2
3 This document defines the coding standards and conventions for writing
4 PMDK code. To ensure readability and consistency within the code,
5 the contributed code must adhere to the rules below.
6
7 ### Introduction
8 The Persistent Memory Development Kit coding style is quite similar to the style
9 used for the SunOS product.
10 A full description of that standard can be found
11 [here.](https://www.cis.upenn.edu/~lee/06cse480/data/cstyle.ms.pdf)
12
13 This document does not cover the entire set of recommendations and formatting rules
14 used in writing PMDK code, but rather focuses on some PMDK-specific conventions,
15 not described in the document mentioned above, as well as the ones the violation
16 of which is most frequently observed during the code review.
17 Also, keep in mind that more important than the particular style is **consistency**
18 of coding style. So, when modifying the existing code, the changes should be
19 coded in the same style as the file being modified.
20
21 ### Code formatting
22 Most of the common stylistic errors can be detected by the
23 [style checker program](https://github.com/pmem/pmdk/blob/master/utils/cstyle)
24 included in the repo.
25 Simply run `make cstyle` or `CSTYLE.ps1` to verify if your code is well-formatted.
26
27 Here is the list of the most important rules:
28 - The limit of line length is 80 characters.
29 - Indent the code with TABs, not spaces. Tab width is 8 characters.
30 - Do not break user-visible strings (even when they are longer than 80 characters)
31 - Put each variable declaration in a separate line.
32 - Do not use C++ comments (`//`).
33 - Spaces around operators are mandatory.
34 - No whitespace is allowed at the end of line.
35 - For multi-line macros, do not put whitespace before `\` character.
36 - Precede definition of each function with a brief, non-trivial description.
37 (Usually a single line is enough.)
38 - Use `XXX` tag to indicate a hack, problematic code, or something to be done.
39 - For pointer variables, place the `*` close to the variable name not pointer type.
40 - Avoid unnecessary variable initialization.
41 - Never type `unsigned int` - just use `unsigned` in such case.
42 Same with `long int` and `long`, etc.
43 - Sized types like `uint32_t`, `int64_t` should be used when there is an on-media format.
44 Otherwise, just use `unsigned`, `long`, etc.
45 - Functions with local scope must be declared as `static`.
46
47 ### License & copyright
48 - Make sure you have the right to submit your contribution under the BSD license,
49 especially if it is based upon previous work.
50 See [CONTRIBUTING.md](https://github.com/pmem/pmdk/blob/master/CONTRIBUTING.md) for details.
51 - A copy of the [BSD-style License](https://github.com/pmem/pmdk/blob/master/LICENSE)
52 must be placed at the beginning of each source file, script or man page
53 (Obviously, it does not apply to README's, Visual Studio projects and \*.match files.)
54 - When adding a new file to the repo, or when making a contribution to an existing
55 file, feel free to put your copyright string on top of it.
56
57 ### Naming convention
58 - Keep identifier names short, but meaningful. One-letter variables are discouraged.
59 - Use proper prefix for function name, depending on the module it belongs to.
60 - Use *under_score* pattern for function/variable names. Please, do not use
61 CamelCase or Hungarian notation.
62 - UPPERCASE constant/macro/enum names.
63 - Capitalize first letter for variables with global or module-level scope.
64 - Avoid using `l` as a variable name, because it is hard to distinguish `l` from `1`
65 on some displays.
66
67 ### Multi-OS support (Linux/FreeBSD/Windows)
68 - Do not add `#ifdef <OS>` sections lightly. They should be treated as technical
69 debt and avoided when possible.
70 - Use `_WIN32` macro for conditional directives when including code using
71 Windows-specific API.
72 - Use `__FreeBSD__` macro for conditional directives for FreeBSD-specific code.
73 - Use `_MSC_VER` macro for conditional directives when including code using VC++
74 or gcc specific extensions.
75 - In case of large portions of code (i.e. a whole function) that have different
76 implementation for each OS, consider moving them to separate files.
77 (i.e. *xxx_linux.c*, *xxx_freebsd.c* and *xxx_windows.c*)
78 - Keep in mind that `long int` is always 32-bit in VC++, even when building for
79 64-bit platforms. Remember to use `long long` types whenever it applies, as well
80 as proper formatting strings and type suffixes (i.. `%llu`, `ULL`).
81 - Standard compliant solutions should be used in preference of compiler-specific ones.
82 (i.e. static inline functions versus statement expressions)
83 - Do not use formatting strings that are not supported by Windows implementations
84 of printf()/scanf() family. (like `%m`)
85 - It is recommended to use `PRI*` and `SCN*` macros in printf()/scanf() functions
86 for width-based integral types (`uint32_t`, `int64_t`, etc.).
87
88 ### Debug traces and assertions
89 - Put `LOG(3, ...)` at the beginning of each function. Consider using higher
90 log level for most frequently called routines.
91 - Make use of `COMPILE_ERROR_ON` and `ASSERT*` macros.
92 - Use `ERR()` macro to log error messages.
93
94 ### Unit tests
95 - There **must** be unit tests provided for each new function/module added.
96 - Test scripts **must** start with `#!/usr/bin/env <shell>` for portability between Linux and FreeBSD.
97 - Please, see [this](https://github.com/pmem/pmdk/blob/master/src/test/README)
98 and [that](https://github.com/pmem/pmdk/blob/master/src/test/unittest/README)
99 document to get familiar with
100 our test framework and the guidelines on how to write and run unit tests.
101
102 ### Commit messages
103 All commit lines (entered when you run `git commit`) must follow the common
104 conventions for git commit messages:
105 - The first line is a short summary, no longer than **50 characters,** starting
106 with an area name and then a colon. There should be no period after
107 the short summary.
108 - Valid area names are: **pmem, pmem2, obj, blk, log,
109 test, doc, daxio, pmreorder, pool** (for *libpmempool* and *pmempool*), **rpmem**
110 (for *librpmem* and *rpmemd*), **benchmark, examples, core** and **common** (for everything else).
111 - It is acceptable for the short summary to be the only thing in the commit
112 message if it is a trivial change. Otherwise, the second line must be
113 a blank line.
114 - Starting at the third line, additional information is given in complete
115 English sentences and, optionally, bulleted points. This content must not
116 extend beyond **column 72.**
117 - The English sentences should be written in the imperative, so you say
118 "Fix bug X" instead of "Fixed bug X" or "Fixes bug X".
119 - Bullet points should use hanging indents when they take up more than
120 one line (see example below).
121 - There can be any number of paragraphs, separated by a blank line, as many
122 as it takes to describe the change.
123 - Any references to GitHub issues are at the end of the commit message.
124
125 For example, here is a properly-formatted commit message:
126 ```
127 doc: fix code formatting in man pages
128
129 This section contains paragraph style text with complete English
130 sentences. There can be as many paragraphs as necessary.
131
132 - Bullet points are typically sentence fragments
133
134 - The first word of the bullet point is usually capitalized and
135 if the point is long, it is continued with a hanging indent
136
137 - The sentence fragments don't typically end with a period
138
139 Ref: pmem/issues#1
140 ```