summaryrefslogtreecommitdiff
path: root/docs/handbook/neozip/code-style.md
diff options
context:
space:
mode:
Diffstat (limited to 'docs/handbook/neozip/code-style.md')
-rw-r--r--docs/handbook/neozip/code-style.md259
1 files changed, 259 insertions, 0 deletions
diff --git a/docs/handbook/neozip/code-style.md b/docs/handbook/neozip/code-style.md
new file mode 100644
index 0000000000..680013d1d9
--- /dev/null
+++ b/docs/handbook/neozip/code-style.md
@@ -0,0 +1,259 @@
+# Code Style
+
+## Overview
+
+Neozip follows conventions derived from zlib-ng and the broader zlib
+ecosystem. This document describes naming patterns, macro usage,
+compiler annotations, and structural conventions observed in the
+codebase.
+
+---
+
+## Naming Conventions
+
+### Functions
+
+| Scope | Convention | Example |
+|---|---|---|
+| Public API | `PREFIX(name)` | `PREFIX(deflateInit2)` → `deflateInit2` or `zng_deflateInit2` |
+| Internal | `Z_INTERNAL` linkage | `Z_INTERNAL uint32_t adler32_c(...)` |
+| Exported | `Z_EXPORT` linkage | `int32_t Z_EXPORT PREFIX(deflate)(...)` |
+| Architecture | `name_arch` | `adler32_avx2`, `crc32_neon` |
+| Template | `name_tpl` | `longest_match_tpl`, `inflate_fast_tpl` |
+
+### Macros
+
+| Pattern | Usage | Example |
+|---|---|---|
+| `PREFIX(name)` | Public symbol namespacing | `PREFIX(inflate)` |
+| `PREFIX3(name)` | Type namespacing | `PREFIX3(stream)` → `z_stream` or `zng_stream` |
+| `WITH_*` | CMake build options | `WITH_AVX2`, `WITH_GZFILEOP` |
+| `X86_*` / `ARM_*` | Architecture feature guards | `X86_AVX2`, `ARM_NEON` |
+| `Z_*` | Public constants | `Z_OK`, `Z_DEFLATED`, `Z_DEFAULT_STRATEGY` |
+| `*_H` | Include guards | `DEFLATE_H`, `INFLATE_H` |
+
+### Types
+
+| Type | Definition |
+|---|---|
+| `Pos` | `uint16_t` — hash chain position |
+| `IPos` | `uint32_t` — index position |
+| `z_word_t` | `uint64_t` (64-bit) or `uint32_t` (32-bit) |
+| `block_state` | `enum { need_more, block_done, finish_started, finish_done }` |
+| `code` | Struct: `{ bits, op, val }` for inflate Huffman tables |
+| `ct_data` | Union: `{ freq/code, dad/len }` for deflate Huffman trees |
+
+---
+
+## Visibility Annotations
+
+```c
+#define Z_INTERNAL // Internal linkage (hidden from shared library API)
+#define Z_EXPORT // Public API export (__attribute__((visibility("default"))))
+```
+
+All internal helper functions use `Z_INTERNAL`. All public API functions
+use `Z_EXPORT`.
+
+---
+
+## Compiler Annotations
+
+From `zbuild.h`:
+
+```c
+// Force inlining
+#define Z_FORCEINLINE __attribute__((always_inline)) inline
+
+// Compiler hints
+#define likely(x) __builtin_expect(!!(x), 1)
+#define unlikely(x) __builtin_expect(!!(x), 0)
+
+// Fallthrough annotation for switch
+#define Z_FALLTHROUGH __attribute__((fallthrough))
+
+// Target-specific compilation
+#define Z_TARGET(x) __attribute__((target(x)))
+
+// Alignment
+#define ALIGNED_(n) __attribute__((aligned(n)))
+
+// Restrict
+#define Z_RESTRICT __restrict__
+```
+
+### Target Attributes vs. Compile Flags
+
+Individual SIMD functions can use `Z_TARGET` instead of file-level flags:
+
+```c
+Z_TARGET("avx2")
+Z_INTERNAL uint32_t adler32_avx2(uint32_t adler, const uint8_t *buf, size_t len) {
+ // AVX2 intrinsics here
+}
+```
+
+However, neozip typically uses per-file compile flags set via CMake
+`set_property(SOURCE ... COMPILE_OPTIONS ...)`.
+
+---
+
+## Include Patterns
+
+### Public Headers
+
+```
+zlib.h — Main public API (generated from zlib.h.in)
+zconf.h — Configuration (generated)
+zlib_name_mangling.h — Symbol renaming
+```
+
+### Internal Headers
+
+```
+zbuild.h — Build macros, compiler abstractions
+zutil.h — Internal utility macros and constants
+deflate.h — deflate_state, internal types
+inflate.h — inflate_state, inflate_mode
+functable.h — Function dispatch table
+cpu_features.h — CPU detection interface
+deflate_p.h — Private deflate helpers
+adler32_p.h — Private Adler-32 helpers
+crc32_braid_p.h — Private CRC-32 braided implementation
+trees_emit.h — Bit emission helpers
+match_tpl.h — Template for longest_match
+insert_string_tpl.h — Template for hash insertion
+inffast_tpl.h — Template for inflate_fast
+```
+
+### Include Order
+
+Source files typically include:
+```c
+#include "zbuild.h" // Always first (defines PREFIX, types)
+#include "deflate.h" // or "inflate.h"
+#include "functable.h" // If dispatching
+#include "<arch>_features.h" // If architecture-specific
+```
+
+---
+
+## Template Pattern
+
+Several functions use a "template" pattern via preprocessor includes:
+
+```c
+// match_tpl.h — template for longest_match
+// Defines LONGEST_MATCH, COMPARE256, INSERT_STRING via macros
+// Then included by each architecture variant:
+
+// In longest_match_sse2.c:
+#define LONGEST_MATCH longest_match_sse2
+#define COMPARE256 compare256_sse2
+#include "match_tpl.h"
+```
+
+This avoids code duplication while allowing architecture-specific
+function names and intrinsics.
+
+---
+
+## Struct Alignment
+
+Performance-critical structures use `ALIGNED_(64)` for cache-line
+alignment:
+
+```c
+struct ALIGNED_(64) internal_state { ... }; // deflate_state
+struct ALIGNED_(64) inflate_state { ... };
+```
+
+This prevents false sharing and ensures SIMD-friendly alignment.
+
+---
+
+## Conditional Compilation
+
+Architecture and feature guards follow a consistent pattern:
+
+```c
+#ifdef X86_AVX2
+ if (cf.x86.has_avx2) {
+ functable.adler32 = adler32_avx2;
+ }
+#endif
+```
+
+The `#ifdef` tests compile-time availability (was the source included
+in the build?). The runtime `if` tests CPU capability.
+
+### Build Option Guards
+
+```c
+#ifdef WITH_GZFILEOP // Gzip file operations
+#ifdef ZLIB_COMPAT // zlib-compatible API
+#ifndef Z_SOLO // Not a standalone/embedded build
+#ifdef HAVE_BUILTIN_CTZ // Compiler has __builtin_ctz
+```
+
+---
+
+## Error Handling Style
+
+Functions return `int` error codes from the `Z_*` set:
+
+```c
+if (strm == NULL || strm->state == NULL)
+ return Z_STREAM_ERROR;
+```
+
+Internal functions that cannot fail return `void` or the computed value
+directly. Error strings are set via `strm->msg`:
+
+```c
+strm->msg = (char *)"incorrect header check";
+state->mode = BAD;
+```
+
+---
+
+## Memory Management
+
+All dynamically allocated memory goes through user-provided allocators:
+
+```c
+void *zalloc(void *opaque, unsigned items, unsigned size);
+void zfree(void *opaque, void *address);
+```
+
+If `strm->zalloc` and `strm->zfree` are `Z_NULL`, default `malloc`/`free`
+wrappers are used. The single-allocation strategy (`alloc_deflate` /
+`alloc_inflate`) minimises the number of allocator calls.
+
+---
+
+## Formatting
+
+- **Indentation**: 4 spaces (no tabs in main source)
+- **Braces**: K&R style (opening brace on same line)
+- **Line length**: ~80–100 characters preferred
+- **Comments**: C-style `/* */` for multi-line, `//` for inline
+- **Pointer declarations**: `type *name` (space before `*`)
+
+```c
+static void pqdownheap(deflate_state *s, ct_data *tree, int k) {
+ int v = s->heap[k];
+ int j = k << 1;
+ while (j <= s->heap_len) {
+ if (j < s->heap_len &&
+ SMALLER(tree, s->heap[j+1], s->heap[j], s->depth))
+ j++;
+ if (SMALLER(tree, v, s->heap[j], s->depth))
+ break;
+ s->heap[k] = s->heap[j];
+ k = j;
+ j <<= 1;
+ }
+ s->heap[k] = v;
+}
+```