vessel/CODE.md
Arija A. ad6b8f849c
refactor: Use stdbool.h
Signed-off-by: Arija A. <ari@ari.lt>
2025-05-02 17:28:47 +03:00

143 lines
4 KiB
Markdown

# Vessel C Code Standards
## 1. Naming Conventions
### 1.1 Prefixing
- All public symbols (functions, variables, constants, macros, types) must be prefixed with `vs_` or `VS_`.
- All private structure members must:
- Be prefixed with `_`
- Be placed at the bottom of the structure definition _if possible_.
### 1.2 Naming Style
- Use `snake_case` for all identifiers: variables, functions, struct/union/enum names.
- Constants and macros should be `UPPER_SNAKE_CASE`.
- Iterators should use `idx`, `jdx`, `kdx` rather than `i`, `j`, `k` for clarity.
- All variables should be at least 2-3 characters.
- Objects should use `PascalCase`.
### 1.3 Function Naming
- All functions operating on a specific type (e.g., `vs_HMap`) must include that type in the name:
```c
vs_HMap_insert(...);
vs_HMap_destroy(...);
```
- Functions working with hashmaps or other container types must include:
- A corresponding `init_` and `destroy_` function
- Preferably a `typedef` alias for the type
## 2. Code Formatting
### 2.1 Formatting Tools
- Use `clang-format` and `clang-tidy` with the project-supplied configuration files.
- All contributors must format code before submission.
### 2.2 Bracing and Indentation
- Use braces even for single-line `if`, `for`, or `while` blocks unless it is the most inner layer and obviously safe.
```c
if (cond) {
...
}
```
- Indentation is 4 spaces. Do not use tabs.
### 2.3 Line Length
- Limit lines to 100 characters unless breaking the line reduces readability.
## 3. Type and Memory Safety
### 3.1 Typing
- Prefer fixed-width types from `<stdint.h>` or `vessel/def.h`:
- `int32_t`, `uint16_t`, etc.
- Avoid `int` and other ambiguous-width types unless interfacing with APIs that require them.
- `size_t` and `ssize_t` are allowed.
- Avoid type casting where possible, especially to smaller types.
### 3.2 Immutability
- Default to `const`-correctness. Treat objects as immutable unless mutation is clearly needed.
### 3.3 Structure Passing
- Always pass structures by pointer, not by value.
### 3.4 Dereferencing
- Avoid two or larger-level dereferencing (e.g., `**obj`, `obj->a->b`, ...) unless implementing a proxy pattern or absolutely necessary.
## 4. Style and Syntax
### 4.1 Comments
- Use C-style block comments only: `/* ... */`. Avoid C++-style `//` comments
- All public headers should use `Doxygen`-compatible comments:
```c
/**
* @brief Brief description.
* @param foo Description of parameter foo.
* @return Description of return value.
*/
```
### 4.2 Constants & Bitsets
- Prefer bitsets like `(1 << N)` over hex or decimal values, explicitly casting to the target type:
```c
#define FLAG_WRITE ((uint16_t)(1 << 0))
#define FLAG_READ ((uint16_t)(1 << 1))
```
## 5. Logging and Debugging
- Logging must use the global logging interface.
- Logs should be:
- Clear
- Prefixed by the function name
## 6. Standard Compliance and Portability
- Avoid reliance on non-portable features:
- Don't use `_POSIX_C_SOURCE` or compiler-specific extensions unless strictly necessary.
- Prefer ANSI-compatible syntax.
## 7. Function and API Design
### 7.1 Dual Interfaces for Strings
- Functions that accept strings must provide both:
- A null-terminated (`char *`) version
- A sized (`char *buf, size_t len`) version
### 7.2 Structure Initialization & Destruction
- All dynamic or heap-using structures must have:
- `vs_type_init(...)`
- `vs_type_destroy(...)`
### 7.3 Error Reporting
- For simple functions, basic error indicators like returning `-1` or a falsy value (e.g., `NULL` or `False`) are sufficient for error handling.
- For functions that operate on objects, error handling and reporting should be managed through the `vessel/error.h` API, ensuring consistent error management across the codebase.
### 7.4 Include guards
- All headers must include a header guard following the convention of:
```c
#ifndef VESSEL_FILE_H_
#define VESSEL_FILE_H_
...
#endif /* VESSEL_FILE_H_ */
```