LibC: Combine string.h functions definitions to single file

This commit is contained in:
Bananymous 2023-04-02 00:00:29 +03:00
parent 79090c2648
commit c5b83074ac
13 changed files with 164 additions and 184 deletions

View File

@ -36,17 +36,7 @@ stdio/printf.o \
stdio/putchar.o \
stdio/puts.o \
stdlib/abort.o \
string/memcmp.o \
string/memcpy.o \
string/memmove.o \
string/memset.o \
string/strcmp.o \
string/strcpy.o \
string/strerror.o \
string/strlen.o \
string/strncmp.o \
string/strncpy.o \
string/strstr.o \
string.o \
HOSTEDOBJS=\
$(ARCH_HOSTEDOBJS) \

163
libc/string.cpp Normal file
View File

@ -0,0 +1,163 @@
#include <string.h>
#include <errno.h>
int errno = 0;
int memcmp(const void* s1, const void* s2, size_t n)
{
const unsigned char* a = static_cast<const unsigned char*>(s1);
const unsigned char* b = static_cast<const unsigned char*>(s2);
for (size_t i = 0; i < n; i++)
if (a[i] != b[i])
return a[i] - b[i];
return 0;
}
void* memcpy(void* __restrict dstp, const void* __restrict srcp, size_t n)
{
unsigned char* dst = static_cast<unsigned char*>(dstp);
const unsigned char* src = static_cast<const unsigned char*>(srcp);
for (size_t i = 0; i < n; i++)
dst[i] = src[i];
return dstp;
}
void* memmove(void* destp, const void* srcp, size_t n)
{
unsigned char* dest = static_cast<unsigned char*>(destp);
const unsigned char* src = static_cast<const unsigned char*>(srcp);
if (dest < src)
{
for (size_t i = 0; i < n; i++)
dest[i] = src[i];
}
else
{
for (size_t i = 1; i <= n; i++)
dest[n - i] = src[n - i];
}
return destp;
}
void* memset(void* s, int c, size_t n)
{
unsigned char* p = static_cast<unsigned char*>(s);
for (size_t i = 0; i < n; i++)
p[i] = c;
return s;
}
int strcmp(const char* s1, const char* s2)
{
const unsigned char* u1 = (unsigned char*)s1;
const unsigned char* u2 = (unsigned char*)s2;
for (; *u1 && *u2; u1++, u2++)
if (*u1 != *u2)
break;
return *u1 - *u2;
}
char* strcpy(char* __restrict dest, const char* __restrict src)
{
size_t i;
for (i = 0; src[i]; i++)
dest[i] = src[i];
dest[i] = '\0';
return dest;
}
char* strerror(int error)
{
static char buffer[100];
buffer[0] = 0;
switch (error)
{
case ENOMEM:
strcpy(buffer, "Cannot allocate memory");
break;
case EINVAL:
strcpy(buffer, "Invalid argument");
break;
case EISDIR:
strcpy(buffer, "Is a directory");
break;
case ENOTDIR:
strcpy(buffer, "Not a directory");
break;
case ENOENT:
strcpy(buffer, "No such file or directory");
break;
case EIO:
strcpy(buffer, "Input/output error");
break;
case ENOTSUP:
strcpy(buffer, "Operation not supported");
break;
case EBADF:
strcpy(buffer, "Bad file descriptor");
break;
case EEXISTS:
strcpy(buffer, "File exists");
break;
case ENOTEMPTY:
strcpy(buffer, "Directory not empty");
break;
case ENAMETOOLONG:
strcpy(buffer, "Filename too long");
break;
case ENOBUFS:
strcpy(buffer, "No buffer space available");
break;
default:
{
// FIXME: sprintf
//sprintf(buffer, "Unknown error %d", error);
strcpy(buffer, "Unknown error");
errno = EINVAL;
break;
}
}
return buffer;
}
size_t strlen(const char* str)
{
size_t len = 0;
while (str[len])
len++;
return len;
}
int strncmp(const char* s1, const char* s2, size_t n)
{
const unsigned char* u1 = (unsigned char*)s1;
const unsigned char* u2 = (unsigned char*)s2;
for (; --n && *u1 && *u2; u1++, u2++)
if (*u1 != *u2)
break;
return *u1 - *u2;
}
char* strncpy(char* __restrict dest, const char* __restrict src, size_t n)
{
size_t i;
for (i = 0; src[i] && i < n; i++)
dest[i] = src[i];
for (; i < n; i++)
dest[i] = '\0';
return dest;
}
char* strstr(const char* haystack, const char* needle)
{
for (size_t i = 0; haystack[i]; i++)
if (memcmp(haystack + i, needle, strlen(needle)) == 0)
return (char*)haystack + i;
return NULL;
}

View File

@ -1,13 +0,0 @@
#include <string.h>
int memcmp(const void* s1, const void* s2, size_t n)
{
const unsigned char* a = static_cast<const unsigned char*>(s1);
const unsigned char* b = static_cast<const unsigned char*>(s2);
for (size_t i = 0; i < n; i++)
if (a[i] != b[i])
return a[i] - b[i];
return 0;
}

View File

@ -1,10 +0,0 @@
#include <string.h>
void* memcpy(void* __restrict dstp, const void* __restrict srcp, size_t n)
{
unsigned char* dst = static_cast<unsigned char*>(dstp);
const unsigned char* src = static_cast<const unsigned char*>(srcp);
for (size_t i = 0; i < n; i++)
dst[i] = src[i];
return dstp;
}

View File

@ -1,20 +0,0 @@
#include <string.h>
void* memmove(void* destp, const void* srcp, size_t n)
{
unsigned char* dest = static_cast<unsigned char*>(destp);
const unsigned char* src = static_cast<const unsigned char*>(srcp);
if (dest < src)
{
for (size_t i = 0; i < n; i++)
dest[i] = src[i];
}
else
{
for (size_t i = 1; i <= n; i++)
dest[n - i] = src[n - i];
}
return destp;
}

View File

@ -1,9 +0,0 @@
#include <string.h>
void* memset(void* s, int c, size_t n)
{
unsigned char* p = static_cast<unsigned char*>(s);
for (size_t i = 0; i < n; i++)
p[i] = c;
return s;
}

View File

@ -1,11 +0,0 @@
#include <string.h>
int strcmp(const char* s1, const char* s2)
{
const unsigned char* u1 = (unsigned char*)s1;
const unsigned char* u2 = (unsigned char*)s2;
for (; *u1 && *u2; u1++, u2++)
if (*u1 != *u2)
break;
return *u1 - *u2;
}

View File

@ -1,10 +0,0 @@
#include <string.h>
char* strcpy(char* __restrict dest, const char* __restrict src)
{
size_t i;
for (i = 0; src[i]; i++)
dest[i] = src[i];
dest[i] = '\0';
return dest;
}

View File

@ -1,60 +0,0 @@
#include <errno.h>
#include <string.h>
int errno = 0;
char* strerror(int error)
{
static char buffer[100];
buffer[0] = 0;
switch (error)
{
case ENOMEM:
strcpy(buffer, "Cannot allocate memory");
break;
case EINVAL:
strcpy(buffer, "Invalid argument");
break;
case EISDIR:
strcpy(buffer, "Is a directory");
break;
case ENOTDIR:
strcpy(buffer, "Not a directory");
break;
case ENOENT:
strcpy(buffer, "No such file or directory");
break;
case EIO:
strcpy(buffer, "Input/output error");
break;
case ENOTSUP:
strcpy(buffer, "Operation not supported");
break;
case EBADF:
strcpy(buffer, "Bad file descriptor");
break;
case EEXISTS:
strcpy(buffer, "File exists");
break;
case ENOTEMPTY:
strcpy(buffer, "Directory not empty");
break;
case ENAMETOOLONG:
strcpy(buffer, "Filename too long");
break;
case ENOBUFS:
strcpy(buffer, "No buffer space available");
break;
default:
{
// FIXME: sprintf
//sprintf(buffer, "Unknown error %d", error);
strcpy(buffer, "Unknown error");
errno = EINVAL;
break;
}
}
return buffer;
}

View File

@ -1,9 +0,0 @@
#include <string.h>
size_t strlen(const char* str)
{
size_t len = 0;
while (str[len])
len++;
return len;
}

View File

@ -1,11 +0,0 @@
#include <string.h>
int strncmp(const char* s1, const char* s2, size_t n)
{
const unsigned char* u1 = (unsigned char*)s1;
const unsigned char* u2 = (unsigned char*)s2;
for (; --n && *u1 && *u2; u1++, u2++)
if (*u1 != *u2)
break;
return *u1 - *u2;
}

View File

@ -1,11 +0,0 @@
#include <string.h>
char* strncpy(char* __restrict dest, const char* __restrict src, size_t n)
{
size_t i;
for (i = 0; src[i] && i < n; i++)
dest[i] = src[i];
for (; i < n; i++)
dest[i] = '\0';
return dest;
}

View File

@ -1,9 +0,0 @@
#include <string.h>
char* strstr(const char* haystack, const char* needle)
{
for (size_t i = 0; haystack[i]; i++)
if (memcmp(haystack + i, needle, strlen(needle)) == 0)
return (char*)haystack + i;
return NULL;
}