Implemented lots of new functions

This commit is contained in:
Max Wash
2020-07-16 14:02:51 +01:00
parent a614cfa25c
commit 405e98717b
24 changed files with 541 additions and 3 deletions

View File

@@ -25,7 +25,7 @@ set(CMAKE_EXE_LINKER_FLAGS
set(malloc_impl dlmalloc) set(malloc_impl dlmalloc)
set(photon_libc_sources "") set(photon_libc_sources "")
set(generic_dirs string stdio stdlib errno internal) set(generic_dirs string stdio stdlib errno internal ctype)
message(STATUS "Memory allocator: ${malloc_impl}") message(STATUS "Memory allocator: ${malloc_impl}")

46
photon/libc/ctype/ctype.c Normal file
View File

@@ -0,0 +1,46 @@
#include <stdbool.h>
static unsigned int random_seed = 53455346;
int isupper(int c) { return (c >= 65 && c <= 90); }
int islower(int c) { return (c >= 97 && c <= 122); }
int toupper(int c) {
if (!islower(c)) {
return c;
}
return c - 32;
}
int tolower(int c) {
if (!isupper(c)) {
return c;
}
return c + 32;
}
int isdigit(int c) { return (c >= 48 && c <= 57); }
int isalpha(int c) { return (c >= 65 && c <= 90) || (c >= 97 && c <= 122); }
int isalnum(int c) { return isalpha(c) | isdigit(c); }
int iscntrl(int c) { return (c <= 31) || (c == 127); }
int isprint(int c) { return (c >= 32 && c <= 126) || (c >= 128 && c <= 254); }
int isgraph(int c) { return isprint(c) && c != 32; }
int ispunct(int c) { return isgraph(c) && !isalnum(c); }
int isspace(int c) {
return (c == ' ') || (c == '\t') || (c == '\n') || (c == '\v') ||
(c == '\f') || (c == '\r');
}
int isxdigit(int c) {
return isdigit(c) || (c >= 65 && c <= 70) || (c >= 97 && c <= 102);
}

View File

@@ -0,0 +1,27 @@
#ifndef TYPES_H_
#define TYPES_H_
#ifdef __cplusplus
extern "C" {
#endif
extern int isalnum(int c);
extern int isalpha(int c);
extern int iscntrl(int c);
extern int isdigit(int c);
extern int isgraph(int c);
extern int islower(int c);
extern int isprint(int c);
extern int ispunct(int c);
extern int isspace(int c);
extern int isupper(int c);
extern int isxdigit(int c);
extern int tolower(int c);
extern int toupper(int c);
extern int fill_random(unsigned char *buffer, unsigned int size);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,24 @@
#ifndef LIMITS_H_
#define LIMITS_H_
#define CHAR_BIT 8
#define SCHAR_MIN -127
#define SCHAR_MAX 127
#define UCHAR_MAX 255
#define CHAR_MIN SCHAR_MIN
#define CHAR_MAX SCHAR_MAX
#define MB_LEN_MAX 1
#define SHRT_MIN -32767
#define SHRT_MAX 32767
#define USHRT_MAX 65535
#define INT_MIN -2147483648
#define INT_MAX 2147483648
#define UINT_MAX 4294967295
#define LONG_MIN -2147483648
#define LONG_MAX 2147483648
#define ULONG_MAX 4294967295
#define _I64_MIN -9223372036854775808
#define _I64_MAX 9223372036854775808
#define _UI64_MAX 18446744073709551615
#endif /* LIMITS_H_ */

View File

@@ -4,7 +4,7 @@
#include "machine/_stdint.h" #include "machine/_stdint.h"
#define NULL ((void *)0) #define NULL ((void *)0)
#define offsetof(t, m) ((size_t)(&(t *)0)->m) #define offsetof(t, m) ((size_t)&(((t *)0)->m))
#if defined(__cplusplus) #if defined(__cplusplus)
extern "C" { extern "C" {

View File

@@ -29,13 +29,22 @@ extern FILE *stderr;
extern FILE *fopen(const char *path, const char *mode); extern FILE *fopen(const char *path, const char *mode);
extern FILE *freopen(const char *path, const char *mode, FILE *fp); extern FILE *freopen(const char *path, const char *mode, FILE *fp);
#ifdef __magenta__
extern FILE *fdopen(mx_handle_t fd, const char *mode);
#else
extern FILE *fdopen(int fd, const char *mode); extern FILE *fdopen(int fd, const char *mode);
#endif
extern int fclose(FILE *fp); extern int fclose(FILE *fp);
extern int fflush(FILE *fp); extern int fflush(FILE *fp);
extern size_t fread(void *ptr, size_t size, size_t count, FILE *fp);
extern size_t fwrite(const void *ptr, size_t size, size_t count, FILE *fp);
extern int fileno(FILE *fp); extern int fileno(FILE *fp);
extern int fputs(const char *str, FILE *fp); extern int fputs(const char *str, FILE *fp);
extern int fputc(int c, FILE *fp); extern int fputc(int c, FILE *fp);
extern int fgetc(FILE *fp);
extern int ungetc(int c, FILE *fp);
extern int printf(const char *restrict format, ...); extern int printf(const char *restrict format, ...);
extern int fprintf(FILE *fp, const char *restrict format, ...); extern int fprintf(FILE *fp, const char *restrict format, ...);

View File

@@ -12,6 +12,11 @@ extern _Noreturn void exit(int code);
extern void *malloc(size_t sz); extern void *malloc(size_t sz);
extern void free(void *ptr); extern void free(void *ptr);
extern int atoi(const char *str);
extern double atof(const char *str);
extern long int strtol(const char *str, char **endptr, int base);
extern double strtod(const char *str, char **endptr);
#if defined(__cplusplus) #if defined(__cplusplus)
} /* extern "C" */ } /* extern "C" */
#endif #endif

View File

@@ -16,6 +16,11 @@ extern size_t strlen(const char *str);
extern int strcmp(const char *a, const char *b); extern int strcmp(const char *a, const char *b);
extern int strncmp(const char *a, const char *b, size_t sz); extern int strncmp(const char *a, const char *b, size_t sz);
extern char *strcpy(char *dest, const char *src);
extern char *strncpy(char *dest, const char *src, size_t sz);
extern char *strdup(const char *s);
#if defined(__cplusplus) #if defined(__cplusplus)
} /* extern "C" */ } /* extern "C" */
#endif #endif

View File

@@ -1,10 +1,17 @@
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <__fio.h> #include <__fio.h>
#ifdef __magenta__
FILE *fdopen(mx_handle_t fd, const char *mode)
#else
FILE *fdopen(int fd, const char *mode) FILE *fdopen(int fd, const char *mode)
#endif
{ {
struct __io_file *fp = malloc(sizeof(*fp)); struct __io_file *fp = malloc(sizeof(*fp));
memset(fp, 0x0, sizeof(*fp));
int res = __fio_fdopen(fd, mode, fp); int res = __fio_fdopen(fd, mode, fp);
if (res != 0) { if (res != 0) {
free(fp); free(fp);

13
photon/libc/stdio/fgetc.c Normal file
View File

@@ -0,0 +1,13 @@
#include <stdio.h>
#include <__fio.h>
int fgetc(FILE *fp)
{
char ch = 0;
__fio_read(fp, &ch, 1);
if (__fio_error(fp)) {
return EOF;
}
return ch;
}

View File

@@ -1,10 +1,13 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <__fio.h> #include <__fio.h>
FILE *fopen(const char *path, const char *mode) FILE *fopen(const char *path, const char *mode)
{ {
struct __io_file *fp = malloc(sizeof(*fp)); struct __io_file *fp = malloc(sizeof(*fp));
memset(fp, 0x0, sizeof(*fp));
int res = __fio_fopen(path, mode, fp); int res = __fio_fopen(path, mode, fp);
if (res != 0) { if (res != 0) {
free(fp); free(fp);

View File

@@ -0,0 +1,12 @@
#include <stdio.h>
#include <__fio.h>
size_t fwrite(const void *ptr, size_t size, size_t count, FILE *fp)
{
if (!size || !count) {
return 0;
}
unsigned int written = __fio_write(fp, ptr, size * count);
return written / size;
}

View File

@@ -0,0 +1,8 @@
#include <stdio.h>
#include <__fio.h>
int ungetc(int c, FILE *fp)
{
int res = __fio_ungetc(fp, c);
return res == -1 ? EOF : c;
}

42
photon/libc/stdlib/atof.c Normal file
View File

@@ -0,0 +1,42 @@
#include <ctype.h>
double atof(const char *s)
{
double a = 0.0;
int e = 0;
int c;
while ((c = *s++) != '\0' && isdigit(c)) {
a = a*10.0 + (c - '0');
}
if (c == '.') {
while ((c = *s++) != '\0' && isdigit(c)) {
a = a*10.0 + (c - '0');
e = e-1;
}
}
if (c == 'e' || c == 'E') {
int sign = 1;
int i = 0;
c = *s++;
if (c == '+')
c = *s++;
else if (c == '-') {
c = *s++;
sign = -1;
}
while (isdigit(c)) {
i = i*10 + (c - '0');
c = *s++;
}
e += i*sign;
}
while (e > 0) {
a *= 10.0;
e--;
}
while (e < 0) {
a *= 0.1;
e++;
}
return a;
}

View File

View File

@@ -0,0 +1,91 @@
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
double strtod(const char *str, char **ptr)
{
if (ptr == (char **)0) {
return atof(str);
}
size_t len = strlen(str);
char rstr[len + 1];
strcpy(rstr, str);
char *p = rstr;
while (isspace(*p)) {
++p;
}
if (*p == '+' || *p == '-') {
++p;
}
if ((p[0] == 'i' || p[0] == 'I')
&& (p[1] == 'n' || p[1] == 'N')
&& (p[2] == 'f' || p[2] == 'F')) {
if ((p[3] == 'i' || p[3] == 'I')
&& (p[4] == 'n' || p[4] == 'N')
&& (p[5] == 'i' || p[5] == 'I')
&& (p[6] == 't' || p[6] == 'T')
&& (p[7] == 'y' || p[7] == 'Y')) {
*ptr = p + 8;
return atof(str);
} else {
*ptr = p + 3;
return atof(str);
}
}
if ((p[0] == 'n' || p[0] == 'N')
&& (p[1] == 'a' || p[1] == 'A')
&& (p[2] == 'n' || p[2] == 'N')) {
p += 3;
if (*p == '(') {
++p;
while (*p != '\0' && *p != ')') {
++p;
}
if (*p == ')') {
++p;
}
}
*ptr = p;
return atof(str);
}
if (isdigit(*p) || *p == '.') {
int got_dot = 0;
while (isdigit(*p) || (!got_dot && *p == '.')) {
if (*p == '.')
got_dot = 1;
++p;
}
if (*p == 'e' || *p == 'E') {
int i;
i = 1;
if (p[i] == '+' || p[i] == '-') {
++i;
}
if (isdigit (p[i])) {
while (isdigit (p[i])) {
++i;
}
*ptr = p + i;
return atof(str);
}
}
*ptr = p;
return atof(str);
}
*ptr = (char *)str;
return 0.0;
}

View File

@@ -0,0 +1,85 @@
#include <ctype.h>
#include <stdint.h>
#include <limits.h>
long strtol(const char *nptr, char **endptr, int base)
{
const char *s = nptr;
unsigned long acc;
int c;
unsigned long cutoff;
int neg = 0, 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.
*/
do {
c = *s++;
} while (isspace(c));
if (c == '-') {
neg = 1;
c = *s++;
} else if (c == '+')
c = *s++;
if ((base == 0 || base == 16) &&
c == '0' && (*s == 'x' || *s == 'X')) {
c = s[1];
s += 2;
base = 16;
} else if ((base == 0 || base == 2) &&
c == '0' && (*s == 'b' || *s == 'B')) {
c = s[1];
s += 2;
base = 2;
}
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 longs is
* [-2147483648..2147483647] and the input base is 10,
* cutoff will be set to 214748364 and cutlim to either
* 7 (neg==0) or 8 (neg==1), meaning that if we have accumulated
* a value > 214748364, 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.
*/
cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
cutlim = cutoff % (unsigned long)base;
cutoff /= (unsigned long)base;
for (acc = 0, any = 0;; c = *s++) {
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
else
break;
if (c >= base)
break;
if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
any = -1;
else {
any = 1;
acc *= base;
acc += c;
}
}
if (any < 0) {
acc = neg ? LONG_MIN : LONG_MAX;
} else if (neg)
acc = -acc;
if (endptr != 0)
*endptr = (char *)(any ? s - 1 : nptr);
return (acc);
}

View File

@@ -0,0 +1,12 @@
#include <stdio.h>
#include <__fio.h>
size_t fread(void *ptr, size_t size, size_t count, FILE *fp)
{
if (!size || !count) {
return 0;
}
unsigned int written = __fio_read(fp, ptr, size * count);
return written / size;
}

View File

View File

@@ -0,0 +1,19 @@
int strcmp(const char *s1, const char *s2)
{
int i;
for (i = 0; s1[i] == s2[i]; i++)
if (s1[i] == '\0')
return 0;
return s1[i] - s2[i];
}
int strncmp(const char *s1, const char *s2, unsigned int n)
{
for (; n > 0; s1++, s2++, --n)
if (*s1 != *s2)
return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : 1);
else if (*s1 == '\0')
return 0;
return 0;
}

View File

@@ -0,0 +1,26 @@
char *strcpy(char *output, const char *input)
{
unsigned int i;
for (i = 0; input[i] != 0; i++) {
output[i] = input[i];
}
output[i] = '\0';
return output;
}
char *strncpy(char *output, const char *input, unsigned int count)
{
unsigned int size = count;
unsigned int i;
for (i = 0; i < size; i++) {
output[i] = input[i];
if (input[i] == 0) {
break;
}
}
output[i] = '\0';
return output;
}

View File

@@ -0,0 +1,11 @@
#include <string.h>
#include <stdlib.h>
char *strdup(const char *str)
{
size_t len = strlen(str);
char *out = malloc(len + 1);
memcpy(out, str, len);
out[len] = 0;
return out;
}

View File

@@ -14,17 +14,20 @@ struct __io_file {
unsigned long buf_idx; unsigned long buf_idx;
mx_handle_t handle; mx_handle_t handle;
char err; char err;
char unget;
}; };
extern int __fileno(struct __io_file *f); extern int __fileno(struct __io_file *f);
extern void __fio_init(mx_handle_t in, mx_handle_t out, mx_handle_t err); extern void __fio_init(mx_handle_t in, mx_handle_t out, mx_handle_t err);
extern unsigned int __fio_read(struct __io_file *f, char *buf, unsigned int sz);
extern unsigned int __fio_write(struct __io_file *f, const char *buf, unsigned int sz); extern unsigned int __fio_write(struct __io_file *f, const char *buf, unsigned int sz);
extern unsigned int __fio_flush(struct __io_file *f); extern unsigned int __fio_flush(struct __io_file *f);
extern int __fio_error(struct __io_file *f); extern int __fio_error(struct __io_file *f);
extern int __fio_ungetc(struct __io_file *f, char c);
extern int __fio_fopen(const char *path, const char *mode, struct __io_file *out); extern int __fio_fopen(const char *path, const char *mode, struct __io_file *out);
extern int __fio_fclose(struct __io_file *in); extern int __fio_fclose(struct __io_file *in);
extern int __fio_fdopen(int fd, const char *mode, struct __io_file *out); extern int __fio_fdopen(mx_handle_t fd, const char *mode, struct __io_file *out);
#if defined(__cplusplus) #if defined(__cplusplus)
} }

View File

@@ -9,6 +9,38 @@ struct __io_file *stdin = &__stdin;
struct __io_file *stdout = &__stdout; struct __io_file *stdout = &__stdout;
struct __io_file *stderr = &__stderr; struct __io_file *stderr = &__stderr;
static mx_flags_t flags_from_mode(const char *r)
{
mx_flags_t out = 0;
while (*r) {
switch (*r) {
case 'r':
out |= MX_FILE_READ;
break;
case 'w':
out |= MX_FILE_WRITE;
break;
case '+':
out |= (MX_FILE_READ | MX_FILE_WRITE);
break;
case 'a':
out |= MX_FILE_APPEND;
break;
case 'b':
/* TODO */
break;
default:
out = 0;
return out;
}
r++;
}
return out;
}
void __fio_init(mx_handle_t in, mx_handle_t out, mx_handle_t err) void __fio_init(mx_handle_t in, mx_handle_t out, mx_handle_t err)
{ {
__stdin.handle = in; __stdin.handle = in;
@@ -16,11 +48,59 @@ void __fio_init(mx_handle_t in, mx_handle_t out, mx_handle_t err)
__stderr.handle = err; __stderr.handle = err;
} }
int __fio_fopen(const char *path, const char *mode, struct __io_file *fp)
{
mx_handle_t h = MX_NULL_HANDLE;
mx_status_t stat = mx_open(MX_NULL_HANDLE, path, 0, &h);
if (stat != MX_OK) {
return -1;
}
fp->handle = h;
return 0;
}
int __fio_fdopen(mx_handle_t fd, const char *mode, struct __io_file *fp)
{
/* TODO validate handle and mode */
fp->handle = fd;
return 0;
}
int __fileno(struct __io_file *f) int __fileno(struct __io_file *f)
{ {
return (int)f->handle; return (int)f->handle;
} }
unsigned int __fio_read(struct __io_file *f, char *buf, unsigned int sz)
{
if (!sz) {
return 0;
}
size_t i = 0;
unsigned long real_sz = 0;
if (f->unget) {
buf[i++] = f->unget;
f->unget = 0;
sz--;
}
if (!sz) {
return real_sz;
}
mx_status_t err = mx_read(f->handle, sz, buf + i, &real_sz);
if (err != MX_OK || real_sz != sz) {
f->err = 1;
}
return real_sz + i;
}
unsigned int __fio_write(struct __io_file *f, const char *buf, unsigned int sz) unsigned int __fio_write(struct __io_file *f, const char *buf, unsigned int sz)
{ {
for (unsigned int i = 0; i < sz; i++) { for (unsigned int i = 0; i < sz; i++) {
@@ -37,6 +117,16 @@ unsigned int __fio_write(struct __io_file *f, const char *buf, unsigned int sz)
return sz; return sz;
} }
int __fio_ungetc(struct __io_file *f, char c)
{
if (f->unget) {
return -1;
}
f->unget = c;
return 0;
}
unsigned int __fio_flush(struct __io_file *f) unsigned int __fio_flush(struct __io_file *f)
{ {
unsigned long written = 0; unsigned long written = 0;