From e312bfb551a371829b77ec6e72f79b291b0dab67 Mon Sep 17 00:00:00 2001 From: SpacingBat3 Date: Wed, 13 May 2026 22:39:18 +0200 Subject: [PATCH] feat(io): Initial implementation Implement `io_readline` and `io_fill` operations and introduce IO API extension to the library. --- CMakeLists.txt | 4 +-- src/alias.h | 3 ++ src/io.c | 62 ++++++++++++++++++++++++++++++++++ src/vec.c | 2 ++ template/include/YAVL/io.h.in | 50 +++++++++++++++++++++++++++ template/include/YAVL/vec.h.in | 1 + 6 files changed, 120 insertions(+), 2 deletions(-) create mode 100644 src/io.c create mode 100644 template/include/YAVL/io.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 26beb96..19c876b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -50,7 +50,7 @@ message(VERBOSE "YAVL: C symbol namespace: ${YAVL_C_NAMESPACE}") ## 2. List of auto-generated headers set("${PROJECT_NAME}_GEN_HEADERS" - "vec.h") + "vec.h" "io.h") # Target list # =========== @@ -126,7 +126,7 @@ endif() # Header generation and inclusion to API # ====================================== -foreach(header "${${PROJECT_NAME}_GEN_HEADERS}") +foreach(header IN LISTS "${PROJECT_NAME}_GEN_HEADERS") configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/template/include/YAVL/${header}.in" "${${PROJECT_NAME}_GEN_HEADERS_OUTPUT_DIRECTORY}/YAVL/${header}" diff --git a/src/alias.h b/src/alias.h index e9e8568..199bdbc 100644 --- a/src/alias.h +++ b/src/alias.h @@ -28,6 +28,9 @@ NS_TYPE(vec_errorable_t); #define vec_fit NS(vec_fit) #define vec_scale NS(vec_scale) #define vec_free NS(vec_free) +#define io_fill NS(io_fill) +#define io_readline NS(io_readline) + #endif /* YAVL_C_NAMESPACE */ #ifdef YAVL_C_NAMESPACE_UPPER diff --git a/src/io.c b/src/io.c new file mode 100644 index 0000000..bfa02d9 --- /dev/null +++ b/src/io.c @@ -0,0 +1,62 @@ +/* + * io.c - I/O API based on vector for dynamic allocation + * + * SPDX-License: GPL-3.0-or-later + * + * Copyright (C) 2026 Dawid Papiewski + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License along with this + * program. If not, see . + * + */ +#include +#include +#include + +#include "alias.h" +#include "macro.h" + +vec_res_t io_fill(vec_t *const vec, FILE *const stream) { + if(vec->allign != sizeof(char)) return VEC_RES_FAIL; + for( + size_t cr=1; + cr!=0; + cr=fread( + /*__ptr=*/ vec->data+(vec->len*vec->allign), + /*__size=*/ vec->allign, + /*__n=*/ vec->reservd-vec->len, + /*__stream=*/ stream + ) + ) { + vec->len += cr; + // Autoscale + vec_res_t res; + if(vec->reservd <= vec->len) res = vec_scale(vec, vec->reservd*2); + if(res != VEC_RES_OK) return res; + } + vec_fit(vec); + return VEC_RES_OK; +} + +vec_res_t io_readline(vec_t *const vec, FILE *const stream) { + if(vec->allign != sizeof(char)) return VEC_RES_FAIL; + for( + int ch=0; + ch!='\n'||ch==EOF; + ch=getc(stream) + ) { + char c = ch; vec_res_t res; + if((res = vec_push(vec,&c,1)) != VEC_RES_OK) + return res; + } + const char trail[] = "\n"; + vec_push(vec, trail, sizeof(trail)/sizeof(trail[0])); + return vec_fit(vec); +} diff --git a/src/vec.c b/src/vec.c index 9ee1d59..9351959 100644 --- a/src/vec.c +++ b/src/vec.c @@ -1,4 +1,6 @@ /* + * vec.c - Core vector API + * * SPDX-License: GPL-3.0-or-later * * Copyright (C) 2026 Dawid Papiewski diff --git a/template/include/YAVL/io.h.in b/template/include/YAVL/io.h.in new file mode 100644 index 0000000..7e81198 --- /dev/null +++ b/template/include/YAVL/io.h.in @@ -0,0 +1,50 @@ +/** @file + * + * I/O API extension + * + * SPDX-License: GPL-3.0-or-later + * + * @author Dawid Papiewski + * @copyright (C) 2026 Dawid Papiewski + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + * You should have received a copy of the GNU General Public License along with this + * program. If not, see . + */ +#pragma once +#ifndef @YAVL_C_NAMESPACE_UPPER_@IO_H +#define @YAVL_C_NAMESPACE_UPPER_@IO_H +#pragma clang final(@YAVL_C_NAMESPACE_UPPER_@IO_H) +#include "vec.h" +/** @defgroup IO I/O API + * + * @brief Stream read and buffering API, + * made for parsers in mind. + * + * @{ + */ + +/** + * Read from stream until finding '\n' + * + * @param vec Vector to push buffer into. + * @param stream Stream to read line from. + */ +@YAVL_C_NAMESPACE_@vec_res_t @YAVL_C_NAMESPACE_@io_readline(@YAVL_C_NAMESPACE_@vec_t *const vec, FILE *const stream); +/** + * Buffer entire stream into vector. + * + * @param vec Vector to buffer stream into. + * @param stream Stream to read data from. + */ +@YAVL_C_NAMESPACE_@vec_res_t @YAVL_C_NAMESPACE_@io_fill(@YAVL_C_NAMESPACE_@vec_t *const vec, FILE *const stream); + +/** @} */ // IO +#endif diff --git a/template/include/YAVL/vec.h.in b/template/include/YAVL/vec.h.in index 2727084..8e6729a 100644 --- a/template/include/YAVL/vec.h.in +++ b/template/include/YAVL/vec.h.in @@ -19,6 +19,7 @@ * program. If not, see . * */ +#pragma once #ifndef @YAVL_C_NAMESPACE_UPPER_@VEC_H #define @YAVL_C_NAMESPACE_UPPER_@VEC_H #pragma clang final(@YAVL_C_NAMESPACE_UPPER_@VEC_H)