diff --git a/libc/include/assert.h b/libc/include/assert.h new file mode 100644 index 0000000..91ab8a4 --- /dev/null +++ b/libc/include/assert.h @@ -0,0 +1,4 @@ +#ifndef _ASSERT_H +#define _ASSERT_H + +#endif diff --git a/libc/include/aux.h b/libc/include/aux.h index 88827ac..d450b59 100644 --- a/libc/include/aux.h +++ b/libc/include/aux.h @@ -1,7 +1,7 @@ #ifndef __FENNIX_LIBC_AUX_H__ #define __FENNIX_LIBC_AUX_H__ -#include +#include #define AT_NULL 0 #define AT_IGNORE 1 @@ -44,11 +44,26 @@ typedef struct { - unsigned long a_type; + uint32_t a_type; union { - unsigned long a_val; + uint32_t a_val; + } a_un; +} Elf32_auxv_t; + +typedef struct +{ + uint64_t a_type; + union + { + uint64_t a_val; } a_un; } Elf64_auxv_t; +#ifdef __LP64__ +#define Elf_auxv_t Elf64_auxv_t +#else +#define Elf_auxv_t Elf32_auxv_t +#endif + #endif // !__FENNIX_LIBC_AUX_H__ diff --git a/libc/include/ctype.h b/libc/include/ctype.h index 02665dc..d8925e1 100644 --- a/libc/include/ctype.h +++ b/libc/include/ctype.h @@ -1,4 +1,8 @@ #ifndef _CTYPE_H #define _CTYPE_H +int tolower(int c); +int toupper(int c); +int isspace(int c); + #endif // !_CTYPE_H diff --git a/libc/include/errno.h b/libc/include/errno.h index 34e6c68..361f042 100644 --- a/libc/include/errno.h +++ b/libc/include/errno.h @@ -1,4 +1,42 @@ #ifndef _ERRNO_H #define _ERRNO_H +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ + +extern int *__errno_location(void) __attribute__((const)); +#define errno (*__errno_location()) + #endif diff --git a/libc/include/limits.h b/libc/include/limits.h new file mode 100644 index 0000000..e259acf --- /dev/null +++ b/libc/include/limits.h @@ -0,0 +1,119 @@ +#ifndef _LIMITS_H +#define _LIMITS_H + +#undef CHAR_BIT +#define CHAR_BIT __CHAR_BIT__ + +#ifndef MB_LEN_MAX +#define MB_LEN_MAX 1 +#endif + +#undef SCHAR_MIN +#define SCHAR_MIN (-SCHAR_MAX - 1) +#undef SCHAR_MAX +#define SCHAR_MAX __SCHAR_MAX__ + +#undef UCHAR_MAX +#if __SCHAR_MAX__ == __INT_MAX__ +#define UCHAR_MAX (SCHAR_MAX * 2U + 1U) +#else +#define UCHAR_MAX (SCHAR_MAX * 2 + 1) +#endif + +#ifdef __CHAR_UNSIGNED__ +#undef CHAR_MIN +#if __SCHAR_MAX__ == __INT_MAX__ +#define CHAR_MIN 0U +#else +#define CHAR_MIN 0 +#endif +#undef CHAR_MAX +#define CHAR_MAX UCHAR_MAX +#else +#undef CHAR_MIN +#define CHAR_MIN SCHAR_MIN +#undef CHAR_MAX +#define CHAR_MAX SCHAR_MAX +#endif + +#undef SHRT_MIN +#define SHRT_MIN (-SHRT_MAX - 1) +#undef SHRT_MAX +#define SHRT_MAX __SHRT_MAX__ + +#undef USHRT_MAX +#if __SHRT_MAX__ == __INT_MAX__ +#define USHRT_MAX (SHRT_MAX * 2U + 1U) +#else +#define USHRT_MAX (SHRT_MAX * 2 + 1) +#endif + +#undef INT_MIN +#define INT_MIN (-INT_MAX - 1) +#undef INT_MAX +#define INT_MAX __INT_MAX__ + +#undef UINT_MAX +#define UINT_MAX (INT_MAX * 2U + 1U) + +#undef LONG_MIN +#define LONG_MIN (-LONG_MAX - 1L) +#undef LONG_MAX +#define LONG_MAX __LONG_MAX__ + +#undef ULONG_MAX +#define ULONG_MAX (LONG_MAX * 2UL + 1UL) + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +#undef LLONG_MIN +#define LLONG_MIN (-LLONG_MAX - 1LL) +#undef LLONG_MAX +#define LLONG_MAX __LONG_LONG_MAX__ + +#undef ULLONG_MAX +#define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL) +#endif + +#if defined(__GNU_LIBRARY__) ? defined(__USE_GNU) : !defined(__STRICT_ANSI__) +#undef LONG_LONG_MIN +#define LONG_LONG_MIN (-LONG_LONG_MAX - 1LL) +#undef LONG_LONG_MAX +#define LONG_LONG_MAX __LONG_LONG_MAX__ + +#undef ULONG_LONG_MAX +#define ULONG_LONG_MAX (LONG_LONG_MAX * 2ULL + 1ULL) +#endif + +#if (defined __STDC_WANT_IEC_60559_BFP_EXT__ || (defined(__STDC_VERSION__) && __STDC_VERSION__ > 201710L)) +#undef CHAR_WIDTH +#define CHAR_WIDTH __SCHAR_WIDTH__ +#undef SCHAR_WIDTH +#define SCHAR_WIDTH __SCHAR_WIDTH__ +#undef UCHAR_WIDTH +#define UCHAR_WIDTH __SCHAR_WIDTH__ +#undef SHRT_WIDTH +#define SHRT_WIDTH __SHRT_WIDTH__ +#undef USHRT_WIDTH +#define USHRT_WIDTH __SHRT_WIDTH__ +#undef INT_WIDTH +#define INT_WIDTH __INT_WIDTH__ +#undef UINT_WIDTH +#define UINT_WIDTH __INT_WIDTH__ +#undef LONG_WIDTH +#define LONG_WIDTH __LONG_WIDTH__ +#undef ULONG_WIDTH +#define ULONG_WIDTH __LONG_WIDTH__ +#undef LLONG_WIDTH +#define LLONG_WIDTH __LONG_LONG_WIDTH__ +#undef ULLONG_WIDTH +#define ULLONG_WIDTH __LONG_LONG_WIDTH__ +#endif + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 201710L +#undef BOOL_MAX +#define BOOL_MAX 1 +#undef BOOL_WIDTH +#define BOOL_WIDTH 1 +#endif + +#endif // !_LIMITS_H diff --git a/libc/include/stdio.h b/libc/include/stdio.h index 4429148..1572138 100644 --- a/libc/include/stdio.h +++ b/libc/include/stdio.h @@ -5,6 +5,8 @@ #include #define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 typedef struct { @@ -31,12 +33,17 @@ extern "C" size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream); void setbuf(FILE *stream, char *buf); int vfprintf(FILE *stream, const char *format, va_list arg); + int vsscanf(const char *s, const char *format, va_list arg); + int sscanf(const char *s, const char *format, ...); - int puts(const char *s); + int fputc(int c, FILE *stream); + int putc(int c, FILE *stream); + int fputs(const char *s, FILE *stream); int putchar(int c); + int puts(const char *s); #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h index fb730ff..9c7589c 100644 --- a/libc/include/stdlib.h +++ b/libc/include/stdlib.h @@ -18,6 +18,9 @@ extern "C" void *realloc(void *Address, size_t Size); void *calloc(size_t Count, size_t Size); void free(void *Address); + int system(const char *command); + + double atof(const char *nptr); #ifdef __cplusplus } diff --git a/libc/include/string.h b/libc/include/string.h index c0eafe7..715ccf5 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -8,11 +8,18 @@ extern "C" { #endif - void *memcpy(void *, const void *, size_t); - void *memset(void *, int, size_t); - char *strcpy(char *, const char *); - size_t strlen(const char *); + size_t strlen(const char *str); + int strcmp(const char *l, const char *r); int strncmp(const char *s1, const char *s2, size_t n); + int strcasecmp(const char *s1, const char *s2); + int strncasecmp(const char *string1, const char *string2, size_t count); + char *strstr(const char *haystack, const char *needle); + char *strncpy(char *destination, const char *source, unsigned long num); + char *strdup(const char *s); + char *strchr(char const *s, int c); + char *strrchr(char const *s, int c); + + void *memmove(void *dest, const void *src, size_t n); #ifdef __cplusplus } diff --git a/libc/include/sys/stat.h b/libc/include/sys/stat.h index 98ebeed..80471f2 100644 --- a/libc/include/sys/stat.h +++ b/libc/include/sys/stat.h @@ -1,4 +1,18 @@ #ifndef _SYS_STAT_H #define _SYS_STAT_H +typedef unsigned int _dev_t; +typedef unsigned short _ino_t; +typedef unsigned short _mode_t; +typedef int _off_t; + +#define dev_t _dev_t +#define ino_t _ino_t +#define mode_t _mode_t +#define off_t _off_t + +int mkdir(const char *path, mode_t mode); +int remove(const char *pathname); +int rename(const char *oldpath, const char *newpath); + #endif diff --git a/libc/include/sys/time.h b/libc/include/sys/time.h new file mode 100644 index 0000000..b24289f --- /dev/null +++ b/libc/include/sys/time.h @@ -0,0 +1,4 @@ +#ifndef _SYS_TIME_H +#define _SYS_TIME_H + +#endif diff --git a/libc/src/Makefile b/libc/src/Makefile index f288986..7b8f030 100644 --- a/libc/src/Makefile +++ b/libc/src/Makefile @@ -19,6 +19,7 @@ ASM_SOURCES = $(shell find ./ -type f -name '*.asm') OBJ = ${C_SOURCES:.c=.o} ${CPP_SOURCES:.cpp=.o} ${ASM_SOURCES:.asm=.o} ${S_SOURCES:.S=.o} INCLUDE = ../include +INCLUDE2 = ../../out/system/include ifeq ($(OSARCH), amd64) ASM_ARCH := elf64 @@ -26,7 +27,7 @@ else ifeq ($(OSARCH), i386) ASM_ARCH := elf32 endif -CFLAGS := -fPIC -I$(INCLUDE) +CFLAGS := -fPIC -I$(INCLUDE) -I$(INCLUDE2) build: $(OBJECT_NAME) diff --git a/libc/src/std/ctype.c b/libc/src/std/ctype.c new file mode 100644 index 0000000..8258be5 --- /dev/null +++ b/libc/src/std/ctype.c @@ -0,0 +1,27 @@ +#include + +int tolower(int c) +{ + if (c >= 'A' && c <= 'Z') + { + c -= 'A'; + c += 'a'; + } + + return c; +} + +int toupper(int c) +{ + if (c >= 'a' && c <= 'z') + { + c -= 'a'; + c += 'A'; + } + return c; +} + +int isspace(int c) +{ + return c == ' ' || c == '\t' || c == '\r' || c == '\n' || c == '\f' || c == '\v'; +} diff --git a/libc/src/std/errno.c b/libc/src/std/errno.c new file mode 100644 index 0000000..88f8478 --- /dev/null +++ b/libc/src/std/errno.c @@ -0,0 +1,6 @@ +#include + +int *__errno_location(void) +{ + return 0; +} \ No newline at end of file diff --git a/libc/src/std/io.c b/libc/src/std/io.c index d15017a..9b769a7 100644 --- a/libc/src/std/io.c +++ b/libc/src/std/io.c @@ -1,5 +1,6 @@ #include #include +#include FILE *stdin; FILE *stdout; @@ -54,17 +55,47 @@ void setbuf(FILE *stream, char *buf) { } -// int vfprintf(FILE *stream, const char *format, va_list arg) -// { -// return 0; -// } - -int puts(const char *s) +int vfprintf(FILE *stream, const char *format, va_list arg) { return 0; } +int vsscanf(const char *s, const char *format, va_list arg) +{ +} + +int sscanf(const char *s, const char *format, ...) +{ + va_list args; + va_start(args, format); + const int ret = vsscanf(s, format, args); + va_end(args); + return ret; +} + +int fputc(int c, FILE *stream) +{ + syscall1(_Print, c); +} + +int putc(int c, FILE *stream) +{ + syscall1(_Print, c); +} + +int fputs(const char *s, FILE *stream) +{ + for (int i = 0; s[i] != '\0'; i++) + fputc(s[i], stream); +} + int putchar(int c) { - return 0; + syscall1(_Print, c); +} + +int puts(const char *s) +{ + for (int i = 0; s[i] != '\0'; i++) + fputc(s[i], stdout); } diff --git a/libc/src/std/lib.c b/libc/src/std/lib.c index 482ec45..286a128 100644 --- a/libc/src/std/lib.c +++ b/libc/src/std/lib.c @@ -23,8 +23,7 @@ void exit(int status) int atoi(const char *nptr) { - // uint64_t Length = strlen((char *)nptr); - uint64_t Length = 0; + uint64_t Length = strlen((char *)nptr); if (nptr) while (nptr[Length] != '\0') ++Length; @@ -62,3 +61,25 @@ void free(void *Address) PREFIX(free) (Address); } + +int system(const char *command) +{ + return 0; +} + +double atof(const char *nptr) +{ + // FIXME: This is a very bad implementation of atof. + uint64_t Length = strlen((char *)nptr); + if (nptr) + while (nptr[Length] != '\0') + ++Length; + double OutBuffer = 0; + double Power = 1; + for (uint64_t i = Length; i > 0; --i) + { + OutBuffer += (nptr[i - 1] - 48) * Power; + Power *= 10; + } + return OutBuffer; +} diff --git a/libc/src/std/string.c b/libc/src/std/string.c new file mode 100644 index 0000000..d3f151d --- /dev/null +++ b/libc/src/std/string.c @@ -0,0 +1,142 @@ +#include + +#include "../mem/liballoc_1_1.h" + +size_t strlen(const char *str) +{ + long unsigned i = 0; + if (str) + while (str[i] != '\0') + ++i; + return i; +} + +int strcmp(const char *l, const char *r) +{ + for (; *l == *r && *l; l++, r++) + ; + return *(unsigned char *)l - *(unsigned char *)r; +} + +int strncmp(const char *s1, const char *s2, size_t n) +{ + for (size_t i = 0; i < n; i++) + { + char c1 = s1[i], c2 = s2[i]; + if (c1 != c2) + return c1 - c2; + if (!c1) + return 0; + } + return 0; +} + +int strcasecmp(const char *s1, const char *s2) +{ + const unsigned char *p1 = (const unsigned char *)s1; + const unsigned char *p2 = (const unsigned char *)s2; + int result; + if (p1 == p2) + return 0; + while ((result = tolower(*p1) - tolower(*p2++)) == 0) + if (*p1++ == '\0') + break; + return result; +} + +int strncasecmp(const char *string1, const char *string2, size_t count) +{ + if (count) + { + const unsigned char *s1 = (const unsigned char *)string1; + const unsigned char *s2 = (const unsigned char *)string2; + int result; + do + { + if ((result = tolower(*s1) - tolower(*s2++)) != 0 || !*s1++) + break; + } while (--count); + return result; + } + return 0; +} + +char *strstr(const char *haystack, const char *needle) +{ + const char *a = haystack, *b = needle; + while (1) + { + if (!*b) + return (char *)haystack; + if (!*a) + return NULL; + if (*a++ != *b++) + { + a = ++haystack; + b = needle; + } + } +} + +char *strncpy(char *destination, const char *source, unsigned long num) +{ + if (destination == NULL) + return NULL; + char *ptr = destination; + while (*source && num--) + { + *destination = *source; + destination++; + source++; + } + *destination = '\0'; + return ptr; +} + +char *strdup(const char *s) +{ + char *buf = (char *)__malloc(strlen((char *)s) + 1); + strncpy(buf, s, strlen(s) + 1); + return buf; +} + +char *strchr(char const *s, int c) +{ + size_t len = strlen(s); + for (size_t i = 0; i < len; i++) + if (s[i] == c) + return (char *)s + i; + + return NULL; +} + +char *strrchr(char const *s, int c) +{ + size_t len = strlen(s); + size_t pos = len; + + while (s[pos] != c && pos-- != 0) + ; + + if (pos == len) + return NULL; + + return (char *)s + pos; +} + +void *memmove(void *dest, const void *src, size_t n) +{ + char *d = dest; + const char *s = src; + if (d < s) + while (n--) + *d++ = *s++; + else + { + const char *lasts = s + (n - 1); + char *lastd = d + (n - 1); + while (n--) + *lastd-- = *lasts--; + } + return dest; +} diff --git a/libc/src/std/sys_stat.c b/libc/src/std/sys_stat.c new file mode 100644 index 0000000..0ba22d6 --- /dev/null +++ b/libc/src/std/sys_stat.c @@ -0,0 +1,16 @@ +#include + +int mkdir(const char *path, mode_t mode) +{ + return 0; +} + +int remove(const char *pathname) +{ + return 0; +} + +int rename(const char *oldpath, const char *newpath) +{ + return 0; +} \ No newline at end of file diff --git a/libc/src/string.c b/libc/src/string.c deleted file mode 100644 index 3ae0908..0000000 --- a/libc/src/string.c +++ /dev/null @@ -1,14 +0,0 @@ -#include - -int strncmp(const char *s1, const char *s2, size_t n) -{ - for (size_t i = 0; i < n; i++) - { - char c1 = s1[i], c2 = s2[i]; - if (c1 != c2) - return c1 - c2; - if (!c1) - return 0; - } - return 0; -}