diff options
| author | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2011-02-05 04:35:27 +0100 | 
|---|---|---|
| committer | Nicolas "Pixel" Noble <pixel@nobis-crew.org> | 2011-02-05 04:35:27 +0100 | 
| commit | 61ba39a23786a7ae9694705af1d146c00a319144 (patch) | |
| tree | f9ad51bee751f7e878ac3e7ad4d45f993605c37d /libc/include | |
| parent | e2d292afdb43cd7d9391128563384e1edd53c52e (diff) | |
Getting rid of newlib, starting to implement a libc. Highly experimental, highly untested.
Diffstat (limited to 'libc/include')
| -rw-r--r-- | libc/include/ctype.h | 20 | ||||
| -rw-r--r-- | libc/include/errno.h | 140 | ||||
| -rw-r--r-- | libc/include/malloc.h | 18 | ||||
| -rw-r--r-- | libc/include/math.h | 4 | ||||
| -rw-r--r-- | libc/include/reent.h | 16 | ||||
| -rw-r--r-- | libc/include/setjmp.h | 13 | ||||
| -rw-r--r-- | libc/include/stdio.h | 153 | ||||
| -rw-r--r-- | libc/include/stdlib.h | 12 | ||||
| -rw-r--r-- | libc/include/string.h | 97 | ||||
| -rw-r--r-- | libc/include/unistd.h | 31 | 
10 files changed, 504 insertions, 0 deletions
| diff --git a/libc/include/ctype.h b/libc/include/ctype.h new file mode 100644 index 0000000..22e3e81 --- /dev/null +++ b/libc/include/ctype.h @@ -0,0 +1,20 @@ +#ifndef __CTYPE_H__ +#define __CTYPE_H__ + +static inline int isascii(int c) { return (c & 0x80) == 0; } +static inline int isblank(int c) { return c == ' ' || c == '\t'; } +static inline int isdigit(int c) { return c >= '0' && c <= '9'; } +static inline int iscntrl(int c) { return c < 32; } +static inline int islower(int c) { return c >= 'a' && c <= 'z'; } +static inline int isspace(int c) { return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v'; } +static inline int isupper(int c) { return c >= 'A' && c <= 'Z'; } +static inline int isxdigit(int c) { return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); } + +static inline int isalpha(int c) { return isupper(c) || islower(c); } +static inline int isalnum(int c) { return isalpha(c) || isdigit(c); } +static inline int isgraph(int c) { return !iscntrl(c) && !isspace(c); } +static inline int isprint(int c) { return !iscntrl(c); } +static inline int ispunct(int c) { return !iscntrl(c) && !isspace(c) && !isalnum(c); } + + +#endif diff --git a/libc/include/errno.h b/libc/include/errno.h new file mode 100644 index 0000000..c88ea64 --- /dev/null +++ b/libc/include/errno.h @@ -0,0 +1,140 @@ +#ifndef __ERRNO_H__ +#define __ERRNO_H__ + +enum errno_t { +    ENOERROR = 0, +    EPERM = 1, +    ENOENT = 2, +    ESRCH = 3, +    EINTR = 4, +    EIO = 5, +    ENXIO = 6, +    E2BIG = 7, +    ENOEXEC = 8, +    EBADF = 9, +    ECHILD = 10, +    EAGAIN = 11, +    ENOMEM = 12, +    EACCES = 13, +    EFAULT = 14, +    ENOTBLK = 15, +    EBUSY = 16, +    EEXIST = 17, +    EXDEV = 18, +    ENODEV = 19, +    ENOTDIR = 20, +    EISDIR = 21, +    EINVAL = 22, +    ENFILE = 23, +    EMFILE = 24, +    ENOTTY = 25, +    ETXTBSY = 26, +    EFBIG = 27, +    ENOSPC = 28, +    ESPIPE = 29, +    EROFS = 30, +    EMLINK = 31, +    EPIPE = 32, +    EDOM = 33, +    ERANGE = 34, +    EDEADLK = 35, +    ENAMETOOLONG = 36, +    ENOLCK = 37, +    ENOSYS = 38, +    ENOTEMPTY = 39, +    ELOOP = 40, +    EWOULDBLOCK = EAGAIN, +    ENOMSG = 42, +    EIDRM = 43, +    ECHRNG = 44, +    EL2NSYNC = 45, +    EL3HLT = 46, +    EL3RST = 47, +    ELNRNG = 48, +    EUNATCH = 49, +    ENOCSI = 50, +    EL2HLT = 51, +    EBADE = 52, +    EBADR = 53, +    EXFULL = 54, +    ENOANO = 55, +    EBADRQC = 56, +    EBADSLT = 57, +    EDEADLOCK = EDEADLK, +    EBFONT = 59, +    ENOSTR = 60, +    ENODATA = 61, +    ETIME = 62, +    ENOSR = 63, +    ENONET = 64, +    ENOPKG = 65, +    EREMOTE = 66, +    ENOLINK = 67, +    EADV = 68, +    ESRMNT = 69, +    ECOMM = 70, +    EPROTO = 71, +    EMULTIHOP = 72, +    EDOTDOT = 73, +    EBADMSG = 74, +    EOVERFLOW = 75, +    ENOTUNIQ = 76, +    EBADFD = 77, +    EREMCHG = 78, +    ELIBACC = 79, +    ELIBBAD = 80, +    ELIBSCN = 81, +    ELIBMAX = 82, +    ELIBEXEC = 83, +    EILSEQ = 84, +    ERESTART = 85, +    ESTRPIPE = 86, +    EUSERS = 87, +    ENOTSOCK = 88, +    EDESTADDRREQ = 89, +    EMSGSIZE = 90, +    EPROTOTYPE = 91, +    ENOPROTOOPT = 92, +    EPROTONOSUPPORT = 93, +    ESOCKTNOSUPPORT = 94, +    EOPNOTSUPP = 95, +    EPFNOSUPPORT = 96, +    EAFNOSUPPORT = 97, +    EADDRINUSE = 98, +    EADDRNOTAVAIL = 99, +    ENETDOWN = 100, +    ENETUNREACH = 101, +    ENETRESET = 102, +    ECONNABORTED = 103, +    ECONNRESET = 104, +    ENOBUFS = 105, +    EISCONN = 106, +    ENOTCONN = 107, +    ESHUTDOWN = 108, +    ETOOMANYREFS = 109, +    ETIMEDOUT = 110, +    ECONNREFUSED = 111, +    EHOSTDOWN = 112, +    EHOSTUNREACH = 113, +    EALREADY = 114, +    EINPROGRESS = 115, +    ESTALE = 116, +    EUCLEAN = 117, +    ENOTNAM = 118, +    ENAVAIL = 119, +    EISNAM = 120, +    EREMOTEIO = 121, +    EDQUOT = 122, +    ENOMEDIUM = 123, +    EMEDIUMTYPE = 124, +    ECANCELED = 125, +    ENOKEY = 126, +    EKEYEXPIRED = 127, +    EKEYREVOKED = 128, +    EKEYREJECTED = 129, +    EOWNERDEAD = 130, +    ENOTRECOVERABLE = 131, +    ERFKILL = 132, +}; + +#endif diff --git a/libc/include/malloc.h b/libc/include/malloc.h new file mode 100644 index 0000000..8dbfc05 --- /dev/null +++ b/libc/include/malloc.h @@ -0,0 +1,18 @@ +#ifndef __MALLOC_H__ +#define __MALLOC_H__ + +#include <reent.h> +#include <stddef.h> +#include <string.h> + +void * malloc(size_t size); +void free(void *ptr); +void * realloc(void *ptr, size_t size); + +static inline void * calloc(size_t nmemb, size_t size) { +    void * r = malloc(nmemb * size); +    memset(r, 0, nmemb * size); +    return r; +} + +#endif diff --git a/libc/include/math.h b/libc/include/math.h new file mode 100644 index 0000000..b41fee0 --- /dev/null +++ b/libc/include/math.h @@ -0,0 +1,4 @@ +#ifndef __MATH_H__ +#define __MATH_H__ + +#endif diff --git a/libc/include/reent.h b/libc/include/reent.h new file mode 100644 index 0000000..c3633ee --- /dev/null +++ b/libc/include/reent.h @@ -0,0 +1,16 @@ +#ifndef __RENT_H__ +#define __RENT_H__ + +#include <errno.h> + +struct _reent { +    enum errno_t _errno; +}; + +static inline void _REENT_INIT_PTR(struct _reent * reent) { +    reent->_errno = ENOERROR; +} + +extern struct _reent * _impure_ptr; + +#endif diff --git a/libc/include/setjmp.h b/libc/include/setjmp.h new file mode 100644 index 0000000..8fc8a12 --- /dev/null +++ b/libc/include/setjmp.h @@ -0,0 +1,13 @@ +#ifndef __SETJMP_H__ +#define __SETJMP_H__ + +#include <stdint.h> + +typedef struct { +    uint32_t buf[32]; +} jmp_buf; + +int setjmp(jmp_buf env); +void longjmp(jmp_buf env, int val); + +#endif diff --git a/libc/include/stdio.h b/libc/include/stdio.h new file mode 100644 index 0000000..1be0c6e --- /dev/null +++ b/libc/include/stdio.h @@ -0,0 +1,153 @@ +#ifndef __STDIO_H__ +#define __STDIO_H__ + +#include <reent.h> +#include <stdarg.h> +#include <stddef.h> +#include <unistd.h> +#include <malloc.h> + +struct _FILE { +    int fd; +}; + +typedef struct _FILE FILE; + +int printf(const char * format, ...); +int fprintf(FILE *stream, const char * format, ...); +int sprintf(char * str, const char * format, ...); +int snprintf(char * str, size_t size, const char * format, ...); +int asprintf(char ** strp, const char * format, ...); + +int vprintf(const char * format, va_list ap); +int vfprintf(FILE *stream, const char * format, va_list ap); +int vsprintf(char * str, const char * format, va_list ap); +int vsnprintf(char * str, size_t size, const char * format, va_list ap); +int vasprintf(char ** strp, const char * format, va_list ap); + +void __sinit(struct _reent *); + +// We don't even buffer, so... +static inline int fflush(FILE *stream) { return 0; } + +// hopefully, since all of the mode crap is static, gcc will optimize most of it away. +static inline FILE * fopen(const char * fname, const char * mode) { +    FILE * r = NULL; +    int flags = 0, plus = 0, append = 0, fd; +    if (!mode || !mode[0]) { +        _impure_ptr->_errno = EINVAL; +        return NULL; +    } +     +    if (mode[1] == 'b') { +        plus = mode[2] == '+'; +    } else if (mode[1]) { +        if (mode[1] != '+') { +            _impure_ptr->_errno = EINVAL; +            return NULL; +        } +        plus = 1; +    } +     +    switch (mode[0]) { +    case 'r': +        if (plus) { +            flags = O_RDWR; +        } else { +            flags = O_RDONLY; +        } +        break; +    case 'w': +        if (plus) { +            flags = O_RDWR | O_CREAT | O_TRUNC; +        } else { +            flags = O_WRONLY | O_CREAT | O_TRUNC; +        } +        break; +    case 'a': +        append = 1; +        if (plus) { // won't be properly supported +            flags = O_RDWR | O_CREAT; +        } else { +            flags = O_WRONLY | O_CREAT; +        } +        break; +    default: +        _impure_ptr->_errno = EINVAL; +        return NULL; +    } +     +    fd = open(fname, flags); +     +    if (fd >= 0) { +        r = (FILE *) malloc(sizeof(FILE)); +        r->fd = fd; +    } +     +    return r; +} + +static inline int fclose(FILE * stream) { +    int fd; +     +    if (!stream) { +        _impure_ptr->_errno = EINVAL; +        return -1; +    } +     +    fd = stream->fd; +    free(stream); +    return close(fd); +} + +// Again, the compiler should do the right thing, and optimize depending on the values of size and nmemb. +// Luckily, we always will get into the short cases. +static inline size_t fread(void * _ptr, size_t size, size_t nmemb, FILE * stream) { +    int i; +    uint8_t * ptr = (uint8_t *) _ptr; +     +    if (!stream) { +        _impure_ptr->_errno = EINVAL; +        return -1; +    } +     +    if (size == 1) +        return read(stream->fd, ptr, nmemb); +     +    if (nmemb == 1) +        return read(stream->fd, ptr, size) == size ? 1 : 0; +     +    for (i = 0; i < nmemb; i++) { +        if (read(stream->fd, ptr + size * i, size) != size) +            return i; +    } +     +    return nmemb; +} + +static inline size_t fwrite(const void * _ptr, size_t size, size_t nmemb, FILE * stream) { +    int i; +    const uint8_t * ptr = (const uint8_t *) _ptr; +     +    if (!stream) { +        _impure_ptr->_errno = EINVAL; +        return -1; +    } +     +    if (size == 1) +        return write(stream->fd, ptr, nmemb); +     +    if (nmemb == 1) +        return write(stream->fd, ptr, size) == size ? 1 : 0; +     +    for (i = 0; i < nmemb; i++) { +        if (write(stream->fd, ptr + size * i, size) != size) +            return i; +    } +     +    return nmemb; +} + +extern FILE * stdin, * stdout, * stderr; + +#endif diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h new file mode 100644 index 0000000..1cfe6c4 --- /dev/null +++ b/libc/include/stdlib.h @@ -0,0 +1,12 @@ +#ifndef __STDLIB_H__ +#define __STDLIB_H__ + +#include <reent.h> +#include <malloc.h> + +typedef void (*atexit_func_t)(void); + +void exit(int status) __attribute__((noreturn)); +int atexit(atexit_func_t); + +#endif diff --git a/libc/include/string.h b/libc/include/string.h new file mode 100644 index 0000000..2ec2a84 --- /dev/null +++ b/libc/include/string.h @@ -0,0 +1,97 @@ +#ifndef __STRING_H__ +#define __STRING_H__ + +#include <stdint.h> +#include <stddef.h> + +static inline void * memcpy(void * _s1, const void * _s2, size_t n) { +    uint8_t * s1 = (uint8_t *) _s1; +    const uint8_t * s2 = (uint8_t *) _s2; +    size_t i; +     +    for (i = 0; i < n; i++) +        *s1++ = *s2++; +     +    return _s1; +} + +static inline int memcmp(const void * _s1, const void * _s2, size_t n) { +    uint8_t * s1 = (uint8_t *) _s1; +    const uint8_t * s2 = (uint8_t *) _s2; +    size_t i; +     +    for (i = 0; i < n; i++, s1++, s2++) { +        if (*s1 < *s2) { +            return -1; +        } else if (*s1 > *s2) { +            return 1; +        } +    } +     +    return 0; +} + +static inline void * memset(void * _s, int c, size_t n) { +    uint8_t * s = (uint8_t *) _s; +    size_t i; +     +    for (i = 0; i < n; i++) +        *s++ = (uint8_t) c; +     +    return _s; +} + +static inline char * strcat(char * s1, const char * s2) { +    char * r = s1; +     +    while (*s1) +        s1++; +     +    while (*s2) +        *s1++ = *s2++; +     +    *s1 = 0; +     +    return r; +} + +static inline char * strcpy(char * s1, const char * s2) { +    char * r = s1; +     +    while ((*s1++ = *s2++)); +     +    return r; +} + +static inline char * strncpy(char * s1, const char * s2, size_t n) { +    char * r = s1; +    size_t i; +     +    for (i = 0; i < n; i++) { +        if (*s2) { +            *s1++ = *s2++; +        } else { +            *s1++ = 0; +        } +    } +     +    return r; +} + +static inline const char * strchr(const char * s, char c) { +    while (*s) +        if (*s++ == c) +            return s; +    return NULL; +} + +static inline size_t strlen(const char * s) { +    size_t r = 0; +     +    while (*s++) +        r++; +     +    return r; +} + +#endif diff --git a/libc/include/unistd.h b/libc/include/unistd.h new file mode 100644 index 0000000..8efd838 --- /dev/null +++ b/libc/include/unistd.h @@ -0,0 +1,31 @@ +#ifndef __UNISTD_H__ +#define __UNISTD_H__ + +#include <reent.h> +#include <stddef.h> +#include <stdint.h> + +typedef int32_t ssize_t; +typedef int32_t off_t; + +enum open_types_t { +    O_RDONLY = 0, +    O_WRONLY = 1, +    O_RDWR = 2, +    O_CREAT = 4, +    O_TRUNC = 8, +    O_APPEND = 16, +}; + +enum seek_wheels_t { +    SEEK_SET = 0, +    SEEK_CUR = 1, +    SEEK_END = 2, +}; + +int open(const char *pathname, int flags); +int close(int fd); +ssize_t read(int fd, void *buf, size_t count); +ssize_t write(int fd, const void *buf, size_t count); + +#endif | 
