From f68c3203966024308b0d9bc5f0bd033260cfd1d3 Mon Sep 17 00:00:00 2001 From: Nathan Giddings Date: Tue, 28 May 2024 14:50:00 -0500 Subject: [PATCH] New repo setup --- .gitignore | 4 + Makefile | 42 ++ README.md | 5 + include/dirent.h | 58 ++ include/dup.h | 0 include/fork.h | 0 include/math.h | 257 +++++++++ include/stdio.h | 63 ++ include/stdlib.h | 45 ++ include/string | 54 ++ include/string.h | 41 ++ include/time.h | 27 + include/unistd.h | 25 + include/vector | 191 +++++++ include/wait.h | 0 main.c | 7 + src/aarch64/crt0.s | 29 + src/dirent.c | 45 ++ src/execve.c | 32 ++ src/fork.c | 9 + src/getcwd.c | 10 + src/heap/heap.c | 299 ++++++++++ src/heap/heap.h | 36 ++ src/math.c | 1078 +++++++++++++++++++++++++++++++++++ src/mkdir.c | 8 + src/stdio/fgetc.c | 21 + src/stdio/fgets.c | 53 ++ src/stdio/file/fio.c | 11 + src/stdio/getchar.c | 8 + src/stdio/print/fprintf.c | 23 + src/stdio/print/printf.c | 16 + src/stdio/print/snprintf.c | 13 + src/stdio/print/sprintf.c | 12 + src/stdio/print/vfprintf.c | 20 + src/stdio/print/vprintf.c | 16 + src/stdio/print/vsnprintf.c | 113 ++++ src/stdio/print/vsprintf.c | 112 ++++ src/stdio/scan/fscanf.c | 11 + src/stdio/scan/scanf.c | 20 + src/stdio/scan/sscanf.c | 13 + src/stdio/scan/vfscanf.c | 10 + src/stdio/scan/vscanf.c | 11 + src/stdio/scan/vsscanf.c | 747 ++++++++++++++++++++++++ src/stdio/stdin.c | 5 + src/stdlib/stdlib.c | 296 ++++++++++ src/string.c | 265 +++++++++ src/stringclass.cpp | 342 +++++++++++ src/uinit.c | 17 + src/unistd.c | 32 ++ src/wait.c | 31 + test-makefile | 29 + 51 files changed, 4612 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 README.md create mode 100644 include/dirent.h create mode 100644 include/dup.h create mode 100644 include/fork.h create mode 100644 include/math.h create mode 100644 include/stdio.h create mode 100644 include/stdlib.h create mode 100644 include/string create mode 100644 include/string.h create mode 100644 include/time.h create mode 100644 include/unistd.h create mode 100644 include/vector create mode 100644 include/wait.h create mode 100644 main.c create mode 100644 src/aarch64/crt0.s create mode 100644 src/dirent.c create mode 100644 src/execve.c create mode 100644 src/fork.c create mode 100644 src/getcwd.c create mode 100644 src/heap/heap.c create mode 100644 src/heap/heap.h create mode 100644 src/math.c create mode 100644 src/mkdir.c create mode 100644 src/stdio/fgetc.c create mode 100644 src/stdio/fgets.c create mode 100644 src/stdio/file/fio.c create mode 100644 src/stdio/getchar.c create mode 100644 src/stdio/print/fprintf.c create mode 100644 src/stdio/print/printf.c create mode 100644 src/stdio/print/snprintf.c create mode 100644 src/stdio/print/sprintf.c create mode 100644 src/stdio/print/vfprintf.c create mode 100644 src/stdio/print/vprintf.c create mode 100644 src/stdio/print/vsnprintf.c create mode 100644 src/stdio/print/vsprintf.c create mode 100644 src/stdio/scan/fscanf.c create mode 100644 src/stdio/scan/scanf.c create mode 100644 src/stdio/scan/sscanf.c create mode 100644 src/stdio/scan/vfscanf.c create mode 100644 src/stdio/scan/vscanf.c create mode 100644 src/stdio/scan/vsscanf.c create mode 100644 src/stdio/stdin.c create mode 100644 src/stdlib/stdlib.c create mode 100644 src/string.c create mode 100644 src/stringclass.cpp create mode 100644 src/uinit.c create mode 100644 src/unistd.c create mode 100644 src/wait.c create mode 100644 test-makefile diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7705ac7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +*.o +*.a +*.so +.vscode \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..dd62b73 --- /dev/null +++ b/Makefile @@ -0,0 +1,42 @@ +CC = aarch64-none-elf-gcc +CXX = aarch64-none-elf-g++ +AS = aarch64-none-elf-as +AR = aarch64-none-elf-ar +prefix:=$(HOME)/.cros/root + +objs = src/aarch64/crt0.o src/uinit.o src/unistd.o src/mkdir.o src/stdio/fgets.o src/stdio/getchar.o\ + src/stdio/print/fprintf.o src/stdio/print/printf.o src/stdio/print/sprintf.o src/stdio/print/vsprintf.o src/stdio/print/snprintf.o src/stdio/print/vfprintf.o src/stdio/print/vprintf.o src/stdio/print/vsnprintf.o \ + src/heap/heap.o src/string.o src/stdlib/stdlib.o src/stringclass.o src/dirent.o src/execve.o src/fork.o src/wait.o\ + src/stdio/stdin.o src/stdio/fgetc.o src/stdio/file/fio.o src/stdio/scan/scanf.o src/stdio/scan/sscanf.o src/stdio/scan/vsscanf.o\ + src/stdio/scan/vscanf.o src/stdio/scan/vfscanf.o src/stdio/scan/fscanf.o\ + + +libname = libc.a +libmname = libm.a +libsys = libsyscall.a + +CFLAGS = -I$(prefix)/include -iquote include/ -Isrc/ -lsyscall -ffreestanding -fpermissive -Wall -Wextra -ggdb -O0 +CXXFLAGS = -I$(prefix)/include -iquote include/ -Isrc/ -ffreestanding -fpermissive -fno-exceptions -fno-rtti -Wall -Wextra -ggdb -O0 + +.PHONY: all +all: $(libname) $(libmname) + +.PHONY: clean +clean: + rm -f $(objs) $(libname) + +.PHONY: install +install: + mkdir -p $(prefix)/include + mkdir -p $(prefix)/lib + cp $(libname) $(prefix)/lib + cp $(libmname) $(prefix)/lib + cp include/*.h $(prefix)/include + cp include/string $(prefix)/include + cp include/vector $(prefix)/include + +$(libname): $(objs) + $(AR) rcs $@ $^ + +$(libmname): + $(AR) rcs $@ \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..8509e3a --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# CROS libc + +## Introduction + +## Building \ No newline at end of file diff --git a/include/dirent.h b/include/dirent.h new file mode 100644 index 0000000..16131d6 --- /dev/null +++ b/include/dirent.h @@ -0,0 +1,58 @@ +#ifndef _DIRENT_H +#define _DIRENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned long ino_t; +typedef signed int off_t; + +typedef struct dirent { + ino_t d_ino; + off_t d_off; + unsigned short d_reclen; + unsigned char d_type; + + char d_name[]; +} DIR; + +enum + { + DT_UNKNOWN = 0, +# define DT_UNKNOWN DT_UNKNOWN + DT_FIFO = 1, +# define DT_FIFO DT_FIFO + DT_CHR = 2, +# define DT_CHR DT_CHR + DT_DIR = 4, +# define DT_DIR DT_DIR + DT_BLK = 6, +# define DT_BLK DT_BLK + DT_REG = 8, +# define DT_REG DT_REG + DT_LNK = 10, +# define DT_LNK DT_LNK + DT_SOCK = 12, +# define DT_SOCK DT_SOCK + DT_WHT = 14 +# define DT_WHT DT_WHT + }; + +int alphasort(const struct dirent **, const struct dirent **); +int closedir(DIR *); +int dirfd(DIR *); +DIR *fdopendir(int); +DIR *opendir(const char *); +struct dirent *readdir(DIR *); +int readdir_r(DIR *restrict, struct dirent *restrictis, struct dirent **restricts); +void rewinddir(DIR *); +int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **)); +void seekdir(DIR *, long); +long telldir(DIR *); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/dup.h b/include/dup.h new file mode 100644 index 0000000..e69de29 diff --git a/include/fork.h b/include/fork.h new file mode 100644 index 0000000..e69de29 diff --git a/include/math.h b/include/math.h new file mode 100644 index 0000000..6fc06d3 --- /dev/null +++ b/include/math.h @@ -0,0 +1,257 @@ +#ifndef _MATH_H_ +#define _MATH_H_ + +#define HUGE_VAL (__builtin_huge_val()) + +#ifdef __cplusplus +extern "C" +{ +#endif + + // trig stuff + + double cos(double x); + float cosf(float x); + long double cosl(long double x); + + double sin(double x); + float sinf(float x); + long double sinl(long double x); + + double tan(double x); + float tanf(float x); + long double tanl(long double x); + + double acos(double x); + float acosf(float x); + long double acosl(long double x); + + double asin(double x); + float asinf(float x); + long double asinl(long double x); + + double atan(double x); + float atanf(float x); + long double atanl(long double x); + + double cosh(double x); + float coshf(float x); + long double coshl(long double x); + + double sinh(double x); + float sinhf(float x); + long double sinhl(long double x); + + double tanh(double x); + float tanhf(float x); + long double tanhl(long double x); + + double acosh(double x); + float acoshf(float x); + long double coshl(long double x); + + double asinh(double x); + float asinhf(float x); + long double asinhl(long double x); + + double atanh(double x); + float atanhf(float x); + long double atanhl(long double x); + + // exp stuff + + double fac(double x); + float facf(float x); + long double facl(long double x); + + double exp(double x); + float expf(float x); + long double expl(long double x); + + double frexp(double x, int *exp); + float frexpf(float x, int *exp); + long double frexpl(long double x, int *exp); + + double ldexp(double x, int exp); + float ldexpf(float x, int exp); + long double ldexpl(long double x, int exp); + + double log(double x); + float logf(float x); + long double logl(long double x); + + double log10(double x); + float log10f(float x); + long double log10l(long double x); + + double modf(double x, double *intpart); + float modff(float x, float *intpart); + long double modfl(long double x, long double *intpart); + + double exp2(double x); + float exp2f(float x); + long double exp2l(long double x); + + double expm1(double x); + float expm1f(float x); + long double expm1l(long double x); + + int ilogb(double x); + int ilogbf(float x); + int ilogbl(long double x); + + double log1p(double x); + float log1pf(float x); + long double log1pl(long double x); + + double log2(double x); + float log2f(float x); + long double log2l(long double x); + + double logb(double x); + float logbf(float x); + long double logbl(long double x); + + double scalbn(double x, int n); + float scalbnf(float x, int n); + long double scalbnl(long double x, int n); + + double scalbln(double x, long int n); + float scalblnf(float x, long int n); + long double scalblnl(long double x, long int n); + + // pow stuff + + double pow(double base, double exponent); + float powf(float base, float exponent); + long double powl(long double base, long double exponent); + + double sqrt(double x); + float sqrtf(float x); + long double sqrtl(long double x); + + double cbrt(double x); + float cbrtf(float x); + long double cbrtl(long double x); + + double hypot(double x, double y); + float hypotf(float x, float y); + long double hypotl(long double x, long double y); + + // gamma stuff + + double erf(double x); + float erff(float x); + long double erfl(long double x); + + double erfc(double x); + float erfcf(float x); + long double erfcl(long double x); + + double tgamma(double x); + float tgammaf(float x); + long double tgammal(long double x); + + double lgamma(double x); + float lgammaf(float x); + long double lgammal(long double x); + + // rounding stuff + + double ceil(double x); + float ceilf(float x); + long double ceill(long double x); + + double floor(double x); + float floorf(float x); + long double floorl(long double x); + + double fmod(double numer, double denom); + float fmodf(float numer, float denom); + long double fmodl(long double numer, long double denom); + + double trunc(double x); + float truncf(float x); + long double truncl(long double x); + + double round(double x); + float roundf(float x); + long double roundl(long double x); + + long int lround(double x); + long int lroundf(float x); + long int lroundl(long double x); + + long long int llround(double x); + long long int llroundf(float x); + long long int llroundl(long double x); + + double rint(double x); + float rintf(float x); + long double rintl(long double x); + + long int lrint(double x); + long int lrintf(float x); + long int lrintl(long double x); + + long long int llrint(double x); + long long int llrintf(float x); + long long int llrintl(long double x); + + double nearbyint(double x); + float nearbyintf(float x); + long double nearbyintl(long double x); + + double remainder(double numer, double denom); + float remainderf(float numer, float denom); + long double remainderl(long double numer, long double denom); + + double remquo(double numer, double denom, int *quot); + float remquof(float numer, float denom, int *quot); + long double remquol(long double numer, long double denom, int *quot); + + // float stuff + + double copysign(double x, double y); + float copysignf(float x, float y); + long double copysignl(long double x, long double y); + + double nan(const char *tagp); + + double nextafter(double x, double y); + float nextafterf(float x, float y); + long double nextafterl(long double x, long double y); + + double nexttoward(double x, long double y); + float nexttowardf(float x, long double y); + long double nexttowardl(long double x, long double y); + + // min stuff + + double fdim(double x, double y); + float fdimf(float x, float y); + long double fdiml(long double x, long double y); + + double fmax(double x, double y); + float fmaxf(float x, float y); + long double fmaxl(long double x, long double y); + + double fmin(double x, double y); + float fminf(float x, float y); + long double fminl(long double x, long double y); + + // other stuff + + double fabs(double x); + float fabsf(float x); + long double fabsl(long double x); + + double fma(double x, double y, double z); + float fmaf(float x, float y, float z); + long double fmal(long double x, long double y, long double z); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/stdio.h b/include/stdio.h new file mode 100644 index 0000000..b3e666e --- /dev/null +++ b/include/stdio.h @@ -0,0 +1,63 @@ +#ifndef _STDIO_H_ +#define _STDIO_H_ + +#define _IOFBF 1 +#define _IOLBF 2 +#define _IONBF 4 +#define BUFSIZ 4096 + +#ifdef __cplusplus +extern "C" +{ +#endif + +#define __need_size_t +#include +#include +#include + +#define SEEK_SET 0 /*unspecified*/ +#define SEEK_CUR 1 /*unspecified*/ +#define SEEK_END 2 /*unspecified*/ + + typedef int FILE; + + extern const int fd_stdin; + extern const int fd_stdout; + extern const int fd_stderr; + +#define stdin &fd_stdin +#define stdout &fd_stdout +#define stderr &fd_stderr + + static const int EOF = -1; // MACRO??? + + int getchar(); + int printf(const char *format, ...); + int scanf(const char *format, ...); + char *fgets(char *str, int n, FILE *stream); + int fgetc(FILE *stream); + static inline int getc(FILE *stream) { return fgetc(stream); }; + int fputc(int ch, FILE *stream); // TODO + static inline int putc(int ch, FILE *stream) { return fputc(ch, stream); }; + long ftell(FILE *stream); + int fseek(FILE *stream, long offset, int origin); + int fprintf(FILE *stream, const char *format, ...); + int sprintf(char *dest, const char *format, ...); + int vfprintf(FILE *stream, const char *format, va_list arg); + int vprintf(const char *format, va_list arg); + int vsprintf(char *s, const char *format, va_list arg); + int vsnprintf(char *s, size_t n, const char *format, va_list arg); + int snprintf(char *s, size_t n, const char *format, ...); + + int sscanf(const char *ibuf, const char *fmt, ...); + int vsscanf(const char *inp, char const *fmt0, va_list ap); + int fscanf(FILE *stream, const char *format, ...); + int vfscanf(FILE *stream, const char *format, va_list arg); + + int mkdir(const char *pathname); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/stdlib.h b/include/stdlib.h new file mode 100644 index 0000000..28a078d --- /dev/null +++ b/include/stdlib.h @@ -0,0 +1,45 @@ +#ifndef CROS_STDLIB_H +#define CROS_STDLIB_H + +#include +#include "stdio.h" + +#ifdef __cplusplus +extern "C" { +#endif + +int dup(int fd); +int dup2(int oldfd, int newfd); // I NEED dup2() FOR THE SHELL -connor +int fork(); // TODO: +int wait(int *addr); // TODO: +void exit(int status); // TODO: + +FILE *fopen(const char *filename, const char *mode); // TODO: +int *fclose(FILE *stream); // TODO: + +void* malloc(size_t size); +void* realloc(void* ptr, size_t size); +void free(void* ptr); + +int rand(void); +void srand(unsigned int seed); + +//conversions +double atof (const char* str); +long int atol (const char* str); +long long atoll (const char * str); +int atoi (const char * str); + +double strtod (const char* str, char** endptr); +float strtof (const char* str, char** endptr); +long double strtold (const char* str, char** endptr); +long int strtol (const char* str, char** endptr, int base); +long long int strtoll (const char* str, char** endptr, int base); +unsigned long int strtoul (const char* str, char** endptr, int base); +unsigned long long int strtoull (const char* str, char** endptr, int base); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/string b/include/string new file mode 100644 index 0000000..7626ec8 --- /dev/null +++ b/include/string @@ -0,0 +1,54 @@ +#ifndef STRING_H +#define STRING_H +#include + +namespace std { + +class string { + public: + string(); + string(const char* other); + string(const string& other); + ~string(); + int size() const; + size_t find(const string& str, size_t pos = 0) const; + string& erase(size_t pos, size_t len); + + bool operator==(const string& other) const; + bool operator!=(const string& other) const; + + string& operator=(char c); + string& operator=(const char* other); + string& operator=(const string& other); + string operator+(char other) const; + string operator+(const char* other) const; + string operator+(const string& other) const; + string& operator+=(char c); + string& operator+=(const char* other); + string& operator+=(const string& other); + + const char& operator[](int index) const; + + const char* c_str() const; + + string substr(int start_index) const; + string substr(int start_index, int end_index) const; + + static bool strcmp(const char* first, const char* second); // differs from standard implemtation + static char* substr(const char* str, int start_index); + static char* substr(const char* str, int start_index, int end_index); + static char* strdup(const char* s); + static void strcpy(char*& dest, const char* src); // differs from standard implemtation, allocates more memory in destination string if its not big enough + static void strncpy(char*& dest, const char* src, int len); // ^ + static void strcat(char*& dest, const char* src); // ^ + static int strlen(const char* s); // doesn't include the null-terminator + + static const size_t npos = -1; + + private: + char* s; +}; + +} // namespace std + +#endif \ No newline at end of file diff --git a/include/string.h b/include/string.h new file mode 100644 index 0000000..477b575 --- /dev/null +++ b/include/string.h @@ -0,0 +1,41 @@ +#ifndef _STRING_H +#define _STRING_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void *memcpy(void *dest, const void *src, size_t n); +void *memmove(void *dest, const void *src, size_t n); +int memcmp(const void *ptr1, const void *ptr2, size_t n); +void *memset(void *ptr, int value, size_t num); + +char *strcpy(char *dest, const char *src); +char *strncpy(char *dest, const char *src, size_t n); +int strcmp(const char *str1, const char *str2); +int strncmp(const char *str1, const char *str2, size_t n); +char *strcat(char *dest, const char *src); +char *strncat(char *dest, const char *src, size_t n); +size_t strlen(const char *str); + +// useless stuff + +int strcoll(const char *str1, const char *str2); +size_t strxfrm(char *dest, const char *src, size_t n); +const void *memchr(const void *ptr, int val, size_t n); +const char *strchr(const char *str, int c); +size_t strcspn(const char *str1, const char *str2); +const char *strpbrk(const char *str1, const char *str2); +const char *strrchr(const char *str, int c); +size_t strspn(const char *str1, const char *str2); +const char *strstr(const char *str1, const char *str2); +char *strtok(char *str, const char *delims); +char *strerror(int errnum); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/time.h b/include/time.h new file mode 100644 index 0000000..416fca7 --- /dev/null +++ b/include/time.h @@ -0,0 +1,27 @@ +#ifndef _TIME_H +#define _TIME_H +/*#ifdef __cplusplus +extern "C"{ +#endif + +#include + +typedef unsigned long time_t; + +struct Time_Structure { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; +} typedef tm; + +time_t time (time_t* timer); +}*/ + + +#endif \ No newline at end of file diff --git a/include/unistd.h b/include/unistd.h new file mode 100644 index 0000000..830a3c7 --- /dev/null +++ b/include/unistd.h @@ -0,0 +1,25 @@ +#ifndef _UNISTD_H +#define _UNISTD_H + +#include +#ifdef __cplusplus +extern "C" +{ +#endif + +#include + + int execve(const char *path, char *argv[], + char const *envp[]); + int execvp(const char *file, char const *argv[]); + int *getcwd(char *, size_t); + int close(int fd); + int open(int fd); + int chdir(const char *path); + int pipe(int fildes[2]); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/include/vector b/include/vector new file mode 100644 index 0000000..4179741 --- /dev/null +++ b/include/vector @@ -0,0 +1,191 @@ +#ifndef VECTOR_H +#define VECTOR_H + +#include +#include + +inline void *operator new(size_t, void *p) throw() +{ + return p; +} + +inline void *operator new[](size_t, void *p) throw() +{ + return p; +} + +inline void operator delete(void *, void *) throw() +{ +} + +inline void operator delete[](void *, void *) throw() +{ +} + +namespace std +{ + + template + class vector + { + public: + vector(); + vector(int capacity); + vector(const vector &other); + ~vector(); + + bool empty() const; + int size() const; + int capacity() const; + + void push_back(const T &data); + void pop_back(); + T &back(); + T &front(); + void remove(int index); + + void clear(); + void resize(int new_capacity); + + T &operator[](int index) const; + + private: + T *array; + int _capacity; + int _size; + }; + + template + vector::vector() + { + _size = 0; + _capacity = 8; + array = malloc(sizeof(T) * _capacity); + memset((void *)array, 0, sizeof(T) * _capacity); + // array = new T[_capacity]; + } + + template + vector::vector(int capacity) + { + _size = 0; + _capacity = capacity; + array = malloc(sizeof(T) * _capacity); + memset((void *)array, 0, sizeof(T) * _capacity); + // array = new T[_capacity]; + } + + template + vector::vector(const vector &other) + { + _size = other.size(); + _capacity = other.capacity(); + array = malloc(sizeof(T) * _capacity); + memset((void *)array, 0, sizeof(T) * _capacity); + // array = new T[_capacity]; + for (int i = 0; i < _size; i++) + array[i] = other[i]; + } + + template + vector::~vector() + { + for (int i = 0; i < _size; i++) + { + array[i].~T(); + } + free(array); + // if (array != nullptr) + // delete[] array; + } + + template + bool vector::empty() const + { + return _size == 0; + } + + template + int vector::size() const + { + return _size; + } + + template + int vector::capacity() const + { + return _capacity; + } + + template + T &vector::operator[](int index) const + { + return array[index]; + } + + template + void vector::push_back(const T &data) + { + if (_size == _capacity) + resize(_capacity * 2); + new (&array[_size]) T(data); + // array[_size] = data; + _size++; + } + + template + void vector::pop_back() + { + array[_size - 1].~T(); + _size--; + } + + template + T &vector::back() + { + return array[_size - 1]; + } + + template + T &vector::front() + { + return array[0]; + } + + template + void vector::remove(int index) + { + while (index < _size - 1) + { + array[index] = array[index + 1]; + index++; + } + pop_back(); + } + + template + void vector::clear() + { + for (int i = 0; i < _size; i++) + array[i].~T(); + _size = 0; + } + + template + void vector::resize(int new_capacity) + { + _capacity = new_capacity; + // T *temp = new T[_capacity]; + T *temp = malloc(sizeof(T) * _capacity); + memset((void *)temp, 0, sizeof(T) * _capacity); + for (int i = 0; i < _size; i++) + { + new (&temp[i]) T(array[i]); + // temp[i] = array[i]; + } + // delete[] array; + free(array); + array = temp; + } +} +#endif \ No newline at end of file diff --git a/include/wait.h b/include/wait.h new file mode 100644 index 0000000..e69de29 diff --git a/main.c b/main.c new file mode 100644 index 0000000..505c716 --- /dev/null +++ b/main.c @@ -0,0 +1,7 @@ +#include +#include "include/math.h" + +int main() { + printf("acosh(%f): %f\n", 5.0, acosh(5.0)); + return 0; +} \ No newline at end of file diff --git a/src/aarch64/crt0.s b/src/aarch64/crt0.s new file mode 100644 index 0000000..4d4699f --- /dev/null +++ b/src/aarch64/crt0.s @@ -0,0 +1,29 @@ + +.section .text +.extern uinit +.extern main +.type _start, "function" +.global _start +_start: + stp x0, x1, [sp, #-16]! + stp x2, x3, [sp, #-16]! + bl uinit + ldp x2, x3, [sp], #16 + ldp x0, x1, [sp], #16 + bl main + mov x0, #4 + svc #0 +_stop: + b _stop + +//char "/init\0" +init: + .string "/uinit\0" + + +// argv {init, 0} +.p2align 2 +argv: + .long init + .long 0 + diff --git a/src/dirent.c b/src/dirent.c new file mode 100644 index 0000000..a617b16 --- /dev/null +++ b/src/dirent.c @@ -0,0 +1,45 @@ +#include "dirent.h" +#include + +int alphasort(const struct dirent **, const struct dirent **) { + printf("Not implemented"); + return 0; +} +int closedir(DIR *) { + printf("Not implemented"); + return 0; +} +int dirfd(DIR *) { + printf("Not implemented"); + return 0; +} +DIR *fdopendir(int) { + printf("Not implemented"); + return NULL; +} +DIR *opendir(const char *) { + printf("Not implemented"); + return NULL; +} +struct dirent *readdir(DIR *) { + printf("Not implemented"); + return NULL; +} +int readdir_r(DIR *restrict, struct dirent *restrict, struct dirent **restrict) { + printf("Not implement"); + return NULL; +} +void rewinddir(DIR *) { + printf("Not implemented"); +} +int scandir(const char *, struct dirent ***, int (*)(const struct dirent *), int (*)(const struct dirent **, const struct dirent **)) { + printf("Not implemented"); + return 0; +} +void seekdir(DIR *, long) { + printf("Not implemented"); +} +long telldir(DIR *) { + printf("Not implemented"); + return 0; +} \ No newline at end of file diff --git a/src/execve.c b/src/execve.c new file mode 100644 index 0000000..9a62065 --- /dev/null +++ b/src/execve.c @@ -0,0 +1,32 @@ +#include "unistd.h" +#include "string.h" +#include + +int execve(const char *path, char *argv[], char const *envp[]) +{ + static char s[256]; + strcpy(s, "/bin/"); + strcat(s, path); + + // Try searching in /bin + exec(s, argv, envp); + + // If that doesn't work, treat 'path' as absolute path + exec(path, argv, envp); + return 0; +} + +int execvp(const char *path, const char *argv[]) +{ + const char *envp[] = {NULL}; + static char s[256]; + strcpy(s, "/bin/"); + strcat(s, path); + + // Try searching in /bin + exec(s, argv, envp); + + // If that doesn't work, treat 'path' as absolute path + exec(path, argv, envp); + return 0; +} \ No newline at end of file diff --git a/src/fork.c b/src/fork.c new file mode 100644 index 0000000..bc70665 --- /dev/null +++ b/src/fork.c @@ -0,0 +1,9 @@ +#include "stdlib.h" + +/*started by kyle Clements + this is all kernal. we can use this as a wrapper if needed*/ +int fork(){ + + //can replace the below line with return fork() for the system call + return 0; +} \ No newline at end of file diff --git a/src/getcwd.c b/src/getcwd.c new file mode 100644 index 0000000..b54ccf3 --- /dev/null +++ b/src/getcwd.c @@ -0,0 +1,10 @@ +#include "stdlib.h" + +//started by Kyle Clements +//small problem, this would normally require us to look into the file system to see where we are. +//kernal does not track user space + +char * getcwd(char *buffer, long size){ + char *pwd; + return buffer; +} \ No newline at end of file diff --git a/src/heap/heap.c b/src/heap/heap.c new file mode 100644 index 0000000..1ac6938 --- /dev/null +++ b/src/heap/heap.c @@ -0,0 +1,299 @@ +/* +Coded by Sam Lane +Adapted by Connor Persels + +Sources: + http://dmitrysoshnikov.com/compilers/writing-a-memory-allocator/ + http://www.osdever.net/tutorials/view/memory-management-2 + https://moss.cs.iit.edu/cs351/slides/slides-malloc.pdf + https://danluu.com/malloc-tutorial/ + +*/ +#include "heap.h" +#include "string.h" +#include + +unsigned long *heap; +unsigned long *linked_list_start = + NULL; // Actually last block in heap, but start of ll +unsigned long *search_start = NULL; // Set at start of search, don't maintain +unsigned long *search_previous = NULL; // Must maintain for search +unsigned long *search_current = NULL; // Must maintain for search +unsigned long *heap_end = NULL; +// unsigned long num_free_blocks; + +void init_heap(void *heap_ptr, unsigned long mem_size) { + int overhead_adj_size = mem_size - (WORD_SIZE * OVERHEAD); + heap = (unsigned long *)heap_ptr; + heap[0] = overhead_adj_size / SIZE_T_SIZE; // Header size var + heap[1] = (unsigned long)NULL; + heap[2] = 0; // Header flag var + heap[(mem_size / SIZE_T_SIZE) - 2] = heap[0]; + heap[(mem_size / SIZE_T_SIZE) - 1] = heap[1]; + linked_list_start = search_start = search_current = heap; + // num_free_blocks = 1; + heap_end = &heap[(mem_size / SIZE_T_SIZE)]; +} + +void expand_heap(unsigned long size) { + unsigned long new_size = size * size; + if (new_size <= 4096) { + new_size = 4096; + } + mmap(heap_end, new_size, 1); + + heap_end = heap_end + new_size; + rebuild_list(search_current); +} + +unsigned long *split_blk(unsigned long size, unsigned long *blk_to_split) { + unsigned long *return_block = blk_to_split; + unsigned long *split_block = + blk_to_split + (size / SIZE_T_SIZE) + + OVERHEAD; // Current address + size + overhead to get address of new block + + split_block[0] = + blk_to_split[0] - (size / SIZE_T_SIZE) - OVERHEAD; // Set header size + split_block[1] = blk_to_split[1]; // What ever blk_to_split points to, split + // block now points to + split_block[2] = 0; // Flag + split_block[split_block[0] + OVERHEAD - 2] = + split_block[0]; // Set footer size + split_block[split_block[0] + OVERHEAD - 1] = 0; // Set footer flag + + // Maintain Linked list pointers + if (search_previous && search_previous[1]) { + search_previous[1] = (unsigned long)split_block; + } + if (blk_to_split == linked_list_start) { + linked_list_start = split_block; + } + if (blk_to_split == search_previous) { + search_previous = split_block; + } + if (blk_to_split == search_current) { + search_current = split_block; + } + return_block[0] = size / SIZE_T_SIZE; // Set header size + return_block[1] = 0; // Reset next address to null + return_block[2] = 1; // Set flag + return_block[return_block[0] + OVERHEAD - 2] = + return_block[0]; // Setting footer size + return_block[return_block[0] + OVERHEAD - 1] = 1; // Setting footer flag + + return &return_block[3]; +} + +unsigned long *find_fit(unsigned long size) { + search_start = search_current; + do { + if ((search_current[0] * SIZE_T_SIZE) == + size + OVERHEAD) { // Block is correct size, use it + unsigned long *return_block = search_current; + if (search_previous && search_current != search_start) { + search_previous[1] = return_block[1]; // Update linked list, removing + // search next as it is now in use + } + search_current = + (unsigned long *)return_block[1]; // Go to next block for future calls + return_block[2] = 1; // Set flag + return_block[return_block[0] + 2] = 1; // Set footer flag + return &return_block[3]; // Return address of start of useable memory + } else if ((search_current[0] * SIZE_T_SIZE) > + ALIGN(size + ((OVERHEAD + 1) * SIZE_T_SIZE * + 2))) { // Block is oversized, split + return split_blk(size, search_current); + } else if (search_current[1]) { // Block is not right size and not end of + // linked list, iterate + search_previous = search_current; + search_current = (unsigned long *)search_current[1]; + } else { // End of list, go to start and iterate + search_previous = search_current; + search_current = linked_list_start; + } + } while (search_previous && search_start != search_current && + search_current < heap_end); + + return NULL; // Failed to find block big enough +} +void *malloc_heap(unsigned long size) { + unsigned long blk_size = ALIGN(size); + unsigned long *block = find_fit(blk_size); + if (!block) { // Out of space, request more; + expand_heap(size); + block = find_fit(blk_size); // Try allocation again + if (!block) { + return NULL; // Panic, mem expansion failed + } + } + return block; +} + +void rebuild_list(unsigned long *current) { + unsigned long *ll_cur, *ll_prev; + ll_prev = linked_list_start; // First block in ll + ll_cur = heap; // First block in physical mem + + // Rebuild ll WATCHME High computation since traversing whole ll? + while (ll_cur < heap_end) { + while (ll_cur[2] != 0) { + ll_cur = ll_cur + ll_cur[0] + OVERHEAD; // Start of next block + } + if (ll_cur != linked_list_start) { + if (ll_cur == current) { // Set previous and current + search_previous = ll_prev; + search_current = ll_cur; + } + ll_prev[1] = (unsigned long)ll_cur; + ll_prev = ll_cur; + ll_cur = ll_cur + ll_cur[0] + OVERHEAD; // Start of next block + } else { + break; // End of heap + } + } + if (current == linked_list_start && + linked_list_start[1]) { // Edge Case when linked_list_start is + search_previous = linked_list_start; + search_current = (unsigned long *)linked_list_start[1]; + } + ll_prev[1] = 0; // End of list, set next addr to 0 so list doesn't loop +} + +void merge(unsigned long *current) { + unsigned long *previous, *next, *ll_cur, *ll_prev; + previous = next = NULL; + + if(current != heap){ + if ((current - 1)[0] == 0) + { // Previous block is free, merge + previous = (current - ((current - 2)[0] + OVERHEAD)); + } + } + + if ((current + current[0] + OVERHEAD + 2)[0] == 0 && + (current + current[0] + OVERHEAD + 2) < + heap_end) { // Next block is free, merge NOTE 2 to get to the flag on + // the next block + next = (current + current[0] + OVERHEAD); + } + + if (previous) { // Merge previous + previous[0] = previous[0] + current[0] + OVERHEAD; // Set size + current[1] = 0; // NOTE Not required, just cleans up heap for debugging + + if (current == + linked_list_start) { // Need to maintain, otherwise rebuild will fail, + // all other pointers set in rebuild + linked_list_start = previous; + } + + if (current == search_current) { + search_current = previous; + } + + previous[previous[0] + OVERHEAD - 2] = + previous[0]; // Set footer size, flag is already set + current = previous; // Set this incase next is also being merged + // num_free_blocks--; + } + + if (next) { // Merge next + current[0] = current[0] + next[0] + OVERHEAD; // Set size + next[1] = 0; // NOTE Not required, just cleans up heap + if (next == linked_list_start) { // Need to maintain, otherwise rebuild will + // fail, all other pointers set in rebuild + linked_list_start = current; + } + + if (next == search_current) { + search_current = current; + } + + current[current[0] + OVERHEAD - 2] = + current[0]; // Set footer size, flag is already set + // num_free_blocks--; + } + + if (previous || next) { // Only rebuild list if merge occured + rebuild_list(current); + } +} + +void free_heap(void *ptr) { + unsigned long *blk_free = + (unsigned long *)ptr - + 3; // Subtract 3 to get from start of data field to start of header + blk_free[2] = 0; // Set flag + blk_free[blk_free[0] + OVERHEAD - 1] = 0; // Set footer flag + // Insert into linked list + if (search_previous) { // Already a list, insert + blk_free[1] = + search_previous[1]; // search_previous-> blk_free -> search_next + search_previous[1] = (unsigned long)blk_free; + } else { // No list, start one + search_previous = linked_list_start; + search_previous[1] = (unsigned long)blk_free; + } + search_current = blk_free; + + // num_free_blocks++; + // Check for merging + merge(blk_free); +} + +void *realloc_heap(void *ptr, unsigned long new_size) { + unsigned long *return_blk, *blk_old; + int flag = 1; // Tries mem expansion twice before failing + blk_old = (unsigned long *)ptr - + 3; // Subtract 3 to get from start of data field to start of header + + if (!ptr) { // If pointer null, same as malloc + return malloc_heap(new_size); + } else if (blk_old[0] > + new_size + OVERHEAD + + 1) { // Need to shrink and free FIXME Potential Fragmentation, + // merge not called on freed block + return_blk = split_blk(new_size, blk_old); + rebuild_list(return_blk); + return return_blk; + } + // Need to expand, check if space in current heap + do { // CLEANME + return_blk = find_fit(new_size); + if (return_blk) { // Found space in current heap, copy data; + memcpy(return_blk, ptr, blk_old[0]); + } + // No mem left, expand + expand_heap(new_size); + flag--; + } while (flag >= 0); + + return NULL; // Panic, expansion failed +} + +/*Debug Fuctions*/ + +uint64_t xorshift64(uint64_t state) // Psuedo Random Number Generator +{ + uint64_t x = state; + x ^= x << 13; + x ^= x >> 7; + x ^= x << 17; + return state = x; +} + +uint64_t randinrange(uint64_t lower, uint64_t upper, uint64_t rand) { + return (rand % (upper - lower + 1)) + lower; +} + +void debug_bounds_check(unsigned long *a, unsigned long *b, uint64_t size_b) { + unsigned long *blk1 = a - 3; + unsigned long *blk2 = b - 3; + if (blk1 == blk2) { + return; + } + if (blk1 >= blk2 && blk1 < blk2 + size_b) { + while (1) { + } + } +} diff --git a/src/heap/heap.h b/src/heap/heap.h new file mode 100644 index 0000000..91e0a79 --- /dev/null +++ b/src/heap/heap.h @@ -0,0 +1,36 @@ +#ifndef _KERNEL_HEAP_H +#define _KERNEL_HEAP_H + +#include +#include "string.h" +#include + +#define WORD_SIZE sizeof(unsigned long) // Either 4 or 8, we're 64 bit so 8 +#define OVERHEAD 5 +#define ALIGN(size) (((size) + (WORD_SIZE - 1)) & ~(WORD_SIZE - 1)) +#define SIZE_T_SIZE (ALIGN(sizeof(unsigned long))) // header size + +void init_heap(void *heap_ptr, unsigned long mem_size); + +void *malloc_heap(unsigned long size); + +void free_heap(void *ptr); + +void rebuild_list(unsigned long *current); + +void *realloc_heap(void *, unsigned long new_size); + +// Testing functions +#define SIZE 30 + +void debug_bounds_check(unsigned long *a, unsigned long *b, uint64_t size_b); +uint64_t xorshift64(uint64_t state); +uint64_t randinrange(uint64_t lower, uint64_t upper, uint64_t rand); + +struct test_struct +{ + unsigned long *pointer; + int size; +}; + +#endif diff --git a/src/math.c b/src/math.c new file mode 100644 index 0000000..4b69130 --- /dev/null +++ b/src/math.c @@ -0,0 +1,1078 @@ +#include "math.h" +#include + +double fac(double x); +float facf(float x); +long double facl(long double x); + +// trig stuff + +double cos(double x) { + double result = 0.0; + int sign = 1; + for (int i = 0; i < 15; i++) { + result += sign * pow(x, 2 * i) / fac(2 * i); + sign *= -1; + } + return result; +} + +float cosf(float x) { + float result = 0.0f; + int sign = 1; + for (int i = 0; i < 10; i++) { + result += sign * powf(x, 2 * i) / facf(2 * i); + sign *= -1; + } + return result; +} + +long double cosl(long double x) { + long double result = 0.0; + int sign = 1; + for (int i = 0; i < 20; i++) { + result += sign * powl(x, 2 * i) / facl(2 * i); + sign *= -1; + } + return result; +} + +double sin(double x) { + double result = 0.0; + int sign = 1; + for (int i = 0; i < 15; i++) { + result += sign * pow(x, 2 * i + 1) / fac(2 * i + 1); + sign *= -1; + } + return result; +} + +float sinf(float x) { + float result = 0.0f; + int sign = 1; + for (int i = 0; i < 10; i++) { + result += sign * powf(x, 2 * i + 1) / facf(2 * i + 1); + sign *= -1; + } + return result; +} + +long double sinl(long double x) { + long double result = 0.0; + int sign = 1; + for (int i = 0; i < 20; i++) { + result += sign * powl(x, 2 * i + 1) / facl(2 * i + 1); + sign *= -1; + } + return result; +} + +double tan(double x) { + return sin(x) / cos(x); +} + +float tanf(float x) { + return sinf(x) / cosf(x); +} + +long double tanl(long double x) { + return sinl(x) / cosl(x); +} + +double acos(double x) { + double result = 0.0; + int sign = -1; + for (int i = 0; i < 15; i++) { + result += sign * pow(x, i) / i; + sign *= -1; + } + return result; +} + +float acosf(float x) { + float result = 0.0f; + int sign = -1; + for (int i = 0; i < 10; i++) { + result += sign * powf(x, i) / i; + sign *= -1; + } + return result; +} + +long double acosl(long double x) { + long double result = 0.0; + int sign = -1; + for (int i = 0; i < 20; i++) { + result += sign * pow(x, i) / i; + sign *= -1; + } + return result; +} + +double asin(double x) { + double result = 0.0; + int sign = 1; + for (int i = 0; i < 15; i++) { + result += sign * pow(x, i) / i; + sign *= -1; + } + return result; +} + +float asinf(float x) { + float result = 0.0f; + int sign = 1; + for (int i = 0; i < 10; i++) { + result += sign * powf(x, i) / i; + sign *= -1; + } + return result; +} + +long double asinl(long double x) { + long double result = 0.0; + int sign = 1; + for (int i = 0; i < 20; i++) { + result += sign * pow(x, i) / i; + sign *= -1; + } + return result; +} + +double atan(double x) { + double result = 0; + int sign = 1; + double term = x; + for (int i = 1; i <= 15; i += 2) { + result += sign * term; + sign *= -1; + term *= x * x; + } + return result; +} + +float atanf(float x) { + float result = 0.0f; + int sign = 1; + float term = x; + for (int i = 1; i <= 10; i += 2) { + result += sign * term; + sign *= -1; + term *= x * x; + } + return result; +} + +long double atanl(long double x) { + long double result = 0; + int sign = 1; + long double term = x; + for (int i = 1; i <= 20; i += 2) { + result += sign * term; + sign *= -1; + term *= x * x; + } + return result; +} + +// double atan2(double x) { +// printf("el no implemento"); +// return 0; +// } + +// float atan2f(float x) { +// printf("el no implemento"); +// return 0; +// } + +// long double atan2l(long double x) { +// printf("el no implemento"); +// return 0; +// } + +double cosh(double x) { + double result = 1.0; + double term = 1.0; + for (int i = 1; i <= 15; i += 2) { + term *= x * x / ((i - 1) * i); + result += term; + } + return result; +} + +float coshf(float x) { + float result = 1.0f; + float term = 1.0f; + for (int i = 1; i <= 10; i += 2) { + term *= x * x / ((i - 1) * i); + result += term; + } + return result; +} + +long double coshl(long double x) { + long double result = 1.0; + long double term = 1.0; + for (int i = 1; i <= 20; i += 2) { + term *= x * x / ((i - 1) * i); + result += term; + } + return result; +} + +double sinh(double x) { + double result = x; + double term = x; + for (int i = 1; i <= 15; i += 2) { + term *= x * x / ((i + 1) * i); + result += term; + } + return result; +} + +float sinhf(float x) { + float result = x; + float term = x; + for (int i = 1; i <= 10; i += 2) { + term *= x * x / ((i + 1) * i); + result += term; + } + return result; +} + +long double sinhl(long double x) { + long double result = x; + long double term = x; + for (int i = 1; i <= 20; i += 2) { + term *= x * x / ((i + 1) * i); + result += term; + } + return result; +} + +double tanh(double x) { + return sinh(x) / cosh(x); +} + +float tanhf(float x) { + return sinhf(x) / coshf(x); +} + +long double tanhl(long double x) { + return sinhl(x) / coshl(x); +} + +double acosh(double x) { + return log(x + sqrt(x * x - 1)); +} + +float acoshf(float x) { + return logf(x + sqrtf(x * x - 1)); +} + +long double acoshl(long double x) { + return logl(x + sqrtl(x * x - 1)); +} + +double asinh(double x) { + return log(x + sqrt(x * x + 1)); +} + +float asinhf(float x) { + return logf(x + sqrtf(x * x + 1)); +} + +long double asinhl(long double x) { + return logl(x + sqrtl(x * x + 1)); +} + +double atanh(double x) { + return 0.5 * log((1 + x) / (1 - x)); +} + +float atanhf(float x) { + return 0.5 * logf((1 + x) / (1 - x)); +} + +long double atanhl(long double x) { + return 0.5 * logl((1 + x) / (1 - x)); +} + +// exp stuff + +double fac(double x) { + if (x == 0) + return 1; + return x * fac(x - 1); +} + +float facf(float x) { + if (x == 0) + return 1; + return x * facf(x - 1); +} + +long double facl(long double x) { + if (x == 0) + return 1; + return x * facl(x - 1); +} + +double exp(double x) { + double result = 0.0; + for (int i = 0; i < 15; i++) { + result += pow(x, i) / fac(i); + } + return result; +} + +float expf(float x) { + float result = 0.0f; + for (int i = 0; i < 10; i++) { + result += powf(x, i) / facf(i); + } + return result; +} + +long double expl(long double x) { + long double result = 0.0; + for (int i = 0; i < 20; i++) { + result += pow(x, i) / fac(i); + } + return result; +} + +double frexp(double x, int* exp) { + printf("el no implemento"); + return 0; +} + +float frexpf(float x, int* exp) { + printf("el no implemento"); + return 0; +} + +long double frexpl(long double x, int* exp) { + printf("el no implemento"); + return 0; +} + +double ldexp(double x, int exp) { + printf("el no implemento"); + return 0; +} + +float ldexpf(float x, int exp) { + printf("el no implemento"); + return 0; +} + +long double ldexpl(long double x, int exp) { + printf("el no implemento"); + return 0; +} + +double log(double x) { + if (x <= 0) + return 0.0; + double result = 0.0; + int sign = 1; + for (int i = 1; i <= 15; i++) { + result += sign * pow(x - 1, i) / i; + sign *= -1; + } + return result; +} + +float logf(float x) { + if (x <= 0) + return 0.0; + float result = 0.0f; + int sign = 1; + for (int i = 1; i <= 10; i++) { + result += sign * powf(x - 1, i) / i; + sign *= -1; + } + return result; +} + +long double logl(long double x) { + if (x <= 0) + return 0.0; + long double result = 0.0; + int sign = 1; + for (int i = 1; i <= 20; i++) { + result += sign * powl(x - 1, i) / i; + sign *= -1; + } + return result; +} + +double log10(double x) { + return log(x) / log(10); +} + +float log10f(float x) { + return logf(x) / logf(10); +} + +long double log10l(long double x) { + return logl(x) / logl(10); +} + +double modf(double x, double* intpart) { + printf("el no implemento"); + return 0; +} + +float modff(float x, float* intpart); +long double modfl(long double x, long double* intpart) { + printf("el no implemento"); + return 0; +} + +double exp2(double x) { + printf("el no implemento"); + return 0; +} + +float exp2f(float x) { + printf("el no implemento"); + return 0; +} + +long double exp2l(long double x) { + printf("el no implemento"); + return 0; +} + +double expm1(double x) { + printf("el no implemento"); + return 0; +} + +float expm1f(float x) { + printf("el no implemento"); + return 0; +} + +long double expm1l(long double x) { + printf("el no implemento"); + return 0; +} + +int ilogb(double x) { + printf("el no implemento"); + return 0; +} + +int ilogbf(float x) { + printf("el no implemento"); + return 0; +} + +int ilogbl(long double x) { + printf("el no implemento"); + return 0; +} + +double log1p(double x) { + printf("el no implemento"); + return 0; +} + +float log1pf(float x) { + printf("el no implemento"); + return 0; +} + +long double log1pl(long double x) { + printf("el no implemento"); + return 0; +} + +double log2(double x) { + return log(x) / log(2); +} + +float log2f(float x) { + return logf(x) / logf(2); +} + +long double log2l(long double x) { + return logl(x) / logl(2); +} + +double logb(double x) { + printf("el no implemento"); + return 0; +} + +float logbf(float x) { + printf("el no implemento"); + return 0; +} + +long double logbl(long double x) { + printf("el no implemento"); + return 0; +} + +double scalbn(double x, int n) { + printf("el no implemento"); + return 0; +} + +float scalbnf(float x, int n) { + printf("el no implemento"); + return 0; +} + +long double scalbnl(long double x, int n) { + printf("el no implemento"); + return 0; +} + +double scalbln(double x, long int n) { + printf("el no implemento"); + return 0; +} + +float scalblnf(float x, long int n) { + printf("el no implemento"); + return 0; +} + +long double scalblnl(long double x, long int n) { + printf("el no implemento"); + return 0; +} + +// pow stuff + +double pow(double base, double exponent) { + double result = 1.0; + for (int i = 0; i < exponent; i++) + result *= base; + return result; +} + +float powf(float base, float exponent) { + float result = 1.0f; + for (int i = 0; i < exponent; i++) + result *= base; + return result; +} + +long double powl(long double base, long double exponent) { + long double result = 1.0; + for (int i = 0; i < exponent; i++) + result *= base; + return result; +} + +double sqrt(double x) { + if (x == 0) + return 0; + double guess = x / 2.0; + double prev_guess = x; + while (guess != prev_guess) { + prev_guess = guess; + guess = (guess + x / guess) / 2.0; + } + return guess; +} + +float sqrtf(float x) { + if (x == 0) + return 0; + float guess = x / 2.0; + float prev_guess = x; + while (guess != prev_guess) { + prev_guess = guess; + guess = (guess + x / guess) / 2.0; + } + return guess; +} + +long double sqrtl(long double x) { + if (x == 0) + return 0; + long double guess = x / 2.0; + long double prev_guess = x; + while (guess != prev_guess) { + prev_guess = guess; + guess = (guess + x / guess) / 2.0; + } + return guess; +} + +double cbrt(double x) { + if (x == 0) + return 0; + double guess = x / 3.0; + double prev_guess = x; + while (guess != prev_guess) { + prev_guess = guess; + guess = (2 * prev_guess + x / (prev_guess * prev_guess)) / 3.0; + } + return guess; +} + +float cbrtf(float x) { + if (x == 0) + return 0; + float guess = x / 3.0; + float prev_guess = x; + while (guess != prev_guess) { + prev_guess = guess; + guess = (2 * prev_guess + x / (prev_guess * prev_guess)) / 3.0; + } + return guess; +} + +long double cbrtl(long double x) { + if (x == 0) + return 0; + long double guess = x / 3.0; + long double prev_guess = x; + while (guess != prev_guess) { + prev_guess = guess; + guess = (2 * prev_guess + x / (prev_guess * prev_guess)) / 3.0; + } + return guess; +} + +double hypot(double x, double y) { + printf("el no implemento"); + return 0; +} + +float hypotf(float x, float y) { + printf("el no implemento"); + return 0; +} + +long double hypotl(long double x, long double y) { + printf("el no implemento"); + return 0; +} + +// gamma stuff + +double erf(double x) { + printf("el no implemento"); + return 0; +} + +float erff(float x) { + printf("el no implemento"); + return 0; +} + +long double erfl(long double x) { + printf("el no implemento"); + return 0; +} + +double erfc(double x) { + printf("el no implemento"); + return 0; +} + +float erfcf(float x) { + printf("el no implemento"); + return 0; +} + +long double erfcl(long double x) { + printf("el no implemento"); + return 0; +} + +double tgamma(double x) { + printf("el no implemento"); + return 0; +} + +float tgammaf(float x); +long double tgammal(long double x) { + printf("el no implemento"); + return 0; +} + +double lgamma(double x) { + printf("el no implemento"); + return 0; +} + +float lgammaf(float x) { + printf("el no implemento"); + return 0; +} + +long double lgammal(long double x) { + printf("el no implemento"); + return 0; +} + +// rounding stuff + +double ceil(double x) { + int result = (int)x; + if (x > 0 && x != result) + result++; + return (double)result; +} + +float ceilf(float x) { + int result = (int)x; + if (x > 0 && x != result) + result++; + return (float)result; +} + +long double ceill(long double x) { + int result = (int)x; + if (x > 0 && x != result) + result++; + return (long double)result; +} + +double floor(double x) { + int result = (int)x; + if (x < 0 && x != result) + result--; + return (double)result; +} + +float floorf(float x) { + int result = (int)x; + if (x < 0 && x != result) + result--; + return (float)result; +} + +long double floorl(long double x) { + int result = (int)x; + if (x < 0 && x != result) + result--; + return (long double)result; +} + +double fmod(double numer, double denom) { + printf("el no implemento"); + return 0; +} + +float fmodf(float numer, float denom) { + printf("el no implemento"); + return 0; +} + +long double fmodl(long double numer, long double denom) { + printf("el no implemento"); + return 0; +} + +double trunc(double x) { + printf("el no implemento"); + return 0; +} + +float truncf(float x) { + printf("el no implemento"); + return 0; +} + +long double truncl(long double x) { + printf("el no implemento"); + return 0; +} + +double round(double x) { + double result; + if (x >= 0) + result = (int)(x + 0.5); + else + result = (int)(x - 0.5); + return result; +} + +float roundf(float x) { + float result; + if (x >= 0) + result = (int)(x + 0.5); + else + result = (int)(x - 0.5); + return result; +} + +long double roundl(long double x) { + long double result; + if (x >= 0) + result = (int)(x + 0.5); + else + result = (int)(x - 0.5); + return result; +} + +long int lround(double x) { + if (x >= 0) + return (long int)(x + 0.5); + else + return (long int)(x - 0.5); +} + +long int lroundf(float x) { + if (x >= 0) + return (long int)(x + 0.5); + else + return (long int)(x - 0.5); +} + +long int lroundl(long double x) { + if (x >= 0) + return (long int)(x + 0.5); + else + return (long int)(x - 0.5); +} + +long long int llround(double x) { + if (x >= 0) + return (long long int)(x + 0.5); + else + return (long long int)(x - 0.5); +} + +long long int llroundf(float x) { + if (x >= 0) + return (long long int)(x + 0.5); + else + return (long long int)(x - 0.5); +} + +long long int llroundl(long double x) { + if (x >= 0) + return (long long int)(x + 0.5); + else + return (long long int)(x - 0.5); +} + +double rint(double x) { + printf("el no implemento"); + return 0; +} + +float rintf(float x) { + printf("el no implemento"); + return 0; +} + +long double rintl(long double x) { + printf("el no implemento"); + return 0; +} + +long int lrint(double x) { + printf("el no implemento"); + return 0; +} + +long int lrintf(float x) { + printf("el no implemento"); + return 0; +} + +long int lrintl(long double x) { + printf("el no implemento"); + return 0; +} + +long long int llrint(double x) { + printf("el no implemento"); + return 0; +} + +long long int llrintf(float x) { + printf("el no implemento"); + return 0; +} + +long long int llrintl(long double x) { + printf("el no implemento"); + return 0; +} + +double nearbyint(double x) { + printf("el no implemento"); + return 0; +} + +float nearbyintf(float x) { + printf("el no implemento"); + return 0; +} + +long double nearbyintl(long double x) { + printf("el no implemento"); + return 0; +} + +double remainder(double numer, double denom) { + printf("el no implemento"); + return 0; +} + +float remainderf(float numer, float denom) { + printf("el no implemento"); + return 0; +} + +long double remainderl(long double numer, long double denom) { + printf("el no implemento"); + return 0; +} + +double remquo(double numer, double denom, int* quot) { + printf("el no implemento"); + return 0; +} + +float remquof(float numer, float denom, int* quot) { + printf("el no implemento"); + return 0; +} + +long double remquol(long double numer, long double denom, int* quot) { + printf("el no implemento"); + return 0; +} + +// float stuff + +double copysign(double x, double y) { + printf("el no implemento"); + return 0; +} + +float copysignf(float x, float y) { + printf("el no implemento"); + return 0; +} + +long double copysignl(long double x, long double y) { + printf("el no implemento"); + return 0; +} + +double nan(const char* tagp) { + printf("el no implemento"); + return 0; +} + +double nextafter(double x, double y) { + printf("el no implemento"); + return 0; +} + +float nextafterf(float x, float y) { + printf("el no implemento"); + return 0; +} + +long double nextafterl(long double x, long double y) { + printf("el no implemento"); + return 0; +} + +double nexttoward(double x, long double y) { + printf("el no implemento"); + return 0; +} + +float nexttowardf(float x, long double y) { + printf("el no implemento"); + return 0; +} + +long double nexttowardl(long double x, long double y) { + printf("el no implemento"); + return 0; +} + +// min stuff + +double fdim(double x, double y) { + printf("el no implemento"); + return 0; +} + +float fdimf(float x, float y) { + printf("el no implemento"); + return 0; +} + +long double fdiml(long double x, long double y) { + printf("el no implemento"); + return 0; +} + +double fmax(double x, double y) { + printf("el no implemento"); + return 0; +} + +float fmaxf(float x, float y) { + printf("el no implemento"); + return 0; +} + +long double fmaxl(long double x, long double y) { + printf("el no implemento"); + return 0; +} + +double fmin(double x, double y) { + printf("el no implemento"); + return 0; +} + +float fminf(float x, float y) { + printf("el no implemento"); + return 0; +} + +long double fminl(long double x, long double y) { + printf("el no implemento"); + return 0; +} + +// other stuff + +double fabs(double x) { + return (x < 0) ? -x : x; +} + +float fabsf(float x) { + return (x < 0) ? -x : x; +} + +long double fabsl(long double x) { + return (x < 0) ? -x : x; +} + +double fma(double x, double y, double z) { + printf("el no implemento"); + return 0; +} + +float fmaf(float x, float y, float z) { + printf("el no implemento"); + return 0; +} + +long double fmal(long double x, long double y, long double z) { + printf("el no implemento"); + return 0; +} diff --git a/src/mkdir.c b/src/mkdir.c new file mode 100644 index 0000000..d8257b2 --- /dev/null +++ b/src/mkdir.c @@ -0,0 +1,8 @@ +#include "stdio.h" + +//TEMPORARY FILE + +int mkdir(const char *pathname) { + printf("LIBC: FUNCTION STUB NOT IMPLEMENTED"); + return 0; +} \ No newline at end of file diff --git a/src/stdio/fgetc.c b/src/stdio/fgetc.c new file mode 100644 index 0000000..9745584 --- /dev/null +++ b/src/stdio/fgetc.c @@ -0,0 +1,21 @@ +#include "stdio.h" +#include + +int fgetc(FILE *stream) +{ + char c; + int check; + check = read(*stream, &c, 1); + if (check < 0) + { + return -1; // eof + } + return c; +} + +int fputc(int ch, FILE *stream) +{ + char c = ch; + write(*stream, &c, 1); + return 0; +} \ No newline at end of file diff --git a/src/stdio/fgets.c b/src/stdio/fgets.c new file mode 100644 index 0000000..82518d8 --- /dev/null +++ b/src/stdio/fgets.c @@ -0,0 +1,53 @@ +#include +#include "stdio.h" +#include "string.h" +#include +#include + +// this needs file read library, def of file +// started by kyle clements + +// gets the space to store characters, the size of the space +// and where to read from + +char *fgets(char *str, int n, FILE *stream) +{ + int i = 0, con = 0; + char c; + while (i + 1 < n) + { + con = read(*stream, &c, 1); + if (con == EEOF) + { + if (i == 0) + return NULL; + break; + } + else if (con < 0) + { + // I/O failure + return NULL; + } + else if (con == 0) + { // file is smaller than wanted stored + /*str[i++] = '\0'; + return str;*/ + yield(); + continue; + } + + if (c == '\n' || c == '\0' || c == '\r') + { + str[i] = '\n'; + i++; + break; + } + else + { + str[i] = c; + i++; + } + } + str[i++] = '\0'; + return str; +} diff --git a/src/stdio/file/fio.c b/src/stdio/file/fio.c new file mode 100644 index 0000000..9a79a2b --- /dev/null +++ b/src/stdio/file/fio.c @@ -0,0 +1,11 @@ +#include "stdio.h" + +long ftell( FILE *stream ) { + printf("Not implemented"); + return 0; +} + +int fseek( FILE *stream, long offset, int origin ) { + printf("Not implemented"); + return 0; +} \ No newline at end of file diff --git a/src/stdio/getchar.c b/src/stdio/getchar.c new file mode 100644 index 0000000..030aa89 --- /dev/null +++ b/src/stdio/getchar.c @@ -0,0 +1,8 @@ +#include "stdio.h" + +/*started by Kyle Clements + all this will do is read one char from stdin. Nothing more. + stdin is typically 0 in the read call.*/ +int getchar(){ + return fgetc(stdin); +} \ No newline at end of file diff --git a/src/stdio/print/fprintf.c b/src/stdio/print/fprintf.c new file mode 100644 index 0000000..42b04e1 --- /dev/null +++ b/src/stdio/print/fprintf.c @@ -0,0 +1,23 @@ +#include "stdio.h" +#include "string.h" +#include + +/*started by Kyle Clements + Stolen from Nathan... + adjust libraries to match kernal + + Will need to adjust to actually target files. + Will need an updated part of this on kernal side.*/ + +int fprintf(FILE *stream, const char *format, ...) +{ + + va_list valist; + va_start(valist, format); + static char strBuffer[1024]; + char *s = strBuffer; + vsprintf(s, format, valist); + va_end(valist); + write(*stream, strBuffer, strlen(strBuffer)); + return 0; +} \ No newline at end of file diff --git a/src/stdio/print/printf.c b/src/stdio/print/printf.c new file mode 100644 index 0000000..4c900b1 --- /dev/null +++ b/src/stdio/print/printf.c @@ -0,0 +1,16 @@ +#include "stdio.h" +#include "string.h" +#include +// #include +/*started by Kyle Clements*/ + +int printf(const char *format, ...) { + static char strBuffer[1024]; + char *s = strBuffer; + va_list valist; + va_start(valist, format); + vsprintf(s, format, valist); + write(1, strBuffer, strlen(strBuffer)); + va_end(valist); + return 0; +} diff --git a/src/stdio/print/snprintf.c b/src/stdio/print/snprintf.c new file mode 100644 index 0000000..14210af --- /dev/null +++ b/src/stdio/print/snprintf.c @@ -0,0 +1,13 @@ +#include "stdio.h" + +/*started by Kyle Clements*/ + + +int snprintf(char *dest, size_t n, const char *format, ...){ + + va_list valist; + va_start(valist, format); + vsnprintf(dest, n, format, valist); + va_end(valist); + return 0; +} \ No newline at end of file diff --git a/src/stdio/print/sprintf.c b/src/stdio/print/sprintf.c new file mode 100644 index 0000000..471bcb0 --- /dev/null +++ b/src/stdio/print/sprintf.c @@ -0,0 +1,12 @@ +#include "stdio.h" + +/*started by Kyle Clements*/ + +int sprintf(char *dest, const char *format, ...){ + + va_list valist; + va_start(valist, format); + vsprintf(dest, format, valist); + va_end(valist); + return 0; +} \ No newline at end of file diff --git a/src/stdio/print/vfprintf.c b/src/stdio/print/vfprintf.c new file mode 100644 index 0000000..617a702 --- /dev/null +++ b/src/stdio/print/vfprintf.c @@ -0,0 +1,20 @@ +#include "stdio.h" +#include "string.h" + +/*started by Kyle Clements + + I am using the convention that whoever starts + the va_list has to end it. + + Will also need to adjust the target when a + kernal call allows us to change print locations*/ + + +int vfprintf(FILE * stream, const char *format, va_list valist){ + + static char strBuffer[1024]; + char *s = strBuffer; + vsprintf(s, format, valist); + write(*stream, strBuffer, strlen(strBuffer)); //this will need to change + return 0; +} \ No newline at end of file diff --git a/src/stdio/print/vprintf.c b/src/stdio/print/vprintf.c new file mode 100644 index 0000000..3db7311 --- /dev/null +++ b/src/stdio/print/vprintf.c @@ -0,0 +1,16 @@ +#include "stdio.h" +#include "string.h" + +/*started by Kyle Clements + + Also, I am using the convention + that whoever starts the va_list has to end it*/ + + +int vprintf(const char *format, va_list arg){ + static char strBuffer[1024]; + char *s = strBuffer; + vsprintf(s, format, arg); + write(1, strBuffer, strlen(strBuffer)); + return 0; +} \ No newline at end of file diff --git a/src/stdio/print/vsnprintf.c b/src/stdio/print/vsnprintf.c new file mode 100644 index 0000000..899b826 --- /dev/null +++ b/src/stdio/print/vsnprintf.c @@ -0,0 +1,113 @@ +#include "stdio.h" +#include +#include "string.h" + +/*started by Kyle Clements + Stolen from Nathan... + adjust libraries to match kernal*/ + +enum format_flags_t { + FORMAT_PADDING = '0', + FORMAT_WIDTH = '*', + + FORMAT_SIGNED_DECIMAL = 'i', + FORMAT_UNSIGNED_DECIMAL = 'u', + FORMAT_UNSIGNED_OCTAL = 'o', + FORMAT_UNSIGNED_HEX = 'x', + FORMAT_STRING = 's', + FORMAT_CHARACTER = 'c', + FORMAT_COUNT = 'n', + FORMAT_PERCENT = '%', + FORMAT_DIGIT = 'd' + +}; + +static char *itoa(unsigned int n, unsigned int base, unsigned int width) { + if (base < 2 || base > 16) { + return NULL; + } + static const char *digits = "0123456789abcdef"; + static char buffer[65]; + char *s = &buffer[64]; + *s = 0; + unsigned int count = 0; + do { + *--s = digits[n % base]; + n /= base; + count++; + } while (count < width || n != 0); + return s; +} + +static char *copyString(char *str, char *s) { + int i; + for (;;) { + if (*str == '\0') { + return s; + } + *s = *str; + s++; + str++; + } + return s; +} + +int vsnprintf(char *dest, size_t n, const char *format, va_list valist) { + size_t i = 0; + while (*format && i < n - 1) { + if (*format == '%') { + size_t width = 0; + bool padding = false; + switch (*++format) { + case FORMAT_PADDING: + padding = true; + format++; + break; + } + while (*format >= '0' && *format <= '9') { + width = (width * 10) + *format - '0'; + format++; + } + switch (*format) { + case FORMAT_SIGNED_DECIMAL: + case FORMAT_DIGIT: { + int n = va_arg(valist, int); + if (n < 0) { + *dest = '-'; + dest++; + n *= -1; + } + dest = copyString(itoa((unsigned int)n, 10, width), dest); + break; + } + case FORMAT_UNSIGNED_DECIMAL: + dest = copyString(itoa(va_arg(valist, unsigned int), 10, width), dest); + break; + case FORMAT_UNSIGNED_OCTAL: + dest = copyString(itoa(va_arg(valist, unsigned int), 8, width), dest); + break; + case FORMAT_UNSIGNED_HEX: + dest = copyString(itoa(va_arg(valist, unsigned int), 16, width), dest); + break; + case FORMAT_STRING: + dest = copyString(va_arg(valist, const char *), dest); + break; + case FORMAT_CHARACTER: + dest = copyString(va_arg(valist, unsigned int), dest); + break; + case FORMAT_PERCENT: + *dest = '%'; + dest++; + break; + } + } else { + *dest = *format; + dest++; + } + format++; + i++; + } + // va_end(valist); + *dest = '\0'; + return 0; +} diff --git a/src/stdio/print/vsprintf.c b/src/stdio/print/vsprintf.c new file mode 100644 index 0000000..81b7a46 --- /dev/null +++ b/src/stdio/print/vsprintf.c @@ -0,0 +1,112 @@ +#include "stdio.h" +#include +#include "string.h" + +/*started by Kyle Clements + Stolen from Nathan... + adjust libraries to match kernal*/ + +enum format_flags_t { + FORMAT_PADDING = '0', + FORMAT_WIDTH = '*', + + FORMAT_SIGNED_DECIMAL = 'i', + FORMAT_UNSIGNED_DECIMAL = 'u', + FORMAT_UNSIGNED_OCTAL = 'o', + FORMAT_UNSIGNED_HEX = 'x', + FORMAT_STRING = 's', + FORMAT_CHARACTER = 'c', + FORMAT_COUNT = 'n', + FORMAT_PERCENT = '%', + FORMAT_DIGIT = 'd' + +}; + +static char *itoa(unsigned int n, unsigned int base, unsigned int width) { + if (base < 2 || base > 16) { + return NULL; + } + static const char *digits = "0123456789abcdef"; + static char buffer[65]; + char *s = &buffer[64]; + *s = 0; + unsigned int count = 0; + do { + *--s = digits[n % base]; + n /= base; + count++; + } while (count < width || n != 0); + return s; +} + +static char *copyString(char *str, char *s) { + int i; + for (;;) { + if (*str == '\0') { + return s; + } + *s = *str; + s++; + str++; + } + return s; +} + +int vsprintf(char *dest, const char *format, va_list valist) { + + while (*format) { + if (*format == '%') { + size_t width = 0; + bool padding = false; + switch (*++format) { + case FORMAT_PADDING: + padding = true; + format++; + break; + } + while (*format >= '0' && *format <= '9') { + width = (width * 10) + *format - '0'; + format++; + } + switch (*format) { + case FORMAT_SIGNED_DECIMAL: + case FORMAT_DIGIT: { + int n = va_arg(valist, int); + if (n < 0) { + *dest = '-'; + dest++; + n *= -1; + } + dest = copyString(itoa((unsigned int)n, 10, width), dest); + break; + } + case FORMAT_UNSIGNED_DECIMAL: + dest = copyString(itoa(va_arg(valist, unsigned int), 10, width), dest); + break; + case FORMAT_UNSIGNED_OCTAL: + dest = copyString(itoa(va_arg(valist, unsigned int), 8, width), dest); + break; + case FORMAT_UNSIGNED_HEX: + dest = copyString(itoa(va_arg(valist, unsigned int), 16, width), dest); + break; + case FORMAT_STRING: + dest = copyString(va_arg(valist, const char *), dest); + break; + case FORMAT_CHARACTER: + dest = copyString(va_arg(valist, unsigned int), dest); + break; + case FORMAT_PERCENT: + *dest = '%'; + dest++; + break; + } + } else { + *dest = *format; + dest++; + } + format++; + } + // va_end(valist); + *dest = '\0'; + return 0; +} diff --git a/src/stdio/scan/fscanf.c b/src/stdio/scan/fscanf.c new file mode 100644 index 0000000..e466d22 --- /dev/null +++ b/src/stdio/scan/fscanf.c @@ -0,0 +1,11 @@ +#include +#include "stdio.h" + +int fscanf(FILE * stream, const char * format, ...){ + va_list ap; + int ret; + va_start(ap, format); + ret = vfscanf(stream, format, ap); + va_end(ap); + return ret; +} \ No newline at end of file diff --git a/src/stdio/scan/scanf.c b/src/stdio/scan/scanf.c new file mode 100644 index 0000000..bb16189 --- /dev/null +++ b/src/stdio/scan/scanf.c @@ -0,0 +1,20 @@ +#include +#include +#include +#include "stdio.h" + +/*Started by Kyle Clements + + scanf will always look into stdin*/ + +int scanf(const char *format, ...) +{ + char mystring[100]; + va_list args; + int ret; + va_start(args, format); + fgets(mystring, 99, stdin); + ret = vsscanf(mystring, format, args); + va_end(args); + return ret; +}; \ No newline at end of file diff --git a/src/stdio/scan/sscanf.c b/src/stdio/scan/sscanf.c new file mode 100644 index 0000000..c3225cd --- /dev/null +++ b/src/stdio/scan/sscanf.c @@ -0,0 +1,13 @@ +#include +#include "stdio.h" + +int sscanf(const char *ibuf, const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vsscanf(ibuf, fmt, ap); + va_end(ap); + return ret; +} \ No newline at end of file diff --git a/src/stdio/scan/vfscanf.c b/src/stdio/scan/vfscanf.c new file mode 100644 index 0000000..f20231d --- /dev/null +++ b/src/stdio/scan/vfscanf.c @@ -0,0 +1,10 @@ +#include "stdio.h" + +//not the correct implementation but is here to do something + +int vfscanf(FILE * stream, const char * format, va_list arg){ + char buffer[100]; + char *b = buffer; + fgets(b, 100, stream); + return vsscanf(b, format, arg); +} \ No newline at end of file diff --git a/src/stdio/scan/vscanf.c b/src/stdio/scan/vscanf.c new file mode 100644 index 0000000..fe1246b --- /dev/null +++ b/src/stdio/scan/vscanf.c @@ -0,0 +1,11 @@ +#include +#include "stdio.h" + +int vscanf(const char *format, va_list arg) +{ + char mystring[100]; + int ret; + fgets(mystring, 99, stdin); + ret = vsscanf(mystring, format, arg); + return ret; +} \ No newline at end of file diff --git a/src/stdio/scan/vsscanf.c b/src/stdio/scan/vsscanf.c new file mode 100644 index 0000000..457919b --- /dev/null +++ b/src/stdio/scan/vsscanf.c @@ -0,0 +1,747 @@ +#include +#include +#include +#include "stdio.h" +#include "string.h" + +/*This uses code from apple open source. + https://opensource.apple.com/source/Libc/Libc-594.9.5/stdio/FreeBSD/vsscanf.c.auto.html + + Has been adjusted to fit our project by Kyle Clements*/ + +#define UQUAD_MAX 0xffffffffffffffffULL /* max unsigned quad */ +#define QUAD_MAX 0x7fffffffffffffffLL /* max signed quad */ +#define QUAD_MIN (-0x7fffffffffffffffLL-1) /* min signed quad */ + +#define SUPPRESS 0x08 // '*' suppresses an assignment +#define POINTER 0x10 // 'p' void * as a hex +#define NOSKIP 0x20 // [ or c: do not skip blanks +#define LONG 0x01 // 'l' long or double +#define LONGLONG 0x400 // 'll' long long +#define SHORT 0x04 // 'h' short +#define SHORTSHORT 0x4000 // 'hh' char +#define UNSIGNED 0x8000 // %[oupxX] Conversions +#define PFXOK 0x100 // 0x prefix + +/* + * The following are used in numeric conversions only: + * SIGNOK, NDIGITS, DPTOK, and EXPOK are for floating point; + * SIGNOK, NDIGITS, PFXOK, and NZDIGITS are for integral. + */ +#define SIGNOK 0x40 /* +/- is (still) legal */ +#define NDIGITS 0x80 /* no digits detected */ + +#define DPTOK 0x100 /* (float) decimal point is still legal */ +#define EXPOK 0x200 /* (float) exponent (e+3, etc) still legal */ + +#define PFXOK 0x100 /* 0x prefix is (still) legal */ +#define NZDIGITS 0x200 /* no zero digits detected */ + +typedef long long quad_t; +typedef unsigned long long u_quad_t; +typedef unsigned long uintptr_t; +typedef unsigned char u_char; + +enum conversion_type +{ + CT_CHAR, + CT_CCL, + CT_STRING, + CT_INT +}; + +bool isspace(char c){ //for the sake of typing + return (c == ' ' || c == '\t' || c == '\n'); +} + +static const u_char *__sccl(char *, const u_char *); + +quad_t +strtoq(nptr, endptr, base) + const char *nptr; + char **endptr; + register int base; +{ + register const char *s; + register u_quad_t acc; + register int c; + register u_quad_t qbase, cutoff; + register int neg, any, cutlim; + + /* + * Skip white space and pick up leading +/- sign if any. + * If base is 0, allow 0x for hex and 0 for octal, else + * assume decimal; if base is already 16, allow 0x. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); //space + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + + /* + * Compute the cutoff value between legal numbers and illegal + * numbers. That is the largest legal value, divided by the + * base. An input number that is greater than this value, if + * followed by a legal input character, is too big. One that + * is equal to this value may be valid or not; the limit + * between valid and invalid numbers is then based on the last + * digit. For instance, if the range for quads is + * [-9223372036854775808..9223372036854775807] and the input base + * is 10, cutoff will be set to 922337203685477580 and cutlim to + * either 7 (neg==0) or 8 (neg==1), meaning that if we have + * accumulated a value > 922337203685477580, or equal but the + * next digit is > 7 (or 8), the number is too big, and we will + * return a range error. + * + * Set any if any `digits' consumed; make it negative to indicate + * overflow. + */ + qbase = (unsigned)base; + cutoff = neg ? -(u_quad_t)QUAD_MIN : QUAD_MAX; + cutlim = cutoff % qbase; + cutoff /= qbase; + for (acc = 0, any = 0;; c = *s++) { + if (c >= 48 && c <= 57) + c -= '0'; + else if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122)) //alpha + c -= (c >= 65 && c <= 90) ? 'A' - 10 : 'a' - 10; //checks on capital letter + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) + any = -1; + else { + any = 1; + acc *= qbase; + acc += c; + } + } + if (any < 0) { + acc = neg ? QUAD_MIN : QUAD_MAX; + //errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + + + +u_quad_t +strtouq(nptr, endptr, base) + const char *nptr; + char **endptr; + register int base; +{ + register const char *s = nptr; + register u_quad_t acc; + register int c; + register u_quad_t qbase, cutoff; + register int neg, any, cutlim; + + /* + * See strtoq for comments as to the logic used. + */ + s = nptr; + do { + c = *s++; + } while (isspace(c)); //space + if (c == '-') { + neg = 1; + c = *s++; + } else { + neg = 0; + if (c == '+') + c = *s++; + } + if ((base == 0 || base == 16) && + c == '0' && (*s == 'x' || *s == 'X')) { + c = s[1]; + s += 2; + base = 16; + } + if (base == 0) + base = c == '0' ? 8 : 10; + qbase = (unsigned)base; + cutoff = (u_quad_t)UQUAD_MAX / qbase; + cutlim = (u_quad_t)UQUAD_MAX % qbase; + for (acc = 0, any = 0;; c = *s++) { + if (c >= 48 && c <= 57) + c -= '0'; + else if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122)) //is alphabet + c -= (c >= 65 && c <= 90) ? 'A' - 10 : 'a' - 10; //checks on capitol letter + else + break; + if (c >= base) + break; + if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim) + any = -1; + else { + any = 1; + acc *= qbase; + acc += c; + } + } + if (any < 0) { + acc = UQUAD_MAX; + //errno = ERANGE; + } else if (neg) + acc = -acc; + if (endptr != 0) + *endptr = (char *)(any ? s - 1 : nptr); + return (acc); +} + +int vsscanf(const char *inp, char const *fmt0, va_list ap) +{ + int inr; + const u_char *fmt = (const u_char *)fmt0; + int c; /* character from format, or conversion */ + size_t width; /* field width, or 0 */ + char *p; /* points into all kinds of strings */ + int n; /* handy integer */ + int flags; /* flags as defined above */ + char *p0; /* saves original value of p when necessary */ + int nassigned; /* number of fields assigned */ + int nconversions; /* number of conversions */ + int nread; /* number of characters consumed from fp */ + int base; /* base argument to conversion function */ + char ccltab[256]; /* character class table for %[...] */ + char buf[32]; /* buffer for numeric conversions */ + + /* `basefix' is used to avoid `if' tests in the integer scanner */ + static short basefix[17] = + { 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; + + inr = strlen(inp); + + nassigned = 0; + nconversions = 0; + nread = 0; + base = 0; /* XXX just to keep gcc happy */ + for (;;) { + c = *fmt++; + if (c == 0) + return (nassigned); + if (isspace(c)) { //space + while (inr > 0 && isspace(*inp)) + nread++, inr--, inp++; + continue; + } + if (c != '%') + goto literal; + width = 0; + flags = 0; + /* + * switch on the format. continue if done; + * break once format type is derived. + */ +again: c = *fmt++; + switch (c) { + case '%': +literal: + if (inr <= 0) + goto input_failure; + if (*inp != c) + goto match_failure; + inr--, inp++; + nread++; + continue; + + case '*': + flags |= SUPPRESS; + goto again; + case 'l': + if (flags & LONG) { + flags &= ~LONG; + flags |= LONGLONG; + } else + flags |= LONG; + goto again; + case 'q': + flags |= LONGLONG; /* not quite */ + goto again; + case 'h': + if (flags & SHORT) { + flags &= ~SHORT; + flags |= SHORTSHORT; + } else + flags |= SHORT; + goto again; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + width = width * 10 + c - '0'; + goto again; + + /* + * Conversions. + */ + case 'd': + c = CT_INT; + base = 10; + break; + + case 'i': + c = CT_INT; + base = 0; + break; + + case 'o': + c = CT_INT; + flags |= UNSIGNED; + base = 8; + break; + + case 'u': + c = CT_INT; + flags |= UNSIGNED; + base = 10; + break; + + case 'X': + case 'x': + flags |= PFXOK; /* enable 0x prefixing */ + c = CT_INT; + flags |= UNSIGNED; + base = 16; + break; + + case 's': + c = CT_STRING; + break; + + case '[': + fmt = __sccl(ccltab, fmt); + flags |= NOSKIP; + c = CT_CCL; + break; + + case 'c': + flags |= NOSKIP; + c = CT_CHAR; + break; + + case 'p': /* pointer format is like hex */ + flags |= POINTER | PFXOK; + c = CT_INT; + flags |= UNSIGNED; + base = 16; + break; + + case 'n': + nconversions++; + if (flags & SUPPRESS) /* ??? */ + continue; + if (flags & SHORTSHORT) + *va_arg(ap, char *) = nread; + else if (flags & SHORT) + *va_arg(ap, short *) = nread; + else if (flags & LONG) + *va_arg(ap, long *) = nread; + else if (flags & LONGLONG) + *va_arg(ap, long long *) = nread; + else + *va_arg(ap, int *) = nread; + continue; + } + + /* + * We have a conversion that requires input. + */ + if (inr <= 0) + goto input_failure; + + /* + * Consume leading white space, except for formats + * that suppress this. + */ + if ((flags & NOSKIP) == 0) { + while (isspace(*inp)) { //space + nread++; + if (--inr > 0) + inp++; + else + goto input_failure; + } + /* + * Note that there is at least one character in + * the buffer, so conversions that do not set NOSKIP + * can no longer result in an input failure. + */ + } + + /* + * Do the conversion. + */ + switch (c) { + + case CT_CHAR: + /* scan arbitrary characters (sets NOSKIP) */ + if (width == 0) + width = 1; + if (flags & SUPPRESS) { + size_t sum = 0; + for (;;) { + if ((n = inr) < (int)width) { + sum += n; + width -= n; + inp += n; + if (sum == 0) + goto input_failure; + break; + } else { + sum += width; + inr -= width; + inp += width; + break; + } + } + nread += sum; + } else { + bcopy(inp, va_arg(ap, char *), width); + inr -= width; + inp += width; + nread += width; + nassigned++; + } + nconversions++; + break; + + case CT_CCL: + /* scan a (nonempty) character class (sets NOSKIP) */ + if (width == 0) + width = (size_t)~0; /* `infinity' */ + /* take only those things in the class */ + if (flags & SUPPRESS) { + n = 0; + while (ccltab[(unsigned char)*inp]) { + n++, inr--, inp++; + if (--width == 0) + break; + if (inr <= 0) { + if (n == 0) + goto input_failure; + break; + } + } + if (n == 0) + goto match_failure; + } else { + p0 = p = va_arg(ap, char *); + while (ccltab[(unsigned char)*inp]) { + inr--; + *p++ = *inp++; + if (--width == 0) + break; + if (inr <= 0) { + if (p == p0) + goto input_failure; + break; + } + } + n = p - p0; + if (n == 0) + goto match_failure; + *p = 0; + nassigned++; + } + nread += n; + nconversions++; + break; + + case CT_STRING: + /* like CCL, but zero-length string OK, & no NOSKIP */ + if (width == 0) + width = (size_t)~0; + if (flags & SUPPRESS) { + n = 0; + while (*inp != 32) { //not space + n++, inr--, inp++; + if (--width == 0) + break; + if (inr <= 0) + break; + } + nread += n; + } else { + p0 = p = va_arg(ap, char *); + while (*inp != 32) { + inr--; + *p++ = *inp++; + if (--width == 0) + break; + if (inr <= 0) + break; + } + *p = 0; + nread += p - p0; + nassigned++; + } + nconversions++; + continue; + + case CT_INT: + /* scan an integer as if by the conversion function */ +#ifdef hardway + if (width == 0 || width > sizeof(buf) - 1) + width = sizeof(buf) - 1; +#else + /* size_t is unsigned, hence this optimisation */ + if (--width > sizeof(buf) - 2) + width = sizeof(buf) - 2; + width++; +#endif + flags |= SIGNOK | NDIGITS | NZDIGITS; + for (p = buf; width; width--) { + c = *inp; + /* + * Switch on the character; `goto ok' + * if we accept it as a part of number. + */ + switch (c) { + + /* + * The digit 0 is always legal, but is + * special. For %i conversions, if no + * digits (zero or nonzero) have been + * scanned (only signs), we will have + * base==0. In that case, we should set + * it to 8 and enable 0x prefixing. + * Also, if we have not scanned zero digits + * before this, do not turn off prefixing + * (someone else will turn it off if we + * have scanned any nonzero digits). + */ + case '0': + if (base == 0) { + base = 8; + flags |= PFXOK; + } + if (flags & NZDIGITS) + flags &= ~(SIGNOK|NZDIGITS|NDIGITS); + else + flags &= ~(SIGNOK|PFXOK|NDIGITS); + goto ok; + + /* 1 through 7 always legal */ + case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + base = basefix[base]; + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* digits 8 and 9 ok iff decimal or hex */ + case '8': case '9': + base = basefix[base]; + if (base <= 8) + break; /* not legal here */ + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* letters ok iff hex */ + case 'A': case 'B': case 'C': + case 'D': case 'E': case 'F': + case 'a': case 'b': case 'c': + case 'd': case 'e': case 'f': + /* no need to fix base here */ + if (base <= 10) + break; /* not legal here */ + flags &= ~(SIGNOK | PFXOK | NDIGITS); + goto ok; + + /* sign ok only as first character */ + case '+': case '-': + if (flags & SIGNOK) { + flags &= ~SIGNOK; + goto ok; + } + break; + + /* x ok iff flag still set & 2nd char */ + case 'x': case 'X': + if (flags & PFXOK && p == buf + 1) { + base = 16; /* if %i */ + flags &= ~PFXOK; + goto ok; + } + break; + } + + /* + * If we got here, c is not a legal character + * for a number. Stop accumulating digits. + */ + break; + ok: + /* + * c is legal: store it and look at the next. + */ + *p++ = c; + if (--inr > 0) + inp++; + else + break; /* end of input */ + } + /* + * If we had only a sign, it is no good; push + * back the sign. If the number ends in `x', + * it was [sign] '0' 'x', so push back the x + * and treat it as [sign] '0'. + */ + if (flags & NDIGITS) { + if (p > buf) { + inp--; + inr++; + } + goto match_failure; + } + c = ((u_char *)p)[-1]; + if (c == 'x' || c == 'X') { + --p; + inp--; + inr++; + } + if ((flags & SUPPRESS) == 0) { + u_quad_t res; + + *p = 0; + if ((flags & UNSIGNED) == 0) + res = strtoq(buf, (char **)NULL, base); + else + res = strtouq(buf, (char **)NULL, base); + if (flags & POINTER) + *va_arg(ap, void **) = (void *)((uintptr_t)res); + else if (flags & SHORTSHORT) + *va_arg(ap, char *) = res; + else if (flags & SHORT) + *va_arg(ap, short *) = res; + else if (flags & LONG) + *va_arg(ap, long *) = res; + else if (flags & LONGLONG) + *va_arg(ap, long long *) = res; + else + *va_arg(ap, int *) = res; + nassigned++; + } + nread += p - buf; + nconversions++; + break; + + } + } +input_failure: + return (nconversions != 0 ? nassigned : -1); +match_failure: + return (nassigned); +} + + +/* + * Fill in the given table from the scanset at the given format + * (just after `['). Return a pointer to the character past the + * closing `]'. The table has a 1 wherever characters should be + * considered part of the scanset. + */ +static const u_char * +__sccl(char *tab, const u_char *fmt) +{ + int c, n, v; + + /* first `clear' the whole table */ + c = *fmt++; /* first char hat => negated scanset */ + if (c == '^') { + v = 1; /* default => accept */ + c = *fmt++; /* get new first char */ + } else + v = 0; /* default => reject */ + + /* XXX: Will not work if sizeof(tab*) > sizeof(char) */ + (void) memset(tab, v, 256); + + if (c == 0) + return (fmt - 1);/* format ended before closing ] */ + + /* + * Now set the entries corresponding to the actual scanset + * to the opposite of the above. + * + * The first character may be ']' (or '-') without being special; + * the last character may be '-'. + */ + v = 1 - v; + for (;;) { + tab[c] = v; /* take character c */ +doswitch: + n = *fmt++; /* and examine the next */ + switch (n) { + + case 0: /* format ended too soon */ + return (fmt - 1); + + case '-': + /* + * A scanset of the form + * [01+-] + * is defined as `the digit 0, the digit 1, + * the character +, the character -', but + * the effect of a scanset such as + * [a-zA-Z0-9] + * is implementation defined. The V7 Unix + * scanf treats `a-z' as `the letters a through + * z', but treats `a-a' as `the letter a, the + * character -, and the letter a'. + * + * For compatibility, the `-' is not considerd + * to define a range if the character following + * it is either a close bracket (required by ANSI) + * or is not numerically greater than the character + * we just stored in the table (c). + */ + n = *fmt; + if (n == ']' || n < c) { + c = '-'; + break; /* resume the for(;;) */ + } + fmt++; + /* fill in the range */ + do { + tab[++c] = v; + } while (c < n); + c = n; + /* + * Alas, the V7 Unix scanf also treats formats + * such as [a-c-e] as `the letters a through e'. + * This too is permitted by the standard.... + */ + goto doswitch; + break; + + case ']': /* end of scanset */ + return (fmt); + + default: /* just another character */ + c = n; + break; + } + } + /* NOTREACHED */ +} diff --git a/src/stdio/stdin.c b/src/stdio/stdin.c new file mode 100644 index 0000000..840b750 --- /dev/null +++ b/src/stdio/stdin.c @@ -0,0 +1,5 @@ +#include "stdio.h" + +const int fd_stdin = 0; +const int fd_stdout = 1; +const int fd_stderr = 2; \ No newline at end of file diff --git a/src/stdlib/stdlib.c b/src/stdlib/stdlib.c new file mode 100644 index 0000000..93f322d --- /dev/null +++ b/src/stdlib/stdlib.c @@ -0,0 +1,296 @@ +#include "heap/heap.h" +#include "stdlib.h" +#include +/*Started by Kyle Clements + */ + +/* started by Kyle Clements + what this will need to do is use a system call to update this file + descriptor to let the file system know that there is another reference to + this "open" file. LOW PRIORITY*/ +int dup(int fd) +{ + // TODO: + return -1; +} + +int dup2(int oldfd, int newfd) +{ + int fd = fddup(oldfd, newfd); + if (fd < 0) + { + return -1; + } + return fd; +} + +void *malloc(size_t size) { return malloc_heap(size); } + +void *realloc(void *ptr, size_t size) { return realloc_heap(ptr, size); } +void free(void *ptr) +{ + // TODO: + return free_heap(ptr); +} + +void exit(int status) +{ + printf("not implemented yet"); +} + +FILE *fopen(const char *filename, const char *mode) +{ + FILE *f = malloc(sizeof(int)); + *f = openf(filename, 0); + // printf("fopen %s\n", filename); + return f; +} + +int *fclose(FILE *stream) +{ + closef(*stream); + // printf("fclose %i\n", *stream); + if (*stream > fd_stderr) + { + free(stream); + } + // printf("Not implemented"); + return 0; +} + +unsigned int rand_seed; + +int rand(void) +{ + const unsigned int a = 1103515245; + const unsigned int c = 12345; + const unsigned int m = 0xFFFFFFFF; + + rand_seed = (a * rand_seed + c) % m; + + return rand_seed; +} + +void srand(unsigned int seed) { rand_seed = seed; } + +double atof(const char *str) +{ + double x = 0.0; + + int e = 0; + int c = *str; + int sign; + int i; + // remove white space + while (c == ' ' || c == '\t' || c == '\n') + { // is a space + c = *str++; + } + // first check for initial numbers before decimal + while (c != '\0' && (c >= '0' && c <= '9')) + { + x = x * 10.0 + (c - '0'); + c = *str++; + } + + // check for decimal + if (c == '.') + { + c = *str++; + while (c != '\0' && (c >= '0' && c <= '9')) + { + // collect values and keep track of where the decimal should land + x = x * 10.0 + (c - '0'); + e = e - 1; + c = *str++; + } + } + + // if no decimal, we will check for e + if (c == 'e' || c == 'E') + { + // assume positive number + sign = 1; + i = 0; + c = *str++; + if (c == '+') + { + c = *str++; + } + else if (c == '-') + { + c = *str++; + sign = -1; + } + while ((c >= '0' && c <= '9')) + { + // collect + i = i * 10 + (c - '0'); + c = *str++; + } + // track decimal position + e = e + i * sign; + } + // now adjust decimal where needed + while (e > 0) + { + x = x * 10; + e--; + } + while (e < 0) + { + x = x * 0.1; + e++; + } + return x; +} + +long int atol(const char *str) +{ + long int x = 0; + char c = *str; + int sign = 1; + // remove white space + while (c == ' ' || c == '\t' || c == '\n') + { // is a space + c = *str++; + } + // check sign first + if (c == '-') + { + sign = -1; + c = *str++; + } + else if (c == '+') + { + c = *str++; + } + + while (c >= '0' && c <= '9') + { + x = 10 * x + (c - '0'); + c = *str++; + } + + return sign * x; +} + +long long atoll(const char *str) +{ + long long x = 0; + char c = *str; + int sign = 1; + // remove white space + while (c == ' ' || c == '\t' || c == '\n') + { // is a space + c = *str++; + } + // check sign first + if (c == '-') + { + sign = -1; + c = *str++; + } + else if (c == '+') + { + c = *str++; + } + + while (c >= '0' && c <= '9') + { + x = 10 * x + (c - '0'); + c = *str++; + } + + return sign * x; +}; + +int atoi(const char *str) +{ + int x = 0; + char c = *str; + int sign = 1; + // remove white space + while (c == ' ' || c == '\t' || c == '\n') + { // is a space + c = *str++; + } + if (c == '-') + { + sign = -1; + c = *str++; + } + else if (c == '+') + { + c = *str++; + } + while (c >= '0' && c <= '9') + { + x = 10 * x + (c - '0'); + c = *str++; + } + + return sign * x; +} + +double strtod(const char *str, char **endptr) +{ + char *s = str; + double x = atof(s); + if (endptr != NULL) + { + *endptr = s; + } + return x; +} + +float strtof(const char *str, char **endptr) +{ + char *s = str; + double x = atof(s); + if (endptr != NULL) + { + *endptr = s; + } + return (float)x; +} + +long double strtold(const char *str, char **endptr) +{ + printf("Not implemented"); + long double x = 0.0; + return x; +} +long int strtol(const char *str, char **endptr, int base) +{ + printf("Not implemented"); + long int x = 0; + if (base == 10 || base == 0) + { + char *s = str; + atol(s); + if (endptr != NULL) + { + *endptr = s; + } + } + return x; +} +long long int strtoll(const char *str, char **endptr, int base) +{ + printf("Not implemented"); + long long x = 0; + return x; +} +unsigned long int strtoul(const char *str, char **endptr, int base) +{ + printf("Not implemented"); + unsigned long int x = 0; + return x; +} +unsigned long long int strtoull(const char *str, char **endptr, int base) +{ + printf("Not implemented"); + unsigned long long int x = 0; + return x; +} diff --git a/src/string.c b/src/string.c new file mode 100644 index 0000000..54d6822 --- /dev/null +++ b/src/string.c @@ -0,0 +1,265 @@ +#include "../include/string.h" +#include "stdlib.h" + +void *memcpy(void *dest, const void *src, size_t n) +{ + char *d = (char *)dest; + const char *s = (const char *)src; + + for (size_t i = 0; i < n; i++) + d[i] = s[i]; + + return dest; +} + +void *memmove(void *dest, const void *src, size_t n) +{ + char *d = (char *)dest; + const char *s = (const char *)src; + + for (size_t i = n; i > 0; i--) + d[i - 1] = s[i - 1]; + + return dest; +} + +int memcmp(const void *ptr1, const void *ptr2, size_t n) +{ + const unsigned char *s1 = (const unsigned char *)ptr1; + const unsigned char *s2 = (const unsigned char *)ptr2; + + return strcmp(s1, s2); +} + +void *memset(void *ptr, int value, size_t num) +{ + unsigned char *p = (unsigned char *)ptr; + unsigned char v = (unsigned char)value; + + for (size_t i = 0; i < num; i++) + p[i] = v; + + return ptr; +} + +char *strcpy(char *dest, const char *src) +{ + char *temp = dest; + + while (*src) + { + *temp = *src; + temp++; + src++; + } + *temp = '\0'; + + return dest; +} + +char *strncpy(char *dest, const char *src, size_t n) +{ + if (dest != NULL) + free(dest); + + dest = (char *)malloc(sizeof(char) * (n + 1)); + char *temp = dest; + + while (*src && n > 0) + { + *temp = *src; + temp++; + src++; + n--; + } + *temp = '\0'; + + return dest; +} + +int strcmp(const char *str1, const char *str2) +{ + while (*str1 && *str2 && *str1 == *str2) + { + str1++; + str2++; + } + return *str1 == *str2; +} + +int strncmp(const char *str1, const char *str2, size_t n) +{ + while (*str1 && *str2 && *str1 == *str2 && n > 0) + { + str1++; + str2++; + n--; + } + return *str1 == *str2; +} + +char *strcat(char *dest, const char *src) +{ + if (dest == NULL) + { + return strcpy(dest, src); + } + + int len_dest = strlen(dest); + int len_src = strlen(src); + // char *temp = (char *)malloc(sizeof(char) * (len_dest + len_src + 1)); + + // char *temp_ptr = temp; + char *dest_ptr = dest + len_dest; + const char *src_ptr = src; + + /*while (*dest_ptr) + { + *temp_ptr = *dest_ptr; + temp_ptr++; + dest_ptr++; + }*/ + + while (*src_ptr) + { + *dest_ptr = *src_ptr; + dest_ptr++; + src_ptr++; + } + *dest_ptr = '\0'; + + // free(dest); + // dest = temp; + + return dest; +} + +char *strncat(char *dest, const char *src, size_t n) +{ + if (dest == NULL) + { + dest = strcpy(dest, src); + return; + } + + int len_dest = strlen(dest); + int len_src = strlen(src); + char *temp = (char *)malloc(sizeof(char) * (len_dest + n + 1)); + + char *temp_ptr = temp; + const char *dest_ptr = dest; + const char *src_ptr = src; + + while (*dest_ptr) + { + *temp_ptr = *dest_ptr; + temp_ptr++; + dest_ptr++; + } + + while (*src_ptr && n > 0) + { + *temp_ptr = *src_ptr; + temp_ptr++; + src_ptr++; + n--; + } + *temp_ptr = '\0'; + + free(dest); + dest = temp; + + return dest; +} + +size_t strlen(const char *str) +{ + int len = 0; + while (*str) + { + len++; + str++; + } + return len; +} + +// useless stuff + +int strcoll(const char *str1, const char *str2) +{ + printf("el no implemento"); + return 0; +} + +size_t strxfrm(char *dest, const char *src, size_t n) +{ + printf("el no implemento"); + return 0; +} + +const void *memchr(const void *ptr, int val, size_t n) +{ + printf("el no implemento"); + return 0; +} + +const char *strchr(const char *str, int c) +{ + printf("el no implemento"); + return 0; +} + +size_t strcspn(const char *str1, const char *str2) +{ + printf("el no implemento"); + return 0; +} + +const char *strpbrk(const char *str1, const char *str2) +{ + printf("el no implemento"); + return 0; +} + +const char *strrchr(const char *str, int c) +{ + printf("el no implemento"); + return 0; +} + +size_t strspn(const char *str1, const char *str2) +{ + printf("el no implemento"); + return 0; +} + +char *strtok(char *str, const char *delims) +{ + printf("el no implemento"); + return 0; +} + +const char *strstr(const char *str1, const char *str2) +{ + if (*str2 == '\0') + return str1; + + while (*str1 != '\0') + { + const char *ptr1 = str1; + const char *ptr2 = str2; + + while (*ptr1 != '\0' && *ptr2 != '\0' && *ptr1 == *ptr2) + { + ptr1++; + ptr2++; + } + + if (*ptr2 == '\0') + return str1; + + str1++; + } + + return NULL; +} \ No newline at end of file diff --git a/src/stringclass.cpp b/src/stringclass.cpp new file mode 100644 index 0000000..599ab4d --- /dev/null +++ b/src/stringclass.cpp @@ -0,0 +1,342 @@ +#include "stdio.h" +#include "stdlib.h" +#include "string" + +using namespace std; + +void *operator new(size_t size) +{ + return malloc(size); +} + +void operator delete(void *ptr) +{ + free(ptr); +} + +void *operator new[](size_t size) +{ + return malloc(size); +} + +void operator delete[](void *ptr) +{ + return free(ptr); +} + +void operator delete(void *ptr, unsigned long sz) +{ + return free(ptr); +} + +void operator delete[](void *ptr, unsigned long sz) +{ + return free(ptr); +} + +string::string() +{ + s = strdup(""); +} + +string::string(const char *other) +{ + s = strdup(other); +} + +string::string(const string &other) +{ + s = strdup(other.s); +} + +string::~string() +{ + if (s != nullptr) + delete[] s; + s = nullptr; +} + +int string::size() const +{ + return strlen(s); +} + +size_t string::find(const string &str, size_t pos = 0) const +{ + int size = strlen(s); + if (pos < 0 || pos >= size) + return -1; + + for (int i = pos; i <= size - str.size(); ++i) + { + bool found = true; + for (int j = 0; j < str.size(); ++j) + { + if (s[i + j] != str[j]) + { + found = false; + break; + } + } + if (found) + return i; + } + return -1; +} + +string &string::erase(size_t pos, size_t len) +{ + int size = strlen(s); + if (pos < 0 || pos + len > size) + return *this; + + char *s1 = string::substr(s, 0, pos); + const char *s2 = string::substr(s, pos + len, size); + string::strcat(s1, s2); + + delete[] s2; + delete[] s; + s = s1; + + return *this; +} + +bool string::operator==(const string &other) const +{ + return strcmp(s, other.s); +} + +bool string::operator!=(const string &other) const +{ + return strcmp(s, other.s); +} + +string &string::operator=(char c) +{ + if (s != nullptr) + delete[] s; + char cnvrt[2] = {c, '\0'}; + s = strdup(cnvrt); + return *this; +} + +string &string::operator=(const char *other) +{ + if (s != nullptr) + delete[] s; + s = strdup(other); + return *this; +} + +string &string::operator=(const string &other) +{ + if (s != nullptr) + delete[] s; + if (other.s != nullptr) + { + s = strdup(other.s); + } + else + { + s = strdup(""); + } + return *this; +} + +string string::operator+(char c) const +{ + string result; + result.s = new char[strlen(s) + 1 + 1]; + strcpy(result.s, s); + char cnvrt[2] = {c, '\0'}; + strcat(result.s, cnvrt); + return result; +} + +string string::operator+(const char *other) const +{ + string result; + result.s = new char[strlen(s) + strlen(other) + 1]; + strcpy(result.s, s); + strcat(result.s, other); + return result; +} + +string string::operator+(const string &other) const +{ + return *this + other.s; +} + +string &string::operator+=(char c) +{ + char *temp = new char[strlen(s) + 1 + 1]; + strcpy(temp, s); + char cnvrt[2] = {c, '\0'}; + strcat(temp, cnvrt); + if (s != nullptr) + delete[] s; + s = temp; + return *this; +} + +string &string::operator+=(const char *other) +{ + char *temp = new char[strlen(s) + strlen(other) + 1]; + strcpy(temp, s); + strcat(temp, other); + if (s != nullptr) + delete[] s; + s = temp; + return *this; +} + +string &string::operator+=(const string &other) +{ + return *this += other.s; +} + +const char &string::operator[](int index) const +{ + return s[index]; +} + +const char *string::c_str() const +{ + return s; +} + +string string::substr(int start_index) const +{ + if (start_index < 0 || start_index >= strlen(s)) // invalid index + return string(); + return string(s + start_index); // pointer arithmatic, eat your heart out rust +} + +string string::substr(int start_index, int end_index) const +{ + if (start_index < 0 || start_index >= strlen(s) || end_index <= start_index || end_index > strlen(s)) // invalid indices + return string(); + + int length = end_index - start_index; + char *temp = new char[length + 1]; + strncpy(temp, s + start_index, length); + temp[length] = '\0'; // make sure to null-terminate the string + return string(temp); +} + +bool string::strcmp(const char *first, const char *second) +{ + while (*first && *second && *first == *second) + { + first++; + second++; + } + return *first == *second; +} + +char *string::substr(const char *str, int start_index) +{ + int len = strlen(str + start_index); + char *substr = new char[len + 1]; + strcpy(substr, str + start_index); + return substr; +} + +char *string::substr(const char *str, int start_index, int end_index) +{ + int len = end_index - start_index; + char *substr = new char[len + 1]; + strncpy(substr, str + start_index, len); + substr[len] = '\0'; + return substr; +} + +char *string::strdup(const char *s) +{ + int len = strlen(s); + char *dup = new char[len + 1]; + strcpy(dup, s); + return dup; +} + +void string::strcpy(char *&dest, const char *src) +{ + if (dest != nullptr) + delete[] dest; + + int len = strlen(src); + dest = new char[len + 1]; + char *temp = dest; + + while (*src) + { + *temp = *src; + temp++; + src++; + } + *temp = '\0'; +} + +void string::strncpy(char *&dest, const char *src, int len) +{ + if (dest != nullptr) + delete[] dest; + + dest = new char[len + 1]; + char *temp = dest; + + while (*src && len > 0) + { + *temp = *src; + temp++; + src++; + len--; + } + *temp = '\0'; +} + +void string::strcat(char *&dest, const char *src) +{ + if (dest == nullptr) + { + dest = strdup(src); + return; + } + + int len_dest = strlen(dest); + int len_src = strlen(src); + char *temp = new char[len_dest + len_src + 1]; + + char *temp_ptr = temp; + const char *dest_ptr = dest; + const char *src_ptr = src; + + while (*dest_ptr) + { + *temp_ptr = *dest_ptr; + temp_ptr++; + dest_ptr++; + } + + while (*src_ptr) + { + *temp_ptr = *src_ptr; + temp_ptr++; + src_ptr++; + } + *temp_ptr = '\0'; + + delete[] dest; + dest = temp; +} + +int string::strlen(const char *s) +{ + int len = 0; + while (*s) + { + len++; + s++; + } + return len; +} diff --git a/src/uinit.c b/src/uinit.c new file mode 100644 index 0000000..3e116bd --- /dev/null +++ b/src/uinit.c @@ -0,0 +1,17 @@ +#include "heap/heap.h" +#include "stdio.h" +#include + +/* need to know the h files for kernal and the h file + for the h file for the userspace*/ + +void uinit() +{ + printf("C library starting...\n"); + + // Heap Initialization + unsigned long heap_ptr = 0x200000000; + unsigned long mem_size = (1 << 20); + mmap((void *)heap_ptr, mem_size, 1); + init_heap((void *)heap_ptr, mem_size); +} diff --git a/src/unistd.c b/src/unistd.c new file mode 100644 index 0000000..a2c4f6c --- /dev/null +++ b/src/unistd.c @@ -0,0 +1,32 @@ +#include "unistd.h" +#include + +int *getcwd(char *, size_t) +{ + return 0; +} + +int fchdir(int fd) +{ + return 0; +} + +int chdir(const char *path) +{ + return 0; +} + +int close(int fd) +{ + return 0; +} + +int open(int fd) +{ + return 0; +} + +int pipe(int fildes[2]) +{ + return 0; +} diff --git a/src/wait.c b/src/wait.c new file mode 100644 index 0000000..3d08102 --- /dev/null +++ b/src/wait.c @@ -0,0 +1,31 @@ +#include "stdlib.h" +#include + +void sigchild_ret() +{ + sigret(); +} + +void sigchild(void *userdata) +{ + *(int *)userdata = 0; +} + +int signal_set = 0; + +/*Started by Kyle Clements + this is all kernel. + we can use this as a wrapper for user side*/ +int wait(int *addr) +{ + int waiting = 1; + if (!signal_set) + { + sigaction(17, sigchild, sigchild_ret, (void *)&waiting); + } + while (waiting) + { + sigwait(); + } + return 0; +} \ No newline at end of file diff --git a/test-makefile b/test-makefile new file mode 100644 index 0000000..a981d36 --- /dev/null +++ b/test-makefile @@ -0,0 +1,29 @@ +#Compiler settings +CC = gcc +CFLAGS = -g -Wall -Werror -std=c11 +LDFLAGS = + +#Directories +SRCDIR = src +INCDIR = include + +#Create executable file +program: main.o math.o + $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) + +#Create Main object file +main.o: main.c $(INCDIR)/math.h + $(CC) $(CFLAGS) -I$(INCDIR) -c $< -o $@ + +#Create Math object file +math.o: $(SRCDIR)/math.c $(INCDIR)/math.h + $(CC) $(CFLAGS) -I$(INCDIR) -c $< -o $@ + +#Remove all executable and object files +clean: + rm -f *.o program + +#Run Main executable file +exec: program + ./program +