std1.0.0-beta-7 SafeC docs
// SafeC Standard Library — System (C11/C17/C23 stdlib coverage)
// Process control, PRNG, conversions, sorting, and clock wrappers.
#pragma once
#include <std/stddef.h>
#include <std/sys.h>
#include <std/time.h>

// ── Explicit extern declarations (avoid complex C header parsing) ─────────────
namespace std {

extern void  exit(int code);
extern void  abort();
extern char* getenv(const char* name);
extern int   system(const char* cmd);
extern int   rand();
extern void  srand(unsigned int seed);
extern int   abs(int x);
extern long long llabs(long long x);
extern int   atoi(const char* s);
extern long long atoll(const char* s);
extern double atof(const char* s);
extern long long strtoll(const char* s, char** end, int base);
extern unsigned long long strtoull(const char* s, char** end, int base);
extern double strtod(const char* s, char** end);
extern float  strtof(const char* s, char** end);
extern int   atexit(fn void() func);
// qsort/bsearch over the elements' bytes, with sys.h's erased comparator.
extern void  qsort(unsigned char* base, size_t n, size_t size, SysCmpRaw_ cmp);
extern const unsigned char* bsearch(const &Erased key, const unsigned char* base, size_t n,
                                    size_t size, SysCmpRaw_ cmp);

// ── Process control ───────────────────────────────────────────────────────────

// Terminate the process with the given exit code.
inline void sys_exit(int code) {
    unsafe { exit(code); }
}

// Terminate the process abnormally (raises SIGABRT / triggers abort handler).
inline void sys_abort() {
    unsafe { abort(); }
}

// Return the value of the environment variable named `name`,
// or NULL if not set.  The returned pointer is owned by the environment.
inline const ?&char sys_getenv(const &char name) {
    unsafe { return getenv(name); }
}

// Return processor time consumed by the program in nanoseconds.
// Same clock as time_cpu_ns() (time.h).  Returns -1 on error.
inline long long sys_cpu_time_ns() {
    return time_cpu_ns();
}

// Return wall-clock time in nanoseconds since the Unix epoch.
// Same clock as time_wall_ns() (time.h).  Returns -1 on error.
inline long long sys_time_now_ns() {
    return time_wall_ns();
}

// Return a monotonic timestamp in nanoseconds (suitable for elapsed-time
// measurement; epoch is unspecified).  Returns -1 on error.
inline long long sys_monotonic_ns() {
    return time_mono_ns();
}

// ── Process control ───────────────────────────────────────────────────────────

// Run a shell command and return its exit status.  NULL → check if shell available.
inline int sys_system(const &char cmd) {
    unsafe { return system(cmd); }
}

// Register a function to be called at normal process exit.
// Returns 0 on success, non-zero if the registration limit is exceeded.
inline int sys_atexit(fn void() func) {
    unsafe { return atexit(func); }
}

// ── PRNG ──────────────────────────────────────────────────────────────────────

// Return a pseudo-random integer in [0, RAND_MAX].
inline int sys_rand() {
    unsafe { return rand(); }
}

// Seed the PRNG.  Use sys_time_now_ns() for a time-based seed.
inline void sys_srand(unsigned int seed) {
    unsafe { srand(seed); }
}

// ── Integer arithmetic ────────────────────────────────────────────────────────

// Absolute value of a 32-bit signed integer.
inline int sys_abs(int x) {
    if (x < 0) { return -x; }
    return x;
}

// Absolute value of a 64-bit signed integer.
inline long long sys_llabs(long long x) {
    if (x < 0LL) { return -x; }
    return x;
}

// ── String → number conversions ───────────────────────────────────────────────

// Convert a decimal string to int.  Stops at the first non-digit.
inline int sys_atoi(const &char s) {
    unsafe { return atoi(s); }
}

// Convert a decimal string to long long.
inline long long sys_atoll(const &char s) {
    unsafe { return atoll(s); }
}

// Convert a decimal/scientific string to double.
inline double sys_atof(const &char s) {
    unsafe { return atof(s); }
}

// Convert string to long long with explicit base (0 = auto-detect 0x/0 prefix).
inline long long sys_strtoll(const &char s, ?&&const char end, int base) {
    unsafe {
        char* e = (char*)0;
        long long v = strtoll(s, &e, base);
        match (end) { case some(out): { *out = e; } case null: { } }
        return v;
    }
}

// Convert string to unsigned long long.
inline unsigned long long sys_strtoull(const &char s, ?&&const char end, int base) {
    unsafe {
        char* e = (char*)0;
        unsigned long long v = strtoull(s, &e, base);
        match (end) { case some(out): { *out = e; } case null: { } }
        return v;
    }
}

// Convert string to double.
inline double sys_strtod(const &char s, ?&&const char end) {
    unsafe {
        char* e = (char*)0;
        double v = strtod(s, &e);
        match (end) { case some(out): { *out = e; } case null: { } }
        return v;
    }
}

// Convert string to float.
inline float sys_strtof(const &char s, ?&&const char end) {
    unsafe {
        char* e = (char*)0;
        float v = strtof(s, &e);
        match (end) { case some(out): { *out = e; } case null: { } }
        return v;
    }
}

// ── Sorting and searching ─────────────────────────────────────────────────────

// Sort n elements of elem_size bytes in place.
// cmp(a, b) compares two elements (int cmp(const T*, const T*), erased).
inline void sys_qsort_raw_(unsigned char* base, unsigned long n, unsigned long elem_size, SysCmpRaw_ cmp) {
    unsafe { qsort(base, n, elem_size, cmp); }
}

// Binary search in sorted array.  Returns pointer to match or NULL.
const unsigned char* sys_bsearch_raw_(const &Erased key, const unsigned char* base,
                                      unsigned long n, unsigned long elem_size, SysCmpRaw_ cmp) {
    unsafe { return bsearch(key, base, n, elem_size, cmp); }
}

} // namespace std