First off, thank you for considering contributing to NextStd! It's people like you that make memory-safe C a reality.
NextStd is built on a dual-language architecture: a lightweight, macro-driven C11 front-end and a highly secure, memory-safe Rust back-end. Whether you are a C veteran or a Rustacean, there is a place for you here.
Before you write any code, it helps to understand how NextStd works:
- The C Front-End (
include/): Contains the C headers and macros (likens_vec_getorns_println). We use C11_Genericmacros for type routing to keep the API clean. - The Rust Back-End (
crates/): Contains the core logic. This is where memory is allocated, bounds are checked, and I/O is safely executed. - The FFI Boundary: C macros call the
extern "C"functions exposed by the Rust backend. If an error occurs, Rust catches it and returns anns_error_tcode instead of crashing.
To start developing, you need gcc (or clang), make, cargo, and the
rumdl markdown linker.
-
Fork and clone the repository.
-
Configure the local Git hooks. We use a pre-commit hook to automatically format Rust code and fix Markdown lint warnings before you commit. Run this in the root of the repository:
git config core.hooksPath .githooks
-
Build the Rust back-end locally:
make rust
-
Test your changes by writing a C file in the
examples/directory and running it:make <example_name_without_extension>
(Note: Do not run
sudo make installon your development branch, or you will overwrite your system's stable NextStd installation!)
- C11 Standard: We strictly target C11 to ensure
_Genericmacro support. - No Format Strings: Never introduce standard
printforscanfinto the library. Always route through the safe Rust backend. - Hot-Path Macros: For performance-critical data structures (like Vectors), try to handle bounds checking via C macros to avoid unnecessary FFI overhead.
- Minimize
unsafe: The whole point of this library is safety. Keep yourunsafeFFI blocks as small and isolated as possible. - Error Handling: Never
panic!orunwrap()in the Rust backend. If a C pointer is null or an index is out of bounds, return the appropriateNsErrorenum variant. - Adding Errors: If you create a new error state, add it to the
NsErrorenum inns_errorand update thens_error_messageC-string translator.
- Create a branch:
git checkout -b feat/my-new-module - Make your changes: Keep commits focused and descriptive.
- Update Documentation: If you add a new macro or module, update the
mdbookfiles in thesrc/directory. - Open a PR: Describe what you changed, why you changed it, and how to test it.
We review all PRs and are happy to help you work through FFI bugs if you get stuck!