lidm/docs/structure.md

3.3 KiB

Introduction

This file aims to explain the basic project structure and some code conventions and patterns used for contributors. If you plan on contributing a considerable amount of code, please read this thoroughly to keep the project behavior consistent.

Even if your changes are not very related to the code, this guide can help to understand how they can be related to the rest of the project and what side changes it can require.

Structure

The file structure is very simple, you have .c files in src/ with their header .h counterpart in include/, they are listed in the Makefile and built all together on the same layer.

Each file contains functions aimed to provide some specialized behavior, they tend to follow a common prefix (like vec_ for vector functions) to avoid name collisions with themselves.

Important Files

The main.c of course provides the entry point of the program, then each file has special functionality, but a special one is util.h, is linked with almost every file and provides some shared utilities to dealing with UTF-8, dynamic Vectors and other stuff.

log.c is also an important file as it provides logging utilities for debugging, there's no need to deal with it's initialization, it behaves just like standard printing utilities but integrated into the configured logfile.

Debugging

The log module can be easily used by just setting up the LIDM_LOG environmental variable to the logs output path.

Header Files

But what if you create a new file? It's important that the definitions are only evaluated once by the compiler, even if they are included by several files. For this, you can use this simple trick (assume this is for a file named mylib.h):

#ifndef MYLIBH_
#define MYLIBH_

// library contents
// ...

#endif

It's also a good idea to include brief comments above functions if it's not evident what they do and name all parameters.

Nullability Checks

Nullability checks are not really enforced in the code but it's never a bad idea to include them, however, gcc doesn't support them under certain conditions.

For this you can use NULLABLE, NNULLABLE and UNULLABLE macros from "macros.h" to conditionally include _Nullable, _Nonnull and _Null-unspecified respectively.

Handling & Support

Every function should properly handle allocation failures (avoid them with stack arrays where possible), support UTF-8 strings, use the log module instead of printing to stdout (messing with the state of the ui) and free all lost memory (if it can be lost before reaching the final stage where it execs another program, I'm fine with not freeing memory still reachable at the end).

Code format, style and linting

Be reasonable and follow clang-format and clang-tidy rules. clang-tidy can be quite pedantic with the current primitive rules, so feel free to use LINTIGNORE or discuss if said rule should be enforced in first place.

Also avoid grammar typos and for shell scripts use shellcheck, you can run this checks with make pre-commit if you have the required tools.

Documentation

Please, also check if there's documentation related to the feature/changes you are implementing, could be on markdown or manpages, if there is and you have some spare time, it's really helpful to update it; although not enforced.