New repo setup

This commit is contained in:
2024-05-28 14:50:00 -05:00
commit f68c320396
51 changed files with 4612 additions and 0 deletions

4
.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
*.o
*.a
*.so
.vscode

42
Makefile Normal file
View File

@@ -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 $@

5
README.md Normal file
View File

@@ -0,0 +1,5 @@
# CROS libc
## Introduction
## Building

58
include/dirent.h Normal file
View File

@@ -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

0
include/dup.h Normal file
View File

0
include/fork.h Normal file
View File

257
include/math.h Normal file
View File

@@ -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

63
include/stdio.h Normal file
View File

@@ -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 <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#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

45
include/stdlib.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef CROS_STDLIB_H
#define CROS_STDLIB_H
#include <stddef.h>
#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

54
include/string Normal file
View File

@@ -0,0 +1,54 @@
#ifndef STRING_H
#define STRING_H
#include <stddef.h>
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

41
include/string.h Normal file
View File

@@ -0,0 +1,41 @@
#ifndef _STRING_H
#define _STRING_H
#include <stddef.h>
#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

27
include/time.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef _TIME_H
#define _TIME_H
/*#ifdef __cplusplus
extern "C"{
#endif
#include <stddef.h>
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

25
include/unistd.h Normal file
View File

@@ -0,0 +1,25 @@
#ifndef _UNISTD_H
#define _UNISTD_H
#include <stddef.h>
#ifdef __cplusplus
extern "C"
{
#endif
#include <types/pid.h>
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

191
include/vector Normal file
View File

@@ -0,0 +1,191 @@
#ifndef VECTOR_H
#define VECTOR_H
#include <stdlib.h>
#include <string.h>
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 <typename T>
class vector
{
public:
vector();
vector(int capacity);
vector(const vector<T> &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 <typename T>
vector<T>::vector()
{
_size = 0;
_capacity = 8;
array = malloc(sizeof(T) * _capacity);
memset((void *)array, 0, sizeof(T) * _capacity);
// array = new T[_capacity];
}
template <typename T>
vector<T>::vector(int capacity)
{
_size = 0;
_capacity = capacity;
array = malloc(sizeof(T) * _capacity);
memset((void *)array, 0, sizeof(T) * _capacity);
// array = new T[_capacity];
}
template <typename T>
vector<T>::vector(const vector<T> &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 <typename T>
vector<T>::~vector()
{
for (int i = 0; i < _size; i++)
{
array[i].~T();
}
free(array);
// if (array != nullptr)
// delete[] array;
}
template <typename T>
bool vector<T>::empty() const
{
return _size == 0;
}
template <typename T>
int vector<T>::size() const
{
return _size;
}
template <typename T>
int vector<T>::capacity() const
{
return _capacity;
}
template <typename T>
T &vector<T>::operator[](int index) const
{
return array[index];
}
template <typename T>
void vector<T>::push_back(const T &data)
{
if (_size == _capacity)
resize(_capacity * 2);
new (&array[_size]) T(data);
// array[_size] = data;
_size++;
}
template <typename T>
void vector<T>::pop_back()
{
array[_size - 1].~T();
_size--;
}
template <typename T>
T &vector<T>::back()
{
return array[_size - 1];
}
template <typename T>
T &vector<T>::front()
{
return array[0];
}
template <typename T>
void vector<T>::remove(int index)
{
while (index < _size - 1)
{
array[index] = array[index + 1];
index++;
}
pop_back();
}
template <typename T>
void vector<T>::clear()
{
for (int i = 0; i < _size; i++)
array[i].~T();
_size = 0;
}
template <typename T>
void vector<T>::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

0
include/wait.h Normal file
View File

7
main.c Normal file
View File

@@ -0,0 +1,7 @@
#include <stdio.h>
#include "include/math.h"
int main() {
printf("acosh(%f): %f\n", 5.0, acosh(5.0));
return 0;
}

29
src/aarch64/crt0.s Normal file
View File

@@ -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

45
src/dirent.c Normal file
View File

@@ -0,0 +1,45 @@
#include "dirent.h"
#include <stddef.h>
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;
}

32
src/execve.c Normal file
View File

@@ -0,0 +1,32 @@
#include "unistd.h"
#include "string.h"
#include <sys/syscall.h>
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;
}

9
src/fork.c Normal file
View File

@@ -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;
}

10
src/getcwd.c Normal file
View File

@@ -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;
}

299
src/heap/heap.c Normal file
View File

@@ -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 <sys/syscall.h>
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) {
}
}
}

36
src/heap/heap.h Normal file
View File

@@ -0,0 +1,36 @@
#ifndef _KERNEL_HEAP_H
#define _KERNEL_HEAP_H
#include <stdint.h>
#include "string.h"
#include <sys/syscall.h>
#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

1078
src/math.c Normal file

File diff suppressed because it is too large Load Diff

8
src/mkdir.c Normal file
View File

@@ -0,0 +1,8 @@
#include "stdio.h"
//TEMPORARY FILE
int mkdir(const char *pathname) {
printf("LIBC: FUNCTION STUB NOT IMPLEMENTED");
return 0;
}

21
src/stdio/fgetc.c Normal file
View File

@@ -0,0 +1,21 @@
#include "stdio.h"
#include <sys/syscall.h>
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;
}

53
src/stdio/fgets.c Normal file
View File

@@ -0,0 +1,53 @@
#include <stddef.h>
#include "stdio.h"
#include "string.h"
#include <sys/syscall.h>
#include <types/status.h>
// 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;
}

11
src/stdio/file/fio.c Normal file
View File

@@ -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;
}

8
src/stdio/getchar.c Normal file
View File

@@ -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);
}

23
src/stdio/print/fprintf.c Normal file
View File

@@ -0,0 +1,23 @@
#include "stdio.h"
#include "string.h"
#include <sys/syscall.h>
/*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;
}

16
src/stdio/print/printf.c Normal file
View File

@@ -0,0 +1,16 @@
#include "stdio.h"
#include "string.h"
#include <sys/syscall.h>
// #include <sys/syscall.h>
/*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;
}

View File

@@ -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;
}

12
src/stdio/print/sprintf.c Normal file
View File

@@ -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;
}

View File

@@ -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;
}

16
src/stdio/print/vprintf.c Normal file
View File

@@ -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;
}

113
src/stdio/print/vsnprintf.c Normal file
View File

@@ -0,0 +1,113 @@
#include "stdio.h"
#include <stddef.h>
#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;
}

112
src/stdio/print/vsprintf.c Normal file
View File

@@ -0,0 +1,112 @@
#include "stdio.h"
#include <stddef.h>
#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;
}

11
src/stdio/scan/fscanf.c Normal file
View File

@@ -0,0 +1,11 @@
#include <stdarg.h>
#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;
}

20
src/stdio/scan/scanf.c Normal file
View File

@@ -0,0 +1,20 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
#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;
};

13
src/stdio/scan/sscanf.c Normal file
View File

@@ -0,0 +1,13 @@
#include <stdarg.h>
#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;
}

10
src/stdio/scan/vfscanf.c Normal file
View File

@@ -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);
}

11
src/stdio/scan/vscanf.c Normal file
View File

@@ -0,0 +1,11 @@
#include <stdarg.h>
#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;
}

747
src/stdio/scan/vsscanf.c Normal file
View File

@@ -0,0 +1,747 @@
#include <stdarg.h>
#include <stddef.h>
#include <stdbool.h>
#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 */
}

5
src/stdio/stdin.c Normal file
View File

@@ -0,0 +1,5 @@
#include "stdio.h"
const int fd_stdin = 0;
const int fd_stdout = 1;
const int fd_stderr = 2;

296
src/stdlib/stdlib.c Normal file
View File

@@ -0,0 +1,296 @@
#include "heap/heap.h"
#include "stdlib.h"
#include <sys/syscall.h>
/*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;
}

265
src/string.c Normal file
View File

@@ -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;
}

342
src/stringclass.cpp Normal file
View File

@@ -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;
}

17
src/uinit.c Normal file
View File

@@ -0,0 +1,17 @@
#include "heap/heap.h"
#include "stdio.h"
#include <sys/syscall.h>
/* 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);
}

32
src/unistd.c Normal file
View File

@@ -0,0 +1,32 @@
#include "unistd.h"
#include <sys/syscall.h>
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;
}

31
src/wait.c Normal file
View File

@@ -0,0 +1,31 @@
#include "stdlib.h"
#include <sys/syscall.h>
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;
}

29
test-makefile Normal file
View File

@@ -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