xref: /netbsd-src/lib/librefuse/HACKING.md (revision 867d70fc718005c0918b8b8b2f9d7f2d52d0a0db)
1<!--
2    $NetBSD: HACKING.md,v 1.1 2022/01/22 08:09:39 pho Exp $
3-->
4
5# How to add support for a new API version
6
71. Update `_REFUSE_MAJOR_VERSION_` and/or `_REFUSE_MINOR_VERSION_` in
8   `fuse.h`.
92. If the new API introduces some new typedefs, enums, constants,
10   functions, or struct fields, define them *unconditionally*. Trying
11   to conditionalize them will only increase complexity of the
12   implementation without necessity.
133. If the new API removes some existing declarations, move them to
14   `./refuse/legacy.[ch]`. There is no need to conditionally hide
15   them.
164. If the new API doesn't change any of existing declarations, you are
17   lucky. You are **tremendously** lucky. But if it does, things get
18   interesting... (Spoiler: this happens all the time. All, the,
19   time. As if there still weren't enough API-breaking changes in the
20   history of FUSE API.)
21
22## If it breaks API compatibility by changing function prototypes or whatever
23
241. Create a new header `./refuse/v${VERSION}.h`. Don't forget to add it
25   in `./refuse/Makefile.inc` and `../../distrib/sets/lists/comp/mi`.
262. Include it from `./fuse.h` and add a new conditionalized section at
27   the bottom of it. The whole point of the section is to choose
28   correct symbols (or types, or whatever) and expose them without a
29   version postfix.
30
31### If it changes `struct fuse_operations`
32
331. Add `#define _FUSE_OP_VERSION__` for the new API version in the
34   conditionalized section.
352. Define `struct fuse_operations_v${VERSION}` in `v${VERSION}.h`.
363. Update `./refuse/fs.c`. This is the abstraction layer which absorbs
37   all the subtle differences in `struct fuse_operations` between
38   versions. Every function has to be updated for the new version.
39
40### If it changes anything else that are already versioned
41
421. Declare them in `./refuse/v${VERSION}.h` with a version postfix.
432. Update the conditionalized section for the version in `./fuse.h` so
44   that it exposes the correct definition to user code.
453. Create `./refuse/v${VERSION}.c` and implement version-specific
46   functions in it. Don't forget to add it to `./refuse/Makefile.inc`.
47
48### If it changes something that have never been changed before
49
501. Move them from the unconditionalized part of the implementation to
51   `./refuse/v${VERSION}.[ch]`.
522. Add a version postfix to them.
533. Update every single conditionalized section in `./fuse.h` so that
54   they will be conditionally exposed without a version postfix
55   depending the value of `FUSE_USE_VERSION`. If you cannot just
56   `#define` them but need to introduce some functions, inline
57   functions are preferred over function macros because the latter
58   lack types and are therefore error-prone. Preprocessor conditionals
59   are already error-prone so don't make them worse.
60