diff options
Diffstat (limited to 'src/nonstd')
32 files changed, 375 insertions, 0 deletions
diff --git a/src/nonstd/ASSERT_NONNULL.c b/src/nonstd/ASSERT_NONNULL.c new file mode 100644 index 00000000..e65020fd --- /dev/null +++ b/src/nonstd/ASSERT_NONNULL.c @@ -0,0 +1,14 @@ +#include <nonstd/assert.h> + +#ifndef NDEBUG +#define ASSERT_NONNULL(_ptr) do { \ + if (!_ptr) { \ + struct __constraint_info _ci = {0}; \ + _ci.func = __func__; \ + __libc.stdlib.constraint_handler("Undefined behavior: " \ + "Parameter " #_ptr " can not be NULL", &_ci, EFAULT); \ + } \ + } while (0) +#else +#define ASSERT_NONNULL(x) +#endif diff --git a/src/nonstd/ASSERT_NONZERO.c b/src/nonstd/ASSERT_NONZERO.c new file mode 100644 index 00000000..24a3f9a9 --- /dev/null +++ b/src/nonstd/ASSERT_NONZERO.c @@ -0,0 +1,14 @@ +#include <nonstd/assert.h> + +#ifndef NDEBUG +#define ASSERT_NONZERO(_n) do { \ + if (!_n) { \ + struct __constraint_info _ci = {0}; \ + _ci.func = __func__; \ + __libc.stdlib.constraint_handler("Undefined behavior: " \ + "Parameter " #_n " can not be 0", &_ci, ERANGE); \ + } \ + } while (0) +#else +#define ASSERT_NONZERO(n) +#endif diff --git a/src/nonstd/ASSERT_NOOVERLAP.c b/src/nonstd/ASSERT_NOOVERLAP.c new file mode 100644 index 00000000..5157c6d3 --- /dev/null +++ b/src/nonstd/ASSERT_NOOVERLAP.c @@ -0,0 +1,9 @@ +#include <nonstd/assert.h> + +#ifndef NDEBUG +#define ASSERT_NOOVERLAP(x, y, s) do { \ + /* TODO */ \ + } while (0) +#else +#define ASSERT_NOOVERLAP(x, y, s) +#endif diff --git a/src/nonstd/ASSERT_REPRESENTABLE.c b/src/nonstd/ASSERT_REPRESENTABLE.c new file mode 100644 index 00000000..0067d9b4 --- /dev/null +++ b/src/nonstd/ASSERT_REPRESENTABLE.c @@ -0,0 +1,21 @@ +#include <nonstd/assert.h> + +#ifndef NDEBUG +#define ASSERT_REPRESENTABLE(_n, _min, _max, _type, _sentinel) do { \ + if (_sentinel && (_n != _sentinel && (_n < _min || _n > _max))) { \ + struct __constraint_info _ci = {0}; \ + _ci.func = __func__; \ + __libc.stdlib.constraint_handler("Undefined behavior: " \ + "Paramater " #_n " must be representable as a " #_type \ + "or be equal to " #_sentinel, &_ci, ERANGE); \ + } else if (_n < _min || _n > _max) { \ + struct __constraint_info _ci = {0}; \ + _ci.func = __func__; \ + __libc.stdlib.constraint_handler("Undefined behavior: " \ + "Parameter " #_n " must be representable as a " #_type, \ + &_ci, ERANGE); \ + } \ + } while (0) +#else +#define ASSERT_REPRESENTABLE(_n, _min, _max, _type, _sentinel) +#endif diff --git a/src/nonstd/BUFSIZ.ref b/src/nonstd/BUFSIZ.ref new file mode 100644 index 00000000..660ed705 --- /dev/null +++ b/src/nonstd/BUFSIZ.ref @@ -0,0 +1,2 @@ +#include <nonstd/io.h> +REFERENCE(stdio/BUFSIZ.c) diff --git a/src/nonstd/LIBC_INTERNAL.c b/src/nonstd/LIBC_INTERNAL.c new file mode 100644 index 00000000..f3c0086a --- /dev/null +++ b/src/nonstd/LIBC_INTERNAL.c @@ -0,0 +1,17 @@ +#include <nonstd/internal.h> + +typedef enum { + ERRNO, + THREAD_LOCALE, + GLOBAL_LOCALE, + SYSCALL_LOOKUP, + PRINTF, + SCANF, + FOPEN, + CTYPE, + TOLOWER, + TOUPPER, + FILE_TAIL, + ATEXIT, + RAND, +} LIBC_INTERNAL; diff --git a/src/nonstd/NULL.ref b/src/nonstd/NULL.ref new file mode 100644 index 00000000..9218f06c --- /dev/null +++ b/src/nonstd/NULL.ref @@ -0,0 +1,2 @@ +#include <nonstd/io.h> +REFERENCE(stddef/NULL.c) diff --git a/src/nonstd/SYSCALL.c b/src/nonstd/SYSCALL.c new file mode 100644 index 00000000..4c04ab1b --- /dev/null +++ b/src/nonstd/SYSCALL.c @@ -0,0 +1,11 @@ +#include <nonstd/syscall.h> + +#define SYSCALL(_name, _type, ...) + static int _scno = -2; \ + if (_scno == -2) { _scno = ((syscall_lookup_t)__libc(SYSCALL_LOOKUP))(_name); } \ + _type _ret = __syscall(_scno, __VA_ARGS__); \ + if (_ret < 0) { \ + errno = -_ret; \ + return -1; \ + } \ + return _ret diff --git a/src/nonstd/SYSCALL0.c b/src/nonstd/SYSCALL0.c new file mode 100644 index 00000000..c52a944d --- /dev/null +++ b/src/nonstd/SYSCALL0.c @@ -0,0 +1,11 @@ +#include <nonstd/syscall.h> + +#define SYSCALL0(_name, _type) + static int _scno = -2; \ + if (_scno == -2) { _scno = ((sycall_lookup_t)__libc(LOOKUP))(_name); } \ + _type _ret = __syscall(_scno); \ + if (_ret < 0) { \ + errno = -_ret; \ + return -1; \ + } \ + return _ret diff --git a/src/nonstd/SYSCALL_NOFAIL.c b/src/nonstd/SYSCALL_NOFAIL.c new file mode 100644 index 00000000..715fde95 --- /dev/null +++ b/src/nonstd/SYSCALL_NOFAIL.c @@ -0,0 +1,6 @@ +#include <nonstd/syscall.h> + +#define SYSCALL_NOFAIL(_name) + static int _scno = -2; \ + if (_scno == -2) { _scno = __libc(SYSCALL_LOOKUP)(_name); } \ + return __libc(SYSCALL)(_scno) diff --git a/src/nonstd/SYSCALL_NUMBER.c b/src/nonstd/SYSCALL_NUMBER.c new file mode 100644 index 00000000..f37e4a21 --- /dev/null +++ b/src/nonstd/SYSCALL_NUMBER.c @@ -0,0 +1,8 @@ +#include <nonstd/syscall.h> + +#define SYSCALL_NUMBER(_var, _name, _notfound) long _var = _notfound + + static int _var = -2; do { \ + if (_var == -2) { (_var) = __libc(SYSCALL_LOOKUP)(_name); } \ + if (_var == -1) { errno = ENOSYS; return (_notfound); } \ + } while (0) diff --git a/src/nonstd/__libc.c b/src/nonstd/__libc.c new file mode 100644 index 00000000..2d246203 --- /dev/null +++ b/src/nonstd/__libc.c @@ -0,0 +1,44 @@ +#include <nonstd/internal.h> +#include "locale.h" +#include "nonstd/locale.h" + +#include "_printf.h" +#include "_syscall.h" + +void *__libc(LIBC_INTERNAL variable) +{ + extern void *__libc_per_thread(LIBC_INTERNAL __variable); + + void *r = (void*)0; + + static struct __locale_t locale; + + switch (variable) { + case ERRNO: + return __libc_per_thread(ERRNO); + + case THREAD_LOCALE: + r = __libc_per_thread(THREAD_LOCALE); + if (r) { + break; + } + /* fallthru */ + + case GLOBAL_LOCALE: + r = &locale; + break; + + case SYSCALL_LOOKUP: + r = (void*)__syscall_lookup; + break; + + case PRINTF: + r = (void*)(__printf); + break; + + default: + break; + } + + return r; +} diff --git a/src/nonstd/__libc_per_thread.c b/src/nonstd/__libc_per_thread.c new file mode 100644 index 00000000..5cc2f2a5 --- /dev/null +++ b/src/nonstd/__libc_per_thread.c @@ -0,0 +1,28 @@ +#include "nonstd/internal.h" +#include "locale.h" +#include "nonstd/locale.h" + +#if defined __STDC_VERSION__ && 201112L <= __STDC_VERSION__ && !defined __STDC_NO_THREADS__ +#define THREAD_LOCAL static _Thread_local +#else +#define THREAD_LOCAL static +#endif + +void *__libc_per_thread(LIBC_INTERNAL variable) +{ + THREAD_LOCAL int errno; + THREAD_LOCAL struct __locale_t *locale; + + switch (variable) { + case ERRNO: + return &errno; + + case THREAD_LOCALE: + return &locale; + + default: + break; + } + + return (void*)0; +} diff --git a/src/nonstd/__libc_start.c b/src/nonstd/__libc_start.c new file mode 100644 index 00000000..8dab57fb --- /dev/null +++ b/src/nonstd/__libc_start.c @@ -0,0 +1,26 @@ +void __libc_start(int argc, char **argv) +{ + /* + struct __fopen_options fo = {0}; + + fo.fd = 0; + stdin = __libc.stdio.fopen(&fo); + + fo.fd = 1; + stdout = __libc.stdio.fopen(&fo); + + fo.fd = 2; + stderr = __libc.stdio.fopen(&fo); + + #if defined _POSIX_SOURCE || defined _POSIX_C_SOURCE || defined _XOPEN_SOURCE + setlocale(LC_ALL, "POSIX"); + #else + setlocale(LC_ALL, "C"); + #endif + */ + extern void exit(int); + extern int main(int, char*[]); + + exit(main(argc, argv)); +} + diff --git a/src/nonstd/__printf.c b/src/nonstd/__printf.c new file mode 100644 index 00000000..5868a15d --- /dev/null +++ b/src/nonstd/__printf.c @@ -0,0 +1,4 @@ +#include <nonstd/io.h> + +#define __printf(_opts, _fmt, _ap) \ + ((int (*)(struct io_options*, const char*, va_list))__libc(PRINTF))(_opts, _fmt, _ap) diff --git a/src/nonstd/__scanf.c b/src/nonstd/__scanf.c new file mode 100644 index 00000000..7508880d --- /dev/null +++ b/src/nonstd/__scanf.c @@ -0,0 +1,4 @@ +#include <nonstd/io.h> + +#define __scanf(_opts, _fmt, _ap) \ + ((int (*)(struct io_options*, const char*, va_list))__libc(SCANF))(_opts, _fmt, _ap) diff --git a/src/nonstd/__syscall.c b/src/nonstd/__syscall.c new file mode 100644 index 00000000..a1d0d1ed --- /dev/null +++ b/src/nonstd/__syscall.c @@ -0,0 +1,4 @@ +#include <nonstd/syscall.h> + +long __syscall(long number, ...) +; diff --git a/src/nonstd/ctype_t.c b/src/nonstd/ctype_t.c new file mode 100644 index 00000000..468214b1 --- /dev/null +++ b/src/nonstd/ctype_t.c @@ -0,0 +1,15 @@ +#include <nonstd/ctype.h> + +typedef enum { + ALPHA = (1 << 0), + CNTRL = (1 << 1), + DIGIT = (1 << 2), + GRAPH = (1 << 3), + LOWER = (1 << 4), + PRINT = (1 << 5), + PUNCT = (1 << 6), + SPACE = (1 << 7), + UPPER = (1 << 8), + XDIGIT = (1 << 9), + BLANK = (1 << 10), +} ctype_t; diff --git a/src/nonstd/flockfile.c b/src/nonstd/flockfile.c new file mode 100644 index 00000000..54c86a36 --- /dev/null +++ b/src/nonstd/flockfile.c @@ -0,0 +1,5 @@ +#include <nonstd/io.h> + +#if !(defined _POSIX_C_SOURCE && 199506L <= _POSIX_C_SOURCE) && !(defined _XOPEN_SOURCE && 500 <= _XOPEN_SOURCE) +#define flockfile(f) (void)(f) +#endif diff --git a/src/nonstd/fpos_t.ref b/src/nonstd/fpos_t.ref new file mode 100644 index 00000000..2f233e07 --- /dev/null +++ b/src/nonstd/fpos_t.ref @@ -0,0 +1,2 @@ +#include <nonstd/io.h> +REFERENCE(stdio/fpos_t.c) diff --git a/src/nonstd/ftrylockfile.c b/src/nonstd/ftrylockfile.c new file mode 100644 index 00000000..61636a7e --- /dev/null +++ b/src/nonstd/ftrylockfile.c @@ -0,0 +1,5 @@ +#include <nonstd/io.h> + +#if !(defined _POSIX_C_SOURCE && 199506L <= _POSIX_C_SOURCE) && !(defined _XOPEN_SOURCE && 500 <= _XOPEN_SOURCE) +#define ftrylockfile(f) (void)(f), 0 +#endif diff --git a/src/nonstd/funlockfile.c b/src/nonstd/funlockfile.c new file mode 100644 index 00000000..0fe52c48 --- /dev/null +++ b/src/nonstd/funlockfile.c @@ -0,0 +1,5 @@ +#include <nonstd/io.h> + +#if !(defined _POSIX_C_SOURCE && 199506L <= _POSIX_C_SOURCE) && !(defined _XOPEN_SOURCE && 500 <= _XOPEN_SOURCE) +#define funlockfile(f) (void)(f) +#endif diff --git a/src/nonstd/getc_unlocked.c b/src/nonstd/getc_unlocked.c new file mode 100644 index 00000000..a575e60a --- /dev/null +++ b/src/nonstd/getc_unlocked.c @@ -0,0 +1,5 @@ +#include <nonstd/io.h> + +#if !(defined _POSIX_C_SOURCE && 199506L <= _POSIX_C_SOURCE) && !(defined _XOPEN_SOURCE && 500 <= _XOPEN_SOURCE) +#define getc_unlocked(f) getc(f) +#endif diff --git a/src/nonstd/intmax_t.ref b/src/nonstd/intmax_t.ref new file mode 100644 index 00000000..b96b2d3b --- /dev/null +++ b/src/nonstd/intmax_t.ref @@ -0,0 +1,2 @@ +#include <nonstd/types.h> +REFERENCE(stdint/intmax_t.c) diff --git a/src/nonstd/pid_t.ref b/src/nonstd/pid_t.ref new file mode 100644 index 00000000..23be346f --- /dev/null +++ b/src/nonstd/pid_t.ref @@ -0,0 +1,2 @@ +#include <nonstd/io.h> +REFERENCE(sys/types/pid_t.c) diff --git a/src/nonstd/size_t.ref b/src/nonstd/size_t.ref new file mode 100644 index 00000000..27c403ab --- /dev/null +++ b/src/nonstd/size_t.ref @@ -0,0 +1,2 @@ +#include <nonstd/io.h> +REFERENCE(stddef/size_t.c) diff --git a/src/nonstd/struct_FILE.c b/src/nonstd/struct_FILE.c new file mode 100644 index 00000000..a3b8610e --- /dev/null +++ b/src/nonstd/struct_FILE.c @@ -0,0 +1,36 @@ +#include <nonstd/io.h> + +struct __FILE { + fpos_t pos; + char *buf; + enum { SUPPLIED, ALLOCED, UNSET } buftype; + int buffering; + int bsize; + int isopen; + int flags; + int lastop; + + /* verified necessary */ + int fd; + int oflag; + int orientation; + int eof; + int err; + int nlocks; + int thread; + + #ifdef _POSIX_SOURCE + pid_t pipe_pid; + #else + long int pipe_pid; + #endif + + struct { + char *buf; + size_t size; + int allocated; + } mem; + + struct __FILE *prev; + struct __FILE *next; +}; diff --git a/src/nonstd/struct_atexit.c b/src/nonstd/struct_atexit.c new file mode 100644 index 00000000..482bbed1 --- /dev/null +++ b/src/nonstd/struct_atexit.c @@ -0,0 +1,8 @@ +#include <nonstd/internal.h> + +struct atexit { + int nfns; + void (*fns[32])(void); + struct atexit *next; + struct atexit *prev; +}; diff --git a/src/nonstd/struct_io_options.c b/src/nonstd/struct_io_options.c new file mode 100644 index 00000000..db125f6d --- /dev/null +++ b/src/nonstd/struct_io_options.c @@ -0,0 +1,10 @@ +#include <nonstd/io.h> + +struct io_options { + const char *fnname; + char *string; + struct __FILE *stream; + size_t maxlen; + int fd; + int flags; +}; diff --git a/src/nonstd/struct_locale_t.c b/src/nonstd/struct_locale_t.c new file mode 100644 index 00000000..1981bd8d --- /dev/null +++ b/src/nonstd/struct_locale_t.c @@ -0,0 +1,48 @@ +#include <nonstd/locale.h> + +struct __locale_t { + int mask; + char *all; + char *collate; + unsigned char *collation; + char *ctype; + unsigned char *ctattr; + unsigned char *ctoupper; + unsigned char *ctolower; + char *message; + struct { + char *yesexpr; + char *noexpr; + } lc_messages; + char *monetary; + char *numeric; + struct lconv mn; + char *time; + struct { + char *abday[7]; + char *day[7]; + char *abmon[12]; + char *mon[12]; + char *d_t_fmt; + char *d_fmt; + char *t_fmt; + char *am_pm[2]; + char *t_fmt_ampm; + struct { + char direction; + int offset; + int start_year; + int start_month; + int start_day; + int end_year; + int end_month; + int end_day; + char *era_name; + char *era_format; + } era; + char *era_d_fmt; + char *era_t_fmt; + char *era_d_t_fmt; + char *alt_digits; + } lc_time; +}; diff --git a/src/nonstd/syscall_lookup_t.c b/src/nonstd/syscall_lookup_t.c new file mode 100644 index 00000000..d30bdbc2 --- /dev/null +++ b/src/nonstd/syscall_lookup_t.c @@ -0,0 +1,3 @@ +#include <nonstd/syscall.h> + +typedef long (*syscall_lookup_t)(const char *); diff --git a/src/nonstd/va_list.ref b/src/nonstd/va_list.ref new file mode 100644 index 00000000..84f0e484 --- /dev/null +++ b/src/nonstd/va_list.ref @@ -0,0 +1,2 @@ +#include <nonstd/io.h> +REFERENCE(stdarg/va_list.c) |