libc: add string operations for libc
This commit is contained in:
parent
70b970e275
commit
dda4dde950
5 changed files with 279 additions and 4 deletions
|
@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.14.0)
|
|||
|
||||
project(gaybsd VERSION 0.1.0 LANGUAGES C ASM)
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_EXTENSIONS OFF)
|
||||
set(CMAKE_C_EXTENSIONS ON)
|
||||
|
||||
if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
|
||||
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||
|
@ -33,11 +33,21 @@ set(CMAKE_LINKER_FLAGS "${CMAKE_LINKER_FLAGS} -nodefaultlibs -static --whole-arc
|
|||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -nostdlib -nodefaultlibs -static")
|
||||
|
||||
set(GAY_INCLUDE_DIRS
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/arch/${ARCH}/include
|
||||
${CMAKE_CURRENT_BINARY_DIR}/include
|
||||
"${CMAKE_SOURCE_DIR}/include"
|
||||
"${CMAKE_SOURCE_DIR}/arch/${ARCH}/include"
|
||||
"${CMAKE_BINARY_DIR}/include"
|
||||
)
|
||||
|
||||
set(GAY_DEFINITIONS
|
||||
"_GAY_SOURCE=202109L"
|
||||
)
|
||||
set(GAY_KERNEL_DEFINITIONS
|
||||
"__KERNEL__"
|
||||
${GAY_DEFINITIONS}
|
||||
)
|
||||
|
||||
include("lib/lib.cmake")
|
||||
|
||||
add_subdirectory("boot")
|
||||
|
||||
add_executable(gaybsd_image.elf)
|
||||
|
|
102
include/string.h
Normal file
102
include/string.h
Normal file
|
@ -0,0 +1,102 @@
|
|||
/* See the end of this file for copyright and license terms. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <gay/types.h>
|
||||
|
||||
/**
|
||||
* @brief Copy `n` bytes from `src` to `dest`.
|
||||
*
|
||||
* @param dest The destination
|
||||
* @param src The source
|
||||
* @param n The amount of bytes to copy
|
||||
* @returns A pointer to `dest`
|
||||
*/
|
||||
void *memcpy(void *dest, const void *src, size_t n);
|
||||
|
||||
/**
|
||||
* @brief Starting from `ptr`, fill `n` bytes with the constant byte `c`.
|
||||
*
|
||||
* @param ptr The start of the memory region
|
||||
* @param c The byte to fill with
|
||||
* @param n The amount of bytes to write
|
||||
* @returns A pointer to `ptr`
|
||||
*/
|
||||
void *memset(void *ptr, int c, size_t n);
|
||||
|
||||
/**
|
||||
* @brief Copy a memory area.
|
||||
* The two areas may overlap since the individual bytes are copied to a
|
||||
* temporary array first.
|
||||
*
|
||||
* @param dest The destination address
|
||||
* @param src The source address
|
||||
* @param n The amount of bytes to copy
|
||||
* @return a pointer to dest
|
||||
*/
|
||||
void *memmove(void *dest, const void *src, size_t n);
|
||||
|
||||
/**
|
||||
* @brief Compare the two strings `s1` and `s2`.
|
||||
*
|
||||
* @param s1 The first string
|
||||
* @param s2 The second string
|
||||
* @returns `0` if both strings are equal, a positive value f `s1` is greater
|
||||
* than `s2`, and a negative value if `s1` is less than `s2`
|
||||
*/
|
||||
int strcmp(const char *s1, const char *s2);
|
||||
|
||||
/**
|
||||
* @brief Copy a `NUL` terminated string from `src` to `dest`.
|
||||
*
|
||||
* @param dest The destination to copy to. The memory region must be able to
|
||||
* hold the entire string plus one byte for the terminator.
|
||||
* @param src The original string to copy from
|
||||
* @returns A pointer to the destination string
|
||||
*/
|
||||
char *strcpy(char *dest, const char *src);
|
||||
|
||||
/**
|
||||
* @brief Copy a `NUL` terminated string from `src` to `dest`, but at most `n` characters.
|
||||
* Note that this may cause `dest` to miss a `NUL` terminator.
|
||||
*
|
||||
* @param dest The destination to copy to. The memory region must be able to
|
||||
* hold the entire string plus one byte for the terminator.
|
||||
* @param src The original string to copy from
|
||||
* @param n The amount of characters to copy at most
|
||||
* @returns A pointer to the destination string
|
||||
*/
|
||||
char *strncpy(char *dest, const char *src, size_t n);
|
||||
|
||||
/**
|
||||
* @brief Compute the length of the `NUL` terminated string `s`.
|
||||
*
|
||||
* @param s The string
|
||||
* @returns The length of `s` without the `NUL` terminator
|
||||
*/
|
||||
size_t strlen(const char *s);
|
||||
|
||||
#if _POSIX_C_SOURCE >= 200809L || _GAY_SOURCE >= 202109L
|
||||
/**
|
||||
* @brief Compute the length of the `NUL` terminated string `s`, but at most `maxlen` bytes.
|
||||
*
|
||||
* @param s The string
|
||||
* @param maxlen Maximum bytes after which to return
|
||||
* @returns The length of `s` without the `NUL` terminator, but at most `maxlen`
|
||||
*/
|
||||
size_t strnlen(const char *s, size_t maxlen);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This file is part of GayBSD.
|
||||
* Copyright (c) 2021 fef <owo@fef.moe>.
|
||||
*
|
||||
* GayBSD is nonviolent software: you may only use, redistribute, and/or
|
||||
* modify it under the terms of the Cooperative Nonviolent Public License
|
||||
* (CNPL) as found in the LICENSE file in the source code root directory
|
||||
* or at <https://git.pixie.town/thufie/npl-builder>; either version 7
|
||||
* of the license, or (at your option) any later version.
|
||||
*
|
||||
* GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
|
||||
* permitted by applicable law. See the CNPL for details.
|
||||
*/
|
21
lib/c/CMakeLists.txt
Normal file
21
lib/c/CMakeLists.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
# See the end of this file for copyright and license terms.
|
||||
|
||||
add_library(c)
|
||||
target_include_directories(c PRIVATE ${GAY_INCLUDE_DIRS})
|
||||
target_compile_definitions(c PRIVATE ${GAY_DEFINITIONS})
|
||||
|
||||
target_sources(c PRIVATE
|
||||
string.c
|
||||
)
|
||||
|
||||
# This file is part of GayBSD.
|
||||
# Copyright (c) 2021 fef <owo@fef.moe>.
|
||||
#
|
||||
# GayBSD is nonviolent software: you may only use, redistribute, and/or
|
||||
# modify it under the terms of the Cooperative Nonviolent Public License
|
||||
# (CNPL) as found in the LICENSE file in the source code root directory
|
||||
# or at <https://git.pixie.town/thufie/npl-builder>; either version 7
|
||||
# of the license, or (at your option) any later version.
|
||||
#
|
||||
# GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
|
||||
# permitted by applicable law. See the CNPL for details.
|
127
lib/c/string.c
Normal file
127
lib/c/string.c
Normal file
|
@ -0,0 +1,127 @@
|
|||
/* See the end of this file for copyright and license terms. */
|
||||
|
||||
#include <gay/types.h>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t n)
|
||||
{
|
||||
int delta = 0;
|
||||
|
||||
while (n-- > 0) {
|
||||
/* POSIX explicitly wants a cast to unsigned char */
|
||||
delta = *(const unsigned char *)s1++ - *(const unsigned char *)s2++;
|
||||
if (delta != 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return delta;
|
||||
}
|
||||
|
||||
void *memcpy(void *dest, const void *src, size_t n)
|
||||
{
|
||||
u8 *tmp = (u8 *)dest;
|
||||
|
||||
while (n-- > 0)
|
||||
*tmp++ = *(const u8 *)src++;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
void *memset(void *ptr, int c, size_t n)
|
||||
{
|
||||
char *tmp = (char *)ptr;
|
||||
|
||||
while (n-- > 0)
|
||||
*tmp++ = (char)c;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void *memmove(void *dest, const void *src, size_t n)
|
||||
{
|
||||
char *tmp = (char *)dest;
|
||||
const char *s = (const char *)src;
|
||||
|
||||
if (dest == src)
|
||||
return dest;
|
||||
|
||||
if (dest < src) {
|
||||
while (n-- != 0)
|
||||
*tmp++ = *s++;
|
||||
} else {
|
||||
tmp += n;
|
||||
s += n;
|
||||
while (n-- != 0)
|
||||
*--tmp = *--s;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
while (*s1 == *s2) {
|
||||
if (*s1++ == '\0' || *s2++ == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
/* POSIX explicitly wants a cast to unsigned char */
|
||||
return *((const unsigned char *)s1) - *((const unsigned char *)s2);
|
||||
}
|
||||
|
||||
char *strcpy(char *dest, const char *src)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while ((*tmp++ = *src++) != '\0');
|
||||
/* nothing */
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
char *strncpy(char *dest, const char *src, size_t n)
|
||||
{
|
||||
char *tmp = dest;
|
||||
|
||||
while (n-- != 0) {
|
||||
if ((*tmp++ = *src++) == '\0')
|
||||
break;
|
||||
}
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *tmp = s;
|
||||
|
||||
while (*tmp++ != '\0');
|
||||
/* nothing */
|
||||
|
||||
return (size_t)tmp - (size_t)s - 1;
|
||||
}
|
||||
|
||||
size_t strnlen(const char *s, size_t maxlen)
|
||||
{
|
||||
const char *tmp = s;
|
||||
|
||||
while (*tmp++ != '\0' && maxlen-- > 0);
|
||||
/* nothing */
|
||||
|
||||
return (size_t)tmp - (size_t)s - 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This file is part of GayBSD.
|
||||
* Copyright (c) 2021 fef <owo@fef.moe>.
|
||||
*
|
||||
* GayBSD is nonviolent software: you may only use, redistribute, and/or
|
||||
* modify it under the terms of the Cooperative Nonviolent Public License
|
||||
* (CNPL) as found in the LICENSE file in the source code root directory
|
||||
* or at <https://git.pixie.town/thufie/npl-builder>; either version 7
|
||||
* of the license, or (at your option) any later version.
|
||||
*
|
||||
* GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
|
||||
* permitted by applicable law. See the CNPL for details.
|
||||
*/
|
15
lib/lib.cmake
Normal file
15
lib/lib.cmake
Normal file
|
@ -0,0 +1,15 @@
|
|||
# See the end of this file for copyright and license terms.
|
||||
|
||||
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/c")
|
||||
|
||||
# This file is part of GayBSD.
|
||||
# Copyright (c) 2021 fef <owo@fef.moe>.
|
||||
#
|
||||
# GayBSD is nonviolent software: you may only use, redistribute, and/or
|
||||
# modify it under the terms of the Cooperative Nonviolent Public License
|
||||
# (CNPL) as found in the LICENSE file in the source code root directory
|
||||
# or at <https://git.pixie.town/thufie/npl-builder>; either version 7
|
||||
# of the license, or (at your option) any later version.
|
||||
#
|
||||
# GayBSD comes with ABSOLUTELY NO WARRANTY, to the extent
|
||||
# permitted by applicable law. See the CNPL for details.
|
Loading…
Reference in a new issue