INCFILES := stdio.h stdlib.h\r
\r
OBJ = stub.o heap.o stdlib.o env.o stdio.o string.o select.o rand.o\r
-OBJ += perror.o scanf.o signals.o strtoi.o\r
+OBJ += perror.o scanf.o signals.o strtoi.o strtof.o\r
OBJ += arch/$(ARCHDIR).ao\r
# signals.o\r
DEPFILES := $(OBJ:%.o=%.d)\r
[bits 32]
[section .text]
-[global setjmp]
+[global setjmp:function]
setjmp:
mov eax, [esp+4] ; Get base of buffer
setjmp.restore:
ret
-[global longjmp]
+[global longjmp:function]
longjmp:
mov ebp, [esp+4] ; jmp_buf
mov eax, [esp+8] ; value
--- /dev/null
+
+#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"
#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
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);
extern unsigned long long strtoull(const char *ptr, char **end, int base);\r
extern unsigned long strtoul(const char *ptr, char **end, int base);\r
extern int atoi(const char *ptr);\r
+\r
+extern double strtod(const char *ptr, char **end);\r
+extern float strtof(const char *ptr, char **end);\r
+extern float atof(const char *ptr);\r
+\r
extern void exit(int status) __attribute__((noreturn));\r
extern void abort(void);\r
extern void atexit(void (*__func)(void));\r
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);
} 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;
}
// %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 == '*' )
* \fn EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
* \brief Write to a stream\r
*/\r
-EXPORT size_t fwrite(void *ptr, size_t size, size_t num, FILE *fp)\r
+EXPORT size_t fwrite(const void *ptr, size_t size, size_t num, FILE *fp)\r
{\r
size_t ret;\r
\r
return ret;\r
}\r
\r
+/**\r
+ * \brief Write a string to a stream (without trailing \n)\r
+ */\r
+EXPORT int fputs(const char *s, FILE *fp)\r
+{\r
+ int len = strlen(s);\r
+ return fwrite(s, 1, len, fp);\r
+}\r
+\r
+/**\r
+ * \brief Read a line (and possible trailing \n into a buffer)\r
+ */\r
+EXPORT char *fgets(char *s, int size, FILE *fp)\r
+{\r
+ int ofs = 0;\r
+ char ch = '\0';\r
+ while( ofs < size && ch != '\n' )\r
+ {\r
+ if( fread(&ch, 1, 1, fp) != 1 )\r
+ break;\r
+ s[ofs ++] = ch;\r
+ }\r
+ if( ofs < size )\r
+ s[ofs] = '\0';\r
+ return s;\r
+}\r
+\r
/**\r
* \fn EXPORT int fputc(int c, FILE *fp)\r
* \brief Write a single character to the stream\r
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
*/
--- /dev/null
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * strtof.c
+ * - strto[df]/atof implimentation
+ */
+#include <ctype.h>
+#include <errno.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdlib.h> // 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);
+}
ASFLAGS +=\r
LDFLAGS += -soname libposix.so -Map map.txt\r
\r
-OBJ = main.o unistd.o\r
+OBJ = main.o unistd.o dirent.o\r
DEPFILES := $(OBJ:%.o=%.d)\r
BIN = libposix.so\r
\r
--- /dev/null
+/*
+ * Acess2 C Library
+ * - By John Hodge (thePowersGang)
+ *
+ * dirent.c
+ * - Directory Functions
+ */
+#include <dirent.h>
+#include <stddef.h> // NULL
+#include <acess/sys.h>
+#include <errno.h>
+
+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 *);
#ifndef _LIBPOSIX__SYS__DIRENT_H_
#define _LIBPOSIX__SYS__DIRENT_H_
+#include "sys/stat.h"
+
#define NAME_MAX 255
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 *);