Implemented lots of new functions
This commit is contained in:
@@ -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
46
photon/libc/ctype/ctype.c
Normal 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);
|
||||||
|
}
|
||||||
27
photon/libc/include/ctype.h
Normal file
27
photon/libc/include/ctype.h
Normal 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
|
||||||
24
photon/libc/include/limits.h
Normal file
24
photon/libc/include/limits.h
Normal 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_ */
|
||||||
@@ -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" {
|
||||||
|
|||||||
@@ -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, ...);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
13
photon/libc/stdio/fgetc.c
Normal 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;
|
||||||
|
}
|
||||||
@@ -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);
|
||||||
|
|||||||
12
photon/libc/stdio/fwrite.c
Normal file
12
photon/libc/stdio/fwrite.c
Normal 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;
|
||||||
|
}
|
||||||
8
photon/libc/stdio/ungetc.c
Normal file
8
photon/libc/stdio/ungetc.c
Normal 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
42
photon/libc/stdlib/atof.c
Normal 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;
|
||||||
|
}
|
||||||
0
photon/libc/stdlib/atoi.c
Normal file
0
photon/libc/stdlib/atoi.c
Normal file
91
photon/libc/stdlib/strtod.c
Normal file
91
photon/libc/stdlib/strtod.c
Normal 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;
|
||||||
|
}
|
||||||
85
photon/libc/stdlib/strtol.c
Normal file
85
photon/libc/stdlib/strtol.c
Normal 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);
|
||||||
|
}
|
||||||
12
photon/libc/string/fread.c
Normal file
12
photon/libc/string/fread.c
Normal 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;
|
||||||
|
}
|
||||||
0
photon/libc/string/fwrite.c
Normal file
0
photon/libc/string/fwrite.c
Normal file
19
photon/libc/string/strcmp.c
Normal file
19
photon/libc/string/strcmp.c
Normal 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;
|
||||||
|
}
|
||||||
26
photon/libc/string/strcpy.c
Normal file
26
photon/libc/string/strcpy.c
Normal 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;
|
||||||
|
}
|
||||||
11
photon/libc/string/strdup.c
Normal file
11
photon/libc/string/strdup.c
Normal 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;
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
Reference in New Issue
Block a user