This commit is contained in:
Niklas Gollenstede
2025-04-14 11:20:52 +02:00
commit 5a2e32aaeb
126 changed files with 16742 additions and 0 deletions

43
utils/flake.lock generated Normal file
View File

@@ -0,0 +1,43 @@
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1740560979,
"narHash": "sha256-Vr3Qi346M+8CjedtbyUevIGDZW8LcA1fTG0ugPY/Hic=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "5135c59491985879812717f4c9fea69604e7f26f",
"type": "github"
},
"original": {
"owner": "NixOS",
"ref": "nixos-unstable",
"repo": "nixpkgs",
"type": "github"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs",
"systems": "systems"
}
},
"systems": {
"locked": {
"lastModified": 1680978846,
"narHash": "sha256-Gtqg8b/v49BFDpDetjclCYXm8mAnTrUzR0JnE2nv5aw=",
"owner": "nix-systems",
"repo": "x86_64-linux",
"rev": "2ecfcac5e15790ba6ce360ceccddb15ad16d08a8",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "x86_64-linux",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

58
utils/flake.nix Normal file
View File

@@ -0,0 +1,58 @@
/*
* This file allows you to run `nix develop` to get a shell with all external dependencies (`make` plus the tools it calls) of this repo (and maybe some beyond).
* The only thing required is an installation of the "Nix" package manager for Linux (/WSL) or MacOS: https://nixos.org/download/
*/
{
description = ''
The educational operating system StuBS.
'';
inputs = {
# The rolling-release of the Nix(OS) package definitions. Use `nix flake lock` to update
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
# Some boilerplate:
systems.url = "github:nix-systems/x86_64-linux"; # no cross compiling and only x86(_64) for now (darwin (MacOS) might work)
};
outputs =
inputs:
let
lib = inputs.nixpkgs.lib;
eachSystem =
f:
lib.foldAttrs lib.mergeAttrs { } (
map (s: lib.mapAttrs (_: v: { ${s} = v; }) (f s)) (import inputs.systems)
);
in
{ }
// (eachSystem (
localSystem:
let
pkgs = import inputs.nixpkgs { system = localSystem; };
in
{
# The shell environment definition used by `nix develop`:
devShells.default = pkgs.mkShell.override { stdenv = pkgs.clangStdenv; } {
nativeBuildInputs =
with pkgs;
[
# for all tasks and maintenance
gdb
qemu_kvm
nasm
ccache
util-linux # mkfs.minix
git
python3
bear # make compile_commands.json
clang-tools # for clangd and clang-format
]
++ (lib.filter (
pkg: lib.isDerivation pkg && pkg.pname or "" != "glibc"
) pkgs.stdenv.allowedRequisites); # basic tools + compilers (gcc/g++)
};
}
));
}

27
utils/math.h Normal file
View File

@@ -0,0 +1,27 @@
// vim: set noet ts=4 sw=4:
/*! \file
* \brief General purpose \ref Math "math functions"
*/
#pragma once
#include "../types.h"
/*! \brief Basic math helper functions
*/
namespace Math {
template <typename T>
T abs(T a) {
return (a >= 0 ? a : -a);
}
template <typename T>
T min(T a, T b) {
return a > b ? b : a;
}
template <typename T>
T max(T a, T b) {
return a > b ? a : b;
}
} // namespace Math

17
utils/size.h Normal file
View File

@@ -0,0 +1,17 @@
/*! \file
* \brief Template function to determine the length of an array
*/
#pragma once
#include "../types.h"
/* \brief Helper to retrieve the number of elements in an array
* (Warning: template magic)
* \param Array
* \return Number of elements
*/
template <class T, size_t N>
constexpr size_t size(T (& /*unused*/)[N]) {
return N;
}

117
utils/string.cc Normal file
View File

@@ -0,0 +1,117 @@
#include "string.h"
extern "C" char *strchrnul(const char *s, int c) {
if (s != nullptr) {
while (*s != '\0') {
if (*s == c) {
break;
}
s++;
}
}
return const_cast<char *>(s);
}
extern "C" char *strchr(const char *s, int c) {
if (s != nullptr) {
s = strchrnul(s, c);
if (*s == c) {
return const_cast<char *>(s);
}
}
return nullptr;
}
extern "C" int strcmp(const char *s1, const char *s2) {
if (s1 == nullptr || s2 == nullptr) {
return 0;
}
while (*s1 == *s2++) {
if (*s1++ == '\0') {
return 0;
}
}
return static_cast<int>(*s1) - static_cast<int>(*(s2 - 1));
}
extern "C" int strncmp(const char *s1, const char *s2, size_t n) {
if (s1 != nullptr && s2 != nullptr) {
for (size_t i = 0; i < n; i++) {
if (s1[i] != s2[i]) {
return static_cast<int>(s1[i]) - static_cast<int>(s2[i]);
} else if (s1[i] == '\0') {
break;
}
}
}
return 0;
}
extern "C" size_t strlen(const char *s) {
size_t len = 0;
if (s != nullptr) {
while (*s++ != '\0') {
len++;
}
}
return len;
}
extern "C" char *strcpy(char *dest, const char *src) { // NOLINT
char *r = dest;
if (dest != nullptr && src != nullptr) {
while ((*dest++ = *src++) != '\0') {
}
}
return r;
}
extern "C" char *strncpy(char *dest, const char *src, size_t n) {
char *r = dest;
if (dest != nullptr && src != nullptr) {
while ((n--) != 0 && (*dest++ = *src++) != '\0') {
}
}
return r;
}
extern "C" void *memcpy(void *__restrict__ dest, void const *__restrict__ src,
size_t size) {
uint8_t *destination = reinterpret_cast<uint8_t *>(dest);
uint8_t const *source = (uint8_t const *)src;
for (size_t i = 0; i != size; ++i) {
destination[i] = source[i];
}
return dest;
}
extern "C" void *memmove(void *dest, void const *src, size_t size) {
uint8_t *destination = reinterpret_cast<uint8_t *>(dest);
uint8_t const *source = reinterpret_cast<uint8_t const *>(src);
if (source > destination) {
for (size_t i = 0; i != size; ++i) {
destination[i] = source[i];
}
} else {
for (size_t i = size; i != 0; --i) {
destination[i - 1] = source[i - 1];
}
}
return dest;
}
extern "C" void *memset(void *dest, int pattern, size_t size) {
uint8_t *destination = reinterpret_cast<uint8_t *>(dest);
for (size_t i = 0; i != size; ++i) {
destination[i] = static_cast<uint8_t>(pattern);
}
return dest;
}

109
utils/string.h Normal file
View File

@@ -0,0 +1,109 @@
/*! \file
* \brief General purpose \ref string "String functions"
*/
#pragma once
#include "../types.h"
/*! \defgroup string String function
* \brief String functions as provided by `%string.h` in the C standard
*library
*/
/*! \brief Find the first occurrence of a character in a string
* \ingroup string
* \param s string to
* \param c character to find
* \return Pointer to first occurrence of the character
* or to null byte at the end of the string if not found
*/
extern "C" char *strchrnul(const char *s, int c);
/*! \brief Find the first occurrence of a character in a string
* \ingroup string
* \param s string to
* \param c character to find
* \return Pointer to first occurrence of the character
* or to nullptr if not found
*/
extern "C" char *strchr(const char *s, int c);
/*! \brief Compare two strings
* \ingroup string
* \param s1 first string
* \param s2 second string
* \return an integer less than, equal to, or greater than zero if first string
* is found, respectively, to be less than, to match, or be greater than second
* string
*/
extern "C" int strcmp(const char *s1, const char *s2);
/*! \brief Compare two strings
* \ingroup string
* \param s1 first string
* \param s2 second string
* \param n number of bytes to compare
* \return an integer less than, equal to, or greater than zero if the given
* number of bytes of the first string are found, respectively, to be less than,
* to match, or be greater than second string
*/
extern "C" int strncmp(const char *s1, const char *s2, size_t n);
/*! \brief Calculate the length of a string
* \ingroup string
* \param s pointer to a string
* \return number of bytes in the string
*/
extern "C" size_t strlen(const char *s);
/*! \brief Copy the contents of a string
* including the terminating null byte (`\0`)
* \ingroup string
* \param dest destination string buffer
* \param src source string buffer
* \return a pointer to the destination string buffer
* \note Beware of buffer overruns!
*/
extern "C" char *strcpy(char *dest, const char *src); // NOLINT
/*! \brief Copy the contents of a string up to a maximum length
* or the terminating null byte (`\0`), whatever comes first.
* \ingroup string
* \param dest destination string buffer
* \param src source string buffer
* \param n maximum number of bytes to copy
* \return a pointer to the destination string buffer
* \note If there is no null byte (`\0`) among the first `n` bytes, the
* destination will not be null-terminated!
*/
extern "C" char *strncpy(char *dest, const char *src, size_t n);
/*! \brief Copy a memory area
* \ingroup string
* \param dest destination buffer
* \param src source buffer
* \param size number of bytes to copy
* \return pointer to destination
* \note The memory must not overlap!
*/
extern "C" void *memcpy(void *__restrict__ dest, void const *__restrict__ src,
size_t size);
/*! \brief Copy a memory area
* while the source may overlap with the destination
* \ingroup string
* \param dest destination buffer
* \param src source buffer
* \param size number of bytes to copy
* \return pointer to destination
*/
extern "C" void *memmove(void *dest, void const *src, size_t size);
/*! \brief Fill a memory area with a pattern
* \ingroup string
* \param dest destination buffer
* \param pattern single byte pattern
* \param size number of bytes to fill with pattern
* \return pointer to destination
*/
extern "C" void *memset(void *dest, int pattern, size_t size);