diff --git a/.DS_Store b/.DS_Store
index efda63e..50d7e99 100644
Binary files a/.DS_Store and b/.DS_Store differ
diff --git a/.clang-format b/.clang-format
index 8d75679..8cf595a 100644
--- a/.clang-format
+++ b/.clang-format
@@ -17,3 +17,4 @@ AllowShortIfStatementsOnASingleLine: AllIfsAndElse
AllowShortLoopsOnASingleLine: true
IndentAccessModifiers: false # Indent access specifiers by one level
AccessModifierOffset: -4 # Optional: adjust offset relative to the class indentation level
+IndentGotoLabels: InnerIndent
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..14d3d7c
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,37 @@
+# AGENTS.md
+
+## Identity & Core Philosophy
+You are an expert bug-hunter agent.
+Speak and reason in **Caveman style** (why use many token when few token do trick).
+
+### Caveman Communication Rules
+- Drop articles (a/an/the), filler (just/really/basically/actually/simply), pleasantries, and greetings.
+- Short, dense, direct phrases. Fragment sentences okay.
+- Never summarize files read. Report only findings.
+- **No tool-call narration:** Fire tools directly. Never explain what you are about to inspect or have just inspected.
+- **Tokenizer rules:** NEVER invent abbreviations (cfg/impl/req/res/fn) or use arrows (→); tokenizers split them. Keep full words.
+- **Safety rules:** NEVER drop `not`, `never`, `no`, `only`, `except` (flips meaning).
+- **Exceptions (Do NOT caveman):** Code snippets, file paths, line numbers, command names, and error traces remain exact and intact.
+- **Output pattern:** `[thing] [action] [reason]. [next step].`
+
+---
+
+## Strict Permissions & Boundaries
+1. **Target Task:** Read codebase, hunt bugs, identify security flaws, edge-case failures, or performance bottlenecks.
+2. **File Mutation Constraint:**
+ - **YOU MAY ONLY CREATE OR EDIT:** `BUGS.md`
+ - **ABSOLUTE BAN:** You are strictly forbidden from modifying, patching, refactoring, deleting, or creating ANY other files in the workspace (no source files, configs, tests, or documentation).
+ - If user asks you to fix code directly, REFUSE in caveman: "No touch code. Rule say only log to BUGS.md."
+
+---
+
+## Operating Instructions
+1. Inspect files in read-only mode using available search/read tools. Call them immediately without introductory text.
+2. Read existing `BUGS.md` first:
+ - Identify existing style, headers, keys, table columns, or list formats.
+ - You MUST mirror existing format, structure, and naming conventions exactly.
+ - If `BUGS.md` is empty or missing, use a minimal markdown list: `File:Line | Severity | Issue | Recommended fix`.
+3. For every confirmed issue found:
+ - Append or edit entry in `BUGS.md` following matched format.
+ - Keep bug descriptions in `BUGS.md` terse and caveman-style.
+4. Do not patch or edit source code under any circumstances.
diff --git a/BUGS.md b/BUGS.md
new file mode 100644
index 0000000..ad0acae
--- /dev/null
+++ b/BUGS.md
@@ -0,0 +1,325 @@
+# libvec bug tracker
+
+> **Verified** `char.c` @ **2026-09-28 12:48:04**, 3 independent passes.
+> `char.h` 108 lines, `utils.h` 31, `utils.c` 12, `CMakeLists.txt` 32, `main.c` 55.
+> Line numbers are the *only* field that drifts. Re-verify before trusting them.
+>
+> **Pass 4** @ **2026-09-28**, `push_back` / `pop_back` (char.c:67-157), ASan.
+> **Pass 5** @ **2026-09-28**, whole file re-read plus 10 harness runs, ASan.
+> Line count moved 804 to 800 with the `create` rewrite; re-measured per pass.
+
+**Open 79** — 11 S1, 27 S2, 11 S3, 29 C
+**1 DECIDE** · **Fixed 12** (listed at the bottom, no rows) · 79 rows
+
+**Severity** `S1` memory safety · `S2` wrong result / broken contract ·
+`S3` edge case · `C` cleanup · `DECIDE` open design question
+
+## How to read this
+
+Each function is a `###` with one table. Rows are sorted by severity (S1 first),
+so the worst thing in each function is on top. Fixed findings are **not** rows —
+they are a flat ID list at the bottom of the file.
+
+Tracking state is a **column**, not a checkbox: a `State` cell carries more than
+"done or not done" — `DECIDE` has no checkbox equivalent, and it is load-bearing
+here. And task-list syntax inside a table cell is renderer-dependent, so a
+`State` column is the form that survives any markdown preview. If your preview
+*does* render checkboxes in tables and you want click-to-toggle, a leading `Done`
+column can be added without disturbing anything else.
+
+## Rules
+
+1. **IDs are permanent.** Never reused, never renumbered. An ID leaves the file
+ only when its row is deleted outright, and only under rule 3.
+2. **Locations drift freely.** The only field updated in place.
+3. **False findings are deleted, not archived.** If a row turns out to be my own
+ error, the row is removed. A new ID carries the accurate finding if there is
+ one. No `DISPUTED` state, no corrections log — a tracker is not a diary.
+4. **State** is `OPEN` / `DECIDE`. `FIXED` means the row is gone and its ID is
+ in the bottom list.
+5. **Fixed findings live in the ID list at the bottom**, nothing else.
+
+## Triage — the 11 open S1s, in suggested order
+
+| # | ID | Location | Summary |
+|----|---|---|---|
+| 1 | RS-7 | char.c:175, 200 | `reserve` on a blank vector allocates 1024 but claims 5000. Ordinary `size`, live overflow |
+| 3 | PB-8 | char.c:89, 131 | live heap overflow, 2-line repro |
+| 4 | PB-14 | char.c:131, 154 | write through the freed buffer after `delete`, 2-line repro |
+| 5 | RS-1 | char.c:180-195 | use-after-free in `reserve`'s truncation loop, ASan confirmed |
+| 6 | IN-1 | char.c:783 | inverted `iter_end > iter_start` |
+| 7 | IN-2 | char.c:783 | dead bounds check sitting behind IN-1 |
+| 8 | DL-1 | char.c:293, 297 | `const` delete, double free on second call |
+| 9 | DL-2 | char.h:11-17 | no ownership marker, struct copy double-frees |
+| 8 | UT-2 | utils.c:3-12 | `error_messages[0]` / `[1]` are `NULL` |
+| 9 | PB-3 | char.c:106, 116 | capacity committed before the realloc check |
+| 10 | PB-15 | char.c:87, 128-131 | null-buffer path has no `else`, so `arr == NULL && size > 0` writes to NULL. Defensive |
+
+> **Two of the eleven are the same class.** RS-7 and PB-8 both end in a
+> write past a small block, and both come from a struct field claiming more
+> bytes than were allocated: `capacity` set from the request rather than the
+> block (RS-7, char.c:200), `calloc(1)` with `capacity` untouched (PB-8,
+> char.c:89). One rule kills both: **never write `_internal_capacity` without
+> writing the allocation it describes.** Verify with a single postcondition —
+> after any function that touches capacity, the block size and the field must
+> agree. CR-8 was a third member of this class; it is fixed as of Pass 5, and
+> `create` now carries the same postcondition in one place (CR-9, char.c:44).
+
+> **Fix IN-1 and IN-2 in the same commit.** The raw read in the 3-arg overload
+> is unreachable *only because* IN-1's inversion empties the loop. Fixing IN-1
+> alone converts a clean rejection into a live out-of-bounds read, because IN-2's
+> bound check stays dead behind the short-circuit.
+
+> **PB-8 and PB-14 are the only two rows in this file with a sanitizer trace
+> attached.** Both reproduce in three lines from `main`. `delete` should null
+> the struct's fields (DL-1) and push should size the materialization from
+> `_internal_capacity` (PB-8); those two fixes close the whole S1 set for this
+> function pair.
+
+> **Reproducer harness**: `clang -std=c2x -g -fsanitize=address -Isrc/lib
+> -Isrc/lib/char t.c src/lib/char/char.c src/lib/utils/utils.c`. `-std=c2x` is
+> required — `char.c` uses `nullptr`, so the project does not compile as C17.
+> Reproducers that ask for a multi-exabyte `calloc` additionally need
+> `ASAN_OPTIONS=allocator_may_return_null=1`, or ASan aborts on the 2^61-byte
+> `calloc` before the interesting line runs.
+
+> **Defensive-only rows.** RZ-2, RS-2, PB-15 and PB-18 are not reachable
+> without an allocation of ~2^61 bytes, or a hand-built struct. Kept as
+> hardening because the guards are cheap and the invariant is worth stating.
+
+---
+
+## Bugs
+
+### `_vec_char_push_back` / `_vec_char_pop_back` — char.c:71, 136
+
+| ID | Sev | Location | Finding | State |
+|-----|---|---|---|---|
+| `PB-8` | S1 | char.c:89, 131 | `calloc(1)` on the null-buffer path leaves `_internal_capacity` at 1024, so the 2nd `push_back` writes `arr[1]` one byte past a 1-byte block. **ASan: `heap-buffer-overflow` WRITE of size 1 at char.c:131**, block allocated at char.c:89 | OPEN |
+| PB-14 | S1 | char.c:75, 131, 154 | neither function checks liveness. `_vec_char_delete` frees without clearing the struct (DL-1), so `delete(&v); push_back(&v,'z')` writes through the freed pointer. **ASan: `heap-use-after-free` WRITE of size 1 at char.c:131**, freed at char.c:297. Same for `pop_back`, which writes `'\0'` at char.c:154 | OPEN |
+| PB-15 | S1 | char.c:87, 128-131 | the materialize branch is guarded by `status == ERR_BUF_NULL && _internal_size == 0` and has no `else`. Any state with `arr == NULL && _internal_size > 0` falls through to char.c:126, takes `res = ptr->_internal_arr` (NULL) and writes `arr[size]`. No in-file producer, but nothing checks the invariant either | OPEN |
+| PB-3 | S1 | char.c:106, 116 | `_internal_capacity` assigned before the `!res` check; on OOM the struct overstates its capacity and the next call writes past the real block. Both branches | OPEN |
+| PB-9 | S2 | char.c:85-99| `push_back` materializes a null vector, making it a second path alongside `reserve`; the two disagree on allocation size (1 byte vs 1024) | OPEN |
+| PB-16 | S2 | char.c:116, 131 vs 154 | the growth `realloc` leaves the new tail uninitialized and `push_back` never writes a terminator at `_internal_size`, so `_vec_char_data` hands back a non-NUL-terminated buffer — `strlen(data(&v))` runs off the end. **ASan: `heap-buffer-overflow` READ of 2049 bytes past a 2048-byte region** grown at char.c:116. The lone `'\0'` write in either function is `pop_back`'s vacated slot, so termination is accidental | OPEN |
+| PB-21 | S2 | char.c:81, 104 | after any `reserve` the vector is permanently full: reserve sets `max_size = capacity`, so char.c:81 fails for good and `push_back` can only return `ERR_MAX_PASSED`. Duplicate view of AS-4, kept so this table stands alone | OPEN |
+| PB-17 | S3 | char.c:144-147 vs 87 | `pop_back` refuses to materialize while `push_back` does. A blank vector reports `ERR_BUF_NULL` (21) and logs a spurious "Buffer :- NULL" instead of `ERR_SIZE_ZERO` (22), so a `while (pop_back(&v) == SUCCESS)` drain reports the wrong reason | OPEN |
+| PB-18 | S3 | char.c:103, 116, 120-124 | `_internal_capacity == 0` makes `dst_cap` 0, and `realloc(arr, 0)` frees the block. The `!res` check then returns `ERR_ALLOC_FAIL` with `_internal_arr` dangling and capacity already committed as 0; the next push writes to freed memory. Capacity 0 is unreachable from this file today, so defensive | OPEN |
+| PB-20 | S3 | char.c:154 | only the vacated slot is zeroed, so bytes past `_internal_size` keep their values and are readable out of band through `data()`. `clear` zeroes the whole range and `erase` zeroes the tail; `pop_back` is the inconsistent one | OPEN |
+
+> PB-1 and PB-2 were originally described as firing "on the very next call" and
+> as "the clamp silently does nothing". Both claims were wrong in detail: PB-1
+> needed `capacity < size+1 <= max_size < 2*capacity`, a band today's `VEC_MAX`
+> never reaches, and PB-2's cause was `cap` being recomputed from the
+> already-clobbered `capacity`, not the branch being skipped.
+
+> **Pass-4 note.** Four pre-existing rows here were my own errors and were
+> deleted: a "dead else" that is the common path, two `is_valid` double-call
+> claims in a function that hoists, and an overflow that `VEC_MAX` makes
+> impossible. Found by diffing the wording against the source, not by testing.
+> The three new S1/S2 rows *were* tested; the reproducer command is above.
+
+### `_vec_char_create` — char.c:23
+
+> **Pass-5 note.** `create`'s growth block was rewritten this pass and the
+> rewrite is correct. The invariant it now enforces in one place is
+> `size <= _internal_capacity <= _internal_max_size` on return, held by the
+> commit-back at char.c:44. Verified under ASan at `size` 0, 1, 1023, 1024,
+> 1025, 2047, 2048, 2049, 2999, 5000 and `VEC_MAX - 1`: `capacity >= size` on
+> every call, the `calloc` block matches the reported capacity, no overflow.
+> One case to know about: `create(NULL, VEC_MAX - 1)` still returns
+> `capacity=4611686018427387902` over `arr == NULL`, because growth is correct
+> and the `calloc` then fails. That is CR-3 below, and it is unchanged.
+> `dst_cap * 2` at char.c:42 cannot wrap, because the loop only doubles while
+> the product stays under `_internal_max_size`. An intermediate revision of
+> this fix omitted the commit-back and overflowed every `size > CAPACITY`; it
+> never reached a build, so no ID was spent on it. Two `create` findings left
+> the table this pass and their IDs are in the bottom list: **CR-7**, the
+> second growth branch, which tested the ceiling (`capacity*2 > max_size`)
+> instead of the loop's own postcondition — a superset that also fired after a
+> successful grow, overwriting `capacity` with `size` and forcing the next
+> `push_back` to reallocate for one byte; its `>` test also disagreed with the
+> loop's `>=` exit on exactly one value, reachable only because `VEC_MAX` is
+> odd. **CR-8**, the `>=` guard at char.c:32, which left `size == VEC_MAX`
+> allocating 1024 bytes and copying `VEC_MAX` bytes into it. Both are gone
+> because the branch they described no longer exists, not because either was
+> re-filed under a new ID.
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| CR-6 | S2 | char.c:29, 39-45| null vector's `_internal_capacity` is set to `CAPACITY` (1024) while nothing is allocated. Currently **masked** by AC-1: `capacity()` returns `ERR_BUF_NULL` first, so the lie is not observable through the public API. The observable form of this same lie is PB-8, after `push_back` materializes the buffer | OPEN |
+| CR-3 | S3 | char.c:48-53 | on `calloc` failure returns a struct with an already-grown `capacity` and `arr == NULL`. Defensive. **Now reachable with an ordinary `size`, not just a huge one**: `create(NULL, 5000)` grows `capacity` to 8192 at char.c:44, then the 8192-byte `calloc` fails and the struct survives claiming 8192 over a null buffer | OPEN |
+| CR-4 | DECIDE | char.c:58-65 | no NUL terminator; is a `const char* src, size_t size` pair a byte range or a C string? Affects whether a `from_cstr` helper is needed | DECIDE |
+
+### `_vec_char_is_valid` — char.c:6
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| IV-1 | S2 | char.c:6 | always returns non-zero, so `if (_vec_char_is_valid(&v))` is true for every input including NULL. Every call site compares codes by luck | OPEN |
+| IV-3 | S2 | char.c:6-17| `is_valid` is the only validation primitive in the file and it requires a non-null **buffer**, not just a non-null vector. Every accessor that only needs to validate the vector pointer therefore inherits `ERR_BUF_NULL`. This is the root cause of AC-1, AC-2, SW-1 and ST-2 | OPEN |
+
+### `_vec_char_reserve` — char.c:156
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| RS-7 | S1 | char.c:175, 200 | the `ERR_BUF_NULL` path allocates `ptr->_internal_capacity` bytes, not the requested `capacity`, then line 200 sets `_internal_capacity = capacity` regardless. So `reserve(&v, 5000)` on a blank vector `calloc`s **1024** bytes and the struct claims 5000. **ASan: `heap-buffer-overflow` WRITE at char.c:131, 0 bytes after a 1024-byte region allocated at char.c:175**, reached by 1026 `push_back`s. The `SUCCESS` path at char.c:184 sizes the `realloc` correctly; only the null-buffer path is wrong. Second producer of PB-8, and unlike CR-7 this one needs no huge `size` — 5000 is ordinary | OPEN |
+| RS-1 | S1 | char.c:180, 186-193, 195| realloc result held in `res`, but the truncation loop writes `ptr->_internal_arr`, which is still the pre-realloc pointer. Use-after-free when a shrinking `reserve` moves the block. Introduced by the FX-3 fix. **ASan confirmed**: `create("abcdefgh",8)` then `reserve(3)` gives `heap-use-after-free WRITE` at char.c:194 into a block freed at char.c:184 | OPEN |
+| RS-2 | S3 | char.c:160-164 | `capacity == 0` checked before the NULL-vector check, so a NULL vector with `capacity == 0` reports `ERR_SIZE_ZERO` instead of `ERR_VECTOR_NULL`. Defensive | OPEN |
+| RS-6 | C | char.c:158, 178, 195| clang `-Wsometimes-uninitialized`: `res` used uninitialized at 195 if the `if`/`else if` chain falls through. Not reachable today since `is_valid` returns exactly 3 values, but real fragility | OPEN |
+| RS-3 | C | char.c:197 | `max_size = capacity` is correct under the hard-cap semantics but is documented nowhere. **This is also the cause of ST-1 and AS-4** | OPEN |
+| RS-4 | C | char.c:188-191 | element-at-a-time loop, should be `memset` | OPEN |
+
+### `_vec_char_shrink_to_fit` — char.c:202
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| ST-1 | S2 | char.c:202, 217 -> 197| calls `reserve(ptr, _internal_size)`, and `reserve` sets `max_size = capacity`. So `max_size` is permanently capped to the current size and **the vector can never grow again** — every later `push_back` trips `size+1 > max_size` and returns `ERR_MAX_PASSED`. Silent brick. No save/restore, unlike `resize` (RZ-3) | OPEN |
+| ST-2 | S3 | char.c:204-211| returns `ERR_SIZE_ZERO` on an empty vector; shrinking an empty vector should be a successful no-op. Two unhoisted `is_valid` calls at 204 and 208 | OPEN |
+
+### `_vec_char_swap` — char.c:221
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| SW-1 | S2 | char.c:229-233 | refuses NULL-buffer operands, so a blank vector can never be swapped against a populated one. Blocks the `create(nullptr, 0)` workflow outright | OPEN |
+| SW-2 | C | char.c:223 | temp built via `_vec_char_create(nullptr, 0)`; a plain initializer states the intent | OPEN |
+
+### `_vec_char_delete` — char.c:289
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| DL-1 | S1 | char.c:289, 293 | takes `const *` so it cannot reset the vector; a second call is a double free. Only function still taking `const` in a mutable API | OPEN |
+| DL-2 | S1 | char.h:11-17 | no ownership marker on the struct, so a by-value copy yields two owners of one buffer and `delete` cannot detect it | OPEN |
+| DL-3 | C | char.c:293 | unnecessary `(void*)` cast; `const` on the struct does not propagate to the pointee | OPEN |
+
+### `_vec_char_capacity` / `_vec_char_max_size` / `_vec_char_data` — char.c:261, 275, 252
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| AC-1 | S2 | char.c:254, 267, 281 | all three return `ERR_BUF_NULL` for a null vector, though none of them needs a buffer. `capacity()` should report capacity, not an error | OPEN |
+| DA-1 | S2 | char.c:251, 257| `char*` returned from a `const _VecCharInternal*`, laundering the const-correctness the mutable refactor was meant to establish | OPEN |
+
+### `_vec_char_clear` / `_vec_char_print_vec` — char.c:298, 341
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| CL-1 | C | char.c:310-313 | element-at-a-time zeroing loop, should be `memset` | OPEN |
+
+### `_vec_char_at` — char.c:320
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| AT-1 | S2 | char.c:323, 328, 335| returns error codes (23/25, and 21) as a `char`; `assign` at char.c:642 pushes such a value into the vector as data | OPEN |
+| AT-2 | C | char.c:332 | raw `fprintf` bypasses `LOGERROR` | OPEN |
+
+### `_vec_char_begin` / `_vec_char_end` — char.c:352, 359
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| BE-1 | S2 | char.c:355, 365, 367, 630, 668 | `FAILURE` (`== 1`) returned as an index, indistinguishable from index 1. Single root cause of the `+ 1` at char.c:630 and char.c:668, of the assign-on-empty failures AS-1, and of the erase-on-empty failure ER-1 | OPEN |
+| BE-2 | C | char.c:364 | `(int)` cast on a `size_t` return | OPEN |
+
+### `_vec_char_front` / `_vec_char_back` / `_vec_char_empty` — char.c:371, 379, 387
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| AC-2 | S2 | char.c:392, 393 | inverted: `SUCCESS` (0) when empty, `FAILURE` (1) when not, so `if (empty(v))` is false for an empty vector | OPEN |
+| FB-1 | S2 | char.c:373, 374, 381, 382 | returns `FAILURE` (1) as a `char`; `1` is valid data | OPEN |
+| FB-2 | C | char.c:373, 381 | validates only `ERR_VECTOR_NULL`, unlike every other accessor | OPEN |
+
+### `_vec_char_erase` (both overloads) — char.c:398, 412
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| ER-1 | S2 | char.c:417, 418 | `iter_start >= iter_end` returns `ERR_OUT_OF_BOUNDS`, so `erase(begin(), end())` on an empty vector always errors. This is what breaks both `assign` overloads. On an empty vector the actual trip is char.c:417 (`iter_end > size`) because `end()` returned 1 and the caller added 1 — see BE-1 | OPEN |
+| ER-2 | C | char.c:396, 410, 422-426 | zeroing loop should be `memset`; two stale `// TODO: Fix return value` comments | OPEN |
+
+### `_vec_char_resize` (both overloads) — char.c:432, 518
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| RZ-8 | S2 | char.c:434-444, 520-530 | both overloads reject a null-buffer vector with `ERR_BUF_NULL` before the `_internal_size == 0` branch that would have materialized one, so `resize` cannot be the first call on a blank vector. `push_back` can. **ASan: `create(NULL,0)` then `resize(0,4)` returns 21** and the vector is still empty, where `push_back` four times would have worked. Same shape as PB-17, opposite direction | OPEN |
+| RZ-3 | S2 | char.c:456, 471, 478, 497, 540, 557, 569, 579| the `max_size` save/restore is load-bearing (it undoes `reserve`'s cap) but looks removable. Nothing documents that | OPEN |
+| RZ-1 | S2 | char.c:442-446, 528-532| `size == _internal_size` returns `ERR_OUT_OF_BOUNDS` for a legitimate no-op; the code is also semantically wrong | OPEN |
+| RZ-4 | S3 | char.c:501-504 vs 583-586| 3-arg fills the discarded tail with `val`, 2-arg with `'\0'`. `data()` exposes the difference | OPEN |
+| RZ-2 | S3 | char.c:481, 567 | unguarded `tmpcp *= 2` wraps on overflow. Defensive | OPEN |
+| RZ-5 | C | char.c:462, 492, 548 | dead post-`reserve` capacity checks; `reserve` always assigns `capacity` to its argument exactly | OPEN |
+| RZ-6 | C | char.c:432-515 vs 518-597 | two ~84-line near-identical bodies, with the growth blocks copy-pasted between them | OPEN |
+| RZ-7 | C | char.c:444, 467, 501, 508, 530, 553, 583, 590| fill loops should be `memset`; misleading `LOG("ERR :- ...")` on what is now a no-op | OPEN |
+
+### `_vec_char_assign` (both overloads) — char.c:600, 652
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| AS-1 | S2 | char.c:630, 668 | fails on an empty destination, via ER-1. Fatal now because status is propagated; the immutable version discarded it and continued | OPEN |
+| AS-2 | S2 | char.c:624-647, 661-687| not atomic: `erase` → `reserve` → `push_back` loop. Reserve failure leaves the destination wiped; a `push_back` failure mid-loop leaves it partially filled | OPEN |
+| AS-3 | S2 | char.c:624, 662, 679| no `> _internal_max_size` guard on the assign count | OPEN |
+| AS-4 | S2 | char.c:635, 673 | the internal `reserve` caps `max_size` at the assign count with no save/restore, which `resize` does have | OPEN |
+| AS-6 | C | char.c:600-649 vs 652-688 | near-duplicate overloads differing only in the value source | OPEN |
+| AS-7 | S3 | char.c:642 | no check that `at()` succeeded before pushing its result. Currently correct **only** because the guards at char.c:611-618 and char.c:624 happen to make every index in range and the buffer non-null. Removing or loosening either guard turns this into AT-1's data-corruption case | OPEN |
+
+### `_vec_char_insert` (all three overloads) — char.c:691, 726, 759
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| IN-1 | S1 | char.c:779 | inverted check: `iter_end > iter_start` should be `iter_end <= iter_start`, so every valid non-empty range is rejected and only an empty range is accepted | OPEN |
+| IN-2 | S1 | char.c:779 | that clause short-circuits first, so the `iter_end > iterator->_internal_size` bound never fires | OPEN |
+| IN-4 | S2 | char.c:742, 747-754 | no `max_size` pre-check, so an oversized `amount` partially inserts and then fails, leaving the vector half-modified | OPEN |
+| IN-6 | S3 | char.c:747 | `iter + amount` can overflow `size_t` | OPEN |
+| IN-5 | S3 | char.c:742 | `amount <= 0` on a `size_t` is always just `== 0` | OPEN |
+| IN-8 | S2 | char.c:747-754, 793 | the loop copies via the raw `iterator->_internal_arr[i]` rather than a bounds-checked accessor. It is **unreachable today** only because IN-1's inversion makes `iter_end <= iter_start` always true, so the loop never runs. It becomes a live out-of-bounds read the moment IN-1 is fixed, unless IN-2 is fixed in the same change | OPEN |
+| IN-9 | C | char.c:747-754 | O(amount²) loop of single inserts where one grow + `memmove` would do | OPEN |
+
+### `utils.h` / `utils.c`
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| UT-2 | S1 | utils.c:3-12 | indices 0 and 1 are never assigned, so `error_messages[0]` and `[1]` are `NULL`. `LOGERROR(SUCCESS)` prints `%s` of `NULL`, and both are values functions return. Latent only because no caller exists yet | OPEN |
+| UT-1 | S2 | utils.h:29 | `SIZE_MAX / sizeof(int)` is what the `char` vector uses, capping it at 1/4 of the usable address space | OPEN |
+| UT-3 | S2 | utils.c:3 | `SUCCESS`/`FAILURE` overlap the error-index namespace, so `0` is both "success" and a table slot | OPEN |
+| UT-5 | C | utils.h:23 | `DEBUG` prints the literal `DEBUB: `, so char.c:109 — the only `DEBUG` call in the tree, on the clamp path in `push_back` — emits a misspelled prefix | OPEN |
+| UT-4 | C | utils.h:7, 17, 20, 22-25, 27, 29 · utils.c:6, 10 | `static const` in a header gives every TU its own copy; `ERR_NULL` is now dead (defined and given a message, never referenced from `char.c`); `ERR_SIZE_ZERO` message mentions `< 0` on a `size_t`; `extern const char*` should be `const char* const[]`; `LOG`/`LOGERROR` are hardwired to stdout and single-arg; `find_len` is UB for pointers; `CAPACITY` is a magic number in a shared header | OPEN |
+
+### `char.h`
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| CH-9 | S2 | char.h:11-106 (29 identifiers)| every public identifier is reserved by the C standard: `_VecCharInternal` and all 28 `_vec_char_*` functions begin with `_` at file scope, which C11 7.1.3 reserves for the implementation. Undefined behaviour on collision with any libc or third-party name. `clang -Weverything` reports all 28 | OPEN |
+| CH-4 | C | char.h:6-8 | ``/``/`` in the header, only needed by the `.c` | OPEN |
+| CH-5 | C | char.h | no doc comments on any function, despite the `/**< */` style in utils.h | OPEN |
+| CH-7 | C | char.h:22-23 | no `from_cstr` / NUL-termination path for the `char` specialization. See CR-4 | OPEN |
+| CH-8 | C | char.h:11-17 | the public struct is named with a `_` prefix and its four fields are named `_internal_*` instead of being `PRIVATE`, so the "internal" contract is expressed only by spelling. Combined with CH-9 this is the whole naming problem | OPEN |
+| CH-1 | C | char.h:32 vs char.c:156 | param named `max_size` in the header, `capacity` in the definition | OPEN |
+| CH-2 | C | char.h:23-106 | `const` on by-value params throughout (`const size_t size`, `const char val`, `const size_t idx`, …) | OPEN |
+| CH-3 | C | char.h | no `size()` accessor, so callers reach into `_internal_size` directly | OPEN |
+
+### Project
+
+| ID | Sev | Location | Finding | State |
+|---|---|---|---|---|
+| PR-2 | C | char.c:1-3 | mixed brace style (single-line `if` in `erase`/`front`/`back`/`begin`/`empty` vs expanded blocks); `.clang-format` exists and is not run | OPEN |
+| PR-3 | C | char.c:204, 208, 224, 225, 229, 230, 254, 255, 263, 267, 277, 281, 291, 300, 304, 322, 326, 343, 344, 354, 361, 373, 381, 389, 390, 400, 401, 415, 416, 434, 438, 520, 524, 603, 607, 611, 615, 654, 658, 693, 697, 763, 767, 771, 775| `is_valid` called 2-3× per function and logging each time, in every function except `push_back`, `pop_back` and `reserve` — those three hoist | OPEN |
+| PR-7 | C | CMakeLists.txt:28, main.c:20-54 | the `test_runner` target exists but `main()` is entirely commented out, so nothing in the tree calls a single function in this tracker. This is the only place a regression in the 10 open S1s could be caught, and it is dead | OPEN |
+| PR-4 | C | main.c:23-53 | 100% commented out, references removed API `Vec8_t` and `v1.size` | OPEN |
+| PR-5 | C | include/libvec.h:4, CMakeLists.txt:12-14 | empty placeholder; `int`/`float`/`string` are empty dirs already listed as comments in CMakeLists.txt | OPEN |
+
+## ID map
+
+`FX-1` … `FX-5` are first-pass IDs. FX-1 was a duplicate of PB-6 and was never
+given a row.
+
+| Prefix | Scope | | Prefix | Scope |
+|---|---|---|---|---|
+| `PB-` | push_back, pop_back | | `AT-` | at |
+| `RS-` | reserve | | `FB-` | front, back |
+| `ST-` | shrink_to_fit | | `BE-` | begin, end |
+| `CR-` | create | | `SW-` | swap |
+| `AC-` | accessors | | `CL-` | clear, print_vec |
+| `DA-` | data | | `IV-` | is_valid |
+| `DL-` | delete | | `UT-` | utils.h, utils.c |
+| `ER-` | erase | | `CH-` | char.h |
+| `RZ-` | resize | | `PR-` | project |
+| `AS-` | assign | | `FX-` | retired first-pass IDs |
+| `IN-` | insert | | | |
+
+---
+
+`PB-1` `PB-2` `PB-4` `PB-6` `PB-7` `FX-2` `FX-3` `FX-4` `FX-5` `PR-1` `CR-7` `CR-8`
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c6259ad..ae7073f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -25,8 +25,9 @@ target_include_directories(libvec
${CMAKE_CURRENT_SOURCE_DIR}/include
)
-add_executable(test_runner src/main.c)
+add_executable(libvec_bin src/main.c)
+set_target_properties(libvec_bin PROPERTIES OUTPUT_NAME "libvec")
# Linking libvec privately gives test_runner access to include/libvec.h,
# but strictly hides src/lib/char/char.h and src/lib/utils/utils.h.
-target_link_libraries(test_runner PRIVATE libvec)
+target_link_libraries(libvec_bin PRIVATE libvec)
diff --git a/src/.DS_Store b/src/.DS_Store
index a67d688..3ef53b6 100644
Binary files a/src/.DS_Store and b/src/.DS_Store differ
diff --git a/src/lib/.DS_Store b/src/lib/.DS_Store
index b953ecf..b856baa 100644
Binary files a/src/lib/.DS_Store and b/src/lib/.DS_Store differ
diff --git a/src/lib/char/char.c b/src/lib/char/char.c
index cb4ed05..ced1a96 100644
--- a/src/lib/char/char.c
+++ b/src/lib/char/char.c
@@ -1,67 +1,58 @@
#include "char.h"
-#include
#include
-#include
-#include
-#include
#include "utils/utils.h"
-size_t
-_vec_char_is_valid(const _VecCharInternal* ptr)
+unsigned int
+_vec_char_raise_err(const _VecCharInternal* ptr, unsigned int mask)
{
- if (ptr == nullptr)
- {
- LOGERROR(ERR_VECTOR_NULL);
- return ERR_VECTOR_NULL;
- }
- else if (ptr->_internal_arr == nullptr)
- {
- LOGERROR(ERR_BUF_NULL);
- return ERR_BUF_NULL;
- }
- return SUCCESS;
+ unsigned int res = SUCCESS;
+ res |= mask;
+ if (ptr == nullptr) res |= ERR_VEC_NULL;
+ if (ptr->_internal_arr == nullptr) res |= ERR_BUF_NULL;
+
+ return res;
}
_VecCharInternal
_vec_char_create(const char* src, const size_t size)
{
+ unsigned int err = 0;
_VecCharInternal self = {
._internal_arr = NULL,
._internal_size = 0,
._internal_capacity = CAPACITY,
._internal_max_size = VEC_MAX,
};
- if (size > self._internal_max_size)
+ if (size >= self._internal_max_size)
{
- LOGERROR(ERR_MAX_PASSED);
LOG("If you need more memory to start, create a blank and "
- "selferve.");
+ "reserve.");
return self;
}
- if (self._internal_capacity < size && size < self._internal_max_size)
+ if (self._internal_capacity < size)
{
- while (self._internal_capacity < size &&
- self._internal_capacity * 2 < self._internal_max_size)
- self._internal_capacity *= 2;
- }
- if (self._internal_capacity * 2 > self._internal_max_size &&
- size < self._internal_max_size)
- {
- self._internal_capacity = size;
+ size_t dst_cap = self._internal_capacity;
+ while (dst_cap < size && dst_cap * 2 < self._internal_max_size)
+ dst_cap *= 2;
+ self._internal_capacity = (dst_cap < size) ? size : dst_cap;
}
if (size > 0)
{
- char* dst_buf = calloc(self._internal_capacity, sizeof(char));
- if (!dst_buf)
+ self._internal_arr =
+ calloc(self._internal_capacity, sizeof(char));
+ err = _vec_char_raise_err(&self, err);
+ if (!(err & SUCCESS))
{
- LOGERROR(ERR_ALLOC_FAIL);
+ self._internal_arr = NULL;
+ vec_print_errs(err);
+ free(self._internal_arr);
return self;
}
- self._internal_arr = dst_buf;
}
- if (src)
+ if (!src) err |= ERR_BUF_NULL;
+ else
{
for (size_t i = 0; i < size; i++)
{
@@ -72,735 +63,742 @@ _vec_char_create(const char* src, const size_t size)
return self;
}
-size_t
-_vec_char_push_back(_VecCharInternal* ptr, const char val)
-{
- char* res;
- size_t status = _vec_char_is_valid(ptr);
- if (status == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
-
- if (ptr->_internal_size + 1 > ptr->_internal_max_size)
- {
- LOGERROR(ERR_MAX_PASSED);
- return ERR_MAX_PASSED;
- }
-
- if (status == ERR_BUF_NULL && ptr->_internal_size == 0)
- {
- res = calloc(1, sizeof(char));
- if (!res)
- {
- LOGERROR(ERR_ALLOC_FAIL);
- return ERR_ALLOC_FAIL;
- }
- ptr->_internal_arr = res;
- ptr->_internal_arr[0] = val;
- ptr->_internal_size++;
- return SUCCESS;
- }
-
- else if (ptr->_internal_size + 1 > ptr->_internal_capacity)
- {
- size_t dst_cap = ptr->_internal_capacity * 2;
- if (dst_cap > ptr->_internal_max_size)
- {
- ptr->_internal_capacity = ptr->_internal_max_size;
- res = realloc(ptr->_internal_arr,
- ptr->_internal_capacity * sizeof(char));
- LOG("DEBUG: Capacity cannot be grown any further due "
- "to hitting max size");
- }
- else
- {
- res =
- realloc(ptr->_internal_arr, dst_cap * sizeof(char));
- ptr->_internal_capacity = dst_cap;
- }
-
- if (!res)
- {
- LOGERROR(ERR_ALLOC_FAIL);
- return ERR_ALLOC_FAIL;
- }
- }
- else
- {
- res = ptr->_internal_arr;
- }
- ptr->_internal_arr = res;
- ptr->_internal_arr[ptr->_internal_size] = val;
- ptr->_internal_size++;
- return SUCCESS;
-}
-
-size_t
-_vec_char_pop_back(_VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (ptr->_internal_size < 1)
- {
- LOGERROR(ERR_SIZE_ZERO);
- return ERR_SIZE_ZERO;
- }
-
- ptr->_internal_arr[ptr->_internal_size - 1] = 0;
- ptr->_internal_size--;
- return SUCCESS;
-}
-
-size_t
-_vec_char_reserve(_VecCharInternal* ptr, const size_t capacity)
-{
- char* res;
- size_t status = _vec_char_is_valid(ptr);
- if (capacity == 0)
- {
- LOGERROR(ERR_SIZE_ZERO);
- return ERR_SIZE_ZERO;
- }
- if (status == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (status == ERR_BUF_NULL)
- {
- res = calloc(ptr->_internal_capacity, sizeof(char));
- if (!res)
- {
- LOGERROR(ERR_ALLOC_FAIL);
- return ERR_ALLOC_FAIL;
- }
- }
- else if (status == SUCCESS)
- {
- res = realloc(ptr->_internal_arr, capacity * sizeof(char));
- if (!res)
- {
- LOGERROR(ERR_ALLOC_FAIL);
- return ERR_ALLOC_FAIL;
- }
- if (ptr->_internal_size > capacity)
- {
- for (size_t i = capacity; i < ptr->_internal_size; i++)
- {
- ptr->_internal_arr[i] = '\0';
- }
- ptr->_internal_size = capacity;
- }
- }
- ptr->_internal_arr = res;
- ptr->_internal_capacity = capacity;
- ptr->_internal_max_size = capacity;
- return SUCCESS;
-}
-
-size_t
-_vec_char_shrink_to_fit(_VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (ptr->_internal_size == 0)
- {
- LOGERROR(ERR_SIZE_ZERO);
- return ERR_SIZE_ZERO;
- }
- return _vec_char_reserve(ptr, ptr->_internal_size);
-}
-
-size_t
-_vec_char_swap(_VecCharInternal* ptr1, _VecCharInternal* ptr2)
-{
- _VecCharInternal self = _vec_char_create(nullptr, 0);
- if (_vec_char_is_valid(ptr1) == ERR_VECTOR_NULL ||
- _vec_char_is_valid(ptr2) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr1) == ERR_BUF_NULL ||
- _vec_char_is_valid(ptr2) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- self._internal_arr = ptr1->_internal_arr;
- ptr1->_internal_arr = ptr2->_internal_arr;
- ptr2->_internal_arr = self._internal_arr;
-
- self._internal_capacity = ptr1->_internal_capacity;
- self._internal_size = ptr1->_internal_size;
- self._internal_max_size = ptr1->_internal_max_size;
- ptr1->_internal_capacity = ptr2->_internal_capacity;
- ptr1->_internal_size = ptr2->_internal_size;
- ptr1->_internal_max_size = ptr2->_internal_max_size;
-
- ptr2->_internal_capacity = self._internal_capacity;
- ptr2->_internal_size = self._internal_size;
- ptr2->_internal_max_size = self._internal_max_size;
- return SUCCESS;
-}
-
-char*
-_vec_char_data(const _VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL ||
- _vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- return nullptr;
- return &ptr->_internal_arr[0];
-}
-
-size_t
-_vec_char_capacity(const _VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- return ptr->_internal_capacity;
-}
-
-size_t
-_vec_char_max_size(const _VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- return ptr->_internal_max_size;
-}
-
-void
-_vec_char_delete(const _VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == SUCCESS)
- {
- free((void*)ptr->_internal_arr);
- }
-}
-
-size_t
-_vec_char_clear(_VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (ptr->_internal_size > 0)
- {
- for (size_t i = 0; i < ptr->_internal_size; i++)
- {
- ptr->_internal_arr[i] = 0;
- }
- ptr->_internal_size = 0;
- }
- return SUCCESS;
-}
-
-char
-_vec_char_at(const _VecCharInternal* ptr, const size_t idx)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (idx >= ptr->_internal_size)
- {
- fprintf(stderr,
- "At Index: [%zu] is out of bounds for size: [%zu]\n",
- idx, ptr->_internal_size);
- return ERR_OUT_OF_BOUNDS;
- }
- return ptr->_internal_arr[idx];
-}
-
-void
-_vec_char_print_vec(const _VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL ||
- _vec_char_is_valid(ptr) == ERR_BUF_NULL)
- return;
- for (size_t i = 0; i < ptr->_internal_size; i++)
- printf("%c ", ptr->_internal_arr[i]);
- printf("\n");
-}
-
-size_t
-_vec_char_begin(const _VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == SUCCESS) return 0;
- return FAILURE;
-}
-
-size_t
-_vec_char_end(const _VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == SUCCESS)
- {
- if (ptr->_internal_size != 0)
- return (int)(ptr->_internal_size - 1);
- else return FAILURE;
- }
- return FAILURE;
-}
-
-char
-_vec_char_front(const _VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE;
- if (ptr->_internal_size == 0) return FAILURE;
- return _vec_char_at(ptr, 0);
-}
-
-char
-_vec_char_back(const _VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE;
- if (ptr->_internal_size == 0) return FAILURE;
- return _vec_char_at(ptr, ptr->_internal_size - 1);
-}
-
-size_t
-_vec_char_empty(const _VecCharInternal* ptr)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL ||
- _vec_char_is_valid(ptr) == ERR_BUF_NULL)
- return FAILURE;
- if (ptr->_internal_size == 0) return SUCCESS;
- return FAILURE;
-}
-
-// TODO: Fix return value
-__attribute__((overloadable)) size_t
-_vec_char_erase(_VecCharInternal* ptr, const size_t iter)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return ERR_VECTOR_NULL;
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) return ERR_BUF_NULL;
- if (iter >= ptr->_internal_size) return ERR_OUT_OF_BOUNDS;
- memmove(&ptr->_internal_arr[iter], &ptr->_internal_arr[iter + 1],
- (ptr->_internal_size - iter - 1) * sizeof(char));
- ptr->_internal_arr[ptr->_internal_size - 1] = 0;
- ptr->_internal_size--;
- return SUCCESS;
-}
-
-// TODO: Fix return value
-__attribute__((overloadable)) size_t
-_vec_char_erase(_VecCharInternal* ptr, const size_t iter_start,
- const size_t iter_end)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return ERR_VECTOR_NULL;
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) return ERR_BUF_NULL;
- if (iter_end > ptr->_internal_size) return ERR_OUT_OF_BOUNDS;
- if (iter_start >= iter_end) return ERR_OUT_OF_BOUNDS;
- size_t diff = iter_end - iter_start;
- memmove(&ptr->_internal_arr[iter_start], &ptr->_internal_arr[iter_end],
- (ptr->_internal_size - iter_end) * sizeof(char));
- for (size_t i = ptr->_internal_size - diff; i < ptr->_internal_size;
- i++)
- {
- ptr->_internal_arr[i] = 0;
- }
- ptr->_internal_size -= diff;
- return SUCCESS;
-}
-
-__attribute__((overloadable)) size_t
-_vec_char_resize(_VecCharInternal* ptr, const size_t size)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (ptr->_internal_size == size)
- {
- LOG("ERR :- Ptr size and size are the same");
- return ERR_OUT_OF_BOUNDS;
- }
-
- else if (size > ptr->_internal_max_size)
- {
- LOGERROR(ERR_MAX_PASSED);
- return ERR_MAX_PASSED;
- }
-
- else if (ptr->_internal_size == 0)
- {
- size_t max = ptr->_internal_max_size;
- size_t status = _vec_char_reserve(ptr, size);
- if (status != SUCCESS)
- {
- return status;
- }
- if (ptr->_internal_capacity != size)
- {
- LOGERROR(ERR_ALLOC_FAIL);
- return ERR_ALLOC_FAIL;
- }
- for (size_t i = 0; i < size; i++)
- {
- ptr->_internal_arr[i] = '\0';
- }
- ptr->_internal_max_size = max;
- ptr->_internal_size = size;
- return SUCCESS;
- }
- else if (size > ptr->_internal_capacity)
- {
- size_t tmpcp = ptr->_internal_capacity;
- size_t tmpmx = ptr->_internal_max_size;
- while (size > tmpcp)
- {
- tmpcp *= 2;
- }
- if (tmpcp > ptr->_internal_max_size)
- {
- tmpcp = size;
- }
- size_t status = _vec_char_reserve(ptr, tmpcp);
- if (status != SUCCESS)
- {
- return status;
- }
- if (ptr->_internal_capacity != tmpcp)
- {
- LOGERROR(ERR_ALLOC_FAIL);
- return ERR_ALLOC_FAIL;
- }
- ptr->_internal_max_size = tmpmx;
- }
- if (size < ptr->_internal_size)
- {
- for (size_t i = size; i < ptr->_internal_size; i++)
- {
- ptr->_internal_arr[i] = '\0';
- }
- }
- if (ptr->_internal_size < size && size <= ptr->_internal_capacity)
- {
- for (size_t i = ptr->_internal_size; i < size; i++)
- {
- ptr->_internal_arr[i] = '\0';
- }
- }
- ptr->_internal_size = size;
- return SUCCESS;
-}
-
-__attribute__((overloadable)) size_t
-_vec_char_resize(_VecCharInternal* ptr, const size_t size, const char val)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (ptr->_internal_size == size)
- {
- LOG("ERR :- Ptr size and size are the same");
- return ERR_OUT_OF_BOUNDS;
- }
-
- else if (size > ptr->_internal_max_size)
- {
- LOGERROR(ERR_MAX_PASSED);
- return ERR_MAX_PASSED;
- }
-
- else if (ptr->_internal_size == 0)
- {
- size_t max = ptr->_internal_max_size;
- size_t status = _vec_char_reserve(ptr, size);
- if (status != SUCCESS)
- {
- return status;
- }
- if (ptr->_internal_capacity != size)
- {
- LOGERROR(ERR_ALLOC_FAIL);
- return ERR_ALLOC_FAIL;
- }
- for (size_t i = 0; i < size; i++)
- {
- ptr->_internal_arr[i] = val;
- }
- ptr->_internal_max_size = max;
- ptr->_internal_size = size;
- return SUCCESS;
- }
- else if (size > ptr->_internal_capacity)
- {
- size_t tmpcp = ptr->_internal_capacity;
- size_t tmpmx = ptr->_internal_max_size;
- while (size > tmpcp)
- {
- tmpcp *= 2;
- }
- if (tmpcp > ptr->_internal_max_size)
- {
- tmpcp = size;
- }
- size_t status = _vec_char_reserve(ptr, tmpcp);
- if (status != SUCCESS)
- {
- LOGERROR(ERR_ALLOC_FAIL);
- return ERR_ALLOC_FAIL;
- }
- ptr->_internal_max_size = tmpmx;
- }
- if (size < ptr->_internal_size)
- {
- for (size_t i = size; i < ptr->_internal_size; i++)
- {
- ptr->_internal_arr[i] = val;
- }
- }
- if (ptr->_internal_size < size && size <= ptr->_internal_capacity)
- {
- for (size_t i = ptr->_internal_size; i < size; i++)
- {
- ptr->_internal_arr[i] = val;
- }
- }
- ptr->_internal_size = size;
- return SUCCESS;
-}
-
-__attribute__((overloadable)) size_t
-_vec_char_assign(_VecCharInternal* ptr, const _VecCharInternal* iterator,
- const size_t iter_start, const size_t iter_end)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (_vec_char_is_valid(iterator) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(iterator) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (ptr->_internal_arr == iterator->_internal_arr)
- {
- LOGERROR(ERR_DOUBLE_BUF);
- return ERR_DOUBLE_BUF;
- }
- if (iterator->_internal_size < iter_end || iter_end <= iter_start)
- {
- LOGERROR(ERR_OUT_OF_BOUNDS);
- return ERR_OUT_OF_BOUNDS;
- }
- size_t status =
- _vec_char_erase(ptr, _vec_char_begin(ptr), _vec_char_end(ptr) + 1);
- if (status != SUCCESS)
- {
- return status;
- }
- status = _vec_char_reserve(ptr, (iter_end - iter_start));
- if (status != SUCCESS)
- {
- return status;
- }
- for (size_t i = iter_start; i < iter_end; i++)
- {
- status = _vec_char_push_back(ptr, _vec_char_at(iterator, i));
- if (status != SUCCESS)
- {
- return status;
- }
- }
- return SUCCESS;
-}
-
-__attribute__((overloadable)) size_t
-_vec_char_assign(_VecCharInternal* ptr, const size_t amount, const char val)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (amount == 0)
- {
- LOGERROR(ERR_SIZE_ZERO);
- return ERR_SIZE_ZERO;
- }
- size_t status =
- _vec_char_erase(ptr, _vec_char_begin(ptr), _vec_char_end(ptr) + 1);
- if (status != SUCCESS)
- {
- return status;
- }
- status = _vec_char_reserve(ptr, amount);
- if (status != SUCCESS)
- {
- return status;
- }
-
- for (size_t i = 0; i < amount; i++)
- {
- status = _vec_char_push_back(ptr, val);
- if (status != SUCCESS)
- {
- return status;
- }
- }
- return SUCCESS;
-}
-
-__attribute__((overloadable)) size_t
-_vec_char_insert(_VecCharInternal* ptr, const size_t iter, const char val)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (ptr->_internal_max_size < ptr->_internal_size + 1)
- {
- LOGERROR(ERR_MAX_PASSED);
- return ERR_MAX_PASSED;
- }
- if (iter > ptr->_internal_size)
- {
- LOGERROR(ERR_OUT_OF_BOUNDS);
- return ERR_OUT_OF_BOUNDS;
- }
- size_t status = _vec_char_push_back(ptr, 0);
- if (status != SUCCESS)
- {
- return status;
- }
- for (size_t i = ptr->_internal_size - 1; i > iter; i--)
- {
- ptr->_internal_arr[i] = ptr->_internal_arr[i - 1];
- }
- ptr->_internal_arr[iter] = val;
-
- return SUCCESS;
-}
-
-__attribute__((overloadable)) size_t
-_vec_char_insert(_VecCharInternal* ptr, const size_t iter, const size_t amount,
- const char val)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (iter > ptr->_internal_size)
- {
- LOGERROR(ERR_OUT_OF_BOUNDS);
- return ERR_OUT_OF_BOUNDS;
- }
- if (amount <= 0)
- {
- LOGERROR(ERR_SIZE_ZERO);
- return ERR_SIZE_ZERO;
- }
- for (size_t i = iter; i < iter + amount; i++)
- {
- size_t status = _vec_char_insert(ptr, i, val);
- if (status != SUCCESS)
- {
- return status;
- }
- }
- return SUCCESS;
-}
-
-__attribute__((overloadable)) size_t
-_vec_char_insert(_VecCharInternal* ptr, const _VecCharInternal* iterator,
- const size_t iter, const size_t iter_start,
- const size_t iter_end)
-{
- if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (_vec_char_is_valid(iterator) == ERR_VECTOR_NULL)
- {
- return ERR_VECTOR_NULL;
- }
- if (_vec_char_is_valid(iterator) == ERR_BUF_NULL)
- {
- return ERR_BUF_NULL;
- }
- if (iter_end > iter_start || iter_end > iterator->_internal_size ||
- iter > ptr->_internal_size)
- {
- LOGERROR(ERR_OUT_OF_BOUNDS);
- return ERR_OUT_OF_BOUNDS;
- }
- if (ptr->_internal_arr == iterator->_internal_arr)
- {
- LOGERROR(ERR_DOUBLE_BUF);
- return ERR_DOUBLE_BUF;
- }
- for (size_t i = iter_start; i < iter_end; i++)
- {
- size_t status = _vec_char_insert(ptr, iter + (i - iter_start),
- iterator->_internal_arr[i]);
- if (status != SUCCESS)
- {
- return status;
- }
- }
- return SUCCESS;
-}
+// size_t
+// _vec_char_push_back(_VecCharInternal* ptr, const char val)
+// {
+// char* res;
+// size_t _ptr_err = _vec_char_is_valid(ptr);
+// if (_ptr_err == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+//
+// if (ptr->_internal_size + 1 > ptr->_internal_max_size)
+// {
+// LOGERROR(ERR_MAX_PASSED);
+// return ERR_MAX_PASSED;
+// }
+//
+// if (_ptr_err == ERR_BUF_NULL && ptr->_internal_size == 0)
+// {
+// res = calloc(1, sizeof(char));
+// if (!res)
+// {
+// LOGERROR(ERR_ALLOC_FAIL);
+// return ERR_ALLOC_FAIL;
+// }
+// ptr->_internal_arr = res;
+// ptr->_internal_arr[0] = val;
+// ptr->_internal_size++;
+// return SUCCESS;
+// }
+//
+// else if (ptr->_internal_size + 1 > ptr->_internal_capacity)
+// {
+// size_t dst_cap = ptr->_internal_capacity * 2;
+// if (dst_cap > ptr->_internal_max_size)
+// {
+// ptr->_internal_capacity = ptr->_internal_max_size;
+// res = realloc(ptr->_internal_arr,
+// ptr->_internal_capacity * sizeof(char));
+// DEBUG(
+// "Capacity cannot be grown any further due "
+// "to hitting max size");
+// }
+// else
+// {
+// res =
+// realloc(ptr->_internal_arr, dst_cap * sizeof(char));
+// ptr->_internal_capacity = dst_cap;
+// }
+//
+// if (!res)
+// {
+// LOGERROR(ERR_ALLOC_FAIL);
+// return ERR_ALLOC_FAIL;
+// }
+// }
+// else
+// {
+// res = ptr->_internal_arr;
+// }
+// ptr->_internal_arr = res;
+// ptr->_internal_arr[ptr->_internal_size] = val;
+// ptr->_internal_size++;
+// return SUCCESS;
+// }
+//
+// size_t
+// _vec_char_pop_back(_VecCharInternal* ptr)
+// {
+// size_t _ptr_err = _vec_char_is_valid(ptr);
+// if (_ptr_err == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_ptr_err == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (ptr->_internal_size < 1)
+// {
+// LOGERROR(ERR_SIZE_ZERO);
+// return ERR_SIZE_ZERO;
+// }
+//
+// ptr->_internal_arr[ptr->_internal_size - 1] = '\0';
+// ptr->_internal_size--;
+// return SUCCESS;
+// }
+//
+// size_t
+// _vec_char_reserve(_VecCharInternal* ptr, const size_t capacity)
+// {
+// char* res;
+// size_t _ptr_err = _vec_char_is_valid(ptr);
+// if (capacity == 0)
+// {
+// LOGERROR(ERR_SIZE_ZERO);
+// return ERR_SIZE_ZERO;
+// }
+// if (_ptr_err == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_ptr_err == ERR_BUF_NULL)
+// {
+// res = calloc(ptr->_internal_capacity, sizeof(char));
+// if (!res)
+// {
+// LOGERROR(ERR_ALLOC_FAIL);
+// return ERR_ALLOC_FAIL;
+// }
+// }
+// else if (_ptr_err == SUCCESS)
+// {
+// res = realloc(ptr->_internal_arr, capacity * sizeof(char));
+// if (!res)
+// {
+// LOGERROR(ERR_ALLOC_FAIL);
+// return ERR_ALLOC_FAIL;
+// }
+// if (ptr->_internal_size > capacity)
+// {
+// for (size_t i = capacity; i < ptr->_internal_size; i++)
+// {
+// ptr->_internal_arr[i] = '\0';
+// }
+// ptr->_internal_size = capacity;
+// }
+// }
+// ptr->_internal_arr = res;
+// ptr->_internal_capacity = capacity;
+// ptr->_internal_max_size = capacity;
+// return SUCCESS;
+// }
+//
+// size_t
+// _vec_char_shrink_to_fit(_VecCharInternal* ptr)
+// {
+// size_t _ptr_err = _vec_char_is_valid(ptr);
+// if (_ptr_err == ERR_VECTOR_NULL)
+// {
+// LOGERROR(ERR_VECTOR_NULL);
+// return ERR_VECTOR_NULL;
+// }
+// if (_ptr_err == ERR_BUF_NULL)
+// {
+// LOGERROR(ERR_BUF_NULL);
+// return ERR_BUF_NULL;
+// }
+// if (_ptr_err == 0)
+// {
+// LOGERROR(ERR_SIZE_ZERO);
+// return ERR_SIZE_ZERO;
+// }
+// return _vec_char_reserve(ptr, ptr->_internal_size);
+// }
+//
+// size_t
+// _vec_char_swap(_VecCharInternal* ptr1, _VecCharInternal* ptr2)
+// {
+// _VecCharInternal self = _vec_char_create(nullptr, 0);
+// size_t _ptr1_err = _vec_char_is_valid(ptr1);
+// size_t _ptr2_err = _vec_char_is_valid(ptr2);
+// if (_ptr1_err == ERR_VECTOR_NULL || _ptr2_err == ERR_VECTOR_NULL)
+// {
+// LOGERROR(ERR_VECTOR_NULL);
+// return ERR_VECTOR_NULL;
+// }
+// if (_ptr1_err == ERR_BUF_NULL || _ptr2_err == ERR_BUF_NULL)
+// {
+// LOGERROR(ERR_BUF_NULL);
+// return ERR_BUF_NULL;
+// }
+// self._internal_arr = ptr1->_internal_arr;
+// ptr1->_internal_arr = ptr2->_internal_arr;
+// ptr2->_internal_arr = self._internal_arr;
+//
+// self._internal_capacity = ptr1->_internal_capacity;
+// self._internal_size = ptr1->_internal_size;
+// self._internal_max_size = ptr1->_internal_max_size;
+// ptr1->_internal_capacity = ptr2->_internal_capacity;
+// ptr1->_internal_size = ptr2->_internal_size;
+// ptr1->_internal_max_size = ptr2->_internal_max_size;
+//
+// ptr2->_internal_capacity = self._internal_capacity;
+// ptr2->_internal_size = self._internal_size;
+// ptr2->_internal_max_size = self._internal_max_size;
+// return SUCCESS;
+// }
+//
+// char*
+// _vec_char_data(const _VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL ||
+// _vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// return nullptr;
+// return &ptr->_internal_arr[0];
+// }
+//
+// size_t
+// _vec_char_capacity(const _VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// return ptr->_internal_capacity;
+// }
+//
+// size_t
+// _vec_char_max_size(const _VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// return ptr->_internal_max_size;
+// }
+//
+// void
+// _vec_char_delete(const _VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == SUCCESS)
+// {
+// free((void*)ptr->_internal_arr);
+// }
+// }
+//
+// size_t
+// _vec_char_clear(_VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (ptr->_internal_size > 0)
+// {
+// for (size_t i = 0; i < ptr->_internal_size; i++)
+// {
+// ptr->_internal_arr[i] = 0;
+// }
+// ptr->_internal_size = 0;
+// }
+// return SUCCESS;
+// }
+//
+// char
+// _vec_char_at(const _VecCharInternal* ptr, const size_t idx)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (idx >= ptr->_internal_size)
+// {
+// fprintf(stderr,
+// "At Index: [%zu] is out of bounds for size: [%zu]\n",
+// idx, ptr->_internal_size);
+// return ERR_OUT_OF_BOUNDS;
+// }
+// return ptr->_internal_arr[idx];
+// }
+//
+// void
+// _vec_char_print_vec(const _VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL ||
+// _vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// return;
+// for (size_t i = 0; i < ptr->_internal_size; i++)
+// printf("%c ", ptr->_internal_arr[i]);
+// printf("\n");
+// }
+//
+// size_t
+// _vec_char_begin(const _VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == SUCCESS) return 0;
+// return FAILURE;
+// }
+//
+// size_t
+// _vec_char_end(const _VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == SUCCESS)
+// {
+// if (ptr->_internal_size != 0)
+// return (int)(ptr->_internal_size - 1);
+// else return FAILURE;
+// }
+// return FAILURE;
+// }
+//
+// char
+// _vec_char_front(const _VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE;
+// if (ptr->_internal_size == 0) return FAILURE;
+// return _vec_char_at(ptr, 0);
+// }
+//
+// char
+// _vec_char_back(const _VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return FAILURE;
+// if (ptr->_internal_size == 0) return FAILURE;
+// return _vec_char_at(ptr, ptr->_internal_size - 1);
+// }
+//
+// size_t
+// _vec_char_empty(const _VecCharInternal* ptr)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL ||
+// _vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// return FAILURE;
+// if (ptr->_internal_size == 0) return SUCCESS;
+// return FAILURE;
+// }
+//
+// // TODO: Fix return value
+// __attribute__((overloadable)) size_t
+// _vec_char_erase(_VecCharInternal* ptr, const size_t iter)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return ERR_VECTOR_NULL;
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) return ERR_BUF_NULL;
+// if (iter >= ptr->_internal_size) return ERR_OUT_OF_BOUNDS;
+// memmove(&ptr->_internal_arr[iter], &ptr->_internal_arr[iter + 1],
+// (ptr->_internal_size - iter - 1) * sizeof(char));
+// ptr->_internal_arr[ptr->_internal_size - 1] = 0;
+// ptr->_internal_size--;
+// return SUCCESS;
+// }
+//
+// // TODO: Fix return value
+// __attribute__((overloadable)) size_t
+// _vec_char_erase(_VecCharInternal* ptr, const size_t iter_start,
+// const size_t iter_end)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL) return ERR_VECTOR_NULL;
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL) return ERR_BUF_NULL;
+// if (iter_end > ptr->_internal_size) return ERR_OUT_OF_BOUNDS;
+// if (iter_start >= iter_end) return ERR_OUT_OF_BOUNDS;
+// size_t diff = iter_end - iter_start;
+// memmove(&ptr->_internal_arr[iter_start], &ptr->_internal_arr[iter_end],
+// (ptr->_internal_size - iter_end) * sizeof(char));
+// for (size_t i = ptr->_internal_size - diff; i < ptr->_internal_size;
+// i++)
+// {
+// ptr->_internal_arr[i] = 0;
+// }
+// ptr->_internal_size -= diff;
+// return SUCCESS;
+// }
+//
+// __attribute__((overloadable)) size_t
+// _vec_char_resize(_VecCharInternal* ptr, const size_t size)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (ptr->_internal_size == size)
+// {
+// LOG("ERR :- Ptr size and size are the same");
+// return ERR_OUT_OF_BOUNDS;
+// }
+//
+// else if (size > ptr->_internal_max_size)
+// {
+// LOGERROR(ERR_MAX_PASSED);
+// return ERR_MAX_PASSED;
+// }
+//
+// else if (ptr->_internal_size == 0)
+// {
+// size_t max = ptr->_internal_max_size;
+// size_t res = _vec_char_reserve(ptr, size);
+// if (res != SUCCESS)
+// {
+// return res;
+// }
+// if (ptr->_internal_capacity != size)
+// {
+// LOGERROR(ERR_ALLOC_FAIL);
+// return ERR_ALLOC_FAIL;
+// }
+// for (size_t i = 0; i < size; i++)
+// {
+// ptr->_internal_arr[i] = '\0';
+// }
+// ptr->_internal_max_size = max;
+// ptr->_internal_size = size;
+// return SUCCESS;
+// }
+// else if (size > ptr->_internal_capacity)
+// {
+// size_t tmpcp = ptr->_internal_capacity;
+// size_t tmpmx = ptr->_internal_max_size;
+// while (size > tmpcp)
+// {
+// tmpcp *= 2;
+// }
+// if (tmpcp > ptr->_internal_max_size)
+// {
+// tmpcp = size;
+// }
+// size_t res = _vec_char_reserve(ptr, tmpcp);
+// if (res != SUCCESS)
+// {
+// return res;
+// }
+// if (ptr->_internal_capacity != tmpcp)
+// {
+// LOGERROR(ERR_ALLOC_FAIL);
+// return ERR_ALLOC_FAIL;
+// }
+// ptr->_internal_max_size = tmpmx;
+// }
+// if (size < ptr->_internal_size)
+// {
+// for (size_t i = size; i < ptr->_internal_size; i++)
+// {
+// ptr->_internal_arr[i] = '\0';
+// }
+// }
+// if (ptr->_internal_size < size && size <= ptr->_internal_capacity)
+// {
+// for (size_t i = ptr->_internal_size; i < size; i++)
+// {
+// ptr->_internal_arr[i] = '\0';
+// }
+// }
+// ptr->_internal_size = size;
+// return SUCCESS;
+// }
+//
+// __attribute__((overloadable)) size_t
+// _vec_char_resize(_VecCharInternal* ptr, const size_t size, const char val)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (ptr->_internal_size == size)
+// {
+// LOG("ERR :- Ptr size and size are the same");
+// return ERR_OUT_OF_BOUNDS;
+// }
+//
+// else if (size > ptr->_internal_max_size)
+// {
+// LOGERROR(ERR_MAX_PASSED);
+// return ERR_MAX_PASSED;
+// }
+//
+// else if (ptr->_internal_size == 0)
+// {
+// size_t max = ptr->_internal_max_size;
+// size_t res = _vec_char_reserve(ptr, size);
+// if (res != SUCCESS)
+// {
+// return res;
+// }
+// if (ptr->_internal_capacity != size)
+// {
+// LOGERROR(ERR_ALLOC_FAIL);
+// return ERR_ALLOC_FAIL;
+// }
+// for (size_t i = 0; i < size; i++)
+// {
+// ptr->_internal_arr[i] = val;
+// }
+// ptr->_internal_max_size = max;
+// ptr->_internal_size = size;
+// return SUCCESS;
+// }
+// else if (size > ptr->_internal_capacity)
+// {
+// size_t tmpcp = ptr->_internal_capacity;
+// size_t tmpmx = ptr->_internal_max_size;
+// while (size > tmpcp)
+// {
+// tmpcp *= 2;
+// }
+// if (tmpcp > ptr->_internal_max_size)
+// {
+// tmpcp = size;
+// }
+// size_t _ptr_err = _vec_char_reserve(ptr, tmpcp);
+// if (_ptr_err != SUCCESS)
+// {
+// LOGERROR(ERR_ALLOC_FAIL);
+// return ERR_ALLOC_FAIL;
+// }
+// ptr->_internal_max_size = tmpmx;
+// }
+// if (size < ptr->_internal_size)
+// {
+// for (size_t i = size; i < ptr->_internal_size; i++)
+// {
+// ptr->_internal_arr[i] = val;
+// }
+// }
+// if (ptr->_internal_size < size && size <= ptr->_internal_capacity)
+// {
+// for (size_t i = ptr->_internal_size; i < size; i++)
+// {
+// ptr->_internal_arr[i] = val;
+// }
+// }
+// ptr->_internal_size = size;
+// return SUCCESS;
+// }
+//
+// __attribute__((overloadable)) size_t
+// _vec_char_assign(_VecCharInternal* ptr, const _VecCharInternal* iterator,
+// const size_t iter_start, const size_t iter_end)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (_vec_char_is_valid(iterator) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(iterator) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (ptr->_internal_arr == iterator->_internal_arr)
+// {
+// LOGERROR(ERR_DOUBLE_BUF);
+// return ERR_DOUBLE_BUF;
+// }
+// if (iterator->_internal_size < iter_end || iter_end <= iter_start)
+// {
+// LOGERROR(ERR_OUT_OF_BOUNDS);
+// return ERR_OUT_OF_BOUNDS;
+// }
+// size_t res =
+// _vec_char_erase(ptr, _vec_char_begin(ptr), _vec_char_end(ptr) + 1);
+// if (res != SUCCESS)
+// {
+// return res;
+// }
+// res = _vec_char_reserve(ptr, (iter_end - iter_start));
+// if (res != SUCCESS)
+// {
+// return res;
+// }
+// for (size_t i = iter_start; i < iter_end; i++)
+// {
+// res = _vec_char_push_back(ptr, _vec_char_at(iterator, i));
+// if (res != SUCCESS)
+// {
+// return res;
+// }
+// }
+// return SUCCESS;
+// }
+//
+// __attribute__((overloadable)) size_t
+// _vec_char_assign(_VecCharInternal* ptr, const size_t amount, const char val)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (amount == 0)
+// {
+// LOGERROR(ERR_SIZE_ZERO);
+// return ERR_SIZE_ZERO;
+// }
+// size_t res =
+// _vec_char_erase(ptr, _vec_char_begin(ptr), _vec_char_end(ptr) + 1);
+// if (res != SUCCESS)
+// {
+// return res;
+// }
+// res = _vec_char_reserve(ptr, amount);
+// if (res != SUCCESS)
+// {
+// return res;
+// }
+//
+// for (size_t i = 0; i < amount; i++)
+// {
+// res = _vec_char_push_back(ptr, val);
+// if (res != SUCCESS)
+// {
+// return res;
+// }
+// }
+// return SUCCESS;
+// }
+//
+// __attribute__((overloadable)) size_t
+// _vec_char_insert(_VecCharInternal* ptr, const size_t iter, const char val)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (ptr->_internal_max_size < ptr->_internal_size + 1)
+// {
+// LOGERROR(ERR_MAX_PASSED);
+// return ERR_MAX_PASSED;
+// }
+// if (iter > ptr->_internal_size)
+// {
+// LOGERROR(ERR_OUT_OF_BOUNDS);
+// return ERR_OUT_OF_BOUNDS;
+// }
+// size_t _ptr_err = _vec_char_push_back(ptr, 0);
+// if (_ptr_err != SUCCESS)
+// {
+// return _ptr_err;
+// }
+// for (size_t i = ptr->_internal_size - 1; i > iter; i--)
+// {
+// ptr->_internal_arr[i] = ptr->_internal_arr[i - 1];
+// }
+// ptr->_internal_arr[iter] = val;
+//
+// return SUCCESS;
+// }
+//
+// __attribute__((overloadable)) size_t
+// _vec_char_insert(_VecCharInternal* ptr, const size_t iter, const size_t
+// amount, const char val)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (iter > ptr->_internal_size)
+// {
+// LOGERROR(ERR_OUT_OF_BOUNDS);
+// return ERR_OUT_OF_BOUNDS;
+// }
+// if (amount <= 0)
+// {
+// LOGERROR(ERR_SIZE_ZERO);
+// return ERR_SIZE_ZERO;
+// }
+// for (size_t i = iter; i < iter + amount; i++)
+// {
+// size_t _ptr_err = _vec_char_insert(ptr, i, val);
+// if (_ptr_err != SUCCESS)
+// {
+// return _ptr_err;
+// }
+// }
+// return SUCCESS;
+// }
+//
+// __attribute__((overloadable)) size_t
+// _vec_char_insert(_VecCharInternal* ptr, const _VecCharInternal* iterator,
+// const size_t iter, const size_t iter_start,
+// const size_t iter_end)
+// {
+// if (_vec_char_is_valid(ptr) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(ptr) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (_vec_char_is_valid(iterator) == ERR_VECTOR_NULL)
+// {
+// return ERR_VECTOR_NULL;
+// }
+// if (_vec_char_is_valid(iterator) == ERR_BUF_NULL)
+// {
+// return ERR_BUF_NULL;
+// }
+// if (iter_end > iter_start || iter_end > iterator->_internal_size ||
+// iter > ptr->_internal_size)
+// {
+// LOGERROR(ERR_OUT_OF_BOUNDS);
+// return ERR_OUT_OF_BOUNDS;
+// }
+// if (ptr->_internal_arr == iterator->_internal_arr)
+// {
+// LOGERROR(ERR_DOUBLE_BUF);
+// return ERR_DOUBLE_BUF;
+// }
+// for (size_t i = iter_start; i < iter_end; i++)
+// {
+// size_t _ptr_err = _vec_char_insert(ptr, iter + (i - iter_start),
+// iterator->_internal_arr[i]);
+// if (_ptr_err != SUCCESS)
+// {
+// return _ptr_err;
+// }
+// }
+// return SUCCESS;
+// }
diff --git a/src/lib/char/char.h b/src/lib/char/char.h
index 60e62c7..86cdeeb 100644
--- a/src/lib/char/char.h
+++ b/src/lib/char/char.h
@@ -16,8 +16,8 @@ typedef struct
size_t _internal_max_size;
} _VecCharInternal;
-size_t
-_vec_char_is_valid(const _VecCharInternal* ptr);
+unsigned int
+_vec_char_raise_err(const _VecCharInternal* ptr, unsigned int mask);
_VecCharInternal
_vec_char_create(const char* src, const size_t size);
diff --git a/src/lib/utils/utils.c b/src/lib/utils/utils.c
index a80b577..ddb82ea 100644
--- a/src/lib/utils/utils.c
+++ b/src/lib/utils/utils.c
@@ -1,12 +1,36 @@
+#include
#include
-const char* error_messages[] = {
- [ERR_ALLOC_FAIL] = "Calloc :- Failed to allocate",
- [ERR_BUF_NULL] = "Buffer :- NULL",
- [ERR_SIZE_ZERO] = "Size :- Size is or is less than 0 or invalid",
- [ERR_VECTOR_NULL] = "Vector :- Given vector is null",
- [ERR_MAX_PASSED] = "Max :- Vector Max value is overloaded",
- [ERR_OUT_OF_BOUNDS] = "Bounds:- Value is out of bounds",
- [ERR_NULL] = "Null:- Vector or buffer is null",
- [ERR_DOUBLE_BUF] = "Buffer :- Both buffers are copies of each other",
-};
+const char*
+vec_get_error_desc(ERROR_CODES err)
+{
+ switch (err)
+ {
+#define X(name, val, desc) \
+ case name: \
+ return desc;
+ ERROR_LIST(X)
+#undef X
+ default:
+ "Unknown";
+ }
+}
+
+void
+vec_print_errs(const unsigned int err)
+{
+ if (err == SUCCESS)
+ {
+ printf("%s", vec_get_error_desc(SUCCESS));
+ return;
+ }
+ {
+#define X(name, val, desc) \
+ if ((val) != 0 && ((err) & (val))) \
+ { \
+ printf("%s\n", vec_get_error_desc(name)); \
+ }
+ ERROR_LIST(X)
+#undef X
+ }
+}
diff --git a/src/lib/utils/utils.h b/src/lib/utils/utils.h
index 657dfa2..00cb768 100644
--- a/src/lib/utils/utils.h
+++ b/src/lib/utils/utils.h
@@ -5,21 +5,35 @@
#include
#define CAPACITY 1024
-#define SUCCESS 0
+#define VEC_FAULT_BITS 32
-#define FAILURE 1
-#define ERR_ALLOC_FAIL 20
-#define ERR_BUF_NULL 21
-#define ERR_SIZE_ZERO 22
-#define ERR_VECTOR_NULL 23
-#define ERR_MAX_PASSED 24
-#define ERR_OUT_OF_BOUNDS 25
-#define ERR_NULL 26
-#define ERR_DOUBLE_BUF 27
+#define ERROR_LIST(X) \
+ X(SUCCESS, 0, "No Errors Found") \
+ X(ERR_ALLOC_FAIL, (1u << 1), "Calloc :- Failed to allocate") \
+ X(ERR_VEC_NULL, (1u << 2), "Vector :- Given vector is null") \
+ X(ERR_BUF_NULL, (1u << 3), "Buffer :- NULL") \
+ X(ERR_SIZE_ZERO, (1u << 4), \
+ "Size :- Size is or is less than 0 or invalid") \
+ X(ERR_OUT_OF_BOUNDS, (1u << 5), "Bounds:- Value is out of bounds") \
+ X(ERR_DOUBLE_BUF, (1u << 6), \
+ "Buffer :- Both buffers are copies of each other") \
+ X(ERR_SIZE_OVERFLOW, (1u << 7), "Max :- Vector Max value is overloaded")
-extern const char* error_messages[];
+typedef enum
+{
+#define X(name, val, desc) name = (val),
+ ERROR_LIST(X)
+#undef X
+} ERROR_CODES;
-#define LOG(msg) printf("LOG: %s\n", msg) /**< Print log message*/
+const char*
+vec_get_error_desc(ERROR_CODES err);
+
+void
+vec_print_errs(const unsigned int err);
+
+#define LOG(msg) printf("LOG: %s\n", msg) /**< Print log message*/
+#define DEBUG(msg) printf("DEBUB: %s\n", msg) /**< Print debug message*/
#define LOGERROR(error_code) \
printf("ERROR: %s\n", \
error_messages[error_code]) /**< Print log error message*/
diff --git a/src/libvec.c b/src/libvec.c
index 3efae2e..1b97595 100644
--- a/src/libvec.c
+++ b/src/libvec.c
@@ -1,3 +1 @@
#include
-
-#include "char/char.h"
diff --git a/src/main.c b/src/main.c
index 08ee948..55698e7 100644
--- a/src/main.c
+++ b/src/main.c
@@ -15,11 +15,152 @@
#include
#include
#include
+#include
#include
+#include "lib/utils/utils.h"
+
+void
+print_bits(unsigned int num);
+
+typedef struct
+{
+ char* _internal_arr;
+ size_t _internal_size;
+ size_t _internal_capacity;
+ size_t _internal_max_size;
+} _VecCharInternal;
+
+/* NOTE
+ * Value is the return value for functions like _vec_char_capacity
+ * Err is the unsigned bit range for all the errors tracked
+ * origin is a string for where the bug started and IS CHANGED ONLY WHEN NULL
+ * */
+
+typedef struct
+{
+ unsigned int err;
+ size_t value;
+ char* origin; // Where the main bug started
+} _err_t;
+
+void
+_vec_update_origin(_err_t* err, char* str)
+{
+ _err_t res;
+ if (err == nullptr)
+ {
+ res.err = 0;
+ res.value = 0;
+ }
+ if (!err->origin) err->origin = str;
+}
+
+unsigned int
+_vec_char_raise_err(const _VecCharInternal* ptr, unsigned int mask)
+
+{
+ unsigned int res = SUCCESS;
+ res |= mask;
+ if (ptr == nullptr) res |= ERR_VEC_NULL;
+ if (ptr->_internal_arr == nullptr) res |= ERR_BUF_NULL;
+
+ return res;
+}
+
+_VecCharInternal
+_vec_char_create(const char* src, const size_t size)
+{
+ unsigned int err = 0;
+ _VecCharInternal self = {
+ ._internal_arr = NULL,
+ ._internal_size = 0,
+ ._internal_capacity = CAPACITY,
+ ._internal_max_size = VEC_MAX,
+ };
+ if (size >= self._internal_max_size)
+ {
+ LOG("If you need more memory to start, create a blank and "
+ "reserve.");
+ return self;
+ }
+ if (self._internal_capacity < size)
+ {
+ size_t dst_cap = self._internal_capacity;
+ while (dst_cap < size && dst_cap * 2 < self._internal_max_size)
+ dst_cap *= 2;
+ self._internal_capacity = (dst_cap < size) ? size : dst_cap;
+ }
+ if (size > 0)
+ {
+ self._internal_arr =
+ calloc(self._internal_capacity, sizeof(char));
+ err = _vec_char_raise_err(&self, err);
+ if ((err & SUCCESS) == 1)
+ {
+ self._internal_arr = NULL;
+ vec_print_errs(err);
+ free(self._internal_arr);
+ return self;
+ }
+ }
+ if (!src) err |= ERR_BUF_NULL;
+ else
+ {
+ for (size_t i = 0; i < size; i++)
+ {
+ self._internal_arr[i] = src[i];
+ self._internal_size++;
+ }
+ }
+ vec_print_errs(err);
+ return self;
+}
+
+void
+print_bits(unsigned int num)
+{
+ // Determine the number of bits in an unsigned int (usually 32)
+ int total_bits = sizeof(num) * 8;
+
+ // Loop from the most significant bit (MSB) down to the least
+ // significant bit (LSB)
+ for (int i = total_bits - 1; i >= 0; i--)
+ {
+ // Shift a 1 to the i-th position and check if that bit is set
+ int bit = (num >> i) & 1;
+ printf("%d", bit);
+
+ // Optional: Add a space every 4 or 8 bits for readability
+ if (i % 8 == 0)
+ {
+ printf(" ");
+ }
+ }
+ printf("\n");
+}
+
int
main()
{
+ char res[4] = { 'a', 'b', 'c', 'd' };
+ _VecCharInternal v1 = _vec_char_create(nullptr, 3);
+ unsigned int mark = 1 << 0;
+ _err_t err = { 0, 0, "Te" };
+ _vec_update_origin(&err, "Test");
+ printf("%s", err.origin);
+ // for (int i = 0; i < VEC_FAULT_BITS; i++)
+ // {
+ // print_bits(mark);
+ // mark <<= 1;
+ // }
+ // const char* str = vec_get_error_desc(ERR_ALLOC_FAIL);
+ // const unsigned int error = ERR_BUF_NULL;
+ // if (!(ERR_ALLOC_FAIL & SUCCESS))
+ // {
+ // printf("Hello\n");
+ // }
+ // printf("%s", str);
// char ar1[] = { '1', '2', '3', '4' };
// char ar2[] = { 'a', 'b', 'c', 'd' };
// Vec8_t v1 = create(ar2, find_len(ar2));