Skip to content

wAIfu-DEV/XSTD

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

33 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

XSTD – A C Standard Library for the 21st Century πŸš€

πŸ“¦ A modern, modular, and powerful C standard library replacement β€” inspired by modern languages but built for C.


πŸ›  What's this?

xstd is a lightweight, flexible, and expressive C standard library focused on developer productivity, safety, and ergonomics. It reimagines the C runtime and standard tooling for 2024 and beyond, introducing idioms and patterns inspired by languages like Rust, Go, and Zig β€” while remaining fully C-compatible and zero-dependency.

✳️ Highlights:

  • Result types (ResultOwnedStr, ResultOwnedBuff, Result<T>) β€” no more NULL checks or magic number errors.
  • Explicit memory ownership though typedefs (OwnedStr, ConstStr, String, OwnedBuff, ConstBuff) β€” ownership is never implicit.
  • Modular allocators: arena allocators, buffer allocators, tracking/debug allocators, and c_allocator a thin wrapper around cstd's malloc/free.
  • Modern tooling: string builders, hashmaps, IO abstractions, file APIs, and more.
  • Safer APIs: bounds-checked string functions, typed list operations, and precise error propagation.
  • Full introspection support: allocation metrics, file metadata, and crash diagnostics.
  • Cross-platform compatibility: completely minimal interface built on top of stdlib.

🀯 Why something other than C standard library?

The C standard library (stdlib) has served faithfully for decades, but:

❌ Memory management is unsafe and sometimes invisible β€” allocations are opaque, leaks happen silently.
❌ Error handling is often unintuitive β€” fopen() returns NULL and you’re already segfaulting.
❌ Working with strings is error-prone β€” strcat, strlen, global buffers...
❌ Arrays are unsafe β€” you never know their size.
❌ Unsafe and deprecated functions are still widely usable.

We think: C deserves better tooling, and we've built xstd to fill that void β€” a modern, fully C99-compatible library with minimal dependencies and huge ergonomics improvements.


✨ Features

βœ… Error-Driven Design
β€’ Result<T> for allocation, file IO, string manipulation, parsing, hashing, etc.
β€’ Clearly defined ErrorCode enum with human-readable messages.

βœ… Modern Allocator System
β€’ Arena allocator β€” blazing fast, rolling block allocator
β€’ Buffer allocator β€” stack-like allocator with free support
β€’ Debug allocator β€” tracks leaks, counts allocations, checks double frees
β€’ Default fallback stdlib allocator (c_allocator)
β€’ Clean, pluggable design with full introspection

βœ… Strings & Buffers Made Safe
β€’ Heap strings (owned), const strings, stack strings
β€’ Builders for appending strings without unsafe strcat
β€’ Fully bounds-checked copies, resizes, and concatenation
β€’ File-safe string/bytes APIs
β€’ UTF-8 compatible (ASCII-safe) character operations

βœ… Containers (with Types!)
β€’ List<T> β€” realloc-style resizable vector with type checked push/pop
β€’ HashMap<Str, T> β€” safe, dynamic key:value store with string key support
β€’ Safe access macros: ListPushT, HashMapSetStrT, etc.

βœ… File IO You've Always Wanted
β€’ file_readall_str() β€” read the whole file as a string
β€’ file_read_bytes(n) β€” read n bytes safely
β€’ file_write_uint(file, 1234)
β€’ Line iterators, flushers, position readers, error checks, etc.

βœ… Writers = No More snprintf()
β€’ Writers to buffered memory, dynamically growing buffers, strings
β€’ Writer w; writer_write_uint(&w, 1234);

βœ… Crash Handling
β€’ Setup crash handler with process_setup_crash_handler()
β€’ Intercepts SIGSEGV, SIGABRT, SIGFPE, etc.

βœ… Math & String Parsing
β€’ Overflow-checked math operations
β€’ Safe string_parse_int, string_from_float, etc.
β€’ Standard math ops: power, abs, mul, div, add with overflow detection

βœ… Fully Modular
β€’ Include only what you need: xstd_io.h, xstd_file.h, xstd_list.h, etc.
β€’ No global state, allocation decoupled from modules
β€’ Platform compatibility via small, replaceable interfaces (xstd_os_int.h)


πŸ“ Project Philosophy

πŸ”’ Safety: All operations favor bounds-checked, well-defined behavior. Unsafe operations are explicitly marked.

🧠 Predictability: Every function either returns a Result<T> or sets up predictable invariants. No silent NULLs.

πŸ’‘ Composability: Allocators plug into lists, writers use buffers, hash maps use allocators β€” everything connects seamlessly.

πŸ’¨ Performance: Header-only, inlined functions. Arena allocators for batch allocations. Avoids unnecessary syscalls.

πŸ’₯ Simplicity: Simple, portable, and transparent. Absolutely no macros unless for type safety. No hacks. Always readable.


πŸ”¨ Example: Using Lists and Strings

#include "xstd_core.h"
#include "xstd_string.h"

i32 main() {
    Allocator *a = default_allocator();

    // Most XSTD functions will either return void, Error, or ResultT
    ResultStrBuilder builderRes = strbuilder_init(a); // Any function allocating memory will take a Allocator*
    
    // Check for errors by comparing error code against 0
    // Error code of 0 (ERR_OK) means success and a defined value,
    // But error code != 0 means failure, and a very likely undefined value.
    if (builderRes.error.code != ERR_OK) {
        io_printerrln(ErrorToString(builderRes.error.code)) // All standard error codes have string representations
        io_printerrln(builderRes.error.msg); // All xstd library errors will also have a descriptive error message!
        return 1;
    }

    StringBuilder builder = builderRes.value; // Extract valid value out of result after error handling

    // Push strings to the builder
    strbuilder_push_copy(&builder, "Yes! "); // `strbuilder_push_owned` can be used for owned strings you want to push without copy.
    strbuilder_push_copy(&builder, "We ");
    strbuilder_push_copy(&builder, "Can!");

    // Strings the user need to free will be returned through OwnedStr or ResultOwnedStr.
    // This way, the intent is clear and explicitly declared through the code.
    ResultOwnedStr builtRes = strbuilder_get_string(&builder);

    // You do not have to compare the code to ERR_OK for it to achieve the same thing
    if (builtRes.error.code) {
        io_printerrln(builtRes.error.msg);
        return 1;
    }

    OwnedStr built = builtRes.value;
    io_println(built);

    // We free the result string, since OwnedStr implies the consumer owns the
    // string, it is our responsibility to free it.
    // Strings that do not require freeing are passed as either ConstStr or String
    a->free(a, built);

    // Any call to x_init() should be followed by a call to x_deinit(),
    // in order to free the memory.
    strbuilder_deinit(&builder);
}

🧩 Something for everyone

  • πŸ” Want to track leaks? Use the DebugAllocator to get peak memory stats and track unfreed blocks.
  • πŸ₯· Building a DSL? Use Writer to generate source-like text output.
  • πŸš₯ Parsing input? Use string_split_lines, string_parse_float, string_trim_whitespace.
  • πŸ’Ύ Need simple caching? Use HashMapSetStrT and free memory easily with hashmap_deinit.

🚫 What xstd isn't

  • A bloated runtime
  • A garbage collector
  • A pthread-heavy concurrency abstraction
  • A C++ STL polyfill

It’s just modern utilities β€” nothing intrusive.


πŸ§ͺ Want to get started?

#include "xstd_io.h"
#include "xstd_string.h"

i32 main(void)
{
    Allocator *a = default_allocator();
    io_println("Hello from xstd!");

    ResultOwnedStr intStr = string_from_int(a, -42);
    if (intStr.error.code) {
        io_printerrln(intStr.error.msg);
        return 1;
    }

    io_println(intStr.value);
    a->free(a, intStr.value);
    return 0;
}

🧬 File Structure

File Description
xstd_core.h Core types like u8, i64, Bool, Buffer, etc.
xstd_alloc.h Allocator interface (Allocator, alloc)
xstd_alloc_arena.h Arena (stack-like) allocator
xstd_alloc_buffer.h Free-able buffer allocator
xstd_alloc_debug.h Allocation-tracking wrapper
xstd_io.h Terminal IO / assertions / prints
xstd_file.h Cross-platform file reading & writing
xstd_error.h Rich error handling
xstd_string.h Safe strings & builders
xstd_list.h Type-safe dynamic arrays
xstd_hashmap.h Type-safe string-keyed hash maps
xstd_writer.h Writers to buffer & string APIs
xstd_math.h Overflow-safe math utilities
xstd_result.h Result<T> structs
xstd_vectors.h Vec2, Vec3 structs
xstd_process.h Crash signal handlers

πŸ‘· Coming Soon

  • JSON & text parsing
  • Cross-platform filesystem APIs
  • More allocator types (slab, fixed-pool)
  • Tighter xstd_string codegen/writer integration
  • Unit tests via xstd_test.h

❀️ Contributing

Want to help improve C ergonomics? Fork this project and improve one of the modules!

We love:

  • Better documentation
  • New allocator types
  • Performance improvements
  • Bug fixes
  • Language bindings

Open an issue or PR and join us!


πŸ§‘β€πŸ’» Who’s it for?

  • C developers who love modern patterns
  • Embedded engineers who need safety without runtime
  • Compiler authors needing tooling
  • Systems programmers who want better ergonomics without C++
  • You. If you're reading this.

πŸ”š TL;DR

βœ… Safer
βœ… Faster
βœ… Type-safe
βœ… Debuggable
βœ… Ergonomic
βœ… Just C


πŸ‘‰ MIT licensed | 100% portable | C99+ Contributions welcome.


Projects making use of xstd:


πŸ›  Built with love for C ❀️


I'd like to thank ChatGPT for writing this README, really cool.

About

A good, modern and safer standard library for C

Resources

License

Stars

9 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages