You've already forked pgbackrest
							
							
				mirror of
				https://github.com/pgbackrest/pgbackrest.git
				synced 2025-10-30 23:37:45 +02:00 
			
		
		
		
	Add coding standards document.
This commit is contained in:
		
							
								
								
									
										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> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user