From df8ced739e79757e9c96bd8ae184f0857574c0d6 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 7 Dec 2012 13:19:18 +0800 Subject: [PATCH] Usermode/libc-libposix - Features for SpiderWeb/SpiderScript - Floating point parsing - inttypes. - A few string functions - readdir & firends --- Usermode/Libraries/libc.so_src/Makefile | 2 +- Usermode/Libraries/libc.so_src/arch/x86.asm | 4 +- .../libc.so_src/include_exp/inttypes.h | 13 ++ .../libc.so_src/include_exp/setjmp.h | 4 +- .../Libraries/libc.so_src/include_exp/stdio.h | 4 +- .../libc.so_src/include_exp/stdlib.h | 5 + .../libc.so_src/include_exp/string.h | 1 + Usermode/Libraries/libc.so_src/scanf.c | 5 +- Usermode/Libraries/libc.so_src/stdio.c | 29 +++- Usermode/Libraries/libc.so_src/string.c | 12 ++ Usermode/Libraries/libc.so_src/strtof.c | 136 ++++++++++++++++++ Usermode/Libraries/libposix.so_src/Makefile | 2 +- Usermode/Libraries/libposix.so_src/dirent.c | 75 ++++++++++ .../libposix.so_src/include_exp/dirent.h | 4 +- 14 files changed, 286 insertions(+), 10 deletions(-) create mode 100644 Usermode/Libraries/libc.so_src/include_exp/inttypes.h create mode 100644 Usermode/Libraries/libc.so_src/strtof.c create mode 100644 Usermode/Libraries/libposix.so_src/dirent.c diff --git a/Usermode/Libraries/libc.so_src/Makefile b/Usermode/Libraries/libc.so_src/Makefile index b890d482..31adb5c2 100644 --- a/Usermode/Libraries/libc.so_src/Makefile +++ b/Usermode/Libraries/libc.so_src/Makefile @@ -11,7 +11,7 @@ LDFLAGS += -soname libc.so -Map map.txt INCFILES := stdio.h stdlib.h OBJ = stub.o heap.o stdlib.o env.o stdio.o string.o select.o rand.o -OBJ += perror.o scanf.o signals.o strtoi.o +OBJ += perror.o scanf.o signals.o strtoi.o strtof.o OBJ += arch/$(ARCHDIR).ao # signals.o DEPFILES := $(OBJ:%.o=%.d) diff --git a/Usermode/Libraries/libc.so_src/arch/x86.asm b/Usermode/Libraries/libc.so_src/arch/x86.asm index f95f28f1..eafc4550 100644 --- a/Usermode/Libraries/libc.so_src/arch/x86.asm +++ b/Usermode/Libraries/libc.so_src/arch/x86.asm @@ -7,7 +7,7 @@ [bits 32] [section .text] -[global setjmp] +[global setjmp:function] setjmp: mov eax, [esp+4] ; Get base of buffer @@ -25,7 +25,7 @@ setjmp: setjmp.restore: ret -[global longjmp] +[global longjmp:function] longjmp: mov ebp, [esp+4] ; jmp_buf mov eax, [esp+8] ; value diff --git a/Usermode/Libraries/libc.so_src/include_exp/inttypes.h b/Usermode/Libraries/libc.so_src/include_exp/inttypes.h new file mode 100644 index 00000000..df92f77d --- /dev/null +++ b/Usermode/Libraries/libc.so_src/include_exp/inttypes.h @@ -0,0 +1,13 @@ + +#define PRId64 "lld" +#define PRIdLEAST64 "lld" +#define PRIdFAST64 "lld" +#define PRIdMAX +#define PRIdPTR +#define PRIi64 +#define PRIiLEAST64 +#define PRIiFAST64 +#define PRIiMAX +#define PRIiPTR + +#define PRIx64 "llx" diff --git a/Usermode/Libraries/libc.so_src/include_exp/setjmp.h b/Usermode/Libraries/libc.so_src/include_exp/setjmp.h index 53f3fbf2..2e59c6d2 100644 --- a/Usermode/Libraries/libc.so_src/include_exp/setjmp.h +++ b/Usermode/Libraries/libc.so_src/include_exp/setjmp.h @@ -9,9 +9,9 @@ #define _LIBC_SETJMP_H_ #if ARCHDIR_is_x86 -typedef uint32_t jmp_buf[8]; +typedef void *jmp_buf[8]; #elif ARCHDIR_is_x86_64 -typedef uint64_t jmp_buf[16]; +typedef void *jmp_buf[16]; #else # error "Unknown Architecture" #endif diff --git a/Usermode/Libraries/libc.so_src/include_exp/stdio.h b/Usermode/Libraries/libc.so_src/include_exp/stdio.h index d8643eb0..4a81c18b 100644 --- a/Usermode/Libraries/libc.so_src/include_exp/stdio.h +++ b/Usermode/Libraries/libc.so_src/include_exp/stdio.h @@ -36,9 +36,11 @@ extern int ferror(FILE *stream); extern int fileno(FILE *stream); extern size_t fread(void *buf, size_t size, size_t n, FILE *fp); -extern size_t fwrite(void *buf, size_t size, size_t n, FILE *fp); +extern size_t fwrite(const void *buf, size_t size, size_t n, FILE *fp); extern int fgetc(FILE *fp); +extern char *fgets(char *s, int size, FILE *fp); extern int fputc(int ch, FILE *fp); +extern int fputs(const char *s, FILE *fp); extern int getchar(void); extern int putchar(int ch); diff --git a/Usermode/Libraries/libc.so_src/include_exp/stdlib.h b/Usermode/Libraries/libc.so_src/include_exp/stdlib.h index 7676afef..acba0821 100644 --- a/Usermode/Libraries/libc.so_src/include_exp/stdlib.h +++ b/Usermode/Libraries/libc.so_src/include_exp/stdlib.h @@ -26,6 +26,11 @@ extern long strtol(const char *ptr, char **end, int base); extern unsigned long long strtoull(const char *ptr, char **end, int base); extern unsigned long strtoul(const char *ptr, char **end, int base); extern int atoi(const char *ptr); + +extern double strtod(const char *ptr, char **end); +extern float strtof(const char *ptr, char **end); +extern float atof(const char *ptr); + extern void exit(int status) __attribute__((noreturn)); extern void abort(void); extern void atexit(void (*__func)(void)); diff --git a/Usermode/Libraries/libc.so_src/include_exp/string.h b/Usermode/Libraries/libc.so_src/include_exp/string.h index 7c38602d..493d5efe 100644 --- a/Usermode/Libraries/libc.so_src/include_exp/string.h +++ b/Usermode/Libraries/libc.so_src/include_exp/string.h @@ -17,6 +17,7 @@ extern int strncasecmp(const char *s1, const char *s2, size_t maxlen); extern char *strcpy(char *dst, const char *src); extern char *strncpy(char *dst, const char *src, size_t num); extern char *strcat(char *dst, const char *src); +extern char *strncat(char *dest, const char *src, size_t n); extern char *strdup(const char *src); extern char *strndup(const char *src, size_t length); extern char *strchr(const char *str, int character); diff --git a/Usermode/Libraries/libc.so_src/scanf.c b/Usermode/Libraries/libc.so_src/scanf.c index 3a561c4b..6a1d584f 100644 --- a/Usermode/Libraries/libc.so_src/scanf.c +++ b/Usermode/Libraries/libc.so_src/scanf.c @@ -148,7 +148,8 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char } ptr; long long ival; //long double rval; - int maxlen = 0, offset = -1; + int maxlen = 0; + // int offset = -1; enum e_vcscanf_sizes size = _VCSCANF_UNDEF; enum e_vcscanf_types valtype; @@ -185,12 +186,14 @@ int _vcscanf(int (*__getc)(void*), void (*__rewind)(void*), void *h, const char } // %n$ - Direct offset selection, shouldn't be mixed with just % + #if 0 for( ; isdigit(fch); fch = *format++ ) maxlen = maxlen * 10 + (fch - '0'); if( fch == '$' ) { offset = maxlen; maxlen = 0; } + #endif // Supress assignemnt? if( fch == '*' ) diff --git a/Usermode/Libraries/libc.so_src/stdio.c b/Usermode/Libraries/libc.so_src/stdio.c index 1dde9ade..840e24d4 100644 --- a/Usermode/Libraries/libc.so_src/stdio.c +++ b/Usermode/Libraries/libc.so_src/stdio.c @@ -300,7 +300,7 @@ EXPORT int fprintf(FILE *fp, const char *format, ...) * \fn EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) * \brief Write to a stream */ -EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp) +EXPORT size_t fwrite(const void *ptr, size_t size, size_t num, FILE *fp) { size_t ret; @@ -354,6 +354,33 @@ EXPORT size_t fread(void *ptr, size_t size, size_t num, FILE *fp) return ret; } +/** + * \brief Write a string to a stream (without trailing \n) + */ +EXPORT int fputs(const char *s, FILE *fp) +{ + int len = strlen(s); + return fwrite(s, 1, len, fp); +} + +/** + * \brief Read a line (and possible trailing \n into a buffer) + */ +EXPORT char *fgets(char *s, int size, FILE *fp) +{ + int ofs = 0; + char ch = '\0'; + while( ofs < size && ch != '\n' ) + { + if( fread(&ch, 1, 1, fp) != 1 ) + break; + s[ofs ++] = ch; + } + if( ofs < size ) + s[ofs] = '\0'; + return s; +} + /** * \fn EXPORT int fputc(int c, FILE *fp) * \brief Write a single character to the stream diff --git a/Usermode/Libraries/libc.so_src/string.c b/Usermode/Libraries/libc.so_src/string.c index d8d08721..3d30f1c6 100644 --- a/Usermode/Libraries/libc.so_src/string.c +++ b/Usermode/Libraries/libc.so_src/string.c @@ -100,6 +100,18 @@ EXPORT char *strcat(char *dst, const char *src) return dst; } +EXPORT char *strncat(char *dst, const char *src, size_t n) +{ + char *to = dst; + // Find the end + while(*to) to++; + // Copy + while(*src && n--) *to++ = *src++; + // End string + *to = '\0'; + return dst; +} + /** * \brief Get the length of a string */ diff --git a/Usermode/Libraries/libc.so_src/strtof.c b/Usermode/Libraries/libc.so_src/strtof.c new file mode 100644 index 00000000..ff5db49d --- /dev/null +++ b/Usermode/Libraries/libc.so_src/strtof.c @@ -0,0 +1,136 @@ +/* + * Acess2 C Library + * - By John Hodge (thePowersGang) + * + * strtof.c + * - strto[df]/atof implimentation + */ +#include +#include +#include +#include +#include // strtoll + +double strtod(const char *ptr, char **end) +{ + int negative = 0; + int is_hex = 0; + double rv = 0; + char *tmp; + + while( isspace(*ptr) ) + ptr ++; + + if( *ptr == '+' || *ptr == '-' ) + { + negative = (*ptr == '-'); + ptr ++; + } + + #if 0 + // NAN.* + if( strncasecmp(ptr, "NAN", 3) == 0) + { + ptr += 3; + while( isalnum(*ptr) || *ptr == '_' ) + ptr ++; + + rv = negative ? -NAN : NAN; + if(end) *end = ptr; + return rv; + } + + // INF/INFINITY + if( strncasecmp(ptr, "INF", 3) == 0 ) + { + if( strncasecmp(ptr, "INFINITY", 8) == 0 ) + ptr += 8; + else + ptr += 3; + rv = negative ? -INFINITY : INFINITY; + if(end) *end = ptr; + return rv; + } + #endif + + if( *ptr == '0' && (ptr[1] == 'X' || ptr[1] == 'x') ) + { + is_hex = 1; + ptr += 2; + } + + rv = strtoll(ptr, &tmp, (is_hex ? 16 : 10)); + + // TODO: errors? + + ptr = tmp; + if( *ptr == '.' ) + { + ptr ++; + if( isspace(*ptr) || *ptr == '-' || *ptr == '+' ) { + goto _err; + } + double frac = strtoll(ptr, &tmp, (is_hex ? 16 : 10)); + // TODO: Error check + while( ptr != tmp ) + { + frac /= 10; + ptr ++; + } + rv += frac; + } + + int exp = 0; + if( is_hex ) + { + if( *ptr == 'P' || *ptr == 'p' ) + { + ptr ++; + exp = strtoll(ptr, &tmp, 16); + ptr = tmp; + } + } + else + { + if( *ptr == 'E' || *ptr == 'e' ) + { + ptr ++; + exp = strtoll(ptr, &tmp, 10); + ptr = tmp; + } + } + + if( exp == 0 ) + ; + else if( exp < 0 ) + while( exp ++ ) + rv /= 10; + else + while( exp -- ) + rv *= 10; + + if( negative ) + rv = -rv; + + if( end ) + *end = (char*)ptr; + + return rv; +_err: + if( end ) + *end = (char*)ptr; + + return 0.0f; +} + +float strtof(const char *ptr, char **end) +{ + double rv = strtod(ptr, end); + // TODO: ERANGE + return rv; +} + +float atof(const char *ptr) +{ + return strtof(ptr, NULL); +} diff --git a/Usermode/Libraries/libposix.so_src/Makefile b/Usermode/Libraries/libposix.so_src/Makefile index 2f472fc7..73a0622f 100644 --- a/Usermode/Libraries/libposix.so_src/Makefile +++ b/Usermode/Libraries/libposix.so_src/Makefile @@ -8,7 +8,7 @@ CFLAGS += -Werror -Wextra ASFLAGS += LDFLAGS += -soname libposix.so -Map map.txt -OBJ = main.o unistd.o +OBJ = main.o unistd.o dirent.o DEPFILES := $(OBJ:%.o=%.d) BIN = libposix.so diff --git a/Usermode/Libraries/libposix.so_src/dirent.c b/Usermode/Libraries/libposix.so_src/dirent.c new file mode 100644 index 00000000..5722aa45 --- /dev/null +++ b/Usermode/Libraries/libposix.so_src/dirent.c @@ -0,0 +1,75 @@ +/* + * Acess2 C Library + * - By John Hodge (thePowersGang) + * + * dirent.c + * - Directory Functions + */ +#include +#include // NULL +#include +#include + +struct DIR_s +{ + int fd; + int pos; + struct dirent tmpent; +}; + +// === CODE === +DIR *fdopendir(int fd) +{ + t_sysFInfo info; + if( _SysFInfo(fd, &info, 0) != 0 ) + return NULL; + + + + return NULL; +} + +DIR *opendir(const char *name) +{ + int fd = _SysOpen(name, OPENFLAG_READ); + if( fd == -1 ) + return NULL; + + DIR *ret = fdopendir(fd); + if( !ret ) { + _SysClose(fd); + } + return ret; +} + +int closedir(DIR *dp) +{ + if( !dp ) { + errno = EINVAL; + return -1; + } + return 0; +} + +struct dirent *readdir(DIR *dp) +{ + if( !dp ) { + errno = EINVAL; + return NULL; + } + + errno = EOK; + int rv = _SysReadDir(dp->fd, dp->tmpent.d_name); + if( rv != 1 ) { + // TODO: Fix kernel-land API + return NULL; + } + dp->tmpent.d_ino = 0; + + return &dp->tmpent; +} + +extern int readdir_r(DIR *, struct dirent *, struct dirent **); +extern void rewinddir(DIR *); +extern void seekdir(DIR *, long int); +extern long int telldir(DIR *); diff --git a/Usermode/Libraries/libposix.so_src/include_exp/dirent.h b/Usermode/Libraries/libposix.so_src/include_exp/dirent.h index 4f2c0b30..747d7ea5 100644 --- a/Usermode/Libraries/libposix.so_src/include_exp/dirent.h +++ b/Usermode/Libraries/libposix.so_src/include_exp/dirent.h @@ -8,6 +8,8 @@ #ifndef _LIBPOSIX__SYS__DIRENT_H_ #define _LIBPOSIX__SYS__DIRENT_H_ +#include "sys/stat.h" + #define NAME_MAX 255 struct dirent @@ -18,8 +20,8 @@ struct dirent typedef struct DIR_s DIR; -extern int closedir(DIR *); extern DIR *opendir(const char *); +extern int closedir(DIR *); extern struct dirent *readdir(DIR *); extern int readdir_r(DIR *, struct dirent *, struct dirent **); extern void rewinddir(DIR *); -- 2.20.1