wiki.js/dev/Style_code.md

122 lines
5.2 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Style Guide
description: Style guidelines used within the Speeduino firmware
published: true
date: 2022-09-08T05:39:42.057Z
tags:
editor: undefined
dateCreated: 2020-01-06T01:54:27.875Z
---
# Goal
The Speeduino firmware aspires to a common, unified approach to code layout based on the guidelines on this page. Any pull requests or submissions should align with these recommendations as much as possible.
## A note on MISRA compliance
Speeduino strives for compliance to the MISRA C:2012 coding standard and many of the conventions below are to align with this. A full description of the requirments of MISRA C:2012 is beyond the scope of this document, but the code does include a MISRA scanning script based on cppcheck that you can use to verify your code changes.
### MISRA Scanning
A MISRA scanning script is available for reviewing the current violations in the code.
**Requirements**:
* [cppcheck](https://github.com/danmar/cppcheck) version 2.7 or above
* Python 3.x
* A Unix-like environment (Linux, Mac or WSL on Windows)
**Usage:**
* Enter the `speeduino/misra` directory of the source code
* Run `./check_misra.sh` with any of the below optional arguments:
* `-s`, `--source=`: Source code directory to scan (Defaults to `../speeduino/`)
* `-e`, `--exts=`: File extensions (Defaults to `ino`)
* `-o`, `--out=`: Output directory (Defaults to `.results`)
* `-c`, `--cppcheck=`: Location of cppcheck binary (No default, assumes `cppcheck` is within the users `$PATH`
* `-q`, `--quiet`: Quiet, will not output the scan results to stout, only to the results file
# Details
## File Structure
Within code files (`.ino`), items must be arranged in the following sequence:
1. A mandatory header comment describing the purpose of the file
2. included files (`#include`)
3. defines (`#define`)
4. local struct typedefs
5. local prototypes
6. Definitions of any global vars
7. Main function (if present)
8. Local functions
In a C header (`.h`) file items must be arranged in the following sequence:
1. Header comment
2. ifndef guard
3. included files (`#include`)
4. defines (`#define`)
5. struct typedefs
6. prototypes
7. (extern) global vars
## File Names
All names should be meaningful and follow existing usage patterns if present.
## Naming Conventions
### Language
Speeduino uses UK/Australian English rather than US. Names and comments should reflect this.
### Examples
| Item | Standard | Example |
|---------------------------------------------|--------------------------------------------------------------|---------------------------|
| Functions | camelCase, lowercase first letter, no spaces or _ | `readSensor();` |
| Variables | Same as functions | `sensorValue = 0;` |
| Anonymous variables (eg some loop counters) | Single lowercase letter (Preferred order or use: x, y, z, i) | `x++;` |
| Constants | UPPER_CASE, words joined with _ | `#define TWO_SQUARED 4` |
## Layout and whitespace
- Use spaces for indents, not tabs
- Indent 2 spaces per level
- Always use { }, even for single statement blocks
- Describe block structures using indentation, do not rely on { } alone
- For multiple line blocks, brackets should always have their own line:
```
void readSensors()
{
analogRead(sensor1);
  analogRead(sensor2);
}
```
- Single line blocks (if/else statements etc) should be on the same line and must includes braces
- When used on a single line, there should be a trailing space after the { and a preceding space before the }
` if(fanEnabled) { digitalWrite(fanPin, HIGH); }`
## Declarations
- Declare variables at the top of the function
- In a block of related definitions vertically align the names, types, and initialisations
- Initialise variables close to where they are first used.
## Functions
- Also put the return type on same line as function name
- Functions should be kept as short, and broken into sub-functions as required
- Each function should have a single clearly defined purpose, this purpose should be reflected in its name.
## Executable Statements
- One per line, not i=0; j=0;
- Multiple operations are permitted per line where appropriate. Eg: i = j = 0;
- True / False if statements should **always** use a comparison (Either to 0 or 1, or to `true` and `false`). Eg:
- Good: `if(isEnabled == 1)`
- Bad: `if(isEnabled)`
- Do no use comma operator for multiple variable definitions on a single line
## Function definitions
- Use inline static for all non-interface functions
- Use prototypes for all functions (even those returning int or void)
- Don't turn parameter type checking off in prototypes with (), use (void) instead
- Give sensible variable names in prototypes
## Comments
- Use of the Doxygen commenting syntax is STRONGLY recommended (http://www.doxygen.nl/manual/docblocks.html)
- Blocks comments should be used for any single comment longer than one line
- Single comments are preferred at the end of a line rather than on their own line beforehand