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.