From 4bd03f267ab0fd5c42a418157c6113f73853cfca Mon Sep 17 00:00:00 2001 From: Andrew Kesterson Date: Sun, 10 May 2026 00:00:31 -0400 Subject: [PATCH] some file ops, some print ops, some memory ops --- CMakeLists.txt | 63 ++++++++++++++++++++ akstdlib.pc.in | 10 ++++ cmake/akstdlib.cmake.in | 5 ++ include/akstdlib.h | 25 ++++++++ rebuild.sh | 11 ++++ src/stdlib.c | 128 ++++++++++++++++++++++++++++++++++++++++ 6 files changed, 242 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 akstdlib.pc.in create mode 100644 cmake/akstdlib.cmake.in create mode 100644 include/akstdlib.h create mode 100644 rebuild.sh create mode 100644 src/stdlib.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..b906197 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,63 @@ +cmake_minimum_required(VERSION 3.10) +project(akstdlib LANGUAGES C) + +include(CTest) +include(GNUInstallDirs) +include(CMakePackageConfigHelpers) + +find_package(PkgConfig REQUIRED) +find_package(akerror REQUIRED) + +set(akstdlib_install_cmakedir "${CMAKE_INSTALL_LIBDIR}/cmake/akstdlib") +set(prefix ${CMAKE_INSTALL_PREFIX}) +set(exec_prefix "\${prefix}") +set(libdir "\${exec_prefix}/lib") +set(includedir "\${prefix}/include") +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/akstdlib.pc.in ${CMAKE_CURRENT_BINARY_DIR}/akstdlib.pc @ONLY) + +add_library(akstdlib SHARED + src/stdlib.c +) + +# Specify include directories for the library's headers (if applicable) +target_include_directories(akstdlib PUBLIC + $ + $ +) + +target_link_libraries(akstdlib PUBLIC akerror::akerror) + +set(main_lib_dest "lib/my_library-${MY_LIBRARY_VERSION}") +install(TARGETS akstdlib EXPORT akstdlib DESTINATION "lib/") +install(TARGETS akstdlib + EXPORT akstdlibTargets + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +install(EXPORT akstdlib FILE akstdlibTargets.cmake DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/akstdlib) + +install(FILES "include/akstdlib.h" DESTINATION "include/") +install(FILES ${CMAKE_CURRENT_BINARY_DIR}/akstdlib.pc DESTINATION "lib/pkgconfig/") + + +install(EXPORT akstdlib + FILE akstdlibTargets.cmake + NAMESPACE akstdlib:: + DESTINATION ${akstdlib_install_cmakedir} +) + +configure_package_config_file( + cmake/akstdlib.cmake.in + "${CMAKE_CURRENT_BINARY_DIR}/akstdlibConfig.cmake" + INSTALL_DESTINATION ${akstdlib_install_cmakedir} +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/akstdlibConfig.cmake" + DESTINATION ${akstdlib_install_cmakedir} +) + +# pkgconfig diff --git a/akstdlib.pc.in b/akstdlib.pc.in new file mode 100644 index 0000000..1e4db10 --- /dev/null +++ b/akstdlib.pc.in @@ -0,0 +1,10 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=${prefix} +libdir=${exec_prefix}/lib +includedir=${exec_prefix}/include + +Name: akstdlib +Description: C stdlib with akerror sanity wrappers +Version: @PROJECT_VERSION@ +Cflags: -I${includedir}/ +Libs: -L${libdir} -lakstdlib \ No newline at end of file diff --git a/cmake/akstdlib.cmake.in b/cmake/akstdlib.cmake.in new file mode 100644 index 0000000..06ac718 --- /dev/null +++ b/cmake/akstdlib.cmake.in @@ -0,0 +1,5 @@ +# cmake/MyLibraryConfig.cmake.in +include(CMakeFindDependencyMacro) # If your library has dependencies +# find_dependency(AnotherDependency REQUIRED) # Example dependency + +include("${CMAKE_CURRENT_LIST_DIR}/akstdlibTargets.cmake") diff --git a/include/akstdlib.h b/include/akstdlib.h new file mode 100644 index 0000000..a61c5da --- /dev/null +++ b/include/akstdlib.h @@ -0,0 +1,25 @@ +#ifndef _AKSTDLIB_H_ +#define _AKSTDLIB_H_ + +#include +#include +#include +#include + +akerr_ErrorContext AKERR_NOIGNORE *aksl_fopen(char *pathname, char *mode, FILE **fp); +akerr_ErrorContext AKERR_NOIGNORE *aksl_fread(void *ptr, size_t size, size_t nmemb, FILE *stream); +akerr_ErrorContext AKERR_NOIGNORE *aksl_fwrite(void *ptr, size_t size, size_t nmemb, FILE *fp); +akerr_ErrorContext AKERR_NOIGNORE *aksl_fclose(FILE *stream); + +akerr_ErrorContext AKERR_NOIGNORE *aksl_malloc(size_t size, void **dst); +akerr_ErrorContext AKERR_NOIGNORE *aksl_memset(void *s, int c, size_t n); +akerr_ErrorContext AKERR_NOIGNORE *aksl_memcpy(void *d, void *s, size_t n); +akerr_ErrorContext AKERR_NOIGNORE *aksl_free(void *ptr); + + +akerr_ErrorContext AKERR_NOIGNORE *aksl_printf(int *count, const char *restrict format, ...); +akerr_ErrorContext AKERR_NOIGNORE *aksl_fprintf(int *count, FILE *restrict stream, const char *restrict format, ...); +akerr_ErrorContext AKERR_NOIGNORE *aksl_sprintf(int *count, char *restrict str, const char *restrict format, ...); + + +#endif diff --git a/rebuild.sh b/rebuild.sh new file mode 100644 index 0000000..6e605d0 --- /dev/null +++ b/rebuild.sh @@ -0,0 +1,11 @@ +#!/bin/bash + + +export CMAKE_PREFIX_PATH=/home/andrew/local:/home/andrew/local/lib/cmake +export CMAKE_MODULE_PATH=/home/andrew/local/lib/cmake +#export SDL3_DIR=/home/andrew/local + +rm -fr ~/local/lib/*akstdlib* ~/local/include/*akstdlib* build +cmake -S . -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo +cmake --build build --parallel 4 +cmake --install build --prefix /home/andrew/local diff --git a/src/stdlib.c b/src/stdlib.c new file mode 100644 index 0000000..fcd6f4d --- /dev/null +++ b/src/stdlib.c @@ -0,0 +1,128 @@ +#include +#include +#include +#include +#include + +akerr_ErrorContext AKERR_NOIGNORE *aksl_malloc(size_t size, void **dst) +{ + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, dst, AKERR_NULLPOINTER, "NULL"); + *dst = malloc(size); + FAIL_ZERO_RETURN(e, *dst, errno, "%ld bytes", size); + SUCCEED_RETURN(e); +} + +akerr_ErrorContext AKERR_NOIGNORE *aksl_free(void *ptr) +{ + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, ptr, AKERR_NULLPOINTER, "NULL"); + free(ptr); + SUCCEED_RETURN(e); +} + +akerr_ErrorContext AKERR_NOIGNORE *aksl_memset(void *s, int c, size_t n) +{ + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, s, AKERR_NULLPOINTER, "s=%p", s); + FAIL_ZERO_RETURN(e, memset(s, c, n), errno, "Failed to memset"); + SUCCEED_RETURN(e); +} + + +akerr_ErrorContext AKERR_NOIGNORE *aksl_memcpy(void *d, void *s, size_t n) +{ + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, d, AKERR_NULLPOINTER, "d=%p, s=%p", d, s); + FAIL_ZERO_RETURN(e, s, AKERR_NULLPOINTER, "d=%p, s=%p", d, s); + FAIL_ZERO_RETURN(e, (memcpy(d, s, n) == d), errno, "Failed to memcpy"); + SUCCEED_RETURN(e); +} + +akerr_ErrorContext AKERR_NOIGNORE *aksl_fopen( + char *pathname, + char *mode, + FILE **fp) +{ + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, fp, AKERR_NULLPOINTER, "NULL"); + *fp = fopen(pathname, mode); + FAIL_ZERO_RETURN(e, *fp, errno, "%s", pathname); + SUCCEED_RETURN(e); +} + +akerr_ErrorContext AKERR_NOIGNORE *aksl_fread( + void *ptr, + size_t size, size_t nmemb, + FILE *fp) +{ + size_t nmemr; + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, fp, AKERR_NULLPOINTER, "NULL"); + nmemr = fread(ptr, size, nmemb, fp); + if ( nmemr != nmemb ) { + FAIL_NONZERO_RETURN(e, feof(fp), AKERR_EOF, "EOF reached"); + FAIL_NONZERO_RETURN(e, ferror(fp), AKERR_IO, "Error reading file"); + } + SUCCEED_RETURN(e); +} + +akerr_ErrorContext AKERR_NOIGNORE *aksl_fwrite( + void *ptr, + size_t size, size_t nmemb, + FILE *fp) +{ + size_t nmemw; + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, fp, AKERR_NULLPOINTER, "NULL argument"); + nmemw = fwrite(ptr, size, nmemb, fp); + if ( nmemw != nmemb ) { + FAIL_NONZERO_RETURN(e, feof(fp), AKERR_EOF, "EOF reached"); + FAIL_NONZERO_RETURN(e, ferror(fp), AKERR_IO, "Error reading file"); + } + SUCCEED_RETURN(e); +} + +akerr_ErrorContext AKERR_NOIGNORE *aksl_fclose(FILE *stream) +{ + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, stream, AKERR_NULLPOINTER, "NULL"); + FAIL_NONZERO_RETURN(e, fclose(stream), errno, "Failed to fclose"); + SUCCEED_RETURN(e); +} + +akerr_ErrorContext AKERR_NOIGNORE *aksl_printf(int *count, const char *restrict format, ...) +{ + va_list args; + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, count, AKERR_NULLPOINTER, "count=%p, format=%p", (void *)count, (void *)format); + FAIL_ZERO_RETURN(e, format, AKERR_NULLPOINTER, "count=%p, format=%p", (void *)count, (void *)format); + *count = vprintf(format, args); + FAIL_NONZERO_RETURN(e, (*count == -1), errno, "Short write"); + SUCCEED_RETURN(e); +} + + +akerr_ErrorContext AKERR_NOIGNORE *aksl_fprintf(int *count, FILE *restrict stream, const char *restrict format, ...) +{ + va_list args; + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, count, AKERR_NULLPOINTER, "count=%p, stream=%p, format=%p", (void *)count, (void *)stream, (void *)format); + FAIL_ZERO_RETURN(e, stream, AKERR_NULLPOINTER, "count=%p, stream=%p, format=%p", (void *)count, (void *)stream, (void *)format); + FAIL_ZERO_RETURN(e, format, AKERR_NULLPOINTER, "count=%p, stream=%p, format=%p", (void *)count, (void *)stream, (void *)format); + *count = vfprintf(stream, format, args); + FAIL_NONZERO_RETURN(e, (*count == -1), errno, "Short write"); + SUCCEED_RETURN(e); +} + +akerr_ErrorContext AKERR_NOIGNORE *aksl_sprintf(int *count, char *restrict str, const char *restrict format, ...) +{ + va_list args; + PREPARE_ERROR(e); + FAIL_ZERO_RETURN(e, count, AKERR_NULLPOINTER, "count=%p, str=%p, format=%p", (void *)count, (void *)str, (void *)format); + FAIL_ZERO_RETURN(e, str, AKERR_NULLPOINTER, "count=%p, str=%p, format=%p", (void *)count, (void *)str, (void *)format); + FAIL_ZERO_RETURN(e, format, AKERR_NULLPOINTER, "count=%p, str=%p, format=%p", (void *)count, (void *)str, (void *)format); + *count = vsprintf(str, format, args); + FAIL_NONZERO_RETURN(e, (*count == -1), errno, "Short write"); + SUCCEED_RETURN(e); +}