Skip to content

Latest commit

 

History

34 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cyan.h

Rust-grade ergonomics for C11, in a header-only include

Options and Results instead of sentinels. Panics instead of undefined behavior. Vectors, slices, strings, hash maps and sets that check their bounds. defer, smart pointers, pattern matching, and Go-style CSP with coroutines and channels.

version standard header-only tests sanitizers platforms license

Pronounced "See-yan" because I'm a monster


#include <cyan/cyan.h>

RESULT_DEFINE(i32, ParseError);

// `?`-style early return: on Err, the whole Result propagates to the caller
Result_i32_ParseError parse_port(const char *s) {
    i32 port = try_ok(parse_int(s, NULL));
    if (port < 1 || port > 65535)
        return Err(i32, ParseError, "port out of range");
    return Ok(i32, ParseError, port);
}

int main(void) {
    match_result(parse_port("8080"), i32, ParseError, port, err,
        { printf("listening on %d\n", port); },
        { fprintf(stderr, "bad config: %s\n", err); }
    );
}

Why Cyan

  • Option_T and Result_T_E make "no value" and "error" impossible to ignore silently, with unwrap, expect, and_then, ok_or, and try_ok/try_some early returns.
  • Plain structs, zero machinery: no vtables, no hidden pointers, no runtime. An Option_i32 is a bool and an i32, and every generated function is static inline.
  • Every convenience macro evaluates each argument exactly once, and type-first naming (VEC_PUSH(i32, v, 42)) mirrors the constructors (Some(i32, 42)).
  • Bounds-checked access returns Options, capacity math is overflow-guarded, and allocation failures panic instead of corrupting. 141 property-based tests (theft) pass clean under ASan/UBSan.
  • Channels called inside coroutines yield instead of failing; coro_run schedules them and detects deadlock.
  • Configurable: custom panic handler, custom allocator hooks, and CYAN_NO_SHORT_NAMES if map/filter/unwrap would collide.

Installation

Copy include/cyan/ into your project. That's the whole install.

#include <cyan/cyan.h>     // everything
// or pick modules:
#include <cyan/option.h>
#include <cyan/vector.h>

Compile with GCC or Clang (-std=gnu11 or -std=c11; both accept the GNU extensions used). On macOS add -D_XOPEN_SOURCE=700 if you use coroutines (see Requirements).

Sixty-second tour

// Options and Results ------------------------------------------------
Option_i32 third = vec_i32_get(&v, 2);              // bounds-checked: Option
i32 x = unwrap_or(third, -1);                       // never a stray NULL

// Collections --------------------------------------------------------
Vec_i32 v = vec_i32_new();                          // growable, bounds-checked
VEC_PUSH(i32, v, 42);
VEC_FOREACH(i32, v, it) printf("%d ", *it);

HashMap_str_i32 counts = hashmap_str_i32_new();     // content-hashed str keys
hashmap_str_i32_insert(&counts, "apple", 1);        // key is copied & owned

// Strings ------------------------------------------------------------
String s = string_from("a,b,c");
Slice_char rest = string_as_slice(&s), part;
while (string_split_next(&rest, ',', &part))        // zero-copy split
    printf("%.*s\n", (int)part.len, part.data);

// Cleanup ------------------------------------------------------------
defer({ close_thing(&thing); });                    // runs on scope exit
string_auto(tmp, string_from("freed automatically"));

Documentation

Every module has its own page in docs/, with runnable counterparts in examples/.

Area Pages
Core Option · Result · Pattern matching · Primitive types
Collections Vector · Slice · String · HashMap · HashSet
Memory Defer · Smart pointers
Concurrency Coroutines · Channels
Utilities Functional · Serialization · Bit-width integers · Bitset
Library Method-style macros · Panic handler · Configuration · Examples guide

Version history lives in the changelog.

Requirements

  • C11 compatible compiler (GCC, Clang, or MSVC with C11 support)
  • GCC/Clang recommended for:
    • defer and auto-cleanup features (uses __attribute__((cleanup)))
    • Statement expressions in pattern matching
    • Nested functions in defer
  • POSIX system for coroutines (uses ucontext.h)
  • pthreads for thread-safe channels
  • macOS note: for the coroutine ucontext APIs to be visible, either include Cyan headers before any system header, or compile with -D_XOPEN_SOURCE=700 (the project Makefile does this)

Building and testing

make test              # 141 property-based tests (theft, vendored submodule)
make test SANITIZE=1   # the same suite under AddressSanitizer + UBSan

Property-based testing via theft (git submodule update --init on first clone).

Examples

Twenty runnable programs in examples/, each an API tour that ends with a realistic "putting it together" scenario. The examples guide describes what each one covers.

cd examples
make        # build all
make run    # run all

License

MIT License. See LICENSE for details.

About

Modern features for C

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages