mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
[TEST] Add unit tests for libc (#1974)
Some tests for libc + fixes --------- Co-authored-by: Christoffer Lerno <christoffer@aegik.com>
This commit is contained in:
@@ -20,6 +20,22 @@ struct LongDivResult
|
||||
CLong rem;
|
||||
}
|
||||
|
||||
struct Fpos_t @if(!env::WIN32)
|
||||
{
|
||||
long __pos;
|
||||
Mbstate_t __state;
|
||||
}
|
||||
|
||||
struct Mbstate_t @if(!env::WIN32)
|
||||
{
|
||||
int __count;
|
||||
union __value
|
||||
{
|
||||
uint __wch;
|
||||
char[4] __wcb;
|
||||
}
|
||||
}
|
||||
|
||||
fn Errno errno()
|
||||
{
|
||||
return (Errno)os::errno();
|
||||
@@ -35,7 +51,7 @@ def TerminateFunction = fn void();
|
||||
def CompareFunction = fn int(void*, void*);
|
||||
def JmpBuf = uptr[$$JMP_BUF_SIZE];
|
||||
def Fd = CInt;
|
||||
def Fpos_t = long; // TODO make sure fpos is correct on all targets.
|
||||
def Fpos_t = long @if(env::WIN32);
|
||||
def SignalFunction = fn void(CInt);
|
||||
|
||||
const CInt SIGHUP = 1;
|
||||
@@ -68,12 +84,12 @@ module libc @if(env::LIBC);
|
||||
extern fn void abort();
|
||||
extern fn CInt abs(CInt n);
|
||||
extern fn ZString asctime(Tm* timeptr);
|
||||
extern fn ZString asctime_r(Tm* timeptr, char* buf);
|
||||
extern fn ZString asctime_r(Tm* timeptr, char* buf) @if(!env::WIN32);
|
||||
extern fn CInt atexit(TerminateFunction func);
|
||||
extern fn double atof(char* str);
|
||||
extern fn int atoi(char* str);
|
||||
extern fn CLongLong atoll(char* str);
|
||||
extern fn void bsearch(void* key, void *base, usz items, usz size, CompareFunction compare);
|
||||
extern fn void* bsearch(void* key, void* base, usz items, usz size, CompareFunction compare);
|
||||
extern fn void* calloc(usz count, usz size);
|
||||
extern fn void clearerr(CFile stream);
|
||||
extern fn Clock_t clock();
|
||||
@@ -107,7 +123,7 @@ extern fn CInt getchar();
|
||||
extern fn ZString getenv(ZString name);
|
||||
extern fn ZString gets(char* buffer);
|
||||
extern fn Tm* gmtime(Time_t* timer);
|
||||
extern fn Tm* gmtime_r(Time_t *timer, Tm* buf) @if(!env::WIN32);
|
||||
extern fn Tm* gmtime_r(Time_t* timer, Tm* buf) @if(!env::WIN32);
|
||||
extern fn CInt isatty(Fd fd) @if(!env::WIN32);
|
||||
extern fn CLong labs(CLong x);
|
||||
extern fn LongDivResult ldiv(CLong number, CLong denom);
|
||||
@@ -169,7 +185,7 @@ extern fn CLong strtol(char* str, char** endptr, CInt base);
|
||||
extern fn CULong strtoul(char* str, char** endptr, CInt base);
|
||||
extern fn usz strxfrm(char* dest, ZString src, usz n);
|
||||
extern fn CInt system(ZString str);
|
||||
extern fn Time_t timegm(Tm *timeptr) @if(!env::WIN32);
|
||||
extern fn Time_t timegm(Tm* timeptr) @if(!env::WIN32);
|
||||
extern fn ZString tmpnam(ZString str);
|
||||
extern fn CFile tmpfile();
|
||||
extern fn CInt ungetc(CInt c, CFile stream);
|
||||
@@ -180,8 +196,8 @@ extern fn CFile fmemopen(void* ptr, usz size, ZString mode);
|
||||
extern fn isz getline(char** linep, usz* linecapp, CFile stream);
|
||||
extern fn CInt timespec_get(TimeSpec* ts, CInt base);
|
||||
extern fn CInt nanosleep(TimeSpec* req, TimeSpec* remaining);
|
||||
extern fn ZString ctime(Time_t *timer);
|
||||
extern fn Time_t time(Time_t *timer);
|
||||
extern fn ZString ctime(Time_t* timer);
|
||||
extern fn Time_t time(Time_t* timer);
|
||||
|
||||
const CInt STDIN_FD = 0;
|
||||
const CInt STDOUT_FD = 1;
|
||||
@@ -405,7 +421,7 @@ struct Tm
|
||||
CInt tm_yday; // days since January 1 [0-365]
|
||||
CInt tm_isdst; // Daylight Savings Time flag
|
||||
TimeOffset tm_gmtoff @if(!env::WIN32); /* offset from UTC in seconds */
|
||||
char *tm_zone @if(!env::WIN32); /* timezone abbreviation */
|
||||
char* tm_zone @if(!env::WIN32); /* timezone abbreviation */
|
||||
CInt tm_nsec @if(env::WASI);
|
||||
}
|
||||
|
||||
@@ -418,7 +434,7 @@ struct TimeSpec
|
||||
|
||||
|
||||
def Clock_t = int @if(env::WIN32);
|
||||
def Clock_t = CULong @if(!env::WIN32);
|
||||
def Clock_t = CLong @if(!env::WIN32);
|
||||
|
||||
def TimeOffset = int @if(env::WASI) ;
|
||||
def TimeOffset = CLong @if(!env::WASI) ;
|
||||
@@ -426,8 +442,10 @@ def TimeOffset = CLong @if(!env::WASI) ;
|
||||
const int TIME_UTC = 1;
|
||||
|
||||
|
||||
// Likely wrong, must be per platform.
|
||||
const CLOCKS_PER_SEC = 1000000;
|
||||
// This is a best-effort aproximation, but the C standard does not enforce
|
||||
// that this is a compile-time standard.
|
||||
const CLOCKS_PER_SEC @if(env::WIN32) = 1000;
|
||||
const CLOCKS_PER_SEC @if(!env::WIN32) = 1000000;
|
||||
|
||||
module libc::errno;
|
||||
|
||||
|
||||
577
test/unit/stdlib/libc/libc.c3
Normal file
577
test/unit/stdlib/libc/libc.c3
Normal file
@@ -0,0 +1,577 @@
|
||||
module libc_tests;
|
||||
import libc;
|
||||
|
||||
// Functions from libc.c3 which do not have a test are still present in
|
||||
// comments here in the same order that they occur within libc.c3
|
||||
|
||||
fn void abort() @test
|
||||
{
|
||||
// Cannot actually test this, so just checking if it's defined.
|
||||
assert($defined(libc::abort));
|
||||
}
|
||||
|
||||
fn void abs() @test
|
||||
{
|
||||
CInt x = 21;
|
||||
assert(libc::abs(x) == 21);
|
||||
assert(libc::abs(-x) == 21);
|
||||
$assert @typeis(libc::abs(x), CInt);
|
||||
$assert @typeis(libc::abs(-x), CInt);
|
||||
}
|
||||
|
||||
fn void asctime() @test
|
||||
{
|
||||
Tm time = {
|
||||
.tm_sec = 13,
|
||||
.tm_min = 42,
|
||||
.tm_hour = 3,
|
||||
.tm_mday = 5,
|
||||
.tm_mon = 8,
|
||||
.tm_year = 11,
|
||||
.tm_wday = 1,
|
||||
.tm_yday = 41,
|
||||
.tm_isdst = 0
|
||||
};
|
||||
ZString formatted_time = libc::asctime(&time);
|
||||
assert(libc::strcmp(formatted_time, "Mon Sep 5 03:42:13 1911\n") == 0);
|
||||
}
|
||||
|
||||
fn void asctime_r() @test @if(!env::WIN32)
|
||||
{
|
||||
Tm time = {
|
||||
.tm_sec = 13,
|
||||
.tm_min = 42,
|
||||
.tm_hour = 3,
|
||||
.tm_mday = 5,
|
||||
.tm_mon = 8,
|
||||
.tm_year = 11,
|
||||
.tm_wday = 1,
|
||||
.tm_yday = 41,
|
||||
.tm_isdst = 0
|
||||
};
|
||||
char[26] formatted_time;
|
||||
libc::asctime_r(&time, &formatted_time);
|
||||
assert(libc::strcmp((ZString) &formatted_time, "Mon Sep 5 03:42:13 1911\n") == 0);
|
||||
}
|
||||
|
||||
fn void test_atexit_function()
|
||||
{
|
||||
assert(5 == 5);
|
||||
// This correctly asserts, but does not fail the tests.
|
||||
// char c = 2;
|
||||
// assert(c == 5);
|
||||
}
|
||||
|
||||
fn void atexit() @test
|
||||
{
|
||||
// No idea how to test this, but we can at least check if this compiles
|
||||
libc::atexit(&test_atexit_function);
|
||||
libc::atexit(fn void() => 4);
|
||||
}
|
||||
|
||||
fn void atof() @test
|
||||
{
|
||||
assert(libc::atof("123.45") == 123.45);
|
||||
$assert @typeis(libc::atof("123.45"), double);
|
||||
assert(libc::atof("-3.14") == -3.14);
|
||||
$assert @typeis(libc::atof("-3.14"), double);
|
||||
assert(libc::atof("x") == 0.0);
|
||||
$assert @typeis(libc::atof("x"), double);
|
||||
assert(libc::atof("") == 0.0);
|
||||
$assert @typeis(libc::atof(""), double);
|
||||
}
|
||||
|
||||
fn void atoi() @test
|
||||
{
|
||||
assert(libc::atoi("123") == 123);
|
||||
$assert @typeis(libc::atoi("123"), int);
|
||||
assert(libc::atoi("-3.14") == -3);
|
||||
$assert @typeis(libc::atoi("-3.14"), int);
|
||||
assert(libc::atoi("x") == 0);
|
||||
$assert @typeis(libc::atoi("x"), int);
|
||||
assert(libc::atoi("") == 0);
|
||||
$assert @typeis(libc::atoi(""), int);
|
||||
}
|
||||
|
||||
fn void atoll() @test
|
||||
{
|
||||
assert(libc::atoi("123") == 123);
|
||||
$assert @typeis(libc::atoi("123"), int);
|
||||
assert(libc::atoi("-3.14") == -3);
|
||||
$assert @typeis(libc::atoi("-3.14"), int);
|
||||
assert(libc::atoi("x") == 0);
|
||||
$assert @typeis(libc::atoi("x"), int);
|
||||
assert(libc::atoi("") == 0);
|
||||
$assert @typeis(libc::atoi(""), int);
|
||||
}
|
||||
|
||||
// Compare function, struct and function for libc::bsearch test
|
||||
fn int compare_cint(void* a, void* b)
|
||||
{
|
||||
CInt a_i = *((CInt*) a);
|
||||
CInt b_i = *((CInt*) b);
|
||||
return a_i - b_i;
|
||||
}
|
||||
|
||||
struct Event
|
||||
{
|
||||
CInt day;
|
||||
CInt month;
|
||||
String desc;
|
||||
}
|
||||
|
||||
fn int compare_event(void* a, void* b)
|
||||
{
|
||||
Event* a_e = a; // Avoid casts if possible
|
||||
Event* b_e = b;
|
||||
return (a_e.month - b_e.month) * 100 + a_e.day - b_e.day;
|
||||
}
|
||||
|
||||
fn void bsearch() @test
|
||||
{
|
||||
CInt[] int_ar = { 0, 1, 2, 3, 4, 5, 6 };
|
||||
CInt key = 0;
|
||||
CInt* found = (CInt*) libc::bsearch(&key, int_ar, 7, CInt.sizeof, &compare_cint);
|
||||
assert(*found == 0);
|
||||
key = 1;
|
||||
found = (CInt*) libc::bsearch(&key, int_ar, 7, CInt.sizeof, &compare_cint);
|
||||
assert(*found == 1);
|
||||
key = 2;
|
||||
found = (CInt*) libc::bsearch(&key, int_ar, 7, CInt.sizeof, &compare_cint);
|
||||
assert(*found == 2);
|
||||
key = 5;
|
||||
found = (CInt*) libc::bsearch(&key, int_ar, 7, CInt.sizeof, &compare_cint);
|
||||
assert(*found == 5);
|
||||
key = 6;
|
||||
found = (CInt*) libc::bsearch(&key, int_ar, 7, CInt.sizeof, &compare_cint);
|
||||
assert(*found == 6);
|
||||
CInt non_existant_key = 12;
|
||||
found = (CInt*) libc::bsearch(&non_existant_key, int_ar, 7, CInt.sizeof, &compare_cint);
|
||||
assert(found == null);
|
||||
|
||||
Event[] events = {
|
||||
{ 2, 1, "2nd of February" },
|
||||
{ 5, 1, "Some day" },
|
||||
{ 1, 5, "Begin of May" },
|
||||
{ 1, 7, "Summer holiday start" },
|
||||
{ 21, 7, "A fine warm day" },
|
||||
{ 11, 11, "Peace" },
|
||||
{ 25, 12, "Family and sharing" },
|
||||
{ 31, 12, "End of the year" }
|
||||
};
|
||||
Event searching = { .day = 1, .month = 5 };
|
||||
Event* found1 = (Event*) libc::bsearch(&searching, events, 7, Event.sizeof, &compare_event);
|
||||
assert(found1.desc == "Begin of May");
|
||||
searching = { .day = 4, .month = 4 };
|
||||
found1 = (Event*) libc::bsearch(&searching, events, 7, Event.sizeof, &compare_event);
|
||||
assert(found1 == null);
|
||||
}
|
||||
|
||||
fn void calloc() @test
|
||||
{
|
||||
usz amount = 10;
|
||||
CInt* int_ar = libc::calloc(amount, CInt.sizeof);
|
||||
for (usz i = 0; i < amount; i++)
|
||||
{
|
||||
assert(int_ar[i] == 0);
|
||||
}
|
||||
libc::free(int_ar);
|
||||
}
|
||||
|
||||
fn void clearerr_feof_ferror() @test
|
||||
{
|
||||
CFile* tmpf = libc::tmpfile();
|
||||
// Example from cppreference.com
|
||||
ZString test_string = (ZString) "cppreference.com\n" +++ '\0';
|
||||
libc::fputs(test_string, tmpf);
|
||||
libc::rewind(tmpf);
|
||||
|
||||
for (int i = 0; i < test_string.len(); i++)
|
||||
{
|
||||
int c = libc::fgetc(tmpf);
|
||||
assert(c != libc::EOF);
|
||||
assert(c == test_string[i]);
|
||||
}
|
||||
|
||||
assert(libc::fgetc(tmpf) == libc::EOF);
|
||||
assert(libc::feof(tmpf) != 0);
|
||||
// there should be no errors (EOF is not an error)
|
||||
assert(libc::ferror(tmpf) == 0);
|
||||
libc::clearerr(tmpf);
|
||||
assert(libc::feof(tmpf) == 0);
|
||||
}
|
||||
|
||||
fn void clock() @test
|
||||
{
|
||||
Clock_t time1 = libc::clock();
|
||||
if (time1 < 0)
|
||||
{
|
||||
// If getting processor-time is not available, do nothing
|
||||
return;
|
||||
}
|
||||
// Waist bit of time
|
||||
int i = 0;
|
||||
for (int j = 0; j <= 1000; j++)
|
||||
{
|
||||
i += j;
|
||||
}
|
||||
assert(i == (1000 / 2) * (1000 + 1)); // Gauss, prevent compiler-optimisation
|
||||
Clock_t time2 = libc::clock();
|
||||
assert(time2 >= time1);
|
||||
}
|
||||
|
||||
fn void close() @test @if(!env::WIN32)
|
||||
{
|
||||
assert(libc::close(13) == -1);
|
||||
// NOTE: errno is part of libc, and is thus recursively imported
|
||||
assert(libc::errno() == errno::EBADF);
|
||||
}
|
||||
|
||||
fn void difftime() @test
|
||||
{
|
||||
Time_t t1 = 1293;
|
||||
Time_t t2 = 919919;
|
||||
assert(libc::difftime(t2, t1) > 0);
|
||||
assert(libc::difftime(t1, t2) < 0);
|
||||
}
|
||||
|
||||
fn void div() @test
|
||||
{
|
||||
DivResult res = libc::div(13, 2);
|
||||
assert(res.quot == 6);
|
||||
assert(res.rem == 1);
|
||||
res = libc::div(-5, 3);
|
||||
assert(res.quot == -1);
|
||||
assert(res.rem == -2);
|
||||
}
|
||||
|
||||
fn void exit() @test
|
||||
{
|
||||
// Cannot actually test this, so just checking if it's defined.
|
||||
assert($defined(libc::exit));
|
||||
}
|
||||
|
||||
fn void fclose() @test
|
||||
{
|
||||
CFile random_file = libc::tmpfile();
|
||||
assert(libc::fclose(random_file) == 0);
|
||||
}
|
||||
|
||||
fn void fdopen() @test @if(!env::WIN32)
|
||||
{
|
||||
CFile stdin = libc::fdopen(-1, "w");
|
||||
assert(libc::errno() == errno::EBADF);
|
||||
}
|
||||
|
||||
fn void fflush() @test
|
||||
{
|
||||
CFile stdin = libc::stdin();
|
||||
assert(libc::fflush(stdin) == 0);
|
||||
}
|
||||
|
||||
fn void fgets_fget() @test
|
||||
{
|
||||
CFile* tmpf = libc::tmpfile();
|
||||
// Example from cppreference.com
|
||||
ZString test_string = (ZString) "cppreference.com\n" +++ '\0';
|
||||
libc::rewind(tmpf);
|
||||
libc::fclose(tmpf);
|
||||
}
|
||||
|
||||
import std::io;
|
||||
fn void fseek_ftell_fgetpos_fsetpos_rewind() @test
|
||||
{
|
||||
CFile* tmpf = libc::tmpfile();
|
||||
// Example from cppreference.com
|
||||
ZString test_string = (ZString) "cppreference.com\n" +++ '\0';
|
||||
libc::fputs(test_string, tmpf);
|
||||
libc::rewind(tmpf);
|
||||
|
||||
Fpos_t pos;
|
||||
libc::fgetpos(tmpf, &pos);
|
||||
assert(libc::fgetc(tmpf) == 'c');
|
||||
assert(libc::fgetc(tmpf) == 'p');
|
||||
|
||||
libc::fsetpos(tmpf, &pos);
|
||||
assert(libc::fgetc(tmpf) == 'c');
|
||||
assert(libc::fgetc(tmpf) == 'p');
|
||||
|
||||
assert(libc::ftell(tmpf) == 2);
|
||||
|
||||
libc::fseek(tmpf, -2, libc::SEEK_END);
|
||||
assert(libc::fgetc(tmpf) == 'm');
|
||||
assert(libc::fgetc(tmpf) == '\n');
|
||||
|
||||
libc::fclose(tmpf);
|
||||
}
|
||||
|
||||
// fn void fileno() @test {}
|
||||
// fn void fopen() @test {}
|
||||
// fn void fprintf() @test {}
|
||||
// fn void fputc() @test {}
|
||||
// fn void fputs() @test {}
|
||||
// fn void fread() @test {}
|
||||
// fn void freopen() @test {}
|
||||
// fn void fscanf() @test {}
|
||||
// fn void fseek() @test {}
|
||||
// fn void ftell() @test {}
|
||||
// fn void fwrite() @test {}
|
||||
// fn void getc() @test {}
|
||||
// fn void getchar() @test {}
|
||||
// fn void getenv() @test {}
|
||||
// fn void gets() @test {}
|
||||
// fn void gmtime() @test {}
|
||||
// fn void gmtime_r() @test {}
|
||||
// fn void isatty() @test {}
|
||||
// fn void labs() @test {}
|
||||
// fn void ldiv() @test {}
|
||||
// fn void localtime() @test {}
|
||||
// fn void localtime_r() @test {}
|
||||
// fn void longjmp() @test {}
|
||||
|
||||
fn void malloc_free() @test
|
||||
{
|
||||
CInt* ar = libc::malloc(3 * CInt.sizeof);
|
||||
ar[0] = 10;
|
||||
ar[1] = -10;
|
||||
ar[2] = 4;
|
||||
assert(ar[0] == 10);
|
||||
assert(ar[1] == -10);
|
||||
assert(ar[2] == 4);
|
||||
libc::free(ar);
|
||||
}
|
||||
|
||||
// fn void memchr() @test {}
|
||||
// fn void memcmp() @test {}
|
||||
// fn void memcpy() @test {}
|
||||
// fn void memmove() @test {}
|
||||
// fn void memset() @test {}
|
||||
// fn void mktime() @test {}
|
||||
// fn void perror() @test {}
|
||||
// fn void printf() @test {}
|
||||
// fn void putc() @test {}
|
||||
// fn void putchar() @test {}
|
||||
// fn void puts() @test {}
|
||||
// fn void qsort() @test {}
|
||||
// fn void raise() @test {}
|
||||
// fn void rand() @test {}
|
||||
// fn void read() @test {}
|
||||
// fn void realloc() @test {}
|
||||
// fn void remove() @test {}
|
||||
// fn void rename() @test {}
|
||||
// fn void scanf() @test {}
|
||||
// fn void setbuf() @test {}
|
||||
// fn void setenv() @test {}
|
||||
// fn void setjmp() @test {}
|
||||
// fn void setvbuf() @test {}
|
||||
// fn void signal() @test {}
|
||||
// fn void snprintf() @test {}
|
||||
// fn void sprintf() @test {}
|
||||
// fn void srand() @test {}
|
||||
// fn void sscanf() @test {}
|
||||
// fn void strcat() @test {}
|
||||
// fn void strchr() @test {}
|
||||
// fn void strcmp() @test {}
|
||||
// fn void strcoll() @test {}
|
||||
// fn void strcspn() @test {}
|
||||
// fn void strcpy() @test {}
|
||||
// fn void strerror() @test {}
|
||||
// fn void strftime() @test {}
|
||||
// fn void strlen() @test {}
|
||||
// fn void strncat() @test {}
|
||||
// fn void strncmp() @test {}
|
||||
// fn void strncpy() @test {}
|
||||
// fn void stroul() @test {}
|
||||
// fn void strpbrk() @test {}
|
||||
// fn void strspn() @test {}
|
||||
// fn void strptime() @test {}
|
||||
// fn void strrchr() @test {}
|
||||
// fn void strstr() @test {}
|
||||
// fn void strtod() @test {}
|
||||
// fn void strtof() @test {}
|
||||
// fn void strtok() @test {}
|
||||
// fn void strtol() @test {}
|
||||
// fn void strtoul() @test {}
|
||||
// fn void strxfrm() @test {}
|
||||
// fn void system() @test {}
|
||||
// fn void timegm() @test {}
|
||||
// fn void tmpnam() @test {}
|
||||
// fn void tmpfile() @test {}
|
||||
// fn void ungetc() @test {}
|
||||
// fn void unsetenv() @test {}
|
||||
// fn void write() @test {}
|
||||
//
|
||||
// extern fn CFile fmemopen(void* ptr, usz size, ZString mode);
|
||||
// extern fn isz getline(char** linep, usz* linecapp, CFile stream);
|
||||
// extern fn CInt timespec_get(TimeSpec* ts, CInt base);
|
||||
// extern fn CInt nanosleep(TimeSpec* req, TimeSpec* remaining);
|
||||
// extern fn ZString ctime(Time_t *timer);
|
||||
// extern fn Time_t time(Time_t *timer);
|
||||
//
|
||||
// const CInt STDIN_FD = 0;
|
||||
// const CInt STDOUT_FD = 1;
|
||||
// const CInt STDERR_FD = 2;
|
||||
//
|
||||
// module libc @if(env::LINUX);
|
||||
// extern CFile __stdin @extern("stdin");
|
||||
// extern CFile __stdout @extern("stdout");
|
||||
// extern CFile __stderr @extern("stderr");
|
||||
// extern fn usz malloc_usable_size(void* ptr);
|
||||
// macro usz malloc_size(void* ptr) => malloc_usable_size(ptr);
|
||||
// extern fn void* aligned_alloc(usz align, usz size);
|
||||
// macro CFile stdin() => __stdin;
|
||||
// macro CFile stdout() => __stdout;
|
||||
// macro CFile stderr() => __stderr;
|
||||
//
|
||||
// module libc @if(env::NETBSD || env::OPENBSD);
|
||||
// extern fn int fcntl(CInt socket, int cmd, ...);
|
||||
// extern fn int _setjmp(void*);
|
||||
// macro int setjmp(void* ptr) => _setjmp(ptr);
|
||||
// extern fn int _longjmp(void*, int);
|
||||
// macro usz longjmp(void* ptr, CInt i) => _longjmp(ptr, i);
|
||||
// extern fn usz malloc_size(void* ptr);
|
||||
// extern fn void* aligned_alloc(usz align, usz size);
|
||||
// macro CFile stdin() { return fdopen(0, "r"); }
|
||||
// macro CFile stdout() { return fdopen(1, "w"); }
|
||||
// macro CFile stderr() { return fdopen(2, "w"); }
|
||||
//
|
||||
// module libc @if(env::DARWIN || env::FREEBSD);
|
||||
// extern CFile __stdinp;
|
||||
// extern CFile __stdoutp;
|
||||
// extern CFile __stderrp;
|
||||
// extern fn usz malloc_size(void* ptr) @if(!env::FREEBSD);
|
||||
// extern fn void* aligned_alloc(usz align, usz size);
|
||||
// macro CFile stdin() => __stdinp;
|
||||
// macro CFile stdout() => __stdoutp;
|
||||
// macro CFile stderr() => __stderrp;
|
||||
//
|
||||
// module libc @if(env::FREEBSD);
|
||||
// extern fn usz malloc_usable_size(void* ptr);
|
||||
// macro usz malloc_size(void* ptr) => malloc_usable_size(ptr);
|
||||
//
|
||||
// module libc @if(env::WIN32);
|
||||
// macro usz malloc_size(void* ptr) => _msize(ptr);
|
||||
// macro CFile stdin() => __acrt_iob_func(STDIN_FD);
|
||||
// macro CFile stdout() => __acrt_iob_func(STDOUT_FD);
|
||||
// macro CFile stderr() => __acrt_iob_func(STDERR_FD);
|
||||
//
|
||||
// module libc @if(env::LIBC && !env::WIN32 && !env::LINUX && !env::DARWIN && !env::BSD_FAMILY);
|
||||
// macro CFile stdin() { return (CFile*)(uptr)STDIN_FD; }
|
||||
// macro CFile stdout() { return (CFile*)(uptr)STDOUT_FD; }
|
||||
// macro CFile stderr() { return (CFile*)(uptr)STDERR_FD; }
|
||||
//
|
||||
// module libc @if(!env::LIBC);
|
||||
//
|
||||
// fn void longjmp(JmpBuf* buffer, CInt value) @weak @extern("longjmp") @nostrip
|
||||
// {
|
||||
// unreachable("longjmp unavailable");
|
||||
// }
|
||||
//
|
||||
// fn CInt setjmp(JmpBuf* buffer) @weak @extern("setjmp") @nostrip
|
||||
// {
|
||||
// unreachable("setjmp unavailable");
|
||||
// }
|
||||
//
|
||||
// fn void* malloc(usz size) @weak @extern("malloc") @nostrip
|
||||
// {
|
||||
// unreachable("malloc unavailable");
|
||||
// }
|
||||
// fn void* calloc(usz count, usz size) @weak @extern("calloc") @nostrip
|
||||
// {
|
||||
// unreachable("calloc unavailable");
|
||||
// }
|
||||
// fn void* free(void*) @weak @extern("free")
|
||||
// {
|
||||
// unreachable("free unavailable");
|
||||
// }
|
||||
//
|
||||
// fn void* realloc(void* ptr, usz size) @weak @extern("realloc") @nostrip
|
||||
// {
|
||||
// unreachable("realloc unavailable");
|
||||
// }
|
||||
//
|
||||
// fn void* memcpy(void* dest, void* src, usz n) @weak @extern("memcpy") @nostrip
|
||||
// {
|
||||
// for (usz i = 0; i < n; i++) ((char*)dest)[i] = ((char*)src)[i];
|
||||
// return dest;
|
||||
// }
|
||||
//
|
||||
// fn void* memmove(void* dest, void* src, usz n) @weak @extern("memmove") @nostrip
|
||||
// {
|
||||
// return memcpy(dest, src, n) @inline;
|
||||
// }
|
||||
//
|
||||
// fn void* memset(void* dest, CInt value, usz n) @weak @extern("memset") @nostrip
|
||||
// {
|
||||
// for (usz i = 0; i < n; i++) ((char*)dest)[i] = (char)value;
|
||||
// return dest;
|
||||
// }
|
||||
//
|
||||
// fn int fseek(CFile stream, SeekIndex offset, int whence) @weak @extern("fseek") @nostrip
|
||||
// {
|
||||
// unreachable("'fseek' not available.");
|
||||
// }
|
||||
// fn CFile fopen(ZString filename, ZString mode) @weak @extern("fopen") @nostrip
|
||||
// {
|
||||
// unreachable("'fopen' not available.");
|
||||
// }
|
||||
//
|
||||
// fn CFile freopen(ZString filename, ZString mode, CFile stream) @weak @extern("fopen") @nostrip
|
||||
// {
|
||||
// unreachable("'freopen' not available.");
|
||||
// }
|
||||
//
|
||||
// fn usz fwrite(void* ptr, usz size, usz nmemb, CFile stream) @weak @extern("fwrite") @nostrip
|
||||
// {
|
||||
// unreachable("'fwrite' not available.");
|
||||
// }
|
||||
//
|
||||
// fn usz fread(void* ptr, usz size, usz nmemb, CFile stream) @weak @extern("fread") @nostrip
|
||||
// {
|
||||
// unreachable("'fread' not available.");
|
||||
// }
|
||||
//
|
||||
// fn CFile fclose(CFile) @weak @extern("fclose") @nostrip
|
||||
// {
|
||||
// unreachable("'fclose' not available.");
|
||||
// }
|
||||
//
|
||||
// fn int fflush(CFile stream) @weak @extern("fflush") @nostrip
|
||||
// {
|
||||
// unreachable("'fflush' not available.");
|
||||
// }
|
||||
//
|
||||
// fn int fputc(int c, CFile stream) @weak @extern("fputc") @nostrip
|
||||
// {
|
||||
// unreachable("'fputc' not available.");
|
||||
// }
|
||||
//
|
||||
// fn char* fgets(ZString str, int n, CFile stream) @weak @extern("fgets") @nostrip
|
||||
// {
|
||||
// unreachable("'fgets' not available.");
|
||||
// }
|
||||
//
|
||||
// fn int fgetc(CFile stream) @weak @extern("fgetc") @nostrip
|
||||
// {
|
||||
// unreachable("'fgetc' not available.");
|
||||
// }
|
||||
//
|
||||
// fn int feof(CFile stream) @weak @extern("feof") @nostrip
|
||||
// {
|
||||
// unreachable("'feof' not available.");
|
||||
// }
|
||||
//
|
||||
// fn int putc(int c, CFile stream) @weak @extern("putc") @nostrip
|
||||
// {
|
||||
// unreachable("'putc' not available.");
|
||||
// }
|
||||
// fn int putchar(int c) @weak @extern("putchar") @nostrip
|
||||
// {
|
||||
// unreachable("'putchar' not available.");
|
||||
// }
|
||||
// fn int puts(ZString str) @weak @extern("puts") @nostrip
|
||||
// {
|
||||
// unreachable("'puts' not available.");
|
||||
// }
|
||||
//
|
||||
// module libc;
|
||||
0
test/unit/stdlib/libc/libc_extra.c3
Normal file
0
test/unit/stdlib/libc/libc_extra.c3
Normal file
0
test/unit/stdlib/libc/os/darwin.c3
Normal file
0
test/unit/stdlib/libc/os/darwin.c3
Normal file
0
test/unit/stdlib/libc/os/errno.c3
Normal file
0
test/unit/stdlib/libc/os/errno.c3
Normal file
0
test/unit/stdlib/libc/os/freebsd.c3
Normal file
0
test/unit/stdlib/libc/os/freebsd.c3
Normal file
0
test/unit/stdlib/libc/os/linux.c3
Normal file
0
test/unit/stdlib/libc/os/linux.c3
Normal file
0
test/unit/stdlib/libc/os/posix.c3
Normal file
0
test/unit/stdlib/libc/os/posix.c3
Normal file
0
test/unit/stdlib/libc/os/win32.c3
Normal file
0
test/unit/stdlib/libc/os/win32.c3
Normal file
0
test/unit/stdlib/libc/termios.c3
Normal file
0
test/unit/stdlib/libc/termios.c3
Normal file
Reference in New Issue
Block a user