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

4 KiB

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:
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.
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:
/**
 * @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:
#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:
#ifndef VESSEL_FILE_H_
#define VESSEL_FILE_H_
...
#endif /* VESSEL_FILE_H_ */