summaryrefslogtreecommitdiff
path: root/05/tcc-0.9.25/stdlib.h
diff options
context:
space:
mode:
authorpommicket <pommicket@gmail.com>2022-02-17 13:22:13 -0500
committerpommicket <pommicket@gmail.com>2022-02-17 13:22:13 -0500
commite900dd8d6f2ff7cef66fbd31898d375b71ef53d6 (patch)
treeae732e8f5d6163acb78355ae4e5ca69d6e0c995e /05/tcc-0.9.25/stdlib.h
parent6e1158f49aa014b801b171b358c47389e7f9964e (diff)
procuding a (non-working) executable for tcc
Diffstat (limited to '05/tcc-0.9.25/stdlib.h')
-rw-r--r--05/tcc-0.9.25/stdlib.h193
1 files changed, 193 insertions, 0 deletions
diff --git a/05/tcc-0.9.25/stdlib.h b/05/tcc-0.9.25/stdlib.h
new file mode 100644
index 0000000..c2f83eb
--- /dev/null
+++ b/05/tcc-0.9.25/stdlib.h
@@ -0,0 +1,193 @@
+#ifndef _STDLIB_H
+#define _STDLIB_H
+
+#include <stdc_common.h>
+
+#define EXIT_FAILURE (-1)
+#define EXIT_SUCCESS 0
+#define RAND_MAX 2147483647
+// @NONSTANDARD: we don't define MB_CUR_MAX or any of the mbtowc functions
+
+typedef struct {
+ int quot;
+ int rem;
+} div_t;
+
+typedef struct {
+ long quot;
+ long rem;
+} ldiv_t;
+
+char *getenv(const char *name) {
+ int i, j;
+ for (i = 0; _envp[i]; ++i) {
+ char *key = _envp[i];
+ for (j = 0; key[j] != '=' && name[j]; ++j)
+ if (name[j] != key[j])
+ break;
+ if (key[j] == '=' && !name[j])
+ return key + (j+1);
+ }
+ return NULL;
+}
+
+double atof(const char *nptr) {
+ return strtod(nptr, NULL);
+}
+
+int atoi(const char *nptr) {
+ return _clamp_long_to_int(strtol(nptr, NULL, 10));
+}
+
+long atol(const char *nptr) {
+ return strtol(nptr, NULL, 10);
+}
+
+int rand(void) {
+ // https://en.wikipedia.org/wiki/Linear_congruential_generator
+ // we're using musl/newlib's constants
+ _rand_seed = 6364136223846793005 * _rand_seed + 1;
+ return _rand_seed >> 33;
+}
+
+void srand(unsigned seed) {
+ _rand_seed = seed;
+}
+
+void *calloc(size_t nmemb, size_t size) {
+ if (nmemb > 0xffffffffffffffff / size)
+ return NULL;
+ // NB: our malloc implementation returns zeroed memory
+ return malloc(nmemb * size);
+}
+
+void *realloc(void *ptr, size_t size) {
+ if (!ptr) return malloc(size);
+ if (!size) {
+ free(ptr);
+ return NULL;
+ }
+ uint64_t *memory = (char *)ptr - 16;
+ uint64_t old_size = *memory;
+ uint64_t *new_memory = _mremap(memory, old_size, size, MREMAP_MAYMOVE);
+ if ((uint64_t)new_memory > 0xffffffffffff0000) return NULL;
+ *new_memory = size;
+ return (char *)new_memory + 16;
+}
+
+
+int atexit(void (*func)(void)) {
+ if (_n_exit_handlers >= 32) return -1;
+ _exit_handlers[_n_exit_handlers++] = func;
+ return 0;
+}
+
+int system(const char *string) {
+ if (!string) return 1;
+
+ int pid = fork();
+ if (pid < 0) {
+ return -1;
+ } else if (pid == 0) {
+ // child
+ char *argv[] = {
+ "/bin/sh",
+ "-c",
+ 0,
+ 0
+ };
+ argv[2] = string;
+ execve("/bin/sh", argv, _envp);
+ // on success, execve does not return.
+ _Exit(-1);
+ } else {
+ // parent
+ int status = 0;
+ int ret = wait4(pid, &status, 0, NULL);
+ if (ret != pid) return -1;
+ if (_WIFSIGNALED(status)) return -1;
+ return _WEXITSTATUS(status);
+ }
+
+}
+
+void *bsearch(const void *key, const void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) {
+ size_t lo = 0;
+ size_t hi = nmemb;
+ while (lo < hi) {
+ size_t mid = (lo + hi) >> 1;
+ void *elem = (char *)base + mid * size;
+ int cmp = compar(key, elem);
+ if (cmp < 0) {
+ // key < elem
+ hi = mid;
+ } else if (cmp) {
+ // key > elem
+ lo = mid + 1;
+ } else {
+ return elem;
+ }
+ }
+ return NULL;
+}
+
+void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *)) {
+ // quicksort
+ if (nmemb < 2) return;
+
+ void *temp = malloc(size);
+ void *mid = (char *)base + ((nmemb >> 1) * size); // choose middle element to speed up sorting an already-sorted array
+ size_t pivot_index = 0, i;
+ for (i = 0; i < nmemb; ++i) {
+ void *elem = (char *)base + i * size;
+ if (compar(elem, mid) < 0)
+ ++pivot_index;
+ }
+ void *pivot = (char *)base + pivot_index * size;
+ memcpy(temp, pivot, size);
+ memcpy(pivot, mid, size);
+ memcpy(mid, temp, size);
+
+ char *l, *r = (char *)base + (nmemb-1) * size;
+ for (l = base; l < r;) {
+ if (compar(l, pivot) > 0) {
+ // swap l and r
+ memcpy(temp, l, size);
+ memcpy(l, r, size);
+ memcpy(r, temp, size);
+ r -= size;
+ } else {
+ // l is already in the right place
+ l += size;
+ }
+ }
+
+ qsort(base, pivot_index, size, compar);
+ qsort((char *)pivot + size, nmemb - 1 - pivot_index, size, compar);
+
+ free(temp);
+}
+
+int abs(int x) {
+ return x >= 0 ? x : -x;
+}
+
+long labs(long x) {
+ return x >= 0 ? x : -x;
+}
+
+div_t div(int numer, int denom) {
+ div_t d;
+ d.quot = numer / denom;
+ d.rem = numer % denom;
+ return d;
+}
+
+ldiv_t ldiv(long numer, long denom) {
+ ldiv_t d;
+ d.quot = numer / denom;
+ d.rem = numer % denom;
+ return d;
+}
+
+#endif // _STDLIB_H