summaryrefslogtreecommitdiff
path: root/libc/include
diff options
context:
space:
mode:
Diffstat (limited to 'libc/include')
-rw-r--r--libc/include/ctype.h20
-rw-r--r--libc/include/errno.h140
-rw-r--r--libc/include/malloc.h18
-rw-r--r--libc/include/math.h4
-rw-r--r--libc/include/reent.h16
-rw-r--r--libc/include/setjmp.h13
-rw-r--r--libc/include/stdio.h153
-rw-r--r--libc/include/stdlib.h12
-rw-r--r--libc/include/string.h97
-rw-r--r--libc/include/unistd.h31
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