A C-based note-taking application with a custom dynamic array implementation.
make # Build, run tests, then run the app
make build # Build only (no tests, no run)
make run # Run the built app
make test # Run tests only
make clean # Remove build artifacts
make rebuild # Clean and rebuild (runs tests then app)make test # Run all testsTests use a custom lightweight testing framework with TEST() and RUN_TEST() macros (see tests/tests.h).
├── main.c # Entry point
├── Makefile # Build configuration
├── compile_commands.json # clangd compilation database (generated via `bear -- make`)
├── src/
│ ├── types/
│ │ ├── array/ # Custom dynamic array with vtable pattern
│ │ └── string/ # String type built on array
│ ├── memo/ # (TODO - not implemented)
│ ├── menu/ # (TODO - not implemented)
│ └── notebook/ # (TODO - not implemented)
├── tests/
│ ├── tests.h # Test framework macros
│ ├── array.c # Array module tests (14 tests)
│ └── string.c # String module tests (7 tests)
└── .gitignore # Excludes build artifacts
- Custom generic dynamic array with vtable for type-specific operations
- Macro-based type generation - Generate type-safe containers with
define_full_array_kind() - Vtable pattern - Supports custom free/copy functions for complex types
- Slice support - Create views into portions of the array
- Iterator pattern - Iterate with
foreachmacro - String type - Built on the array system
- K&R coding style with C11 standard
The Array module (types/array/) provides a generic container with:
-
Core struct:
Arraywith data, size, len, cap, and vtable -
VTable:
ArrayVTablewith optionalfreeandcopyfunction pointers -
Macro system:
define_full_array_kind(name, type, vtable)- Creates typedef + functionsdefine_array_kind(name, type, vtable)- Creates only functionsforeach(var, array)- Iterate over elementsarray_get_as(array, index, type)- Type-safe element accessarray_begin_as(array, type)/array_end_as(array, type)- Typed iterators
-
Functions:
array_init_with_cap()- Initialize with custom capacityarray_push()- Add element (auto-grows 2x when full)array_get()/array_set()- Random accessarray_streach()- Manual capacity increasearray_clone()- Deep copyarray_slice()- Create slice/viewarray_free()- Free with vtable cleanup
// Define a type with custom vtable
define_full_array_kind(Tags, String, &Tags_vtable);
// Create and use
Tags tags = Tags_new();
Tags_push(&tags, &myString);
String *tag;
foreach (tag, &tags) {
printf("%.*s\n", StringFMT(tag));
}
Tags_free(&tags);- GCC (or compatible C compiler)
- GNU Make
Compiles to notebook executable with flags: -Wall -Wextra -std=c11 -ggdb -I. -Isrc
The project generates compile_commands.json for clangd. Run bear -- make to regenerate it after building.