1 Coding Conventions
Watersrc-stack edited this page 2026-10-11 14:31:31 +02:00

Coding conventions

Files

Every file starts with a header comment:

//
// Author: watersrc-stack@proton.me
// File: renames.c
// Desc: The renamings of the analysis view, and their replacement
//       in a text
//

The Desc: line is what the Function explorer shows for the file, so keep it accurate.

Include guards use this form:

#ifndef FILTERS_H_
    #define FILTERS_H_
...
#endif

New .c files must be added to SRCS (or ADDSRCS for OS-specific files) in the Makefile, which lists files explicitly.

Comments

A comment above a function says what it does, what it returns and when it fails. The explorer and the wiki's Functions-* pages are generated from these comments, either above the definition or above the prototype in a header.

// Removes the renaming of from. 0 on success, 1 if there is none.
static int rename_remove(rename_t **list, const char *from)

Output

  • Use my_write() for display code, never write() or printf(): my_write(OUT_MEMORY, ...) is how the analysis view collects output to apply the renamings. printf appears only in debug output.
  • Prefer the helpers in libs/utils/ over libc's string and stdio functions:
    • my_strlen (LSTR) and my_strncpy;
    • my_putstr (PSTR(start, str, end, fd): writes up to three strings, skips any NULL one);
    • my_putunbr (PNBR, takes a uint32_t);
    • my_strtok;
    • the if_tab_* functions.
  • Watch out for these traps:
    • my_strcpy does not copy the closing '\0': terminate the destination yourself.
    • my_nlen / NLEN takes an int: don't use it on values above 2³¹.
    • my_strtok(str, delim, skip_empty) returns a NULL-terminated array to free with tab_free (NULL if an allocation fails). With skip_empty = 0, "a,,b" gives "a", "", "b".

Data from outside

  • Byte order: multi-byte network and file fields are big-endian. Use read_u16() / read_u32(), never a cast.
  • Lengths: check every length before reading. Frames, save files and DNS answers can come from anyone.
  • Names: names that reach the terminal must be printable ASCII.

Portability

  • OS-specific code belongs in the backends, behind common_lib.h: headers like poll.h, sys/socket.h, linux/*, windows.h, and stat fields like st_ino. Check with make windows.
  • O_BINARY: open files with it. It's defined as 0 where it doesn't exist; without it, Windows translates \r\n and stops reading at the first 0x1A byte.
  • O_NONBLOCK for -I / -O: a FIFO is then rejected by the regular-file check instead of blocking open(). It's 0 on Windows, which has no FIFOs.
  • Sleeping: my_usleep(), not usleep().

Build hygiene

  • Warnings: -W -Wall -Wextra -Werror, so fix every warning. The release build adds fortify warnings; make release must build too.
  • Memory checks: run make asan (valgrind doesn't work everywhere).
  • Struct changes: run make re after changing a struct in a header.

Commits and branches

  • Commit tags: messages start with a tag: (feat), (fix), (add), (wip), (ref), (clean), (enhancement).
  • Branches:
    • master is the release branch.
    • Integration happens on dev.
    • Each feature gets its own branch from dev, named like feat/..., enhancement/... or parsing/....