diff --git a/userspace/libraries/LibC/CMakeLists.txt b/userspace/libraries/LibC/CMakeLists.txt index f0bef2c6..7fc564fc 100644 --- a/userspace/libraries/LibC/CMakeLists.txt +++ b/userspace/libraries/LibC/CMakeLists.txt @@ -10,6 +10,7 @@ set(LIBC_SOURCES ftw.cpp grp.cpp inttypes.cpp + libgen.cpp locale.cpp malloc.cpp math.cpp diff --git a/userspace/libraries/LibC/libgen.cpp b/userspace/libraries/LibC/libgen.cpp new file mode 100644 index 00000000..83150e2d --- /dev/null +++ b/userspace/libraries/LibC/libgen.cpp @@ -0,0 +1,69 @@ +#include +#include +#include + +char* basename(char* path) +{ + static char buffer[PATH_MAX]; + + constexpr auto prep_string = + [](const char* str) -> char* + { + strcpy(buffer, str); + return buffer; + }; + + if (path == nullptr || path[0] == '\0') + return prep_string("."); + + char* endp = path + strlen(path); + + while (endp > path && endp[-1] == '/') + endp--; + if (endp == path) + return prep_string("/"); + + char* startp = endp; + while (startp > path && startp[-1] != '/') + startp--; + + memcpy(buffer, startp, endp - startp); + buffer[endp - startp] = '\0'; + return buffer; +} + +char* dirname(char* path) +{ + static char buffer[PATH_MAX]; + + constexpr auto prep_string = + [](const char* str) -> char* + { + strcpy(buffer, str); + return buffer; + }; + + if (path == nullptr || path[0] == '\0') + return prep_string("."); + + char* endp = path + strlen(path); + + while (endp > path && endp[-1] == '/') + endp--; + if (endp == path) + return prep_string("/"); + + while (endp > path && endp[-1] != '/') + endp--; + if (endp == path) + return prep_string("."); + + while (endp > path && endp[-1] == '/') + endp--; + if (endp == path) + return prep_string("/"); + + memcpy(buffer, path, endp - path); + buffer[endp - path] = '\0'; + return buffer; +}