mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2025-03-03 14:52:21 +02:00
Add coding standards document.
This commit is contained in:
parent
74d6398ad2
commit
c5ea53bcf9
143
CODING.md
Normal file
143
CODING.md
Normal file
@ -0,0 +1,143 @@
|
||||
# pgBackRest <br/> Coding Standards
|
||||
|
||||
## Standards
|
||||
|
||||
### Indentation
|
||||
|
||||
Indentation is four spaces -- no tabs. Only file types that absolutely require tabs (e.g. `Makefile`) may use them.
|
||||
|
||||
### Naming
|
||||
|
||||
#### Variables
|
||||
|
||||
Variable names use camel case with the first letter lower-case.
|
||||
|
||||
- `stanzaName` - the name of the stanza
|
||||
|
||||
- `nameIdx` - loop variable for iterating through a list of names
|
||||
|
||||
Variable names should be descriptive. Avoid `i`, `j`, etc.
|
||||
|
||||
#### Types
|
||||
|
||||
Type names use camel case with the first letter upper case:
|
||||
|
||||
`typedef struct MemContext <...>`
|
||||
|
||||
`typedef enum {<...>} ErrorState;`
|
||||
|
||||
#### Constants
|
||||
|
||||
**#define Constants**
|
||||
|
||||
`#define` constants should be all caps with `_` separators.
|
||||
```
|
||||
#DEFINE MY_CONSTANT "STRING"
|
||||
```
|
||||
The value should be aligned at column 69 whenever possible.
|
||||
|
||||
This type of constant should mostly be used for strings. Use enums whenever possible for integer constants.
|
||||
|
||||
**Enum Constants**
|
||||
|
||||
Enum elements follow the same case rules as variables. They are strongly typed so this shouldn't present any confusion.
|
||||
```
|
||||
typedef enum
|
||||
{
|
||||
cipherModeEncrypt,
|
||||
cipherModeDecrypt,
|
||||
} CipherMode;
|
||||
```
|
||||
Note the comma after the last element. This reduces diff churn when new elements are added.
|
||||
|
||||
#### Macros
|
||||
|
||||
Macro names should be upper-case with underscores between words. Macros (except simple constants) should be avoided whenever possible as they make code less clear and test coverage harder to measure.
|
||||
|
||||
Macros should follow the format:
|
||||
```
|
||||
#define MACRO(paramName1, paramName2) \
|
||||
<code>
|
||||
```
|
||||
If the macro defines a block it should look like:
|
||||
```
|
||||
#define MACRO_2(paramName1, paramName2) \
|
||||
{ \
|
||||
<code> \
|
||||
}
|
||||
```
|
||||
Continuation characters should be aligned at column 132 (unlike the examples above that have been shortened for display purposes).
|
||||
|
||||
To avoid conflicts, variables in a macro will be named `[macro name]_[var name]`, e.g. `TEST_RESULT_resultExpected`. Variables that need to be accessed in wrapped code should be provided accessor macros.
|
||||
|
||||
#### Begin / End
|
||||
|
||||
Use `Begin` / `End` for names rather than `Start` / `Finish`, etc.
|
||||
|
||||
#### New / Free
|
||||
|
||||
Use `New` / `Free` for constructors and destructors rather than `Create` / `Destroy`, etc.
|
||||
|
||||
### Formatting
|
||||
|
||||
#### Braces
|
||||
|
||||
C allows braces to be excluded for a single statement. However, braces should be used when the control statement (if, while, etc.) spans more than one line or the statement to be executed spans more than one line.
|
||||
|
||||
No braces needed:
|
||||
```
|
||||
if (condition)
|
||||
return value;
|
||||
```
|
||||
Braces needed:
|
||||
```
|
||||
if (conditionThatUsesEntireLine1 &&
|
||||
conditionThatUsesEntireLine2)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
```
|
||||
```
|
||||
if (condition)
|
||||
{
|
||||
return
|
||||
valueThatUsesEntireLine1 &&
|
||||
valueThatUsesEntireLine2;
|
||||
}
|
||||
```
|
||||
|
||||
## Language Elements
|
||||
|
||||
### Data Types
|
||||
|
||||
Don't get exotic - use the simplest type that will work.
|
||||
|
||||
Use `int` or `unsigned int` for general cases. `int` will be at least 32 bits. When not using `int` use one of the types defined in `common/type.h`.
|
||||
|
||||
### Macros
|
||||
|
||||
Don't use a macro when a function could be used instead. Macros make it hard to measure code coverage.
|
||||
|
||||
### Objects
|
||||
|
||||
Object-oriented programming is used extensively. The object pointer is always referred to as `this`.
|
||||
|
||||
## Testing
|
||||
|
||||
### Uncoverable/Uncovered Code
|
||||
|
||||
#### Uncoverable Code
|
||||
|
||||
The `uncoverable` keyword marks code that can never be covered. For instance, a function that never returns because it always throws a error. Uncoverable code should be rare to non-existent outside the common libraries and test code.
|
||||
```
|
||||
} // {uncoverable - function throws error so never returns}
|
||||
```
|
||||
Subsequent code that is uncoverable for the same reason is marked with `// {+uncoverable}`.
|
||||
|
||||
#### Uncovered Code
|
||||
|
||||
Marks code that is not tested for one reason or another. This should be kept to a minimum and an excuse given for each instance.
|
||||
```
|
||||
exit(EXIT_FAILURE); // {uncoverable - test harness does not support non-zero exit}
|
||||
```
|
||||
Subsequent code that is uncovered for the same reason is marked with `// {+uncovered}`.
|
@ -72,6 +72,7 @@
|
||||
<source key="user-guide"/>
|
||||
<source key="reference" type="custom"/>
|
||||
<source key="release" type="custom"/>
|
||||
<source key="coding"/>
|
||||
<source key="test"/>
|
||||
</source-list>
|
||||
|
||||
@ -90,6 +91,7 @@
|
||||
|
||||
<render type="markdown">
|
||||
<render-source key="index" file="../../../README.md"/>
|
||||
<render-source key="coding" file="../../../CODING.md"/>
|
||||
<render-source key="test" file="../../../test/README.md"/>
|
||||
</render>
|
||||
</render-list>
|
||||
|
202
doc/xml/coding.xml
Normal file
202
doc/xml/coding.xml
Normal file
@ -0,0 +1,202 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE doc SYSTEM "doc.dtd">
|
||||
<doc title="{[project]}" subtitle="Coding Standards" toc="y">
|
||||
<description>{[project]} Coding Standard.</description>
|
||||
|
||||
<section id="standards">
|
||||
<title>Standards</title>
|
||||
|
||||
<section id="indentation">
|
||||
<title>Indentation</title>
|
||||
|
||||
<p>Indentation is four spaces -- no tabs. Only file types that absolutely require tabs (e.g. `Makefile`) may use them.</p>
|
||||
</section>
|
||||
|
||||
<section id="naming">
|
||||
<title>Naming</title>
|
||||
|
||||
<section id="variables">
|
||||
<title>Variables</title>
|
||||
|
||||
<p>Variable names use camel case with the first letter lower-case.</p>
|
||||
|
||||
<list>
|
||||
<list-item><id>stanzaName</id> - the name of the stanza</list-item>
|
||||
<list-item><id>nameIdx</id> - loop variable for iterating through a list of names</list-item>
|
||||
</list>
|
||||
|
||||
<p>Variable names should be descriptive. Avoid <id>i</id>, <id>j</id>, etc.</p>
|
||||
</section>
|
||||
|
||||
<section id="types">
|
||||
<title>Types</title>
|
||||
|
||||
<p>Type names use camel case with the first letter upper case:
|
||||
|
||||
<code>typedef struct MemContext <...></code>
|
||||
|
||||
<code>typedef enum {<...>} ErrorState;</code></p>
|
||||
</section>
|
||||
|
||||
<section id="constants">
|
||||
<title>Constants</title>
|
||||
|
||||
<p><b>#define Constants</b></p>
|
||||
|
||||
<p><code>#define</code> constants should be all caps with <id>_</id> separators.</p>
|
||||
|
||||
<code-block>
|
||||
#DEFINE MY_CONSTANT "STRING"
|
||||
</code-block>
|
||||
|
||||
<p>The value should be aligned at column 69 whenever possible.</p>
|
||||
|
||||
<p>This type of constant should mostly be used for strings. Use enums whenever possible for integer constants.</p>
|
||||
|
||||
<p><b>Enum Constants</b></p>
|
||||
|
||||
<p>Enum elements follow the same case rules as variables. They are strongly typed so this shouldn't present any confusion.</p>
|
||||
|
||||
<code-block>
|
||||
typedef enum
|
||||
{
|
||||
cipherModeEncrypt,
|
||||
cipherModeDecrypt,
|
||||
} CipherMode;
|
||||
</code-block>
|
||||
|
||||
<p>Note the comma after the last element. This reduces diff churn when new elements are added.</p>
|
||||
</section>
|
||||
|
||||
<section id="macros">
|
||||
<title>Macros</title>
|
||||
|
||||
<p>Macro names should be upper-case with underscores between words. Macros (except simple constants) should be avoided whenever possible as they make code less clear and test coverage harder to measure.</p>
|
||||
|
||||
<p>Macros should follow the format:</p>
|
||||
|
||||
<code-block>
|
||||
#define MACRO(paramName1, paramName2) \
|
||||
<code>
|
||||
</code-block>
|
||||
|
||||
<p>If the macro defines a block it should look like:</p>
|
||||
|
||||
<code-block>
|
||||
#define MACRO_2(paramName1, paramName2) \
|
||||
{ \
|
||||
<code> \
|
||||
}
|
||||
</code-block>
|
||||
|
||||
<p>Continuation characters should be aligned at column 132 (unlike the examples above that have been shortened for display purposes).</p>
|
||||
|
||||
<p>To avoid conflicts, variables in a macro will be named <id>[macro name]_[var name]</id>, e.g. <id>TEST_RESULT_resultExpected</id>. Variables that need to be accessed in wrapped code should be provided accessor macros.</p>
|
||||
</section>
|
||||
|
||||
<section id="begin-end">
|
||||
<title>Begin / End</title>
|
||||
|
||||
<p>Use <id>Begin</id> / <id>End</id> for names rather than <id>Start</id> / <id>Finish</id>, etc.</p>
|
||||
</section>
|
||||
|
||||
<section id="new-free">
|
||||
<title>New / Free</title>
|
||||
|
||||
<p>Use <id>New</id> / <id>Free</id> for constructors and destructors rather than <id>Create</id> / <id>Destroy</id>, etc.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="formatting">
|
||||
<title>Formatting</title>
|
||||
|
||||
<section id="braces">
|
||||
<title>Braces</title>
|
||||
|
||||
<p>C allows braces to be excluded for a single statement. However, braces should be used when the control statement (if, while, etc.) spans more than one line or the statement to be executed spans more than one line.</p>
|
||||
|
||||
<p>No braces needed:</p>
|
||||
|
||||
<code-block>
|
||||
if (condition)
|
||||
return value;
|
||||
</code-block>
|
||||
|
||||
<p>Braces needed:</p>
|
||||
|
||||
<code-block>
|
||||
if (conditionThatUsesEntireLine1 &&
|
||||
conditionThatUsesEntireLine2)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
</code-block>
|
||||
|
||||
<code-block>
|
||||
if (condition)
|
||||
{
|
||||
return
|
||||
valueThatUsesEntireLine1 &&
|
||||
valueThatUsesEntireLine2;
|
||||
}
|
||||
</code-block>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="language-elements">
|
||||
<title>Language Elements</title>
|
||||
|
||||
<section id="data-types">
|
||||
<title>Data Types</title>
|
||||
|
||||
<p>Don't get exotic - use the simplest type that will work.
|
||||
|
||||
Use <id>int</id> or <id>unsigned int</id> for general cases. <id>int</id> will be at least 32 bits. When not using <id>int</id> use one of the types defined in <file>common/type.h</file>.</p>
|
||||
</section>
|
||||
|
||||
<section id="macros">
|
||||
<title>Macros</title>
|
||||
|
||||
<p>Don't use a macro when a function could be used instead. Macros make it hard to measure code coverage.</p>
|
||||
</section>
|
||||
|
||||
<section id="objects">
|
||||
<title>Objects</title>
|
||||
|
||||
<p>Object-oriented programming is used extensively. The object pointer is always referred to as <id>this</id>.</p>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<section id="testing">
|
||||
<title>Testing</title>
|
||||
|
||||
<section id="uncoverable-uncovered">
|
||||
<title>Uncoverable/Uncovered Code</title>
|
||||
|
||||
<section id="uncoverable">
|
||||
<title>Uncoverable Code</title>
|
||||
|
||||
<p>The <id>uncoverable</id> keyword marks code that can never be covered. For instance, a function that never returns because it always throws a error. Uncoverable code should be rare to non-existent outside the common libraries and test code.</p>
|
||||
|
||||
<code-block>
|
||||
} // {uncoverable - function throws error so never returns}
|
||||
</code-block>
|
||||
|
||||
<p>Subsequent code that is uncoverable for the same reason is marked with <code>// {+uncoverable}</code>.</p>
|
||||
</section>
|
||||
|
||||
<section id="uncovered">
|
||||
<title>Uncovered Code</title>
|
||||
|
||||
<p>Marks code that is not tested for one reason or another. This should be kept to a minimum and an excuse given for each instance.</p>
|
||||
|
||||
<code-block>
|
||||
exit(EXIT_FAILURE); // {uncoverable - test harness does not support non-zero exit}
|
||||
</code-block>
|
||||
|
||||
<p>Subsequent code that is uncovered for the same reason is marked with `// {+uncovered}`.</p>
|
||||
</section>
|
||||
</section>
|
||||
</section>
|
||||
</doc>
|
@ -46,6 +46,10 @@
|
||||
<release-item>
|
||||
<p>Split <quote>refactor</quote> sections into <quote>improvements</quote> and <quote>development</quote> in the release notes. Many development notes are not relevant to users and simply clutter the release notes, so they are no longer shown on the website.</p>
|
||||
</release-item>
|
||||
|
||||
<release-item>
|
||||
<p>Add coding standards document.</p>
|
||||
</release-item>
|
||||
</release-development-list>
|
||||
</release-doc-list>
|
||||
</release>
|
||||
|
Loading…
x
Reference in New Issue
Block a user