11.1Spho<!--
21.1Spho    $NetBSD: HACKING.md,v 1.1 2022/01/22 08:09:39 pho Exp $
31.1Spho-->
41.1Spho
51.1Spho# How to add support for a new API version
61.1Spho
71.1Spho1. Update `_REFUSE_MAJOR_VERSION_` and/or `_REFUSE_MINOR_VERSION_` in
81.1Spho   `fuse.h`.
91.1Spho2. If the new API introduces some new typedefs, enums, constants,
101.1Spho   functions, or struct fields, define them *unconditionally*. Trying
111.1Spho   to conditionalize them will only increase complexity of the
121.1Spho   implementation without necessity.
131.1Spho3. If the new API removes some existing declarations, move them to
141.1Spho   `./refuse/legacy.[ch]`. There is no need to conditionally hide
151.1Spho   them.
161.1Spho4. If the new API doesn't change any of existing declarations, you are
171.1Spho   lucky. You are **tremendously** lucky. But if it does, things get
181.1Spho   interesting... (Spoiler: this happens all the time. All, the,
191.1Spho   time. As if there still weren't enough API-breaking changes in the
201.1Spho   history of FUSE API.)
211.1Spho
221.1Spho## If it breaks API compatibility by changing function prototypes or whatever
231.1Spho
241.1Spho1. Create a new header `./refuse/v${VERSION}.h`. Don't forget to add it
251.1Spho   in `./refuse/Makefile.inc` and `../../distrib/sets/lists/comp/mi`.
261.1Spho2. Include it from `./fuse.h` and add a new conditionalized section at
271.1Spho   the bottom of it. The whole point of the section is to choose
281.1Spho   correct symbols (or types, or whatever) and expose them without a
291.1Spho   version postfix.
301.1Spho
311.1Spho### If it changes `struct fuse_operations`
321.1Spho
331.1Spho1. Add `#define _FUSE_OP_VERSION__` for the new API version in the
341.1Spho   conditionalized section.
351.1Spho2. Define `struct fuse_operations_v${VERSION}` in `v${VERSION}.h`.
361.1Spho3. Update `./refuse/fs.c`. This is the abstraction layer which absorbs
371.1Spho   all the subtle differences in `struct fuse_operations` between
381.1Spho   versions. Every function has to be updated for the new version.
391.1Spho
401.1Spho### If it changes anything else that are already versioned
411.1Spho
421.1Spho1. Declare them in `./refuse/v${VERSION}.h` with a version postfix.
431.1Spho2. Update the conditionalized section for the version in `./fuse.h` so
441.1Spho   that it exposes the correct definition to user code.
451.1Spho3. Create `./refuse/v${VERSION}.c` and implement version-specific
461.1Spho   functions in it. Don't forget to add it to `./refuse/Makefile.inc`.
471.1Spho
481.1Spho### If it changes something that have never been changed before
491.1Spho
501.1Spho1. Move them from the unconditionalized part of the implementation to
511.1Spho   `./refuse/v${VERSION}.[ch]`.
521.1Spho2. Add a version postfix to them.
531.1Spho3. Update every single conditionalized section in `./fuse.h` so that
541.1Spho   they will be conditionally exposed without a version postfix
551.1Spho   depending the value of `FUSE_USE_VERSION`. If you cannot just
561.1Spho   `#define` them but need to introduce some functions, inline
571.1Spho   functions are preferred over function macros because the latter
581.1Spho   lack types and are therefore error-prone. Preprocessor conditionals
591.1Spho   are already error-prone so don't make them worse.
60