Coding style

Cahute is made to be compatible with as much platforms as possible, adopting the lowest C standard (C89/C90) and protecting platform-specific usage behind macros as much as possible.

Formatting

In order to focus as much as possible on the work that matters, Cahute relies heavily on autoformatting and uncompromising sets of rules enforceable through tooling. This includes:

  • For C code, the use the clang-format with a set of rules described in .clang-format, installed as a pre-commit hook.

  • For Python code, the use of Black.

Otherwise, the rules are not yet clearly defined, and may be as a few contributions have gone by, and the standard for Cahute shapes itself a bit more clearly.

Namespace

Cahute reserves both the cahute_ and CAHUTE_ prefixes for all symbols and macros, i.e. it is recommended a library user does not use that prefix in any of their work.

Cahute respects reserved namespaces from C and POSIX; see Open Group Base Specifications Issue 7, section 2.2.2 The Name Space for more information.

Note

This notably prevents us from using the _t suffix, since it is reserved by POSIX / Single UNIX Specification.

To avoid overlapping with user macros, function and macro parameters are also defined within the Cahute namespaces, more specifically in the cahute__ and CAHUTE__ (double underscore) namespaces.

For example, a preprocessed Cahute macro and function declaration in public headers are the following:

#define CAHUTE_MY_MACRO(CAHUTE__ARG1, CAHUTE__ARG2) ...

int cahute_open_usb_link(
    cahute_link *cahute__linkp,
    unsigned long cahute__flags,
    int cahute__bus,
    int cahute__address
);

Note

The namespace mainly applies to public headers from Cahute. Within internal headers and source files, only exported symbols need to be placed within the reserved namespaces.

Exported symbols in the Cahute static library can be found using nm:

nm -CgU libcahute.a

Compatibility

Cahute is designed to be more compatible than not, but to make use of compiler and platform specific tools for static analysis if possible. As such, you must use the relevant compatibility macros for your case:

Only utilities available in C89 / C90 must be used.

For easier implementation, the following out-of-standard general utilities are available:

Warning

When fopen() is used, the b flag must be used to ensure that platforms don’t operate conversions by default:

/* WRONG. */
FILE *fp = fopen("myfile.txt", "r");

/* Correct! */
FILE *fp = fopen("myfile.txt", "rb");

This is notably useful for platforms such as Windows, that operates conversions by default (i.e. use rt instead of rb by default), except on seeking / telling, which could cause problems where the computed file size does not match with the size of the actually read data.