lib: Introduce unic

unic is a small library of C functions that is currently written
in plain C. It's purpose isn't to be fast, but "universal" - as
in include as little architecture-specific code as possible.

The old neatlibc still resides, but isn't being built. There is
still more to do, including implementation of memory management,
so keep it there for now.

Signed-off-by: Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
This commit is contained in:
Ivaylo Ivanov 2024-09-23 20:17:44 +03:00
parent 3fae0e9880
commit 3ab64bed39
6 changed files with 286 additions and 32 deletions

View File

@ -199,7 +199,7 @@ KBUILD_CFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
-Wno-format-security \
-fno-delete-null-pointer-checks \
-Wno-builtin-declaration-mismatch -Wno-main -nostdinc \
-I$(srctree)/lib/neatlibc
-I$(srctree)/lib/unic
KBUILD_AFLAGS_KERNEL :=
KBUILD_CFLAGS_KERNEL :=
KBUILD_AFLAGS := -D__ASSEMBLY__

View File

@ -4,34 +4,5 @@ lib-$(CONFIG_SIMPLE_FB) += simplefb/simplefb.o
# DEBUG
lib-y += debug/debug.o
# Neatlibc (excluding signal and syscalls)
ifeq ($(ARCH), arm)
lib-y += neatlibcarm/arm/bits.o \
neatlibcarm/arm/lmem.o \
neatlibcarm/arm/string.o
else
lib-y += neatlibcaarch64/$(ARCH)/bits.o \
neatlibcaarch64/$(ARCH)/lmem.o \
neatlibcaarch64/$(ARCH)/string.o
endif
lib-y += neatlibc/ctype.o \
neatlibc/strftime.o \
neatlibc/mkstemp.o \
neatlibc/regex.o \
neatlibc/rand.o \
neatlibc/stdarg.o \
neatlibc/memtst.o \
neatlibc/dirent.o \
neatlibc/localtime.o \
neatlibc/malloc.o \
neatlibc/termios.o \
neatlibc/atoi.o \
neatlibc/errno.o \
neatlibc/stdio.o \
neatlibc/stdlib.o \
neatlibc/qsort.o \
neatlibc/stringc.o \
neatlibc/isatty.o \
neatlibc/scanf.o \
neatlibc/string.o
# unic (neatlibc still temporarily resides)
lib-y += unic/string.o

18
lib/unic/stdbool.h Normal file
View File

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright (c) 2024, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/
#ifndef STDBOOL_H_ /* Include guard */
#define STDBOOL_H_
#define bool _Bool
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
#endif // STDBOOL_H_

14
lib/unic/stddef.h Normal file
View File

@ -0,0 +1,14 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright (c) 2024, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/
#ifndef STDDEF_H_ /* Include guard */
#define STDDEF_H_
#define NULL ((void *) 0)
#define offsetof(type, field) ((int) (&((type *) 0)->field))
typedef unsigned long size_t;
#endif // STDDEF_H_

209
lib/unic/string.c Normal file
View File

@ -0,0 +1,209 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright (c) 2024, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/
#include "stdbool.h"
#include "string.h"
void *memcpy(void *s1, const void *s2, size_t n)
{
char *dest = (char *)s1;
const char *src = (const char *)s2;
while (n--) {
*dest++ = *src++;
}
return s1;
}
void *memmove(void *s1, const void *s2, size_t n)
{
char *dest = (char *)s1;
const char *src = (const char *)s2;
if (dest <= src) {
while (n--) {
*dest++ = *src++;
}
} else {
src += n;
dest += n;
while (n--) {
*--dest = *--src;
}
}
return s1;
}
int memcmp(const void *s1, const void *s2, size_t n)
{
const unsigned char *p1 = (const unsigned char *)s1;
const unsigned char *p2 = (const unsigned char *)s2;
while (n--) {
if (*p1 != *p2) {
return *p1 - *p2;
}
++p1;
++p2;
}
return 0;
}
void *memset(void *s, int c, size_t n)
{
unsigned char *p = (unsigned char *)s;
while (n--) {
*p++ = (unsigned char)c;
}
return s;
}
void *memchr(const void *s, int c, size_t n)
{
const unsigned char *p = (const unsigned char *)s;
while (n--) {
if (*p == (unsigned char)c) {
return (void *)p;
}
++p;
}
return NULL;
}
char *strcpy(char *s1, const char *s2)
{
char *rc = s1;
while ((*s1++ = *s2++)) {
/* EMPTY */
}
return rc;
}
char *strncpy(char *s1, const char *s2, size_t n)
{
char *rc = s1;
while (n && (*s1++ = *s2++)) {
/* Cannot do "n--" in the conditional as size_t is unsigned and we have
to check it again for >0 in the next loop below, so we must not risk
underflow.
*/
--n;
}
/* Checking against 1 as we missed the last --n in the loop above. */
while (n-- > 1) {
*s1++ = '\0';
}
return rc;
}
int strcmp(const char *s1, const char *s2)
{
while ((*s1) && (*s1 == *s2)) {
++s1;
++s2;
}
return (*(unsigned char *)s1 - *(unsigned char *)s2);
}
int strncmp(const char *s1, const char *s2, size_t n)
{
while (n && *s1 && (*s1 == *s2)) {
++s1;
++s2;
--n;
}
if (n == 0) {
return 0;
} else {
return (*(unsigned char *)s1 - *(unsigned char *)s2);
}
}
size_t strlen(const char *s)
{
size_t rc = 0;
while (s[rc]) {
++rc;
}
return rc;
}
size_t strnlen(const char *s, size_t n)
{
size_t rc = 0;
while (rc < n && s[rc]) {
++rc;
}
return rc;
}
char *strchr(const char *s, int c)
{
do {
if (*s == (char)c) {
return (char *)s;
}
} while (*s++);
return NULL;
}
char *strrchr(const char *s, int c)
{
size_t i = 0;
while (s[i++]) {
/* EMPTY */
}
do {
if (s[--i] == (char)c) {
return (char *)s + i;
}
} while (i);
return NULL;
}
/* Very naive, no attempt to check for errors */
long atol(const char *s)
{
long val = 0;
bool neg = false;
if (*s == '-') {
neg = true;
s++;
}
while (*s >= '0' && *s <= '9')
val = (val * 10) + (*s++ - '0');
if (neg)
val = -val;
return val;
}

42
lib/unic/string.h Normal file
View File

@ -0,0 +1,42 @@
/* SPDX-License-Identifier: MIT */
/*
* Copyright (c) 2024, Ivaylo Ivanov <ivo.ivanov.ivanov1@gmail.com>
*/
#ifndef STRING_H_ /* Include guard */
#define STRING_H_
#include "stddef.h"
void *memcpy(void *s1, const void *s2, size_t n);
void *memmove(void *s1, const void *s2, size_t n);
int memcmp(const void *s1, const void *s2, size_t n);
void *memset(void *s, int c, size_t n);
void *memchr(const void *s, int c, size_t n);
char *strcpy(char *s1, const char *s2);
char *strncpy(char *s1, const char *s2, size_t n);
int strcmp(const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
size_t strlen(const char *s);
size_t strnlen(const char *s, size_t n);
char *strchr(const char *s, int c);
char *strrchr(const char *s, int c);
long atol(const char *s);
static inline int tolower(int c)
{
if (c >= 'A' && c <= 'Z')
return c - 'A' + 'a';
else
return c;
}
static inline int toupper(int c)
{
if (c >= 'a' && c <= 'z')
return c - 'a' + 'A';
else
return c;
}
#endif // STRING_H_