diff --git a/Minishell.mk b/Minishell.mk index c1b0ba81..950d2fc8 100644 --- a/Minishell.mk +++ b/Minishell.mk @@ -6,7 +6,7 @@ # By: maiboyer +#+ +:+ +#+ # # +#+#+#+#+#+ +#+ # # Created: 2024/04/28 17:28:30 by maiboyer #+# #+# # -# Updated: 2024/07/05 18:00:14 by maiboyer ### ########.fr # +# Updated: 2024/07/10 21:02:49 by maiboyer ### ########.fr # # # # **************************************************************************** # @@ -19,7 +19,7 @@ link_group = -Wl,--start-group $(1) -Wl,--end-group BUILD_DIR ?= $(shell realpath ./build/) # Flags -CFLAGS = -Werror -Wextra -Wall -Wno-unused-command-line-argument -g3 -MMD -lreadline -I./includes -I./output/include -I./stdme/output/include -rdynamic -Wl,-E +CFLAGS = -Werror -Wextra -Wall -Wno-unused-command-line-argument -g3 -MMD -I./includes -I./output/include -I./stdme/output/include -rdynamic -Wl,-E # CFLAGS += -fsanitize=address -fno-omit-frame-pointer -fsanitize-address-use-after-return=runtime -fno-common -fsanitize-address-use-after-scope # Sources # LIB = ./libft/ft_bzero.c \ diff --git a/allocator/include/aq/alloc.h b/allocator/include/aq/alloc.h index 68a0e7ae..1bd9ec28 100644 --- a/allocator/include/aq/alloc.h +++ b/allocator/include/aq/alloc.h @@ -11,14 +11,14 @@ /* ************************************************************************** */ #ifndef ALLOC_H -#define ALLOC_H +# define ALLOC_H -#include "me/types.h" +# include "me/types.h" -void *me_malloc(t_usize size); -void *me_calloc(t_usize elem_count, t_usize elem_size); -void *me_realloc(void *ptr, t_usize size); -void *me_realloc_array(void *ptr, t_usize elem_size, t_usize elem_count); -void uninit_allocator(void); +void *me_malloc(t_usize size); +void *me_calloc(t_usize elem_count, t_usize elem_size); +void *me_realloc(void *ptr, t_usize size); +void *me_realloc_array(void *ptr, t_usize elem_size, t_usize elem_count); +void uninit_allocator(void); #endif /* ALLOC_H */ diff --git a/allocator/include/aq/alloc_internal.h b/allocator/include/aq/alloc_internal.h deleted file mode 100644 index b7b89212..00000000 --- a/allocator/include/aq/alloc_internal.h +++ /dev/null @@ -1,50 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* alloc_internal.h :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: maiboyer +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2024/05/07 09:48:17 by maiboyer #+# #+# */ -/* Updated: 2024/05/14 16:12:54 by maiboyer ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#ifndef ALLOC_INTERNAL_H -#define ALLOC_INTERNAL_H - -#include "aq/alloc.h" -#include "me/types.h" -#include - -#define PAGE_SIZE_DEFAULT 4096 -#define BLOCK_PADDING "\xFE\xDC\xAB\xC0\xFE\xEE\x66" -#define POOL_ADDR (void *)0xDeadBeef - -typedef struct s_mblock -{ - struct s_mblock *next; - struct s_mpage *page; - t_usize size; - bool used; - t_u8 padding[7]; -} t_mblock; - -typedef struct s_mpage -{ - t_usize page_size; - t_mblock *first; - struct s_mpage *next; -} t_mpage; - -// Will never be null, as it will allocate a new arena if it needs to do so -t_mpage *get_head_arena(void); - -// Will return ERROR if it couldn't malloc the page -t_error alloc_arena_page(t_usize min_size, t_mpage **out); - -t_mblock *get_block_for_size(t_usize size); -void print_pages_info(void); -bool merge_block(t_mblock *self, t_usize min_size); - -#endif /* ALLOC_INTERNAL_H */ diff --git a/allocator/include/aq/allocator.h b/allocator/include/aq/allocator.h index 5c6f15b8..484a0e33 100644 --- a/allocator/include/aq/allocator.h +++ b/allocator/include/aq/allocator.h @@ -11,32 +11,34 @@ /* ************************************************************************** */ #ifndef ALLOCATOR_H -#define ALLOCATOR_H +# define ALLOCATOR_H -#include "me/types.h" +# include "me/types.h" -typedef struct s_allocator t_allocator; +typedef struct s_allocator t_allocator; -typedef void *(*t_allocator_alloc)(t_allocator *self, t_usize size); -typedef void *(*t_allocator_alloc_array)(t_allocator *self, t_usize size, - t_usize count); -typedef void *(*t_allocator_realloc)(t_allocator *self, void *ptr, - t_usize requested_size); -typedef void *(*t_allocator_realloc_array)(t_allocator *self, void *ptr, - t_usize requested_size, - t_usize requested_count); -typedef void (*t_allocator_free)(t_allocator *self, void *ptr); -typedef void (*t_allocator_uninit)(t_allocator *self); +typedef void *(*t_allocator_alloc)(t_allocator *self, + t_usize size); +typedef void *(*t_allocator_alloc_array)(t_allocator *self, + t_usize size, t_usize count); +typedef void *(*t_allocator_realloc)(t_allocator *self, + void *ptr, t_usize requested_size); +typedef void *(*t_allocator_realloc_array)(t_allocator *self, + void *ptr, t_usize requested_size, + t_usize requested_count); +typedef void (*t_allocator_free)(t_allocator *self, + void *ptr); +typedef void (*t_allocator_uninit)(t_allocator *self); -struct s_allocator +struct s_allocator { - t_allocator_alloc alloc; - t_allocator_alloc_array alloc_array; - t_allocator_realloc realloc; - t_allocator_realloc_array realloc_array; - t_allocator_free free; - t_allocator_uninit uninit; - void *alloc_data; + t_allocator_alloc alloc; + t_allocator_alloc_array alloc_array; + t_allocator_realloc realloc; + t_allocator_realloc_array realloc_array; + t_allocator_free free; + t_allocator_uninit uninit; + void *alloc_data; }; #endif /* ALLOCATOR_H */ diff --git a/allocator/include/aq/internal_vg_funcs.h b/allocator/include/aq/internal_vg_funcs.h index 6a4e2cbd..0e9e4513 100644 --- a/allocator/include/aq/internal_vg_funcs.h +++ b/allocator/include/aq/internal_vg_funcs.h @@ -6,59 +6,63 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/12 22:20:30 by maiboyer #+# #+# */ -/* Updated: 2024/05/17 15:34:26 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 16:40:57 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef INTERNAL_VG_FUNCS_H -#define INTERNAL_VG_FUNCS_H +# define INTERNAL_VG_FUNCS_H -#include "me/types.h" -#if !defined(NVALGRIND) || defined(VGHEADER) -# ifdef NVALGRIND -# undef NVALGRIND +# include "me/types.h" + +# if !defined(NVALGRIND) || defined(VGHEADER) +# ifdef NVALGRIND +# undef NVALGRIND +# endif +# define VGFUNCS +# include +# include # endif -# define VGFUNCS -# include -# include -#endif -#define ZEROED_POOL 1 -#define ZEROED_ALLOC 1 +# define ZEROED_POOL 1 +# define ZEROED_ALLOC 1 -static inline t_usize redzone_size(void) +static inline t_usize redzone_size(void) { return (8); } -#ifdef VGFUNCS -static inline bool vg_running(void) +# ifdef VGFUNCS + +static inline bool vg_running(void) { return (RUNNING_ON_VALGRIND != 0); } -#else -static inline bool vg_running(void) +# else + +static inline bool vg_running(void) { return (false); } -#endif +# endif -#define MEMPOOL_FLAG_MALLOCLIKE 1 -#define MEMPOOL_FLAG_AUTOFREE 2 +# define MEMPOOL_FLAG_MALLOCLIKE 1 +# define MEMPOOL_FLAG_AUTOFREE 2 -void vg_block_malloc(void *ptr, t_usize size); -void vg_block_resize(void *ptr, t_usize oldsize, t_usize newsize); -void vg_block_free(void *ptr); +void vg_block_malloc(void *ptr, t_usize size); +void vg_block_resize(void *ptr, t_usize oldsize, + t_usize newsize); +void vg_block_free(void *ptr); -void vg_mem_no_access(void *ptr, t_usize size); -void vg_mem_undefined(void *ptr, t_usize size); -void vg_mem_defined(void *ptr, t_usize size); +void vg_mem_no_access(void *ptr, t_usize size); +void vg_mem_undefined(void *ptr, t_usize size); +void vg_mem_defined(void *ptr, t_usize size); -void vg_mempool_create(void *pool); -void vg_mempool_create_ext(void *pool, t_usize flags); -void vg_mempool_destroy(void *pool); -void vg_mempool_alloc(void *pool, void *addr, t_usize size); -void vg_mempool_free(void *pool, void *addr); -void vg_mempool_resize(void *pool, void *psrc, t_usize size); +void vg_mempool_create(void *pool); +void vg_mempool_create_ext(void *pool, t_usize flags); +void vg_mempool_destroy(void *pool); +void vg_mempool_alloc(void *pool, void *addr, t_usize size); +void vg_mempool_free(void *pool, void *addr); +void vg_mempool_resize(void *pool, void *psrc, t_usize size); #endif /* INTERNAL_VG_FUNCS_H */ diff --git a/allocator/include/aq/libc_wrapper.h b/allocator/include/aq/libc_wrapper.h index cf3ba8dd..fa548647 100644 --- a/allocator/include/aq/libc_wrapper.h +++ b/allocator/include/aq/libc_wrapper.h @@ -11,19 +11,19 @@ /* ************************************************************************** */ #ifndef LIBC_WRAPPER_H -#define LIBC_WRAPPER_H +# define LIBC_WRAPPER_H -#include "aq/allocator.h" -#include "me/types.h" +# include "aq/allocator.h" +# include "me/types.h" -void *lc_malloc(t_allocator *self, t_usize size); -void *lc_calloc(t_allocator *self, t_usize size, t_usize count); -void *lc_realloc(t_allocator *self, void *ptr, t_usize min_size); -void *lc_realloc_array(t_allocator *self, void *ptr, t_usize size, - t_usize count); -void lc_free(t_allocator *self, void *ptr); -void lc_uninit(t_allocator *self); +void *lc_malloc(t_allocator *self, t_usize size); +void *lc_calloc(t_allocator *self, t_usize size, t_usize count); +void *lc_realloc(t_allocator *self, void *ptr, t_usize min_size); +void *lc_realloc_array(t_allocator *self, void *ptr, t_usize size, + t_usize count); +void lc_free(t_allocator *self, void *ptr); +void lc_uninit(t_allocator *self); -t_allocator lc_init(void); +t_allocator lc_init(void); #endif /* LIBC_WRAPPER_H */ diff --git a/allocator/include/aq/melloc.h b/allocator/include/aq/melloc.h index 7a46757c..719d8248 100644 --- a/allocator/include/aq/melloc.h +++ b/allocator/include/aq/melloc.h @@ -11,18 +11,18 @@ /* ************************************************************************** */ #ifndef MELLOC_H -#define MELLOC_H +# define MELLOC_H -#include "aq/allocator.h" +# include "aq/allocator.h" -void *m_malloc(t_allocator *self, t_usize size); -void *m_alloc_array(t_allocator *self, t_usize size, t_usize count); -void *m_realloc(t_allocator *self, void *ptr, t_usize min_size); -void *m_realloc_array(t_allocator *self, void *ptr, t_usize size, - t_usize count); -void m_free(t_allocator *self, void *ptr); -void m_uninit(t_allocator *self); +void *m_malloc(t_allocator *self, t_usize size); +void *m_alloc_array(t_allocator *self, t_usize size, t_usize count); +void *m_realloc(t_allocator *self, void *ptr, t_usize min_size); +void *m_realloc_array(t_allocator *self, void *ptr, t_usize size, + t_usize count); +void m_free(t_allocator *self, void *ptr); +void m_uninit(t_allocator *self); -t_allocator m_init(void); +t_allocator m_init(void); #endif /* MELLOC_H */ diff --git a/allocator/include/aq/melloc_interal.h b/allocator/include/aq/melloc_interal.h index 7a798496..6b108de3 100644 --- a/allocator/include/aq/melloc_interal.h +++ b/allocator/include/aq/melloc_interal.h @@ -6,59 +6,80 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/15 15:27:46 by maiboyer #+# #+# */ -/* Updated: 2024/05/16 14:58:27 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 16:55:59 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef MELLOC_INTERAL_H -#define MELLOC_INTERAL_H +# define MELLOC_INTERAL_H -#include "aq/allocator.h" -#include "me/types.h" +# include "aq/allocator.h" +# include "me/types.h" -#define PAGE_LIST_MAX 255 -#define PAGE_POW_2 12 -#define PAGE_ALIGN 3 +# define PAGE_LIST_MAX 255 +# define PAGE_POW_2 12 +# define PAGE_ALIGN 3 typedef struct s_chunk { - bool used : 1; - t_u64 size : 63; -} t_chunk; + bool used : 1; + t_u64 size : 63; +} t_chunk; typedef struct s_page { - t_usize size; - void *data; -} t_page; + t_usize size; + void *data; +} t_page; typedef struct s_page_list { - t_usize len; - t_page pages[PAGE_LIST_MAX]; - struct s_page_list *next; -} t_page_list; + t_usize len; + t_page pages[PAGE_LIST_MAX]; + struct s_page_list *next; +} t_page_list; -struct s_allocator_melloc +struct s_allocator_melloc { - t_allocator_alloc alloc; - t_allocator_alloc_array alloc_array; - t_allocator_realloc realloc; - t_allocator_realloc_array realloc_array; - t_allocator_free free; - t_allocator_uninit uninit; - t_page_list *list; + t_allocator_alloc alloc; + t_allocator_alloc_array alloc_array; + t_allocator_realloc realloc; + t_allocator_realloc_array realloc_array; + t_allocator_free free; + t_allocator_uninit uninit; + t_page_list *list; }; -t_error alloc_page_list(t_page_list **out); +void *m_malloc(struct s_allocator_melloc *self, t_usize size); +void *m_alloc_array(struct s_allocator_melloc *self, \ + t_usize size, t_usize count); +void *m_realloc(struct s_allocator_melloc *self, \ + void *ptr, t_usize min_size); +void *m_realloc_array(struct s_allocator_melloc *self, \ + void *ptr, t_usize size, t_usize count); +void m_free(struct s_allocator_melloc *self, void *ptr); +void m_uninit(struct s_allocator_melloc *self); -void *m_malloc(struct s_allocator_melloc *self, t_usize size); -void *m_alloc_array(struct s_allocator_melloc *self, t_usize size, - t_usize count); -void *m_realloc(struct s_allocator_melloc *self, void *ptr, t_usize min_size); -void *m_realloc_array(struct s_allocator_melloc *self, void *ptr, t_usize size, - t_usize count); -void m_free(struct s_allocator_melloc *self, void *ptr); -void m_uninit(struct s_allocator_melloc *self); +t_chunk *find_chunk_of_size(struct s_allocator_melloc *alloc, t_usize size); +t_chunk *get_first_block(t_page *page); +t_chunk *get_next_block(t_chunk *chunk, bool find_zero); +t_chunk *split_block(t_chunk *chunk, t_usize size); +void merge_blocks(t_page *page); + +t_error alloc_page_list(t_page_list **out); +t_error alloc_new_page(struct s_allocator_melloc *alloc, t_usize page_size); + +static inline t_usize round_to_pow2(t_usize val, t_usize pow) +{ + pow = (1 << pow) - 1; + return ((val + pow) & (~pow)); +} + +static inline void *m_alloc_error(struct s_allocator_melloc *self, t_str msg) +{ + self->uninit((void *)self); + me_abort(msg); + return (NULL); +} #endif /* MELLOC_INTERAL_H */ diff --git a/allocator/src.list b/allocator/src.list index 6be242f4..9df69ea2 100644 --- a/allocator/src.list +++ b/allocator/src.list @@ -1,12 +1,17 @@ -alloc -get_arena lc_alloc/functions1 lc_alloc/functions2 +me_alloc/find_block me_alloc/functions1 me_alloc/functions2 +me_alloc/internals +me_alloc/merge_blocks +me_alloc/pages +me_alloc/realloc vg/dummy_block -vg/dummy_mempool vg/dummy_mem_status +vg/dummy_mempool +vg/dummy_mempool_bis vg/valgrind_block -vg/valgrind_mempool vg/valgrind_mem_status +vg/valgrind_mempool +vg/valgrind_mempool_bis diff --git a/allocator/src/alloc.c b/allocator/src/alloc.c deleted file mode 100644 index dfeef9db..00000000 --- a/allocator/src/alloc.c +++ /dev/null @@ -1,196 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* alloc.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: maiboyer +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2024/05/07 10:13:06 by maiboyer #+# #+# */ -/* Updated: 2024/05/14 18:26:01 by maiboyer ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "aq/allocator.h" -#include "aq/libc_wrapper.h" - -typedef struct s_allocator_page -{ - void *data; - t_usize size; -} t_allocator_page; - -typedef struct s_page_list -{ - t_usize allocated; - t_allocator_page a[10]; - struct s_page_list *next; -} t_page_list; - -/* -void *me_malloc(t_usize size) -{ - t_mblock *block; - - size = usize_round_up_to(size, 16); - block = get_block_for_size(size); - if (block == NULL) - return (me_abort("Found no page for me_malloc"), NULL); - vg_mem_defined(block, sizeof(*block)); - vg_mempool_alloc(POOL_ADDR, (void *)(((t_usize)block) + sizeof(*block)), -block->size); block->used = true; mem_set_zero((t_u8 *)block + sizeof(*block), -block->size); vg_mem_no_access(block, sizeof(*block)); return ((void -*)(((t_usize)block) + sizeof(*block))); -} - -void *me_calloc(t_usize elem_size, t_usize elem_count) -{ - if (elem_size != 0 && elem_count > SIZE_MAX / elem_size) - me_abort("calloc overflow !"); - return (me_malloc(elem_size * elem_count)); -} - -void *me_realloc(void *ptr, t_usize new_size) -{ - t_mblock *block; - void *ret; - t_usize old_size; - - if (ptr == NULL) - return (me_malloc(new_size)); - block = (void *)((t_usize)(ptr) - sizeof(*block)); - vg_mem_defined(block, sizeof(*block)); - VALGRIND_CHECK_MEM_IS_ADDRESSABLE(ptr, block->size); - block->used = true; - if (block->size <= new_size) - return (vg_mem_no_access(block, sizeof(*block)), ptr); - old_size = block->size; - vg_mem_no_access(block, sizeof(*block)); - if (false && merge_block(block, new_size)) - { - vg_mem_defined(block, sizeof(*block)); - vg_mempool_resize(POOL_ADDR, ptr, block->size); - VALGRIND_CHECK_MEM_IS_ADDRESSABLE(ptr, block->size); - mem_set_zero((t_u8 *)ptr + old_size, block->size - old_size); - vg_mem_no_access(block, sizeof(*block)); - return (ptr); - } - else - { - ret = me_malloc(new_size); - mem_copy(ret, ptr, block->size); - mem_free(ptr); - return (ret); - } -} - -void *me_realloc_array(void *ptr, t_usize elem_size, t_usize elem_count) -{ - if (elem_size != 0 && elem_count > SIZE_MAX / elem_size) - me_abort("realloc_array overflow !"); - return (me_realloc(ptr, elem_size * elem_count)); -} - -void mem_free(void *ptr) -{ - t_mblock *cur; - - if (ptr == NULL) - return; - cur = (void *)(((t_usize)ptr) - sizeof(t_mblock)); - vg_mempool_free(POOL_ADDR, ptr); - vg_mem_defined(cur, sizeof(*cur)); - cur->used = false; - merge_block(cur, ~(t_usize)0); - vg_mem_no_access(cur, sizeof(*cur)); -} -*/ -// void uninit_allocator(void) -// { -// t_ptr_table *table; -// t_ptr_table *table_next; -// t_usize i; -// t_usize unfree_count; -// -// unfree_count = 0; -// table = get_table(); -// -// while (table) -// { -// i = 0; -// while (i < PTR_LENS) -// { -// if (table->table[i].ptr != NULL) -// { -// __libc_free(table->table[i].ptr); -// unfree_count++; -// } -// i++; -// } -// table_next = table->next; -// __libc_free(table); -// table = table_next; -// } -// if (unfree_count != 0) -// { -// me_putstr_fd("A total of ", 2); -// me_putnbr_fd(unfree_count, 2); -// me_putendl_fd(" blocks weren't freed !", 2); -// } -// } -// void *me_malloc(t_usize size) -// { -// t_mblock *block; -// void *ret; -// -// size = usize_round_up_to(size, 16); -// printf("Allocating %zu.\n", size); -// block = get_block_for_size(size); -// if (block -// == NULL) -// return (me_abort("Found no page for me_malloc"), NULL); -// block->used = true; -// ret = ((t_u8 *)block->page->data) + block->offset; -// mem_set_zero(ret, block->size); -// return (ret); -// } -// -// void *me_calloc(t_usize elem_size, t_usize elem_count) -// { -// if (elem_size != 0 && elem_count > SIZE_MAX / elem_size) -// return (NULL); -// return (me_malloc(elem_size * elem_count)); -// } -// -// void *me_realloc(void *ptr, t_usize new_size) -// { -// t_mblock *block; -// void *ret; -// -// if (ptr == NULL) -// return (me_malloc(new_size)); -// block = get_block_from_ptr(ptr); -// if (block == NULL || block->size <= new_size) -// return (ptr); -// if (!merge_next_block(block, new_size)) -// return (ptr); -// else -// { -// ret = me_malloc(new_size); -// mem_copy(ret, ptr, block->size); -// mem_free(ptr); -// return (ret); -// } -// } -// -// void mem_free(void *ptr) -// { -// t_mblock *cur; -// -// if (ptr == NULL) -// return; -// cur = get_block_from_ptr(ptr); -// if (cur == NULL) -// return (me_abort("Invalid free (not allocated with me_*alloc)!")); -// cur->used = false; -// merge_next_block(cur, ~(t_usize)0); -// } diff --git a/allocator/src/get_arena.c b/allocator/src/get_arena.c deleted file mode 100644 index 6465024c..00000000 --- a/allocator/src/get_arena.c +++ /dev/null @@ -1,362 +0,0 @@ -/* ************************************************************************** */ -/* */ -/* ::: :::::::: */ -/* get_arena.c :+: :+: :+: */ -/* +:+ +:+ +:+ */ -/* By: maiboyer +#+ +:+ +#+ */ -/* +#+#+#+#+#+ +#+ */ -/* Created: 2024/05/07 09:47:50 by maiboyer #+# #+# */ -/* Updated: 2024/05/14 16:52:37 by maiboyer ### ########.fr */ -/* */ -/* ************************************************************************** */ - -#include "aq/alloc.h" -#include "aq/alloc_internal.h" -#include "aq/internal_vg_funcs.h" -#include "me/fs/putendl_fd.h" -#include "me/fs/putnbr_fd.h" -#include "me/fs/putstr_fd.h" -#include "me/mem/mem.h" -#include "me/mem/mem.h" -#include "me/mem/mem.h" -#include "me/num/usize.h" -#include -#include -/* - -void *__libc_malloc(size_t size); -void __libc_free(void *ptr); - -t_mpage *alloc_page(t_usize size) -{ - t_mpage *val; - - size = usize_round_up_to(size + sizeof(t_mpage), PAGE_SIZE_DEFAULT); - val = __libc_malloc(size); - if (val == NULL) - return (NULL); - mem_set_zero(val, size); - val->next = NULL; - val->page_size = size - sizeof(*val); - val->first = (t_mblock *)(((t_usize)val) + sizeof(t_mpage)); - val->first->page = val; - val->first->next = NULL; - val->first->used = false; - val->first->size = size - sizeof(t_mpage) - sizeof(t_mblock) * 2; - mem_copy(val->first->padding, BLOCK_PADDING, 7); - vg_mem_no_access(val, size); - return (val); -} - -t_mpage *get_head_arena(void) -{ - static t_mpage *val = NULL; - - if (val == NULL && - PAGE_SIZE_DEFAULT > sizeof(t_mpage) + sizeof(t_mblock) * 2 + 16) - { - vg_mempool_create(POOL_ADDR); - val = alloc_page(PAGE_SIZE_DEFAULT - sizeof(t_mpage)); - } - if (val == NULL) - (me_putstr_fd("Failed to alloc first page", 2), exit(1)); - return (val); -} - -t_mblock *split_block(t_mblock *self, t_usize min_size) -{ - t_usize remaining; - t_mblock *old_next; - - vg_mem_defined(self, sizeof(*self)); - min_size = usize_round_up_to(min_size, 16); - if (self->size > (min_size + sizeof(t_mblock) + 16)) - { - remaining = self->size - min_size - sizeof(t_mblock); - printf("splitting %zu into %zu and %zu\n", self->size, min_size, - remaining); - self->size = min_size; - old_next = self->next; - self->next = (t_mblock *)(((t_usize)self) + sizeof(*self) + self->size); - vg_mem_defined(self->next, sizeof(*self->next)); - self->next->page = self->page; - self->next->next = old_next; - self->next->used = false; - self->next->size = remaining; - mem_copy(self->next->padding, BLOCK_PADDING, 7); - vg_mem_no_access(self->next, sizeof(*self->next)); - } - vg_mem_no_access(self, sizeof(*self)); - return (self); -} - -t_mblock *get_block_for_size(t_usize size) -{ - t_mblock *last; - t_mblock *cur; - t_mpage *head; - - last = NULL; - head = get_head_arena(); - vg_mem_defined(head, sizeof(*head)); - cur = head->first; - vg_mem_no_access(head, sizeof(*head)); - while (cur) - { - vg_mem_defined(cur, sizeof(*cur)); - if (!cur->used && cur->size >= size) - return (split_block(cur, size)); - last = cur; - cur = cur->next; - vg_mem_no_access(last, sizeof(*last)); - } - if (last == NULL) - return (NULL); - vg_mem_defined(last, sizeof(*last)); - vg_mem_defined(last->page, sizeof(*last->page)); - last->page->next = alloc_page(size + sizeof(t_mblock)); - if (last->page->next == NULL) - me_abort("Failed to alloc page!"); - vg_mem_defined(last->page->next, sizeof(*last->page->next)); - last->next = last->page->next->first; - cur = last->page->next->first; - vg_mem_no_access(last->page->next, sizeof(*last->page->next)); - vg_mem_no_access(last->page, sizeof(*last->page)); - vg_mem_no_access(last, sizeof(*last)); - return (split_block(cur, size)); -} - -void print_pages_info(void) -{ - t_mpage *page; - t_mpage *old; - t_i32 page_nb; - - page = get_head_arena(); - page_nb = 0; - while (page != NULL) - { - vg_mem_defined(page, sizeof(*page)); - me_putstr_fd("Page ", 2); - me_putnbr_fd(page_nb++, 2); - me_putstr_fd(" with size ", 2); - me_putnbr_fd((t_i32)page->page_size, 2); - me_putstr_fd("\n", 2); - old = page; - page = page->next; - vg_mem_no_access(old, sizeof(*old)); - } -} - -bool merge_block(t_mblock *self, t_usize min_size) -{ - t_mblock *old_next; - - vg_mem_defined(self, sizeof(*self)); - vg_mem_defined(self->next, sizeof(*self->next)); - if (!(self->next && !self->next->used && self->next->page == self->page && - self->size + self->next->size + sizeof(t_mblock) >= min_size)) - return (vg_mem_no_access(self->next, sizeof(*self->next)), - vg_mem_no_access(self, sizeof(*self)), false); - old_next = self->next; - self->size += sizeof(*self) + self->next->size; - self->next = self->next->next; - vg_mem_no_access(self, sizeof(*self)); - vg_mem_no_access(old_next, sizeof(*old_next)); - return (true); -} - -void uninit_allocator(void) -{ - t_mpage *page; - void *tmp; - t_mblock *block; - t_usize count_block; - - page = get_head_arena(); - count_block = 0; - vg_mem_defined(page, sizeof(*page)); - block = page->first; - while (block) - { - vg_mem_defined(block, sizeof(*block)); - if (block->used) - count_block += 1; - block = block->next; - } - while (page) - { - vg_mem_defined(page, sizeof(*page)); - tmp = page->next; - __libc_free(page); - page = tmp; - } - if (count_block != 0) - (me_putnbr_fd(count_block, 2), - me_putendl_fd(" Blocks weren't freed when exiting !", 2)); -}*/ - -// -// void free_ifn(void *ptr) -// { -// if (ptr != NULL) -// __libc_free(ptr); -// } -// -// t_mpage *alloc_page(t_usize size) -// { -// t_mpage *page; -// void *data; -// t_mblock *block; -// -// size = usize_round_up_to(size, PAGE_SIZE_DEFAULT); -// page = __libc_malloc(sizeof(t_mpage)); -// block = __libc_malloc(sizeof(t_mblock)); -// data = __libc_malloc(size); -// if (page == NULL || data == NULL || block == NULL || -// PAGE_SIZE_DEFAULT <= (t_usize)0) -// return (free_ifn(page), free_ifn(data), free_ifn(block), NULL); -// page->data = data; -// page->next = NULL; -// page->page_size = size; -// page->first = block; -// block->offset = 0; -// block->page = page; -// block->next = NULL; -// block->used = false; -// block->size = size; -// mem_copy(block->padding, BLOCK_PADDING, 7); -// return (page); -// } -// -// t_mpage *get_head_arena(void) -// { -// static t_mpage *val = NULL; -// -// if (val == NULL) -// { -// val = alloc_page(PAGE_SIZE_DEFAULT); -// if (val == NULL) -// (me_putstr_fd("Failed to alloc first page", 2), exit(1)); -// } -// return (val); -// } -// -// t_mblock *split_block(t_mblock *self, t_usize min_size) -// { -// t_usize remaining; -// t_mblock *new_next; -// -// min_size = usize_round_up_to(min_size, 16); -// if (self->size > min_size) -// { -// remaining = self->size - min_size - 1; -// new_next = __libc_malloc(sizeof(t_mblock)); -// if (new_next == NULL) -// return (me_abort("Failed to alloc block"), NULL); -// printf("splitting %zu into %zu and %zu\n", self->size, min_size, -// remaining); -// self->size = min_size; -// new_next->page = self->page; -// new_next->next = self->next; -// new_next->offset = self->offset + self->size + 1; -// new_next->used = false; -// new_next->size = remaining; -// mem_copy(new_next->padding, BLOCK_PADDING, 7); -// self->next = new_next; -// } -// return (self); -// } -// -// t_mblock *get_block_for_size(t_usize size) -// { -// t_mblock *last; -// t_mblock *cur; -// -// last = NULL; -// cur = get_head_arena()->first; -// while (cur) -// { -// if (cur->page == NULL) -// me_abort("block doesn't have a page ?????"); -// if (!cur->used && cur->size >= size) -// return (split_block(cur, size)); -// last = cur; -// cur = cur->next; -// } -// if (last == NULL) -// return (NULL); -// last->page->next = alloc_page(size); -// if (last->page->next == NULL) -// me_abort("Failed to alloc page!"); -// last->next = last->page->next->first; -// return (split_block(last->page->next->first, size)); -// } -// -// t_mblock *get_block_from_ptr(void *ptr) -// { -// t_mpage *page; -// t_mblock *block; -// -// page = get_page_from_ptr(ptr); -// if (page == NULL) -// return (NULL); -// block = page->first; -// while (block && block->page == page) -// { -// if (((t_u8 *)page->data) + block->offset == (t_u8 *)ptr) -// return (block); -// block = block->next; -// } -// return (NULL); -// } -// -// t_mpage *get_page_from_ptr(void *ptr) -// { -// t_mpage *page; -// -// page = get_head_arena(); -// while (page) -// { -// if ((t_u8 *)page->data <= (t_u8 *)ptr && -// (t_u8 *)ptr < (((t_u8 *)page->data) + page->page_size)) -// return (page); -// page = page->next; -// } -// return (NULL); -// } -// -// void print_pages_info(void) -// { -// t_mpage *page; -// t_i32 page_nb; -// -// page = get_head_arena(); -// page_nb = 0; -// while (page != NULL) -// { -// me_putstr_fd("Page ", 2); -// me_putnbr_fd(page_nb++, 2); -// me_putstr_fd(" with size ", 2); -// me_putnbr_fd((t_i32)page->page_size, 2); -// me_putstr_fd("\n", 2); -// page = page->next; -// } -// } -// -// bool merge_next_block(t_mblock *cur, t_usize min_size) -// { -// t_mblock *next; -// -// if (cur->next != NULL && cur->page == cur->next->page && !cur->next->used && -// cur->size + cur->next->size >= min_size) -// { -// cur->size += cur->next->size; -// next = cur->next; -// cur->next = cur->next->next; -// printf("merging two blocks %p and %p\n", cur, cur->next); -// __libc_free(next); -// return (NO_ERROR); -// } -// return (ERROR); -// } diff --git a/allocator/src/lc_alloc/functions1.c b/allocator/src/lc_alloc/functions1.c index b23aaf05..20f0f2f7 100644 --- a/allocator/src/lc_alloc/functions1.c +++ b/allocator/src/lc_alloc/functions1.c @@ -14,39 +14,39 @@ #include "aq/libc_wrapper.h" #include "me/types.h" -void *__libc_malloc(t_usize size); -void *__libc_calloc(t_usize size, t_usize elem); -void *__libc_realloc(void *ptr, t_usize size); -void *__libc_reallocarray(void *ptr, t_usize size, t_usize elem); -void __libc_free(void *ptr); +void *__libc_malloc(t_usize size); +void *__libc_calloc(t_usize size, t_usize elem); +void *__libc_realloc(void *ptr, t_usize size); +void *__libc_reallocarray(void *ptr, t_usize size, t_usize elem); +void __libc_free(void *ptr); -void *lc_malloc(t_allocator *self, t_usize size) +void *lc_malloc(t_allocator *self, t_usize size) { (void)(self); return (__libc_malloc(size)); } -void *lc_calloc(t_allocator *self, t_usize size, t_usize elem) +void *lc_calloc(t_allocator *self, t_usize size, t_usize elem) { (void)(self); return (__libc_calloc(size, elem)); } -void *lc_realloc(t_allocator *self, void *ptr, t_usize size) +void *lc_realloc(t_allocator *self, void *ptr, t_usize size) { (void)(self); return (__libc_realloc(ptr, size)); } -void *lc_realloc_array(t_allocator *self, void *ptr, t_usize size, t_usize elem) +void *lc_realloc_array(t_allocator *self, void *ptr, t_usize size, + t_usize elem) { (void)(self); return (__libc_reallocarray(ptr, size, elem)); } -void lc_free(t_allocator *self, void *ptr) +void lc_free(t_allocator *self, void *ptr) { (void)(self); return (__libc_free(ptr)); } - diff --git a/allocator/src/lc_alloc/functions2.c b/allocator/src/lc_alloc/functions2.c index db95a561..ad4770f1 100644 --- a/allocator/src/lc_alloc/functions2.c +++ b/allocator/src/lc_alloc/functions2.c @@ -13,12 +13,12 @@ #include "aq/allocator.h" #include "aq/libc_wrapper.h" -void lc_uninit(t_allocator *self) +void lc_uninit(t_allocator *self) { (void)(self); } -t_allocator lc_init(void) +t_allocator lc_init(void) { return ((t_allocator){ .alloc = lc_malloc, diff --git a/allocator/src/me_alloc/find_block.c b/allocator/src/me_alloc/find_block.c new file mode 100644 index 00000000..acaa346e --- /dev/null +++ b/allocator/src/me_alloc/find_block.c @@ -0,0 +1,56 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* find_block.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/10 17:40:12 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 17:41:07 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "aq/internal_vg_funcs.h" +#include "aq/melloc_interal.h" +#include "me/types.h" + +static bool _find_chunk_of_size_inner(t_usize size, t_page_list *list, \ + t_chunk **chunk) +{ + vg_mem_defined(*chunk, sizeof(**chunk)); + if (!(*chunk)->used && (*chunk)->size >= size) + { + vg_mem_no_access(*chunk, sizeof(**chunk)); + vg_mem_no_access(list, sizeof(*list)); + return (*chunk = split_block(*chunk, size), true); + } + vg_mem_no_access(*chunk, sizeof(**chunk)); + *chunk = get_next_block(*chunk, false); + return (false); +} + +t_chunk *find_chunk_of_size(struct s_allocator_melloc *alloc, t_usize size) +{ + t_page_list *list; + t_page_list *list_next; + t_usize idx; + t_chunk *chunk; + + list = alloc->list; + while (list != NULL) + { + vg_mem_defined(list, sizeof(*list)); + idx = 0; + while (idx < list->len) + { + chunk = get_first_block(&list->pages[idx++]); + while (chunk) + if (_find_chunk_of_size_inner(size, list, &chunk)) + return (chunk); + } + list_next = list->next; + vg_mem_no_access(list, sizeof(*list)); + list = list_next; + } + return (NULL); +} diff --git a/allocator/src/me_alloc/functions1.c b/allocator/src/me_alloc/functions1.c index bd4ad03d..a1fe62db 100644 --- a/allocator/src/me_alloc/functions1.c +++ b/allocator/src/me_alloc/functions1.c @@ -6,321 +6,41 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/14 18:02:12 by maiboyer #+# #+# */ -/* Updated: 2024/06/28 19:44:43 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:21:55 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#include "me/mem/mem.h" -#include "me/types.h" - #include "aq/allocator.h" #include "aq/internal_vg_funcs.h" #include "aq/melloc_interal.h" - +#include "me/mem/mem.h" +#include "me/types.h" #include #include -#include -#include -#include -void *__libc_malloc(t_usize size); -void *__libc_calloc(t_usize size, t_usize elem); -void *__libc_realloc(void *ptr, t_usize size); -void *__libc_realloc_array(void *ptr, t_usize size, t_usize elem); -void __libc_free(void *ptr); +void *__libc_malloc(t_usize size); +void __libc_free(void *ptr); -t_chunk *get_first_block(t_page *page) -{ - t_chunk *chunk; - if (page == NULL) - return (NULL); - vg_mem_defined(page, sizeof(*page)); - chunk = page->data; - vg_mem_no_access(page, sizeof(*page)); - return (chunk); -} - -t_chunk *get_next_block(t_chunk *chunk, bool find_zero) -{ - t_chunk *next; - - if (chunk == NULL) - return (NULL); - vg_mem_defined(chunk, sizeof(*chunk)); - next = (void *)(chunk) + sizeof(*chunk) + chunk->size; - vg_mem_no_access(chunk, sizeof(*chunk)); - vg_mem_defined(next, sizeof(*next)); - if (!find_zero && next->size == 0) - { - vg_mem_no_access(next, sizeof(*next)); - return (NULL); - } - vg_mem_no_access(next, sizeof(*next)); - return (next); -} - -t_usize round_to_pow2(t_usize val, t_usize pow) -{ - pow = (1 << pow) - 1; - - return ((val + pow) & (~pow)); -} - -t_error alloc_page_list(t_page_list **out) -{ - t_page_list *val; - - if (out == NULL) - return (ERROR); - val = __libc_calloc(sizeof(*val), 1); - if (val == NULL) - return (ERROR); - *out = val; - vg_mem_no_access(val, sizeof(*val)); - vg_mempool_create_ext(val, MEMPOOL_FLAG_MALLOCLIKE); - return (NO_ERROR); -} - -void merge_blocks(t_page *page) -{ - t_chunk *cur; - t_chunk *next; - bool did_merge; - - did_merge = true; - while (did_merge) - { - cur = get_first_block(page); - next = get_next_block(cur, false); - did_merge = false; - while (cur != NULL && next != NULL) - { - (vg_mem_defined(cur, sizeof(*cur)), vg_mem_defined(next, sizeof(*next))); - if (!cur->used && !next->used) - { - did_merge = true; - cur->size += sizeof(*cur); - cur->size += next->size; - (vg_mem_no_access(cur, sizeof(*cur)), vg_mem_no_access(next, sizeof(*next))); - next = get_next_block(cur, false); - } - else - { - (vg_mem_no_access(cur, sizeof(*cur)), vg_mem_no_access(next, sizeof(*next))); - cur = next; - next = get_next_block(cur, false); - } - } - } -} - -t_chunk *split_block(t_chunk *chunk, t_usize size) -{ - t_usize remaining; - t_chunk *next; - t_chunk *ac_next; - - if (chunk == NULL) - return (NULL); - vg_mem_defined(chunk, sizeof(*chunk)); - if (chunk->size > size + sizeof(*chunk) + (2 << PAGE_ALIGN)) - { - remaining = chunk->size - size - sizeof(*chunk); - next = get_next_block(chunk, true); - vg_mem_defined(chunk, sizeof(*chunk)); - // eprintf("before size = %zu\n", (t_usize)chunk->size); - chunk->size = size; - // eprintf("after size = %zu\n", (t_usize)chunk->size); - ac_next = get_next_block(chunk, true); - // eprintf("chunk = %p\n", chunk); - // eprintf("next = %p\n", next); - // eprintf("ac_next = %p\n", ac_next); - // eprintf("get_next_block(ac_next, true) = %p\n", - // get_next_block(ac_next, true)); - vg_mem_defined(ac_next, sizeof(*ac_next)); - ac_next->used = false; - ac_next->size = remaining; - assert(next == get_next_block(ac_next, true)); - vg_mem_no_access(ac_next, sizeof(*ac_next)); - } - vg_mem_no_access(chunk, sizeof(*chunk)); - return (chunk); -} - -t_chunk *find_chunk_of_size(struct s_allocator_melloc *alloc, t_usize size) -{ - t_page_list *list; - t_page_list *list_next; - t_usize idx; - t_chunk *chunk; - - list = alloc->list; - while (list != NULL) - { - vg_mem_defined(list, sizeof(*list)); - idx = 0; - while (idx < list->len) - { - // printf("[%zu]list\n", idx); - chunk = get_first_block(&list->pages[idx++]); - while (chunk) - { - vg_mem_defined(chunk, sizeof(*chunk)); - if (!chunk->used && chunk->size >= size) - { - vg_mem_no_access(chunk, sizeof(*chunk)); - vg_mem_no_access(list, sizeof(*list)); - return (split_block(chunk, size)); - } - vg_mem_no_access(chunk, sizeof(*chunk)); - chunk = get_next_block(chunk, false); - } - } - list_next = list->next; - vg_mem_no_access(list, sizeof(*list)); - list = list_next; - } - return (NULL); -} - -t_error alloc_new_page(struct s_allocator_melloc *alloc, t_usize page_size) -{ - t_page_list *list; - t_page_list *list_bis; - t_chunk *chunk; - - page_size = round_to_pow2(page_size, PAGE_POW_2); - if (alloc->list == NULL && alloc_page_list(&alloc->list)) - return (ERROR); - list = alloc->list; - while (list) - { - vg_mem_defined(list, sizeof(*list)); - if (list->len != PAGE_LIST_MAX) - break; - if (list->next == NULL && alloc_page_list(&list->next)) - return (vg_mem_no_access(list, sizeof(*list)), ERROR); - list_bis = list; - list = list->next; - vg_mem_no_access(list_bis, sizeof(*list_bis)); - } - if (list == NULL) - return (ERROR); - vg_mem_defined(list, sizeof(*list)); - list->pages[list->len].data = __libc_calloc(page_size, 1); - if (list->pages[list->len].data == NULL) - return (ERROR); - list->pages[list->len].size = page_size; - - // eprintf("thingy!\n"); - // eprintf("(%p)pool_exist = %s\n", list, - // VALGRIND_MEMPOOL_EXISTS(list) ? "true" : "false"); - vg_mempool_alloc(list, list->pages[list->len].data, page_size); - chunk = get_first_block(&list->pages[list->len]); - chunk->used = false; - chunk->size = page_size - sizeof(*chunk) * 2; - vg_mem_no_access(chunk, sizeof(*chunk)); - list->len++; - vg_mem_no_access(list, sizeof(*list)); - return (NO_ERROR); -} - -void *m_alloc_error(struct s_allocator_melloc *self, t_str msg) -{ - self->uninit((void *)self); - me_abort(msg); - return (NULL); -} - -void *m_malloc(struct s_allocator_melloc *self, t_usize size) +void *m_malloc(struct s_allocator_melloc *self, t_usize size) { return (m_realloc(self, NULL, size)); } -void *m_alloc_array(struct s_allocator_melloc *self, t_usize size, t_usize count) +void *m_alloc_array(struct s_allocator_melloc *self, t_usize size, + t_usize count) { if (size != 0 && count > SIZE_MAX / size) return (m_alloc_error(self, "Alloc array overflow")); return (m_realloc(self, NULL, size * count)); } -#include "stdlib.h" - -void *m_realloc(struct s_allocator_melloc *self, void *ptr, t_usize size) +void m_free(struct s_allocator_melloc *self, void *ptr) { - t_chunk *chunk; - t_chunk *next; - t_usize old_size; - - if (size > INT32_MAX - sizeof(t_chunk) * 10) - return (errno = ENOMEM, NULL); - size = round_to_pow2(size, PAGE_ALIGN); - if (ptr != NULL && size == 0) - return (m_free(self, ptr), NULL); - if (ptr == NULL) - { - chunk = find_chunk_of_size(self, size); - if (chunk == NULL) - { - if (alloc_new_page(self, size + sizeof(t_chunk) * 2)) - return (m_alloc_error(self, "Unable to alloc page")); - chunk = find_chunk_of_size(self, size); - if (chunk == NULL) - return (m_alloc_error(self, "Unable to find block")); - } - vg_mem_defined((void *)chunk, sizeof(*chunk)); - chunk->used = true; - vg_mem_defined((void *)chunk + sizeof(*chunk), chunk->size); - mem_set_zero((void *)chunk + sizeof(*chunk), chunk->size); - vg_block_malloc((void *)chunk + sizeof(*chunk), chunk->size); - vg_mem_no_access((void *)chunk, sizeof(*chunk)); - return ((void *)chunk + sizeof(*chunk)); - } - else - { - chunk = ptr - sizeof(*chunk); - vg_mem_defined(chunk, sizeof(*chunk)); - if (chunk->size >= size) - return (vg_mem_no_access(chunk, sizeof(*chunk)), ptr); - next = get_next_block(chunk, false); - vg_mem_defined(next, sizeof(*next)); - vg_mem_defined(chunk, sizeof(*chunk)); - if (next != NULL && !next->used && chunk->size + next->size + sizeof(*next) >= size) - { - old_size = chunk->size; - chunk->size += next->size + sizeof(*next); - vg_mem_undefined(next, next->size + sizeof(*next)); - vg_block_resize((void *)chunk + sizeof(*chunk), old_size, chunk->size); - vg_mem_no_access(chunk, sizeof(*chunk)); - return (ptr); - } - else - { - vg_mem_no_access(next, sizeof(*next)); - next = m_realloc(self, NULL, size); - vg_mem_defined(chunk, sizeof(*chunk)); - mem_move(next, ptr, chunk->size); - vg_mem_no_access(chunk, sizeof(*chunk)); - m_free(self, ptr); - return (next); - } - } -} - -void *m_realloc_array(struct s_allocator_melloc *self, void *ptr, t_usize size, t_usize count) -{ - if (size != 0 && count > SIZE_MAX / size) - return (m_alloc_error(self, "Realloc array overflow")); - return (m_realloc(self, ptr, size * count)); -} - -void m_free(struct s_allocator_melloc *self, void *ptr) -{ - t_chunk *chunk; + t_chunk *chunk; (void)(self); if (ptr == NULL) - return; + return ; vg_block_free(ptr); chunk = ptr - sizeof(*chunk); vg_mem_defined(chunk, sizeof(*chunk)); @@ -328,11 +48,11 @@ void m_free(struct s_allocator_melloc *self, void *ptr) vg_mem_no_access(chunk, sizeof(*chunk)); } -void m_uninit(struct s_allocator_melloc *self) +void m_uninit(struct s_allocator_melloc *self) { - t_page_list *list; - t_page_list *list_next; - t_usize idx; + t_page_list *list; + t_page_list *list_next; + t_usize idx; list = self->list; while (list) @@ -351,16 +71,15 @@ void m_uninit(struct s_allocator_melloc *self) idx++; } list_next = list->next; - __libc_free(list); - vg_mempool_destroy(list); - vg_mem_no_access(list, sizeof(*list)); + (__libc_free(list), vg_mempool_destroy(list), \ + vg_mem_no_access(list, sizeof(*list))); list = list_next; } } -t_allocator m_init(void) +t_allocator m_init(void) { - t_allocator out; + t_allocator out; out.free = (t_allocator_free)m_free; out.alloc = (t_allocator_alloc)m_malloc; diff --git a/allocator/src/me_alloc/internals.c b/allocator/src/me_alloc/internals.c new file mode 100644 index 00000000..024ef2f1 --- /dev/null +++ b/allocator/src/me_alloc/internals.c @@ -0,0 +1,69 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* internals.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/10 16:49:31 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 20:54:31 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "aq/internal_vg_funcs.h" +#include "aq/melloc_interal.h" +#include "me/types.h" + +t_chunk *get_first_block(t_page *page) +{ + t_chunk *chunk; + + if (page == NULL) + return (NULL); + vg_mem_defined(page, sizeof(*page)); + chunk = page->data; + vg_mem_no_access(page, sizeof(*page)); + return (chunk); +} + +t_chunk *get_next_block(t_chunk *chunk, bool find_zero) +{ + t_chunk *next; + + if (chunk == NULL) + return (NULL); + vg_mem_defined(chunk, sizeof(*chunk)); + next = (void *)(chunk) + sizeof(*chunk) + chunk->size; + vg_mem_no_access(chunk, sizeof(*chunk)); + vg_mem_defined(next, sizeof(*next)); + if (!find_zero && next->size == 0) + { + vg_mem_no_access(next, sizeof(*next)); + return (NULL); + } + vg_mem_no_access(next, sizeof(*next)); + return (next); +} + +t_chunk *split_block(t_chunk *chunk, t_usize size) +{ + t_usize remaining; + t_chunk *ac_next; + + if (chunk == NULL) + return (NULL); + vg_mem_defined(chunk, sizeof(*chunk)); + if (chunk->size > size + sizeof(*chunk) + (2 << PAGE_ALIGN)) + { + remaining = chunk->size - size - sizeof(*chunk); + vg_mem_defined(chunk, sizeof(*chunk)); + chunk->size = size; + ac_next = get_next_block(chunk, true); + vg_mem_defined(ac_next, sizeof(*ac_next)); + ac_next->used = false; + ac_next->size = remaining; + vg_mem_no_access(ac_next, sizeof(*ac_next)); + } + vg_mem_no_access(chunk, sizeof(*chunk)); + return (chunk); +} diff --git a/allocator/src/me_alloc/merge_blocks.c b/allocator/src/me_alloc/merge_blocks.c new file mode 100644 index 00000000..89248e5a --- /dev/null +++ b/allocator/src/me_alloc/merge_blocks.c @@ -0,0 +1,55 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* merge_blocks.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/10 17:39:14 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 17:41:30 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/types.h" +#include "aq/internal_vg_funcs.h" +#include "aq/melloc_interal.h" + +static void _merge_blocks(t_chunk **cur, t_chunk **next, \ + bool *did_merge) +{ + (vg_mem_defined(*cur, sizeof(**cur)), vg_mem_defined(next, + sizeof(**next))); + if (!(*cur)->used && !(*next)->used) + { + *did_merge = true; + (*cur)->size += sizeof(**cur); + (*cur)->size += (*next)->size; + (vg_mem_no_access(*cur, sizeof(**cur)), vg_mem_no_access(*next, \ + sizeof(**next))); + *next = get_next_block(*cur, false); + } + else + { + (vg_mem_no_access(*cur, sizeof(**cur)), vg_mem_no_access(*next, \ + sizeof(**next))); + *cur = *next; + *next = get_next_block(*cur, false); + } +} + +void merge_blocks(t_page *page) +{ + t_chunk *cur; + t_chunk *next; + bool did_merge; + + did_merge = true; + while (did_merge) + { + cur = get_first_block(page); + next = get_next_block(cur, false); + did_merge = false; + while (cur != NULL && next != NULL) + _merge_blocks(&cur, &next, &did_merge); + } +} diff --git a/allocator/src/me_alloc/pages.c b/allocator/src/me_alloc/pages.c new file mode 100644 index 00000000..a2138ca7 --- /dev/null +++ b/allocator/src/me_alloc/pages.c @@ -0,0 +1,82 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* pages.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/10 16:51:10 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 17:25:19 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "aq/allocator.h" +#include "aq/internal_vg_funcs.h" +#include "aq/melloc_interal.h" +#include "me/mem/mem.h" +#include "me/types.h" +#include + +void *__libc_malloc(t_usize size); +void __libc_free(void *ptr); + +t_error alloc_page_list(t_page_list **out) +{ + t_page_list *val; + + if (out == NULL) + return (ERROR); + val = __libc_malloc(sizeof(*val)); + if (val == NULL) + return (ERROR); + mem_set_zero(val, sizeof(*val)); + *out = val; + vg_mem_no_access(val, sizeof(*val)); + vg_mempool_create_ext(val, MEMPOOL_FLAG_MALLOCLIKE); + return (NO_ERROR); +} + +t_error _alloc_new_page_inner(t_usize page_size, t_page_list *list) +{ + t_chunk *chunk; + + if (list == NULL) + return (ERROR); + vg_mem_defined(list, sizeof(*list)); + list->pages[list->len].data = __libc_malloc(page_size); + mem_set_zero(list->pages[list->len].data, page_size); + if (list->pages[list->len].data == NULL) + return (ERROR); + list->pages[list->len].size = page_size; + vg_mempool_alloc(list, list->pages[list->len].data, page_size); + chunk = get_first_block(&list->pages[list->len]); + chunk->used = false; + chunk->size = page_size - sizeof(*chunk) * 2; + vg_mem_no_access(chunk, sizeof(*chunk)); + list->len++; + vg_mem_no_access(list, sizeof(*list)); + return (NO_ERROR); +} + +t_error alloc_new_page(struct s_allocator_melloc *alloc, t_usize page_size) +{ + t_page_list *list; + t_page_list *list_bis; + + page_size = round_to_pow2(page_size, PAGE_POW_2); + if (alloc->list == NULL && alloc_page_list(&alloc->list)) + return (ERROR); + list = alloc->list; + while (list) + { + vg_mem_defined(list, sizeof(*list)); + if (list->len != PAGE_LIST_MAX) + break ; + if (list->next == NULL && alloc_page_list(&list->next)) + return (vg_mem_no_access(list, sizeof(*list)), ERROR); + list_bis = list; + list = list->next; + vg_mem_no_access(list_bis, sizeof(*list_bis)); + } + return (_alloc_new_page_inner(page_size, list)); +} diff --git a/allocator/src/me_alloc/realloc.c b/allocator/src/me_alloc/realloc.c new file mode 100644 index 00000000..c3b957b0 --- /dev/null +++ b/allocator/src/me_alloc/realloc.c @@ -0,0 +1,102 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* realloc.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/10 16:48:19 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 17:25:37 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "aq/allocator.h" +#include "aq/internal_vg_funcs.h" +#include "aq/melloc_interal.h" +#include "me/mem/mem.h" +#include "me/types.h" +#include + +static void *_realloc_inner_copy(struct s_allocator_melloc *self, void *ptr, \ + t_usize size, t_chunk *next) +{ + t_chunk *chk; + + chk = ptr - sizeof(*chk); + vg_mem_no_access(next, sizeof(*next)); + next = m_realloc(self, NULL, size); + vg_mem_defined(chk, sizeof(*chk)); + mem_move(next, ptr, chk->size); + vg_mem_no_access(chk, sizeof(*chk)); + m_free(self, ptr); + return (next); +} + +static void *_realloc_inner(struct s_allocator_melloc *self, void *ptr, \ + t_usize size) +{ + t_usize old_size; + t_chunk *chk; + t_chunk *next; + + chk = ptr - sizeof(*chk); + vg_mem_defined(chk, sizeof(*chk)); + if (chk->size >= size) + return (vg_mem_no_access(chk, sizeof(*chk)), ptr); + next = get_next_block(chk, false); + (vg_mem_defined(next, sizeof(*next)), vg_mem_defined(chk, sizeof(*chk))); + if (next != NULL && !next->used && chk->size + next->size + + sizeof(*next) >= size) + { + old_size = chk->size; + chk->size += next->size + sizeof(*next); + return (vg_mem_undefined(next, next->size + sizeof(*next)), \ + vg_block_resize((void *)chk + sizeof(*chk), old_size, chk->size), \ + vg_mem_no_access(chk, sizeof(*chk)), ptr); + } + else + return (_realloc_inner_copy(self, ptr, size, next)); +} + +static void *_realloc_alloc(struct s_allocator_melloc *self, t_usize size) +{ + t_chunk *chunk; + + chunk = find_chunk_of_size(self, size); + if (chunk == NULL) + { + if (alloc_new_page(self, size + sizeof(t_chunk) * 2)) + return (m_alloc_error(self, "Unable to alloc page")); + chunk = find_chunk_of_size(self, size); + if (chunk == NULL) + return (m_alloc_error(self, "Unable to find block")); + } + vg_mem_defined((void *)chunk, sizeof(*chunk)); + chunk->used = true; + vg_mem_defined((void *)chunk + sizeof(*chunk), chunk->size); + mem_set_zero((void *)chunk + sizeof(*chunk), chunk->size); + vg_block_malloc((void *)chunk + sizeof(*chunk), chunk->size); + vg_mem_no_access((void *)chunk, sizeof(*chunk)); + return ((void *)chunk + sizeof(*chunk)); +} + +void *m_realloc(struct s_allocator_melloc *self, void *ptr, t_usize size) +{ + if (size > INT32_MAX - sizeof(t_chunk) * 10) + return (errno = ENOMEM, NULL); + size = round_to_pow2(size, PAGE_ALIGN); + if (ptr != NULL && size == 0) + return (m_free(self, ptr), NULL); + if (ptr == NULL) + return (_realloc_alloc(self, size)); + else + return (_realloc_inner(self, ptr, size)); +} + +void *m_realloc_array(struct s_allocator_melloc *self, void *ptr, + t_usize size, t_usize count) +{ + if (size != 0 && count > SIZE_MAX / size) + return (m_alloc_error(self, "Realloc array overflow")); + return (m_realloc(self, ptr, size * count)); +} diff --git a/allocator/src/vg/dummy_block.c b/allocator/src/vg/dummy_block.c index e8769f1e..1b711be7 100644 --- a/allocator/src/vg/dummy_block.c +++ b/allocator/src/vg/dummy_block.c @@ -14,20 +14,20 @@ #ifndef VGFUNCS -void vg_block_malloc(void *ptr, t_usize size) +void vg_block_malloc(void *ptr, t_usize size) { (void)(ptr); (void)(size); } -void vg_block_resize(void *ptr, t_usize oldsize, t_usize newsize) +void vg_block_resize(void *ptr, t_usize oldsize, t_usize newsize) { (void)(ptr); (void)(oldsize); (void)(newsize); } -void vg_block_free(void *ptr) +void vg_block_free(void *ptr) { (void)(ptr); } diff --git a/allocator/src/vg/dummy_mem_status.c b/allocator/src/vg/dummy_mem_status.c index 123604c5..c9fe9539 100644 --- a/allocator/src/vg/dummy_mem_status.c +++ b/allocator/src/vg/dummy_mem_status.c @@ -14,19 +14,19 @@ #ifndef VGFUNCS -void vg_mem_no_access(void *ptr, t_usize size) +void vg_mem_no_access(void *ptr, t_usize size) { (void)(ptr); (void)(size); } -void vg_mem_undefined(void *ptr, t_usize size) +void vg_mem_undefined(void *ptr, t_usize size) { (void)(ptr); (void)(size); } -void vg_mem_defined(void *ptr, t_usize size) +void vg_mem_defined(void *ptr, t_usize size) { (void)(ptr); (void)(size); diff --git a/allocator/src/vg/dummy_mempool.c b/allocator/src/vg/dummy_mempool.c index 68d5f617..d0170872 100644 --- a/allocator/src/vg/dummy_mempool.c +++ b/allocator/src/vg/dummy_mempool.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/12 22:33:30 by maiboyer #+# #+# */ -/* Updated: 2024/05/17 15:29:59 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:24:32 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,37 +14,31 @@ #ifndef VGFUNCS -void vg_mempool_create_ext(void *pool, t_usize flags) -{ - (void)(pool); - (void)(flags); -} - -void vg_mempool_resize(void *pool, void *ptr, t_usize size) +void vg_mempool_resize(void *pool, void *ptr, t_usize size) { (void)(pool); (void)(ptr); (void)(size); } -void vg_mempool_create(void *pool) +void vg_mempool_create(void *pool) { (void)(pool); } -void vg_mempool_destroy(void *pool) +void vg_mempool_destroy(void *pool) { (void)(pool); } -void vg_mempool_alloc(void *pool, void *addr, t_usize size) +void vg_mempool_alloc(void *pool, void *addr, t_usize size) { (void)(pool); (void)(addr); (void)(size); } -void vg_mempool_free(void *pool, void *addr) +void vg_mempool_free(void *pool, void *addr) { (void)(pool); (void)(addr); diff --git a/allocator/src/vg/dummy_mempool_bis.c b/allocator/src/vg/dummy_mempool_bis.c new file mode 100644 index 00000000..4be4e77d --- /dev/null +++ b/allocator/src/vg/dummy_mempool_bis.c @@ -0,0 +1,23 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* dummy_mempool_bis.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/12 22:33:30 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 17:24:39 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "aq/internal_vg_funcs.h" + +#ifndef VGFUNCS + +void vg_mempool_create_ext(void *pool, t_usize flags) +{ + (void)(pool); + (void)(flags); +} + +#endif diff --git a/allocator/src/vg/valgrind_block.c b/allocator/src/vg/valgrind_block.c index c4c19e13..6ddad468 100644 --- a/allocator/src/vg/valgrind_block.c +++ b/allocator/src/vg/valgrind_block.c @@ -15,17 +15,17 @@ #ifdef VGFUNCS -void vg_block_malloc(void *ptr, t_usize size) +void vg_block_malloc(void *ptr, t_usize size) { VALGRIND_MALLOCLIKE_BLOCK(ptr, size, redzone_size(), ZEROED_ALLOC); } -void vg_block_resize(void *ptr, t_usize oldsize, t_usize newsize) +void vg_block_resize(void *ptr, t_usize oldsize, t_usize newsize) { VALGRIND_RESIZEINPLACE_BLOCK(ptr, oldsize, newsize, redzone_size()); } -void vg_block_free(void *ptr) +void vg_block_free(void *ptr) { VALGRIND_FREELIKE_BLOCK(ptr, redzone_size()); } diff --git a/allocator/src/vg/valgrind_mem_status.c b/allocator/src/vg/valgrind_mem_status.c index bbe5ee0e..4e82482f 100644 --- a/allocator/src/vg/valgrind_mem_status.c +++ b/allocator/src/vg/valgrind_mem_status.c @@ -14,17 +14,17 @@ #ifdef VGFUNCS -void vg_mem_no_access(void *ptr, t_usize size) +void vg_mem_no_access(void *ptr, t_usize size) { VALGRIND_MAKE_MEM_NOACCESS(ptr, size); } -void vg_mem_undefined(void *ptr, t_usize size) +void vg_mem_undefined(void *ptr, t_usize size) { VALGRIND_MAKE_MEM_UNDEFINED(ptr, size); } -void vg_mem_defined(void *ptr, t_usize size) +void vg_mem_defined(void *ptr, t_usize size) { VALGRIND_MAKE_MEM_DEFINED(ptr, size); } diff --git a/allocator/src/vg/valgrind_mempool.c b/allocator/src/vg/valgrind_mempool.c index 80b46f8f..c24e00e8 100644 --- a/allocator/src/vg/valgrind_mempool.c +++ b/allocator/src/vg/valgrind_mempool.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/12 22:33:30 by maiboyer #+# #+# */ -/* Updated: 2024/05/17 15:30:09 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:24:19 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,41 +15,27 @@ #ifdef VGFUNCS -void vg_mempool_create_ext(void *pool, t_usize flags) -{ - t_usize actual_flags; - - actual_flags = 0; - if (flags & MEMPOOL_FLAG_MALLOCLIKE) - actual_flags |= VALGRIND_MEMPOOL_METAPOOL; - if (flags & MEMPOOL_FLAG_AUTOFREE) - actual_flags |= VALGRIND_MEMPOOL_AUTO_FREE; - - VALGRIND_CREATE_MEMPOOL_EXT(pool, 0, ZEROED_POOL, actual_flags); -} - -void vg_mempool_resize(void *pool, void *ptr, t_usize size) +void vg_mempool_resize(void *pool, void *ptr, t_usize size) { VALGRIND_MEMPOOL_CHANGE(pool, ptr, ptr, size); } -void vg_mempool_create(void *pool) +void vg_mempool_create(void *pool) { VALGRIND_CREATE_MEMPOOL(pool, 0, ZEROED_POOL); - } -void vg_mempool_destroy(void *pool) +void vg_mempool_destroy(void *pool) { VALGRIND_DESTROY_MEMPOOL(pool); } -void vg_mempool_alloc(void *pool, void *addr, t_usize size) +void vg_mempool_alloc(void *pool, void *addr, t_usize size) { VALGRIND_MEMPOOL_ALLOC(pool, addr, size); } -void vg_mempool_free(void *pool, void *addr) +void vg_mempool_free(void *pool, void *addr) { VALGRIND_MEMPOOL_FREE(pool, addr); } diff --git a/allocator/src/vg/valgrind_mempool_bis.c b/allocator/src/vg/valgrind_mempool_bis.c new file mode 100644 index 00000000..cca01ae8 --- /dev/null +++ b/allocator/src/vg/valgrind_mempool_bis.c @@ -0,0 +1,30 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* valgrind_mempool_bis.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/05/12 22:33:30 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 17:24:11 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "aq/internal_vg_funcs.h" +#include "valgrind/valgrind.h" + +#ifdef VGFUNCS + +void vg_mempool_create_ext(void *pool, t_usize flags) +{ + t_usize actual_flags; + + actual_flags = 0; + if (flags & MEMPOOL_FLAG_MALLOCLIKE) + actual_flags |= VALGRIND_MEMPOOL_METAPOOL; + if (flags & MEMPOOL_FLAG_AUTOFREE) + actual_flags |= VALGRIND_MEMPOOL_AUTO_FREE; + VALGRIND_CREATE_MEMPOOL_EXT(pool, 0, ZEROED_POOL, actual_flags); +} + +#endif diff --git a/flake.nix b/flake.nix index f03e1b66..36e8d65b 100644 --- a/flake.nix +++ b/flake.nix @@ -36,14 +36,12 @@ valgrind.dev valgrind gnumake - readline.out - readline.dev generic_c.packages.${system}.default c_formatter_42.packages.${system}.default llvmPackages.bintools norminette rust-bin.stable.latest.default - (tree-sitter.override {webUISupport = true;}) + #(tree-sitter.override {webUISupport = true;}) nodejs ]; VALGRIND_INC_OPT = "${pkgs.valgrind.dev}/include"; diff --git a/includes/app/signal_handler.h b/includes/app/signal_handler.h index c5455f06..533ed4fb 100644 --- a/includes/app/signal_handler.h +++ b/includes/app/signal_handler.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/02 13:20:25 by maiboyer #+# #+# */ -/* Updated: 2024/05/08 21:52:34 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 21:03:38 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,8 +17,6 @@ #include #include -#include - typedef t_i32 t_signal; t_error install_signal(void); diff --git a/includes/minishell.h b/includes/minishell.h index af08e076..5095437c 100644 --- a/includes/minishell.h +++ b/includes/minishell.h @@ -6,7 +6,7 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/28 14:41:15 by rparodi #+# #+# */ -/* Updated: 2024/05/09 16:28:26 by rparodi ### ########.fr */ +/* Updated: 2024/07/10 21:02:59 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -18,12 +18,6 @@ #include "me/types.h" #include -#include -#include -#include -#include -#include -#include #include #include #include diff --git a/line/include/line/_line_functions.h b/line/include/line/_line_functions.h new file mode 100644 index 00000000..15b240da --- /dev/null +++ b/line/include/line/_line_functions.h @@ -0,0 +1,46 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* _line_functions.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/10 15:23:25 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 15:38:46 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef _LINE_FUNCTIONS_H +# define _LINE_FUNCTIONS_H + +# include "line/_line_structs.h" +# include "me/fs/fs.h" +# include "me/types.h" +# include "me/vec/vec_str.h" + +t_error line_edit_insert(t_line_state *state, char c); +t_error line_edit_start(t_line_state *state, t_fd *stdin_fd, t_fd *stdout_fd, + t_const_str prompt); +t_str line_edit_feed(t_line_state *state); +void line_edit_backspace(t_line_state *state); +void line_edit_delete(t_line_state *state); +void line_edit_history_next(t_line_state *state, t_history_direction dir); +void line_edit_move_end(t_line_state *state); +void line_edit_move_home(t_line_state *state); +void line_edit_move_left(t_line_state *state); +void line_edit_move_right(t_line_state *state); +void line_edit_stop(t_line_state *state); + +t_str linenoise(t_const_str prompt); +t_str line_blocking_edit(t_fd *stdin_fd, t_fd *stdout_fd, t_const_str prompt); + +bool line_history_add(t_const_str line); +t_error line_history_load(t_str name); +t_error line_history_save(t_str name); + +void line_clear_screen(t_fd *output); +void line_refresh(t_line_state *state, t_line_flags flags); +void line_hide(t_line_state *state); +void line_show(t_line_state *state); + +#endif /* _LINE_FUNCTIONS_H */ diff --git a/line/include/line/_line_internal.h b/line/include/line/_line_internal.h new file mode 100644 index 00000000..902dfb19 --- /dev/null +++ b/line/include/line/_line_internal.h @@ -0,0 +1,39 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* _line_internal.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/10 15:37:40 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 15:48:56 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef _LINE_INTERNAL_H +# define _LINE_INTERNAL_H + +# include "line/_line_functions.h" +# include "me/fs/fs.h" +# include "me/string/string.h" +# include "me/types.h" +# include "me/vec/vec_str.h" + +t_const_str get_unfinished_str(void); +t_raw_mode_state *get_raw_mode_state(void); +t_vec_str *get_history(void); +void free_history(void); + +t_error gnl_wrapper(t_fd *fd, t_string *out); +void line_uninit_lib(void); +t_error line_get_cursor_position(t_fd *input, t_fd *output, + t_u32 *column_out); +t_u32 line_get_columns(t_fd *input, t_fd *output); +t_usize line_get_prompt_len(t_const_str s); +t_str line_no_tty_impl(void); +void line_print_key_codes(void); + +t_error line_enable_raw_mode(t_fd *fd); +void line_disable_raw_mode(t_fd *fd); + +#endif /* _LINE_INTERAL_H */ diff --git a/line/include/line/_line_structs.h b/line/include/line/_line_structs.h new file mode 100644 index 00000000..c7929445 --- /dev/null +++ b/line/include/line/_line_structs.h @@ -0,0 +1,90 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* _line_structs.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/10 15:24:34 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 15:53:54 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef _LINE_STRUCTS_H +# define _LINE_STRUCTS_H + +# include "me/fs/fs.h" +# include "me/string/string.h" +# include "me/types.h" +# include + +typedef struct s_line_state t_line_state; +typedef struct s_raw_mode_state t_raw_mode_state; +typedef enum e_line_flags t_line_flags; +typedef enum e_key_action t_key_action; +typedef enum e_history_direction t_history_direction; + +/// @param input_fd Terminal stdin file descriptor. +/// @param output_fd Terminal stdout file descriptor. +/// @param buf Edited line buffer. +/// @param prompt_len Prompt to display. +/// @param pos Prompt length. +/// @param prompt_len Current cursor position. +/// @param columns Number of columns in terminal. +/// @param history_index The history index we are currently editing. +struct s_line_state +{ + t_fd *input_fd; + t_fd *output_fd; + t_string buf; + t_const_str prompt; + t_usize prompt_len; + t_usize pos; + t_usize columns; + t_i32 history_index; +}; + +struct s_raw_mode_state +{ + bool enabled; + struct termios state; +}; + +enum e_key_action +{ + K_KEY_NULL = 0, + K_CTRL_A = 1, + K_CTRL_B = 2, + K_CTRL_C = 3, + K_CTRL_D = 4, + K_CTRL_E = 5, + K_CTRL_F = 6, + K_CTRL_H = 8, + K_TAB = 9, + K_NEWLINE = 10, + K_CTRL_K = 11, + K_CTRL_L = 12, + K_ENTER = 13, + K_CTRL_N = 14, + K_CTRL_P = 16, + K_CTRL_T = 20, + K_CTRL_U = 21, + K_CTRL_W = 23, + K_ESC = 27, + K_BACKSPACE = 127 +}; + +enum e_line_flags +{ + REFRESH_CLEAN = 1 << 0, + REFRESH_WRITE = 1 << 1, + REFRESH_ALL = REFRESH_CLEAN | REFRESH_WRITE, +}; + +enum e_history_direction +{ + HIST_PREV, + HIST_NEXT, +}; + +#endif /* _LINE_STRUCTS_H */ diff --git a/line/include/line/line.h b/line/include/line/line.h index 583adb3f..5fefc5a7 100644 --- a/line/include/line/line.h +++ b/line/include/line/line.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/05 18:07:02 by maiboyer #+# #+# */ -/* Updated: 2024/07/05 19:59:47 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 15:28:51 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,62 +14,9 @@ /// https://github.com/antirez/linenoise #ifndef LINE_H -#define LINE_H +# define LINE_H -#include "me/fs/fs.h" -#include "me/types.h" -#include - -extern t_str linenoiseEditMore; - -typedef struct s_line_state t_line_state; - -/* The linenoiseState structure represents the state during line editing. - * We pass this state to functions implementing specific editing - * functionalities. */ -struct s_line_state -{ - t_fd *input_fd; /* Terminal stdin file descriptor. */ - t_fd *output_fd; /* Terminal stdout file descriptor. */ - t_str buf; /* Edited line buffer. */ - t_usize buflen; /* Edited line buffer size. */ - t_const_str prompt; /* Prompt to display. */ - t_usize prompt_len; /* Prompt length. */ - t_usize pos; /* Current cursor position. */ - t_usize old_pos; /* Previous refresh cursor position. */ - t_usize len; /* Current edited line length. */ - t_usize columns; /* Number of columns in terminal. */ - t_usize old_rows; /* Rows used by last refrehsed line (multiline mode) */ - t_i32 history_index; /* The history index we are currently editing. */ -}; - -struct s_raw_mode_state -{ - bool enabled; - struct termios state; -}; - -typedef struct s_raw_mode_state t_raw_mode_state; - -/* Non blocking API. */ -int linenoiseEditStart(t_line_state *l, int stdin_fd, int stdout_fd, char *buf, t_usize buflen, const char *prompt); -char *linenoiseEditFeed(t_line_state *l); -void linenoiseEditStop(t_line_state *l); -void linenoiseHide(t_line_state *l); -void linenoiseShow(t_line_state *l); - -/* Blocking API. */ -char *linenoise(const char *prompt); -void linenoise_free(void *ptr); - -/* History API. */ -bool linenoise_history_add(t_const_str line); -t_error linenoiseHistorySave(t_str name); -t_error linenoise_history_load(t_str name); - -/* Other utilities. */ -void linenoiseClearScreen(void); -void linenoiseSetMultiLine(int ml); -void linenoisePrintKeyCodes(void); +# include "line/_line_functions.h" +# include "line/_line_structs.h" #endif /* LINE_H */ diff --git a/line/src.list b/line/src.list index a999a0c2..cadaec57 100644 --- a/line/src.list +++ b/line/src.list @@ -1 +1,2 @@ line +line_globals diff --git a/line/src/line.c b/line/src/line.c index 8ce16f22..2dfd6a08 100644 --- a/line/src/line.c +++ b/line/src/line.c @@ -1,15 +1,16 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/07 16:53:27 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 16:37:02 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - +#include "line/_line_internal.h" #include "line/line.h" #include "me/fs/fs.h" #include "me/gnl/gnl.h" @@ -19,202 +20,101 @@ #include "me/string/string.h" #include "me/types.h" #include "me/vec/vec_str.h" - -static t_str linenoiseNoTTY(void); -static void refreshLineWithFlags(t_line_state *l, int flags); - -t_vec_str *get_history(void) -{ - static t_vec_str history = {}; - static bool init = false; - - if (!init) - { - history = vec_str_new(256, (void (*)())mem_free); - init = true; - } - return (&history); -} - -enum e_key_action -{ - KEY_NULL = 0, /* NULL */ - CTRL_A = 1, /* Ctrl+a */ - CTRL_B = 2, /* Ctrl-b */ - CTRL_C = 3, /* Ctrl-c */ - CTRL_D = 4, /* Ctrl-d */ - CTRL_E = 5, /* Ctrl-e */ - CTRL_F = 6, /* Ctrl-f */ - CTRL_H = 8, /* Ctrl-h */ - TAB = 9, /* Tab */ - CTRL_K = 11, /* Ctrl+k */ - CTRL_L = 12, /* Ctrl+l */ - ENTER = 13, /* Enter */ - CTRL_N = 14, /* Ctrl-n */ - CTRL_P = 16, /* Ctrl-p */ - CTRL_T = 20, /* Ctrl-t */ - CTRL_U = 21, /* Ctrl+u */ - CTRL_W = 23, /* Ctrl+w */ - ESC = 27, /* Escape */ - BACKSPACE = 127 /* Backspace */ -}; - -#define REFRESH_CLEAN (1 << 0) // Clean the old prompt from the screen -#define REFRESH_WRITE (1 << 1) // Rewrite the prompt on the screen. -#define REFRESH_ALL (REFRESH_CLEAN | REFRESH_WRITE) // Do both. - -int linenoiseHistoryAdd(const char *line); -static void linenoise_uninit_lib(void); -static void refreshLine(t_line_state *l); - -/* Debugging macro. */ -#if 0 -FILE *lndebug_fp = NULL; -# define lndebug(...) \ - do \ - { \ - if (lndebug_fp == NULL) \ - { \ - lndebug_fp = fopen("/tmp/lndebug.txt", "a"); \ - fprintf(lndebug_fp, "[%d %d %d] p: %d, rows: %d, rpos: %d, max: %d, oldmax: %d\n", (int)l->len, (int)l->pos, (int)l->oldpos, \ - plen, rows, rpos, (int)l->oldrows, old_rows); \ - } \ - fprintf(lndebug_fp, ", " __VA_ARGS__); \ - fflush(lndebug_fp); \ - } while (0) -#else -# define lndebug(fmt, ...) -#endif +#include +#include +#include /* ======================= Low level terminal handling ====================== */ +// FIXME: remove the sscanf here ! /* Use the ESC [6n escape sequence to query the horizontal cursor position * and return it. On error -1 is returned, on success the position of the * cursor. */ -static int getCursorPosition(int ifd, int ofd) +t_error line_get_cursor_position(t_fd *input, t_fd *output, t_u32 *column_out) { - char buf[32]; - int cols, rows; - unsigned int i = 0; + char buf[32]; + t_u32 i; + t_i32 cols; + t_i32 rows; - /* Report cursor location */ - if (write(ofd, "\x1b[6n", 4) != 4) - return -1; - - /* Read the response: ESC [ rows ; cols R */ + i = 0; + if (write_fd(output, (t_u8 *)"\x1b[6n", 4, NULL)) + return (ERROR); while (i < sizeof(buf) - 1) { - if (read(ifd, buf + i, 1) != 1) - break; + if (read_fd(input, (t_u8 *)(buf + i), 1, NULL)) + break ; if (buf[i] == 'R') - break; + break ; i++; } buf[i] = '\0'; - - /* Parse it. */ - if (buf[0] != ESC || buf[1] != '[') - return -1; + if (buf[0] != K_ESC && buf[1] != '[') + return (ERROR); if (sscanf(buf + 2, "%d;%d", &rows, &cols) != 2) - return -1; - return cols; + return (ERROR); + return (*column_out = cols, NO_ERROR); } /* Try to get the number of columns in the current terminal, or assume 80 * if it fails. */ -static t_u32 getColumns(int ifd, int ofd) +t_u32 line_get_columns(t_fd *input, t_fd *output) { - struct winsize ws; - t_u32 start, cols; + struct winsize ws; + t_u32 cols; + t_u32 start; if (ioctl(1, TIOCGWINSZ, &ws) == -1 || ws.ws_col == 0) { - /* ioctl() failed. Try to query the terminal itself. */ - - /* Get the initial position so we can restore it later. */ - start = getCursorPosition(ifd, ofd); - if (start == -1) - return 80; - - /* Go to right margin and get position. */ - if (write(ofd, "\x1b[999C", 6) != 6) - return 80; - cols = getCursorPosition(ifd, ofd); - if (cols == -1) - return 80; - - /* Restore position. */ + if (line_get_cursor_position(input, output, &start)) + return (80); + me_printf_fd(output, "\x1b[999C"); + if (line_get_cursor_position(input, output, &cols)) + return (80); if (cols > start) - { - t_u8 seq[32]; - me_printf(seq, 32, "\x1b[%dD", cols - start); - (void)!(write(ofd, seq, strlen(seq)) == -1); - } - return cols; + me_printf_fd(output, "\x1b[%dD", cols - start); + return (cols); } else - { - return ws.ws_col; - } - -failed: + return (ws.ws_col); } /* Clear the screen. Used to handle ctrl+l */ -void linenoiseClearScreen(void) +void line_clear_screen(t_fd *output) { - (void)!write(STDOUT_FILENO, "\x1b[H\x1b[2J", 7); -} - -t_raw_mode_state *get_raw_mode_state(void) -{ - static t_raw_mode_state state = {}; - - return (&state); + me_printf_fd(output, "\x1b[H\x1b[2J"); } /* Raw mode: 1960 magic shit. */ -static t_error enableRawMode(int fd) +t_error line_enable_raw_mode(t_fd *fd) { - struct termios raw; - t_raw_mode_state *raw_state; + struct termios raw; + t_raw_mode_state *raw_state; raw_state = get_raw_mode_state(); - - if (!isatty(STDIN_FILENO)) + if (!isatty(fd->fd)) return (errno = ENOTTY, ERROR); - if (tcgetattr(fd, &raw_state->state) == -1) + if (tcgetattr(fd->fd, &raw_state->state) == -1) return (errno = ENOTTY, ERROR); - - raw = raw_state->state; /* modify the original mode */ - /* input modes: no break, no CR to NL, no parity check, no strip char, - * no start/stop output control. */ + raw = raw_state->state; raw.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON); - /* output modes - disable post processing */ raw.c_oflag &= ~(OPOST); - /* control modes - set 8 bit chars */ raw.c_cflag |= (CS8); - /* local modes - choing off, canonical off, no extended functions, - * no signal chars (^Z,^C) */ raw.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG); - /* control chars - set return condition: min number of bytes and timer. - * We want read to return every single byte, without timeout. */ raw.c_cc[VMIN] = 1; - raw.c_cc[VTIME] = 0; /* 1 byte, no timer */ - - /* put terminal in raw mode after flushing */ - if (tcsetattr(fd, TCSAFLUSH, &raw) < 0) + raw.c_cc[VTIME] = 0; + if (tcsetattr(fd->fd, TCSAFLUSH, &raw) < 0) return (errno = ENOTTY, ERROR); raw_state->enabled = true; return (NO_ERROR); } -static void disableRawMode(int fd) +void line_disable_raw_mode(t_fd *fd) { - t_raw_mode_state *state; + t_raw_mode_state *state; state = get_raw_mode_state(); - if (state->enabled && tcsetattr(fd, TCSAFLUSH, &state->state) != -1) + if (state->enabled && tcsetattr(fd->fd, TCSAFLUSH, &state->state) != -1) state->enabled = false; } @@ -224,32 +124,47 @@ static void disableRawMode(int fd) * allocated string where we can append to. This is useful in order to * write all the escape sequences in a buffer and flush them to the standard * output in a single call, to avoid flickering effects. */ -struct abuf -{ - char *b; - int len; -}; -static void abInit(struct abuf *ab) +void _modify_vars(t_usize *a, t_usize *b, bool operation) { - ab->b = NULL; - ab->len = 0; + if (!operation) + { + *a = 0; + *b = 0; + } + else + { + *a += 1; + *b += 1; + } } -static void abAppend(struct abuf *ab, const char *s, int len) +t_usize line_get_prompt_len(t_const_str s) { - char *new = mem_realloc(ab->b, ab->len + len); + t_usize i; + t_usize ret; + t_isize color; - if (new == NULL) - return; - memcpy(new + ab->len, s, len); - ab->b = new; - ab->len += len; -} - -static void abFree(struct abuf *ab) -{ - mem_free(ab->b); + if ((_modify_vars(&i, &ret, false), true) && s == NULL) + return (0); + while (s[i]) + { + if (s[i] == '\x1b' && s[i++] == '[') + { + color = ((void)(i++), 0); + while (color >= 0) + { + while (((void)color--, true) && s[i] >= '0' && s[i] <= '9') + color += ((void)(i++), 2); + if (s[i] == ';') + i++; + else if (s[i] == 'm' && ((void)i++, true)) + break ; + } + } + _modify_vars(&i, &ret, true); + } + return (ret); } /* Single line low level line refresh. @@ -259,227 +174,143 @@ static void abFree(struct abuf *ab) * * Flags is REFRESH_* macros. The function can just remove the old * prompt, just write it, or both. */ -static void refreshSingleLine(struct s_line_state *l, int flags) +void line_refresh(t_line_state *state, t_line_flags flags) { - char seq[64]; - size_t plen = strlen(l->prompt); - int fd = l->output_fd; - char *buf = l->buf; - size_t len = l->len; - size_t pos = l->pos; - struct abuf ab; - - while ((plen + pos) >= l->columns) - { - buf++; - len--; - pos--; - } - while (plen + len > l->columns) - { - len--; - } - - abInit(&ab); - /* Cursor to left edge */ - snprintf(seq, sizeof(seq), "\r"); - abAppend(&ab, seq, strlen(seq)); + t_string str; + str = string_new(64); + string_push(&str, "\r\x1b[2K"); if (flags & REFRESH_WRITE) - { - /* Write the prompt and the current buffer content */ - abAppend(&ab, l->prompt, strlen(l->prompt)); - abAppend(&ab, buf, len); - } - - /* Erase to right */ - snprintf(seq, sizeof(seq), "\x1b[0K"); - abAppend(&ab, seq, strlen(seq)); - - if (flags & REFRESH_WRITE) - { - /* Move cursor to original position. */ - snprintf(seq, sizeof(seq), "\r\x1b[%dC", (int)(pos + plen)); - abAppend(&ab, seq, strlen(seq)); - } - - if (write(fd, ab.b, ab.len) == -1) - { - } /* Can't recover from write error. */ - abFree(&ab); -} - -/* Calls the two low level functions refreshSingleLine() or - * refreshMultiLine() according to the selected mode. */ -static void refreshLineWithFlags(struct s_line_state *l, int flags) -{ - refreshSingleLine(l, flags); + me_printf_str(&str, "%s%s\x1b[0G\x1b[%uC", state->prompt, + state->buf.buf, state->pos + line_get_prompt_len(state->prompt)); + me_printf_fd(state->output_fd, "%s", str.buf); + string_free(str); } /* Utility function to avoid specifying REFRESH_ALL all the times. */ -static void refreshLine(struct s_line_state *l) +void line_refresh_line(t_line_state *state) { - refreshLineWithFlags(l, REFRESH_ALL); + line_refresh(state, REFRESH_ALL); } /* Hide the current line, when using the multiplexing API. */ -void linenoiseHide(struct s_line_state *l) +void line_hide(t_line_state *state) { - refreshSingleLine(l, REFRESH_CLEAN); + line_refresh(state, REFRESH_CLEAN); } /* Show the current line, when using the multiplexing API. */ -void linenoiseShow(struct s_line_state *l) +void line_show(t_line_state *state) { - refreshLineWithFlags(l, REFRESH_WRITE); + line_refresh(state, REFRESH_WRITE); } /* Insert the character 'c' at cursor current position. * * On error writing to the terminal -1 is returned, otherwise 0. */ -int linenoiseEditInsert(struct s_line_state *l, char c) +t_error line_edit_insert(t_line_state *state, char c) { - if (l->len < l->buflen) + if (state->pos == state->buf.len) { - if (l->len == l->pos) - { - l->buf[l->pos] = c; - l->pos++; - l->len++; - l->buf[l->len] = '\0'; - refreshLine(l); - } - else - { - memmove(l->buf + l->pos + 1, l->buf + l->pos, l->len - l->pos); - l->buf[l->pos] = c; - l->len++; - l->pos++; - l->buf[l->len] = '\0'; - refreshLine(l); - } + if (string_push_char(&state->buf, c)) + return (ERROR); } - return 0; + else if (string_insert_char(&state->buf, state->pos, c)) + return (ERROR); + state->pos++; + line_refresh_line(state); + return (NO_ERROR); } /* Move cursor on the left. */ -void linenoiseEditMoveLeft(struct s_line_state *l) +void line_edit_move_left(t_line_state *state) { - if (l->pos > 0) + if (state->pos > 0) { - l->pos--; - refreshLine(l); + state->pos--; + line_refresh_line(state); } } /* Move cursor on the right. */ -void linenoiseEditMoveRight(struct s_line_state *l) +void line_edit_move_right(t_line_state *state) { - if (l->pos != l->len) + if (state->pos != state->buf.len) { - l->pos++; - refreshLine(l); + state->pos++; + line_refresh_line(state); } } /* Move cursor to the start of the line. */ -void linenoiseEditMoveHome(struct s_line_state *l) +void line_edit_move_home(t_line_state *state) { - if (l->pos != 0) + if (state->pos != 0) { - l->pos = 0; - refreshLine(l); + state->pos = 0; + line_refresh_line(state); } } /* Move cursor to the end of the line. */ -void linenoiseEditMoveEnd(struct s_line_state *l) +void line_edit_move_end(t_line_state *state) { - if (l->pos != l->len) + if (state->pos != state->buf.len) { - l->pos = l->len; - refreshLine(l); + state->pos = state->buf.len; + line_refresh_line(state); } } /* Substitute the currently edited line with the next or previous history * entry as specified by 'dir'. */ -#define LINENOISE_HISTORY_NEXT 0 -#define LINENOISE_HISTORY_PREV 1 -void linenoiseEditHistoryNext(struct s_line_state *l, int dir) +void line_edit_history_next(t_line_state *state, + t_history_direction direction) { - t_vec_str *history; + t_vec_str *history; + t_isize dir; history = get_history(); - if (history->len > 1) { - /* Update the current history entry before to - * overwrite it with the next one. */ - mem_free(history->buffer[history->len - 1 - l->history_index]); - history->buffer[history->len - 1 - l->history_index] = strdup(l->buf); - /* Show the new entry */ - l->history_index += (dir == LINENOISE_HISTORY_PREV) ? 1 : -1; - if (l->history_index < 0) - { - l->history_index = 0; - return; - } - else if (l->history_index >= history->len) - { - l->history_index = history->len - 1; - return; - } - strncpy(l->buf, history->buffer[history->len - 1 - l->history_index], l->buflen); - l->buf[l->buflen - 1] = '\0'; - l->len = l->pos = strlen(l->buf); - refreshLine(l); + mem_free(history->buffer[history->len - 1 - state->history_index]); + history->buffer[history->len - 1 + - state->history_index] = str_clone(state->buf.buf); + dir = -1; + if (direction == HIST_PREV) + dir = 1; + state->history_index += dir; + if (state->history_index < 0) + return ((void)(state->history_index = 0)); + else if ((t_usize)state->history_index >= history->len) + return ((void)(state->history_index = history->len - 1)); + string_clear(&state->buf); + string_push(&state->buf, history->buffer[history->len - 1 + - state->history_index]); + state->pos = state->buf.len; + line_refresh_line(state); } } /* Delete the character at the right of the cursor without altering the cursor * position. Basically this is what happens with the "Delete" keyboard key. */ -void linenoiseEditDelete(struct s_line_state *l) +void line_edit_delete(t_line_state *state) { - if (l->len > 0 && l->pos < l->len) - { - memmove(l->buf + l->pos, l->buf + l->pos + 1, l->len - l->pos - 1); - l->len--; - l->buf[l->len] = '\0'; - refreshLine(l); - } + string_remove(&state->buf, state->pos, NULL); + line_refresh_line(state); } /* Backspace implementation. */ -void linenoiseEditBackspace(struct s_line_state *l) +void line_edit_backspace(t_line_state *state) { - if (l->pos > 0 && l->len > 0) + if (state->pos > 0) { - memmove(l->buf + l->pos - 1, l->buf + l->pos, l->len - l->pos); - l->pos--; - l->len--; - l->buf[l->len] = '\0'; - refreshLine(l); + string_remove(&state->buf, state->pos - 1, NULL); + state->pos--; + line_refresh_line(state); } } -/* Delete the previosu word, maintaining the cursor at the start of the - * current word. */ -void linenoiseEditDeletePrevWord(struct s_line_state *l) -{ - size_t old_pos = l->pos; - size_t diff; - - while (l->pos > 0 && l->buf[l->pos - 1] == ' ') - l->pos--; - while (l->pos > 0 && l->buf[l->pos - 1] != ' ') - l->pos--; - diff = old_pos - l->pos; - memmove(l->buf + l->pos, l->buf + old_pos, l->len - old_pos + 1); - l->len -= diff; - refreshLine(l); -} - /* This function is part of the multiplexed API of Linenoise, that is used * in order to implement the blocking variant of the API but can also be * called by the user directly in an event driven program. It will: @@ -504,57 +335,39 @@ void linenoiseEditDeletePrevWord(struct s_line_state *l) * fails. If stdin_fd or stdout_fd are set to -1, the default is to use * STDIN_FILENO and STDOUT_FILENO. */ -int linenoiseEditStart(struct s_line_state *l, int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt) +t_error line_edit_start(t_line_state *state, t_fd *stdin_fd, t_fd *stdout_fd, + t_const_str prompt) { - /* Populate the linenoise state that we pass to functions implementing - * specific editing functionalities. */ - l->in_completion = 0; - l->input_fd = stdin_fd != -1 ? stdin_fd : STDIN_FILENO; - l->output_fd = stdout_fd != -1 ? stdout_fd : STDOUT_FILENO; - l->buf = buf; - l->buflen = buflen; - l->prompt = prompt; - l->prompt_len = strlen(prompt); - l->oldpos = l->pos = 0; - l->len = 0; - - // /* Enter raw mode. */ - // if (enableRawMode(l->ifd) == -1) - // return -1; - - l->columns = getColumns(stdin_fd, stdout_fd); - l->old_rows = 0; - l->history_index = 0; - - /* Buffer starts empty. */ - l->buf[0] = '\0'; - l->buflen--; /* Make sure there is always space for the nulterm */ - - /* If stdin is not a tty, stop here with the initialization. We - * will actually just read a line from standard input in blocking - * mode later, in linenoiseEditFeed(). */ - if (!isatty(l->input_fd)) - return 0; - - /* The latest history entry is always our current buffer, that - * initially is just an empty string. */ - linenoise_history_add(""); - - if (write(l->output_fd, prompt, l->prompt_len) == -1) - return -1; - return 0; + if (stdin_fd == NULL) + stdin_fd = get_stdin(); + if (stdout_fd == NULL) + stdout_fd = get_stdout(); + state->input_fd = stdin_fd; + state->output_fd = stdout_fd; + state->buf = string_new(4096); + state->prompt = prompt; + state->prompt_len = str_len(state->prompt); + state->pos = 0; + if (line_enable_raw_mode(state->input_fd)) + return (ERROR); + state->columns = line_get_columns(stdin_fd, stdout_fd); + state->history_index = 0; + if (!isatty(state->input_fd->fd)) + return (NO_ERROR); + line_history_add(""); + if (write_fd(state->output_fd, (t_u8 *)prompt, state->prompt_len, NULL)) + return (ERROR); + return (NO_ERROR); } -char *linenoiseEditMore = "If you see this, you are misusing the API: when linenoiseEditFeed() is called, if it returns linenoiseEditMore " - "the user is yet editing the line. See the README file for more information."; - /* This function is part of the multiplexed API of linenoise, see the top * comment on linenoiseEditStart() for more information. Call this function * each time there is some data to read from the standard input file * descriptor. In the case of blocking operations, this function can just be * called in a loop, and block. * - * The function returns linenoiseEditMore to signal that line editing is still + + * The function returns get_unfinished_str() to signal that line editing is still * in progress, that is, the user didn't yet pressed enter / CTRL-D. Otherwise * the function returns the pointer to the heap-allocated buffer with the * edited line, that the user should mem_free with linenoiseFree(). @@ -566,235 +379,139 @@ char *linenoiseEditMore = "If you see this, you are misusing the API: when linen * * Some other errno: I/O error. */ -char *linenoiseEditFeed(struct s_line_state *l) +t_str line_edit_feed(t_line_state *state) { - /* Not a TTY, pass control to line reading without character - * count limits. */ - if (!isatty(l->input_fd)) - return linenoiseNoTTY(); + char c; + t_isize nread; + char seq[3]; + t_vec_str *history; + t_str tmp; - char c; - int nread; - char seq[3]; - t_vec_str *history = get_history(); - - nread = read(l->input_fd, &c, 1); - if (nread <= 0) - return NULL; - - switch (c) + if (!isatty(state->input_fd->fd)) + return (line_no_tty_impl()); + history = get_history(); + if (read_fd(state->input_fd, (t_u8 *)&c, 1, &nread)) + return (NULL); + if (c == K_NEWLINE || c == K_ENTER) { - case ENTER: /* enter */ - history->len--; - mem_free(history->buffer[history->len]); - return strdup(l->buf); - case CTRL_C: /* ctrl-c */ - errno = EAGAIN; - return NULL; - case BACKSPACE: /* backspace */ - case 8: /* ctrl-h */ - linenoiseEditBackspace(l); - break; - case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the - line is empty, act as end-of-file. */ - if (l->len > 0) - { - linenoiseEditDelete(l); - } + if (!vec_str_pop(history, &tmp)) + mem_free(tmp); + return (str_clone(state->buf.buf)); + } + else if (c == K_CTRL_C) + return (errno = EAGAIN, NULL); + else if (c == K_BACKSPACE || c == K_CTRL_H) + line_edit_backspace(state); + else if (c == K_CTRL_D) + { + if (state->buf.len > 0) + line_edit_delete(state); else { history->len--; mem_free(history->buffer[history->len]); - errno = ENOENT; - return NULL; + return (errno = ENOENT, NULL); } - break; - case CTRL_T: /* ctrl-t, swaps current character with previous. */ - if (l->pos > 0 && l->pos < l->len) - { - int aux = l->buf[l->pos - 1]; - l->buf[l->pos - 1] = l->buf[l->pos]; - l->buf[l->pos] = aux; - if (l->pos != l->len - 1) - l->pos++; - refreshLine(l); - } - break; - case CTRL_B: /* ctrl-b */ - linenoiseEditMoveLeft(l); - break; - case CTRL_F: /* ctrl-f */ - linenoiseEditMoveRight(l); - break; - case CTRL_P: /* ctrl-p */ - linenoiseEditHistoryNext(l, LINENOISE_HISTORY_PREV); - break; - case CTRL_N: /* ctrl-n */ - linenoiseEditHistoryNext(l, LINENOISE_HISTORY_NEXT); - break; - case ESC: /* escape sequence */ - /* Read the next two bytes representing the escape sequence. - * Use two calls to handle slow terminals returning the two - * chars at different times. */ - if (read(l->input_fd, seq, 1) == -1) - break; - if (read(l->input_fd, seq + 1, 1) == -1) - break; - - /* ESC [ sequences. */ + } + else if (c == K_CTRL_B) + line_edit_move_left(state); + else if (c == K_CTRL_F) + line_edit_move_right(state); + else if (c == K_CTRL_P) + line_edit_history_next(state, HIST_PREV); + else if (c == K_CTRL_N) + line_edit_history_next(state, HIST_PREV); + else if (c == K_ESC) + { + if (read_fd(state->input_fd, (t_u8 *)seq, 1, NULL)) + return ((t_str)get_unfinished_str()); + if (read_fd(state->input_fd, (t_u8 *)(seq + 1), 1, NULL)) + return ((t_str)get_unfinished_str()); if (seq[0] == '[') { if (seq[1] >= '0' && seq[1] <= '9') { - /* Extended escape, read additional byte. */ - if (read(l->input_fd, seq + 2, 1) == -1) - break; - if (seq[2] == '~') - { - switch (seq[1]) - { - case '3': /* Delete key. */ - linenoiseEditDelete(l); - break; - } - } + if (read_fd(state->input_fd, (t_u8 *)(seq + 2), 1, NULL)) + return ((t_str)get_unfinished_str()); + if (seq[1] == '3' && seq[2] == '~') + line_edit_delete(state); } else { - switch (seq[1]) - { - case 'A': /* Up */ - linenoiseEditHistoryNext(l, LINENOISE_HISTORY_PREV); - break; - case 'B': /* Down */ - linenoiseEditHistoryNext(l, LINENOISE_HISTORY_NEXT); - break; - case 'C': /* Right */ - linenoiseEditMoveRight(l); - break; - case 'D': /* Left */ - linenoiseEditMoveLeft(l); - break; - case 'H': /* Home */ - linenoiseEditMoveHome(l); - break; - case 'F': /* End*/ - linenoiseEditMoveEnd(l); - break; - } + if (seq[1] == 'A') + line_edit_history_next(state, HIST_PREV); + if (seq[1] == 'B') + line_edit_history_next(state, HIST_NEXT); + if (seq[1] == 'C') + line_edit_move_right(state); + if (seq[1] == 'D') + line_edit_move_left(state); + if (seq[1] == 'H') + line_edit_move_home(state); + if (seq[1] == 'F') + line_edit_move_end(state); } } - - /* ESC O sequences. */ else if (seq[0] == 'O') { - switch (seq[1]) - { - case 'H': /* Home */ - linenoiseEditMoveHome(l); - break; - case 'F': /* End*/ - linenoiseEditMoveEnd(l); - break; - } + if (seq[1] == 'H') + line_edit_move_home(state); + if (seq[1] == 'F') + line_edit_move_end(state); } - break; - default: - if (linenoiseEditInsert(l, c)) - return NULL; - break; - case CTRL_U: /* Ctrl+u, delete the whole line. */ - l->buf[0] = '\0'; - l->pos = l->len = 0; - refreshLine(l); - break; - case CTRL_K: /* Ctrl+k, delete from current to end of line. */ - l->buf[l->pos] = '\0'; - l->len = l->pos; - refreshLine(l); - break; - case CTRL_A: /* Ctrl+a, go to the start of the line */ - linenoiseEditMoveHome(l); - break; - case CTRL_E: /* ctrl+e, go to the end of the line */ - linenoiseEditMoveEnd(l); - break; - case CTRL_L: /* ctrl+l, clear screen */ - linenoiseClearScreen(); - refreshLine(l); - break; - case CTRL_W: /* ctrl+w, delete previous word */ - linenoiseEditDeletePrevWord(l); - break; } - return linenoiseEditMore; + else if (c == K_CTRL_U) + { + string_clear(&state->buf); + state->pos = 0; + line_refresh_line(state); + } + else if (c == K_CTRL_K) + { + string_clear_after(&state->buf, state->pos); + line_refresh_line(state); + } + else if (c == K_CTRL_A) + line_edit_move_home(state); + else if (c == K_CTRL_E) + line_edit_move_end(state); + else if (c == K_CTRL_L) + { + line_clear_screen(state->output_fd); + line_refresh_line(state); + } + else if (line_edit_insert(state, c)) + return (NULL); + return ((t_str)get_unfinished_str()); } /* This is part of the multiplexed linenoise API. See linenoiseEditStart() * for more information. This function is called when linenoiseEditFeed() * returns something different than NULL. At this point the user input * is in the buffer, and we can restore the terminal in normal mode. */ -void linenoiseEditStop(struct s_line_state *l) +void line_edit_stop(t_line_state *state) { - if (!isatty(l->input_fd)) - return; - // disableRawMode(l->ifd); - printf("\n"); + if (!isatty(state->input_fd->fd)) + return ; + line_disable_raw_mode(state->input_fd); + me_printf_fd(state->output_fd, "\n"); + string_free(state->buf); } /* This just implements a blocking loop for the multiplexed API. * In many applications that are not event-drivern, we can just call * the blocking linenoise API, wait for the user to complete the editing * and return the buffer. */ -static char *linenoiseBlockingEdit(int stdin_fd, int stdout_fd, char *buf, size_t buflen, const char *prompt) +t_str line_blocking_edit(t_fd *stdin_fd, t_fd *stdout_fd, t_const_str prompt) { - t_line_state l; + t_line_state l; + t_str res; - /* Editing without a buffer is invalid. */ - if (buflen == 0) - { - errno = EINVAL; - return (NULL); - } - - linenoiseEditStart(&l, stdin_fd, stdout_fd, buf, buflen, prompt); - char *res; - while ((res = linenoiseEditFeed(&l)) == linenoiseEditMore) + line_edit_start(&l, stdin_fd, stdout_fd, prompt); + while ((res = line_edit_feed(&l)) == get_unfinished_str()) ; - linenoiseEditStop(&l); - return res; -} - -/* This special mode is used by linenoise in order to print scan codes - * on screen for debugging / development purposes. It is implemented - * by the linenoise_example program using the --keycodes option. */ -void linenoisePrintKeyCodes(void) -{ - char quit[4]; - - printf("Linenoise key codes debugging mode.\n" - "Press keys to see scan codes. Type 'quit' at any time to exit.\n"); - // if (enableRawMode(STDIN_FILENO) == -1) - // return; - memset(quit, ' ', 4); - while (1) - { - char c; - int nread; - - nread = read(STDIN_FILENO, &c, 1); - if (nread <= 0) - continue; - memmove(quit, quit + 1, sizeof(quit) - 1); /* shift string to left. */ - quit[sizeof(quit) - 1] = c; /* Insert current char on the right. */ - if (memcmp(quit, "quit", sizeof(quit)) == 0) - break; - - printf("'%c' %02x (%d) (type quit to exit)\n", isprint(c) ? c : '?', (int)c, (int)c); - printf("\r"); /* Go left edge manually, we are in raw mode. */ - fflush(stdout); - } - // disableRawMode(STDIN_FILENO); + line_edit_stop(&l); + return (res); } /* This function is called when linenoise() is called with the standard @@ -802,21 +519,24 @@ void linenoisePrintKeyCodes(void) * program using linenoise is called in pipe or with a file redirected * to its standard input. In this case, we want to be able to return the * line regardless of its length (by default we are limited to 4k). */ -static t_str linenoiseNoTTY(void) +t_str line_no_tty_impl(void) { - t_string line; - t_isize ret; - char chr; + t_string line; + t_isize ret; + char chr; line = string_new(16); while (true) { chr = '\n'; - ret = read(STDIN_FILENO, &chr, 1); - if (ret < 0) + if (read_fd(get_stdin(), (t_u8 *)&chr, 1, &ret)) return (string_free(line), NULL); if (ret == 0 || chr == '\n') + { + if (line.len == 0) + return (string_free(line), NULL); return (line.buf); + } else string_push_char(&line, chr); } @@ -827,50 +547,18 @@ static t_str linenoiseNoTTY(void) * for a blacklist of stupid terminals, and later either calls the line * editing function or uses dummy fgets() so that you will be able to type * something even in the most desperate of the conditions. */ -char *linenoise(const char *prompt) +t_str linenoise(t_const_str prompt) { - char buf[4096]; + t_str retval; - if (!isatty(STDIN_FILENO)) - { - /* Not a tty: read from file / pipe. In this mode we don't want any - * limit to the line size, so we call a function to handle that. */ - return linenoiseNoTTY(); - } - { - char *retval = linenoiseBlockingEdit(STDIN_FILENO, STDOUT_FILENO, buf, 4096, prompt); - return retval; - } -} - -/* This is just a wrapper the user may want to call in order to make sure - * the linenoise returned buffer is mem_freed with the same allocator it was - * created with. Useful when the main program is using an alternative - * allocator. */ -void linenoise_free(void *ptr) -{ - if (ptr == linenoiseEditMore) - return; // Protect from API misuse. - mem_free(ptr); + if (!isatty(get_stdin()->fd)) + return (line_no_tty_impl()); + retval = line_blocking_edit(get_stdin(), get_stdout(), prompt); + return (retval); } /* ================================ History ================================= */ -/* Free the history, but does not reset it. Only used when we have to - * exit() to avoid memory leaks are reported by valgrind & co. */ -static void free_history(void) -{ - t_vec_str *history = get_history(); - vec_str_free(*history); -} - -/* At exit we'll try to fix the terminal to the initial conditions. */ -static void linenoise_uninit_lib(void) -{ - // disableRawMode(STDIN_FILENO); - free_history(); -} - /* This is the API call to add a new entry in the linenoise history. * It uses a fixed array of char pointers that are shifted (memmoved) * when the history max length is reached in order to remove the older @@ -878,14 +566,13 @@ static void linenoise_uninit_lib(void) * histories, but will work well for a few hundred of entries. * * Using a circular buffer is smarter, but a bit more complex to handle. */ -bool linenoise_history_add(t_const_str line) +bool line_history_add(t_const_str line) { - t_str linecopy; - t_vec_str *history; + t_str linecopy; + t_vec_str *history; history = get_history(); - - if (history->len != 0 && !strcmp(history->buffer[history->len - 1], line)) + if (history->len != 0 && str_compare(history->buffer[history->len - 1], line)) return (false); linecopy = str_clone(line); if (linecopy == NULL) @@ -896,32 +583,33 @@ bool linenoise_history_add(t_const_str line) /* Save the history in the specified file. On success 0 is returned * otherwise -1 is returned. */ -t_error linenoise_history_save(t_str name) +t_error line_history_save(t_str name) { - t_fd *fd; - t_usize j; - t_vec_str *history; + t_fd *fd; + t_usize j; + t_vec_str *history; history = get_history(); - - fd = open_fd(name, FD_READ, FD_CLOSE_ON_EXEC | FD_TRUNCATE | FD_CREATE, FP_OWRITE); + fd = open_fd(name, FD_READ, FD_CLOSE_ON_EXEC | FD_TRUNCATE | FD_CREATE, \ + FP_OWRITE); if (fd == NULL) return (ERROR); j = 0; while (j < history->len) { - write(fd->fd, history->buffer[j], str_len(history->buffer[j])); - write(fd->fd, "\n", 1); + write_fd(fd, (t_u8 *)history->buffer[j], str_len(history->buffer[j]), + NULL); + write_fd(fd, (t_u8 *)"\n", 1, NULL); j++; } close_fd(fd); return (NO_ERROR); } -t_error gnl_wrapper(t_fd *fd, t_string *out) +t_error gnl_wrapper(t_fd *fd, t_string *out) { - bool error; - t_string value; + bool error; + t_string value; if (out == NULL || fd == NULL) return (ERROR); @@ -936,18 +624,20 @@ t_error gnl_wrapper(t_fd *fd, t_string *out) * * If the file exists and the operation succeeded 0 is returned, otherwise * on error -1 is returned. */ -t_error linenoise_history_load(t_str name) +t_error line_history_load(t_str name) { - t_fd *fd; - t_string tmp; - t_vec_str *history; + t_fd *fd; + t_string tmp; + t_vec_str *history; fd = open_fd(name, FD_READ, FD_CLOSE_ON_EXEC, FP_ALL_READ); if (fd == NULL) return (ERROR); + history = get_history(); while (!gnl_wrapper(fd, &tmp)) { - while (tmp.len != 0 && (tmp.buf[tmp.len - 1] == '\n' || tmp.buf[tmp.len - 1] == '\r')) + while (tmp.len != 0 && (tmp.buf[tmp.len - 1] == '\n' || \ + tmp.buf[tmp.len - 1] == '\r')) string_pop(&tmp); vec_str_push(history, tmp.buf); } diff --git a/line/src/line_globals.c b/line/src/line_globals.c new file mode 100644 index 00000000..ae089a8f --- /dev/null +++ b/line/src/line_globals.c @@ -0,0 +1,62 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* line_globals.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/10 15:47:12 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 15:56:48 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/types.h" +#include "line/_line_internal.h" +#include "line/_line_structs.h" +#include "me/mem/mem.h" + +t_const_str get_unfinished_str(void) +{ + return ("If you see this," + " you are misusing the API" + " if it returns get_unfinished_str()" + " the user is yet editing the line." + " See the README file for more information."); +} + +t_vec_str *get_history(void) +{ + static t_vec_str history = {}; + static bool init = false; + + if (!init) + { + history = vec_str_new(256, (void (*)())mem_free); + init = true; + } + return (&history); +} + +t_raw_mode_state *get_raw_mode_state(void) +{ + static t_raw_mode_state state = {}; + + return (&state); +} + +/* Free the history, but does not reset it. Only used when we have to + * exit() to avoid memory leaks are reported by valgrind & co. */ +void free_history(void) +{ + t_vec_str *history; + + history = get_history(); + vec_str_free(*history); +} + +/* At exit we'll try to fix the terminal to the initial conditions. */ +__attribute__((destructor)) void line_uninit_lib(void) +{ + line_disable_raw_mode(get_stdin()); + free_history(); +} diff --git a/sources/main.c b/sources/main.c index d9c2acd6..804464cd 100644 --- a/sources/main.c +++ b/sources/main.c @@ -6,13 +6,14 @@ /* By: rparodi +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/03/28 14:40:38 by rparodi #+# #+# */ -/* Updated: 2024/07/03 21:23:17 by maiboyer ### ########.fr */ +/* Updated: 2024/07/08 21:11:43 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "app/env.h" #include "app/node.h" #include "app/signal_handler.h" +#include "line/line.h" #include "me/hashmap/hashmap_env.h" #include "me/str/str.h" #include "me/types.h" @@ -128,14 +129,13 @@ void ft_take_args(t_utils *shcat) while (1) { shcat->str_input = NULL; - cmd = readline((t_const_str)shcat->name_shell); + cmd = linenoise((t_const_str)shcat->name_shell); if (cmd == NULL) ft_exit(shcat, 0); - shcat->str_input = str_clone(cmd); - free(cmd); + shcat->str_input = cmd; + line_history_add(shcat->str_input); shcat->current_node = parse_str(&shcat->parser, shcat->str_input); exec_shcat(shcat); - add_history(shcat->str_input); mem_free(shcat->str_input); } } @@ -158,6 +158,9 @@ void free_myparser(t_parser self) ts_parser_delete(self.parser); } +#define IGN_START "\1" +#define IGN_END "\2" + t_i32 main(t_i32 argc, t_str argv[], t_str envp[]) { t_utils utils; @@ -172,11 +175,11 @@ t_i32 main(t_i32 argc, t_str argv[], t_str envp[]) utils.env = create_env_map(); if (populate_env(utils.env, envp)) me_abort("Unable to build env hashmap"); - utils.name_shell = "\001\x1B[93m\002" + utils.name_shell = "\x1B[93m" "42sh" - "\001\x1B[32m\002" + "\x1B[32m" ">" - "\001\x1B[0m\002" + "\x1B[0m" "$ "; ft_take_args(&utils); } diff --git a/sources/signal_handler.c b/sources/signal_handler.c index 638a5626..ae2448d4 100644 --- a/sources/signal_handler.c +++ b/sources/signal_handler.c @@ -6,14 +6,14 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/02 13:22:14 by maiboyer #+# #+# */ -/* Updated: 2024/05/23 17:07:03 by maiboyer ### ########.fr */ +/* Updated: 2024/07/09 14:43:30 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "app/signal_handler.h" +#include "me/fs/fs.h" #include "me/printf/printf.h" #include "me/types.h" -#include "readline/readline.h" #include #include @@ -22,10 +22,11 @@ void sigint_handle(int sig, siginfo_t *info, void *ucontext) (void)(sig); (void)(info); (void)(ucontext); - printf("\n"); - rl_replace_line("", 0); - rl_on_new_line(); - rl_redisplay(); + write_fd(get_stdout(), (void *)"\n", 1, NULL); + // TODO: change this to the linenoise verison + // rl_replace_line("", 0); + // rl_on_new_line(); + // rl_redisplay(); } void sigquit_handle(int sig, siginfo_t *info, void *ucontext) @@ -33,10 +34,10 @@ void sigquit_handle(int sig, siginfo_t *info, void *ucontext) (void)(sig); (void)(info); (void)(ucontext); - printf("\n"); - rl_replace_line("", 0); - rl_on_new_line(); - rl_redisplay(); + write_fd(get_stdout(), (void *)"\n", 1, NULL); + // rl_replace_line("", 0); + // rl_on_new_line(); + // rl_redisplay(); } void sigsegv_handle(int sig, siginfo_t *info, void *ucontext) @@ -56,8 +57,8 @@ t_error install_signal(void) data = (struct sigaction){}; data.sa_sigaction = sigint_handle; data.sa_flags = SA_SIGINFO | SA_NOCLDWAIT; - if (sigaction(SIGINT, &data, NULL)) - return (ERROR); + // if (sigaction(SIGINT, &data, NULL)) + // return (ERROR); data.sa_sigaction = sigquit_handle; if (sigaction(SIGQUIT, &data, NULL)) diff --git a/stdme/include/me/fs/fs.h b/stdme/include/me/fs/fs.h index 411a37a0..a54b8ca4 100644 --- a/stdme/include/me/fs/fs.h +++ b/stdme/include/me/fs/fs.h @@ -6,14 +6,13 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/19 15:12:18 by maiboyer #+# #+# */ -/* Updated: 2024/05/24 15:03:40 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:50:18 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef FS_H #define FS_H -#include "me/fs/read_to_vec.h" #include "me/types.h" #include #include @@ -78,9 +77,9 @@ typedef enum e_file_open_option /// `G` means group /// `U` means user /// `ALL` means all -/// There are the raw permission, you can combine them to get the permission you want -/// And there are "aliases" that are common permission set -/// @note you can combine them with the `|` operator +/// There are the raw permission, you can combine them to get the permission you +/// want And there are "aliases" that are common permission set +/// @note you can combine them with the `|` operator typedef enum e_file_perm { FP_OEXEC = 1 << 0, @@ -139,7 +138,6 @@ union u_file_slot { t_file file; }; - /// @brief File slot structure /// ty: the type of the slot /// slot: the slot itself @@ -164,46 +162,44 @@ typedef t_const_str t_mode; /// @note this is a simple typedef because I hate the struct keyword typedef struct stat t_stat; - /// @brief Directory entry structure -/// @note this is a simple typedef because I hate the struct keyword and it is always behind a pointer +/// @note this is a simple typedef because I hate the struct keyword and it is +/// always behind a pointer typedef struct dirent *t_dir_entry; -/*_____ _ _ _______ ______ _____ _ _ _ - |_ _| \ | |__ __| ____| __ \| \ | | /\ | | - | | | \| | | | | |__ | |__) | \| | / \ | | - | | | . ` | | | | __| | _ /| . ` | / /\ \ | | - _| |_| |\ | | | | |____| | \ \| |\ |/ ____ \| |____ - |_____|_| \_| |_| |______|_| \_\_| \_/_/ \_\______| +/*_____ _ _ _______ ______ _____ _ _ _ + |_ _| \ | |__ __| ____| __ \| \ | | /\ | | + | | | \| | | | | |__ | |__) | \| | / \ | | + | | | . ` | | | | __| | _ /| . ` | / /\ \ | | + _| |_| |\ | | | | |____| | \ \| |\ |/ ____ \| |____ + |_____|_| \_| |_| |______|_| \_\_| \_/_/ \_\______| */ /// @brief Get the fd arrays object /// @return pointer to the files's array /// @note internal function used to get the files array -t_fd_array *get_fd_arrays(void); +t_fd_array *get_fd_arrays(void); /// @brief Get the unused fd slot object /// @return pointer to the unused file slot /// @note Will abort if no slot is available struct s_file_slot *get_unused_fd_slot(void); - /// @brief Close all slots /// @note This is probably NOT what you want -void close_all_slots(void); +void close_all_slots(void); /// @note Close the given slot /// @param[in] slot the slot to close /// @note this is probably NOT what you want -void close_slot(struct s_file_slot *slot); +void close_slot(struct s_file_slot *slot); - -/* ______ _____ - | ____| __ \ +/* ______ _____ + | ____| __ \ | |__ | | | | | __| | | | | | | | |__| | - |_| |_____/ + |_| |_____/ */ /// @brief Open a file descriptor @@ -212,8 +208,8 @@ void close_slot(struct s_file_slot *slot); /// @param open_options the options to open the file /// @param fileperm the file permission /// @return the file descriptor* on success, NULL otherwise -t_fd *open_fd(t_str name, t_fd_perm perms, t_file_open_option open_options, - t_file_perm file_perm); +t_fd *open_fd(t_str name, t_fd_perm perms, t_file_open_option open_options, + t_file_perm file_perm); /// @brief Read from a file descriptor /// @param[in] fd the file descriptor @@ -241,29 +237,28 @@ t_error stat_fd(t_fd *fd, t_stat *stat); /// @brief Close a file descriptor /// @param[in] fd the file descriptor /// @note Will close the file descriptor and free the slot -void close_fd(t_fd *fd); +void close_fd(t_fd *fd); /// @brief write a number to a file descriptor /// @note will fail silently if the fd is not open in write mode -void put_number_fd(t_fd *fd, t_u64 number); +void put_number_fd(t_fd *fd, t_u64 number); /// @brief write a string to a file descriptor /// @note will fail silently if the fd is not open in write mode -void put_string_fd(t_fd *fd, t_const_str string); +void put_string_fd(t_fd *fd, t_const_str string); /// @brief write a char to a file descriptor /// @note will fail silently if the fd is not open in write mode -void put_char_fd(t_fd *fd, t_u8 c); +void put_char_fd(t_fd *fd, t_u8 c); /* _____ _____ _____ ______ _____ _______ ____ _______ __ | __ \_ _| __ \| ____/ ____|__ __/ __ \| __ \ \ / / - | | | || | | |__) | |__ | | | | | | | | |__) \ \_/ / - | | | || | | _ /| __|| | | | | | | | _ / \ / - | |__| || |_| | \ \| |___| |____ | | | |__| | | \ \ | | - |_____/_____|_| \_\______\_____| |_| \____/|_| \_\ |_| + | | | || | | |__) | |__ | | | | | | | | |__) \ \_/ / + | | | || | | _ /| __|| | | | | | | | _ / \ / + | |__| || |_| | \ \| |___| |____ | | | |__| | | \ \ | | + |_____/_____|_| \_\______\_____| |_| \____/|_| \_\ |_| */ - /// @brief Open a file /// @param[in] name the name of the file /// @param[out] dir the file structure to fill @@ -283,11 +278,11 @@ t_error read_dir(t_dir *dir, t_dir_entry *out); /// @note Will close the directory and free the slot void close_dir(t_dir *dir); -/*______ _____ _ ______ +/*______ _____ _ ______ | ____|_ _| | | ____| - | |__ | | | | | |__ - | __| | | | | | __| - | | _| |_| |____| |____ + | |__ | | | | | |__ + | __| | | | | | __| + | | _| |_| |____| |____ |_| |_____|______|______| */ @@ -304,7 +299,8 @@ t_error open_file(t_str name, t_mode mode, t_file **file); /// @param[in] size the size of the buffer /// @param[out] read_count the number of bytes read /// @return true on error, false otherwise -t_error read_file(t_file *file, t_u8 *buffer, t_usize size, t_isize *read_count); +t_error read_file(t_file *file, t_u8 *buffer, t_usize size, + t_isize *read_count); /// @brief Write to a file /// @param[in] file the file to write to @@ -313,11 +309,25 @@ t_error read_file(t_file *file, t_u8 *buffer, t_usize size, t_isize *read_count) /// @param[out] write_count the number of bytes written /// @return true on error, false otherwise /// @note write_count can be NULL -t_error write_file(t_file *file, t_u8 *buffer, t_usize size, t_isize *write_count); +t_error write_file(t_file *file, t_u8 *buffer, t_usize size, + t_isize *write_count); /// @brief Close the underlying file stream /// @param[in] file the file to close /// @note Will close the file and free the slot void close_file(t_file *file); +/* _____ ______ _______ _______ ______ _____ _____ + / ____| ____|__ __|__ __| ____| __ \ / ____| + | | __| |__ | | | | | |__ | |__) | (___ + | | |_ | __| | | | | | __| | _ / \___ \ + | |__| | |____ | | | | | |____| | \ \ ____) | + \_____|______| |_| |_| |______|_| \_\_____/ +*/ + +//TODO: Documentation! +t_fd *get_stdin(void); +t_fd *get_stdout(void); +t_fd *get_stderr(void); + #endif /* FS_H */ diff --git a/stdme/include/me/os/process.h b/stdme/include/me/os/process.h index 95ca6628..261f7a74 100644 --- a/stdme/include/me/os/process.h +++ b/stdme/include/me/os/process.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/03 15:43:08 by maiboyer #+# #+# */ -/* Updated: 2024/01/06 18:39:58 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 18:25:23 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -29,14 +29,14 @@ enum e_redirection union u_redirection { - struct s_fd + struct s_fd_redirection { int value; } fd; - struct s_piped + struct s_piped_redirection { } piped; - struct s_inherited + struct s_inherited_redirection { } inherited; }; diff --git a/stdme/include/me/printf/_internal_printf.h b/stdme/include/me/printf/_internal_printf.h new file mode 100644 index 00000000..e8b743fe --- /dev/null +++ b/stdme/include/me/printf/_internal_printf.h @@ -0,0 +1,81 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* _internal_printf.h :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/07 17:36:38 by maiboyer #+# #+# */ +/* Updated: 2024/07/07 18:01:17 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#ifndef _INTERNAL_PRINTF_H +#define _INTERNAL_PRINTF_H + +#include "me/fs/fs.h" +#include "me/string/string.h" +#include "me/types.h" + +typedef enum e_printf_flags t_printf_flags; +typedef enum e_printf_type t_printf_type; +typedef struct s_fprintf_arg t_fprintf_arg; +typedef struct s_printf_args t_printf_arg; +typedef struct s_printf_extra_args t_printf_extra_args; +typedef struct s_sprintf_arg t_sprintf_arg; + +typedef void (*t_printf_func)(t_const_str to_write, t_usize to_write_len, + void *p_args); + +struct s_fprintf_arg +{ + t_usize total_print; + t_fd *fd; +}; + +struct s_sprintf_arg +{ + t_usize total_print; + t_string *buffer; +}; +enum e_printf_flags +{ + PRECISION = 1 << 1, + ALIGN = 1 << 2, + ZERO_ALIGN = 1 << 3, + SIGN = 1 << 4, +}; + +enum e_printf_type +{ + CHAR = 1 << 0, + STR = 1 << 1, + U64 = 1 << 2, + I64 = 1 << 3, + VOID_PTR = 1 << 4, + I32 = 1 << 5, + U32 = 1 << 6, +}; + +struct s_printf_extra_args +{ + t_u64 precision; + t_u64 align; + bool left_align; + bool space_align; + bool pretty; +}; + +struct s_printf_args +{ + void *argument; + void *p_args; + t_printf_extra_args extra; + t_printf_flags flags; +}; + +void me_printf_write(t_const_str to_write, t_usize to_write_len, void *p_args); +void me_printf_append_string(t_const_str to_write, t_usize to_write_len, + void *p_args); + +#endif /* _INTERNAL_PRINTF_H */ diff --git a/stdme/include/me/printf/formatter/formatter.h b/stdme/include/me/printf/formatter/formatter.h index 67346c59..e7a733ce 100644 --- a/stdme/include/me/printf/formatter/formatter.h +++ b/stdme/include/me/printf/formatter/formatter.h @@ -6,14 +6,13 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 18:18:19 by maiboyer #+# #+# */ -/* Updated: 2023/11/18 19:11:23 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:38:52 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef FORMATTER_H # define FORMATTER_H -# include "me/printf/printf.h" -# include "me/types.h" +# include "me/printf/_internal_printf.h" void printf_x_low(t_printf_arg data, t_printf_func f); void printf_x_up(t_printf_arg data, t_printf_func f); diff --git a/stdme/include/me/printf/formatter/utils.h b/stdme/include/me/printf/formatter/utils.h index 150d5aaa..cac45906 100644 --- a/stdme/include/me/printf/formatter/utils.h +++ b/stdme/include/me/printf/formatter/utils.h @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 17:58:41 by maiboyer #+# #+# */ -/* Updated: 2023/12/01 21:24:21 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:38:49 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,7 @@ # define UTILS_H # include "me/printf/matchers/matchers.h" -# include "me/printf/printf.h" +# include "me/printf/_internal_printf.h" # include "me/types.h" # include diff --git a/stdme/include/me/printf/matchers/matchers.h b/stdme/include/me/printf/matchers/matchers.h index 7dc4239c..ff6efe09 100644 --- a/stdme/include/me/printf/matchers/matchers.h +++ b/stdme/include/me/printf/matchers/matchers.h @@ -6,14 +6,14 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 18:09:07 by maiboyer #+# #+# */ -/* Updated: 2023/11/18 18:10:33 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:38:46 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef MATCHERS_H # define MATCHERS_H -# include "me/printf/printf.h" +# include "me/printf/_internal_printf.h" # include "me/types.h" # include # define PRINTF_BUFFER_CHUNK 20 diff --git a/stdme/include/me/printf/printf.h b/stdme/include/me/printf/printf.h index 265852e1..70351769 100644 --- a/stdme/include/me/printf/printf.h +++ b/stdme/include/me/printf/printf.h @@ -6,100 +6,72 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 18:10:27 by maiboyer #+# #+# */ -/* Updated: 2024/07/05 19:54:25 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:37:02 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef PRINTF_H -# define PRINTF_H -# include "me/types.h" -# include +#define PRINTF_H +#include "me/types.h" +#include -# ifndef FS_H +#ifndef FS_H typedef struct s_fd t_fd; -# endif +#endif -typedef struct s_fprintf_arg -{ - t_usize total_print; - int fd; -} t_fprintf_arg; - -typedef enum e_printf_flags -{ - PRECISION = 1 << 1, - ALIGN = 1 << 2, - ZERO_ALIGN = 1 << 3, - SIGN = 1 << 4, -} t_printf_flags; - -typedef enum e_printf_type -{ - CHAR = 1 << 0, - STR = 1 << 1, - U64 = 1 << 2, - I64 = 1 << 3, - VOID_PTR = 1 << 4, - I32 = 1 << 5, - U32 = 1 << 6, -} t_printf_type; - -typedef struct s_printf_extra_args -{ - t_u64 precision; - t_u64 align; - bool left_align; - bool space_align; - bool pretty; -} t_printf_extra_args; - -typedef struct s_printf_args -{ - void *argument; - void *p_args; - t_printf_extra_args extra; - t_printf_flags flags; -} t_printf_arg; - -typedef void (*t_printf_func)(t_const_str to_write, - t_usize to_write_len, void *p_args); +#ifndef STRING_H +typedef struct s_string t_string; +#endif /// @brief Print a formatted string to stdout /// @param fmt the format string /// @param ... the arguments to format /// @return the number of characters printed -t_usize me_printf(t_const_str fmt, ...); +t_usize me_printf(t_const_str fmt, ...); /// @brief Print a formatted string to a stderr /// @param fmt the format string /// @param ... the arguments to format /// @return the number of characters printed -t_usize me_eprintf(t_const_str fmt, ...); +t_usize me_eprintf(t_const_str fmt, ...); /// @brief Print a formatted string to a stdout /// @param fmt the format string /// @param args the arguments to format as a va_list /// @return the number of characters printed -t_usize me_vprintf(t_const_str fmt, va_list *args); +t_usize me_vprintf(t_const_str fmt, va_list *args); /// @brief Print a formatted string to a stderr /// @param fmt the format string /// @param args the arguments to format as a va_list /// @return the number of characters printed -t_usize me_veprintf(t_const_str fmt, va_list *args); - +t_usize me_veprintf(t_const_str fmt, va_list *args); /// @brief Print a formatted string to the given fd /// @param fmt the format string /// @param ... the arguments to format /// @return the number of characters printed -t_usize me_printf_fd(t_fd *, t_const_str fmt, ...); +t_usize me_printf_fd(t_fd *, t_const_str fmt, ...); /// @brief Print a formatted string to the given fd /// @param fmt the format string /// @param args the arguments to format as a va_list /// @return the number of characters printed -t_usize me_vprintf_fd(t_fd *, t_const_str fmt, va_list *args); +t_usize me_vprintf_fd(t_fd *, t_const_str fmt, va_list *args); + +/// @brief print a formatted string to a buffer +/// @param buffer the buffer to append to +/// @param fmt the format string +/// @param ... the arguments to format +/// @return the number of characters printed +t_usize me_printf_str(t_string *buffer, t_const_str fmt, ...); + +/// @brief print a formatted string to a buffer +/// @param buffer the buffer to append to +/// @param fmt the format string +/// @param args the arguments to format +/// @return the number of characters printed +t_usize me_vprintf_str(t_string *buffer, t_const_str fmt, va_list *args); #endif diff --git a/stdme/include/me/string/string.h b/stdme/include/me/string/string.h index ce59fab9..e4b8748e 100644 --- a/stdme/include/me/string/string.h +++ b/stdme/include/me/string/string.h @@ -6,54 +6,53 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 17:54:28 by maiboyer #+# #+# */ -/* Updated: 2024/04/30 14:14:42 by maiboyer ### ########.fr */ +/* Updated: 2024/07/08 21:58:11 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #ifndef STRING_H -# define STRING_H -# include "me/types.h" +#define STRING_H +#include "me/types.h" typedef struct s_string { - t_str buf; - t_usize capacity; - t_usize len; -} t_string; + t_str buf; + t_usize capacity; + t_usize len; +} t_string; /// @brief Push a string to a buffer /// @param buf the string to be pushed to /// @param to_push the string to push -/// @return true if it failed, false otherwise -t_error string_push(t_string *buf, t_const_str to_push); - +/// @return true if it failed, false otherwise +t_error string_push(t_string *buf, t_const_str to_push); /// @brief Push a character to a buffer /// @param buf the string to be pushed to /// @param to_push the character to push /// @return true if it failed, false otherwise -t_error string_push_char(t_string *buf, char to_push); +t_error string_push_char(t_string *buf, char to_push); /// @brief Clear a string /// @param buf the string to clear -void string_clear(t_string *buf); +void string_clear(t_string *buf); /// @brief Create a new string /// @param capacity the initial capacity of the string /// @return the created string -t_string string_new(t_usize capacity); +t_string string_new(t_usize capacity); /// @brief Make the string able to hold at least size characters if not already /// @param buf the string to operate on /// @param size the minimum size of the string wanted /// @return true if it failed, false otherwise -t_error string_reserve(t_string *buf, t_usize size); +t_error string_reserve(t_string *buf, t_usize size); /// @brief free a string /// @param buf the string to free -static inline void string_free(t_string buf) +static inline void string_free(t_string buf) { - void mem_free(void *); + void mem_free(void *); mem_free(buf.buf); } @@ -61,9 +60,9 @@ static inline void string_free(t_string buf) /// @brief Pop a character from a string /// @param buf the string to pop from /// @return the popped character, or '\0' if the string is empty -static inline char string_pop(t_string *buf) +static inline char string_pop(t_string *buf) { - char c; + char c; c = '\0'; if (buf->buf && buf->len) @@ -74,4 +73,33 @@ static inline char string_pop(t_string *buf) return (c); } +/// @brief Insert a string into self +/// @param self the string to insert into +/// @param pos the index to start inserting at +/// @param str the string to insert +/// @return Error in case pos was over the string length, self was equal to NULL +/// or str was equal to NULL +t_error string_insert(t_string *self, t_usize pos, t_str str); + +/// @brief Insert a char into self +/// @param self the string to insert into +/// @param pos the index to start inserting at +/// @param str the character to insert +/// @return Error in case pos was over the string length, self was equal to NULL +/// or chr was '\0' +t_error string_insert_char(t_string *self, t_usize pos, char chr); + +/// @brief Clear the string, keeping everything before `pos` +/// @param self the string to operate on +/// @param pos the position to start remove from +/// @return returns an Error if self is null or pos is after the string length +t_error string_clear_after(t_string *self, t_usize pos); + +/// @brief Remove a single character from the string, putting it in `out` +/// @param self the string to operate on +/// @param pos the position to start remove +/// @param out[out] the place to put the removed character, if any. Can be NULL +/// @return returns an Error if self is null or pos is after the string length +t_error string_remove(t_string *self, t_usize pos, char *out); + #endif diff --git a/stdme/src.list b/stdme/src.list index bb0e2b82..d0bc717f 100644 --- a/stdme/src.list +++ b/stdme/src.list @@ -73,6 +73,7 @@ os/pipe os/process os/process_inner os/process_inner2 +printf/callbacks printf/formatter/char printf/formatter/decimal printf/formatter/hex @@ -85,6 +86,8 @@ printf/formatter/utils3 printf/formatter/utils_numbers printf/matchers printf/printf +printf/printf_fd +printf/printf_str printf/vprintf str/str_clone str/str_compare @@ -103,3 +106,6 @@ str/str_split str/str_substring str/str_trim string/mod +string/string_insert +string/string_remove +string/string_reserve diff --git a/stdme/src/fs/fs_internal.c b/stdme/src/fs/fs_internal.c index 9fbcf341..dff2b60d 100644 --- a/stdme/src/fs/fs_internal.c +++ b/stdme/src/fs/fs_internal.c @@ -6,19 +6,20 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/19 15:53:50 by maiboyer #+# #+# */ -/* Updated: 2024/05/30 16:02:12 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 19:17:05 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#include "me/types.h" #include "me/fs/fs.h" #include "me/mem/mem.h" #include "me/str/str.h" +#include "me/types.h" +#include "unistd.h" -#include #include -#include #include +#include +#include t_fd_array *get_fd_arrays(void) { @@ -45,7 +46,7 @@ struct s_file_slot *get_unused_fd_slot(void) return (NULL); } -void close_all_slots(void) +__attribute__((destructor(201))) void close_all_slots(void) { t_usize i; t_fd_array *arr; @@ -63,30 +64,30 @@ void close_slot(struct s_file_slot *slot) if (slot->ty == SLOT_UNUSED) ; else if (slot->ty == SLOT_FD) - close_fd(&slot->slot.fd); + (mem_free(slot->slot.fd.name), close_fd(&slot->slot.fd)); else if (slot->ty == SLOT_DIR) - close_dir(&slot->slot.dir); + (mem_free(slot->slot.dir.name), close_dir(&slot->slot.dir)); else if (slot->ty == SLOT_FILE) - close_file(&slot->slot.file); + (mem_free(slot->slot.file.name), close_file(&slot->slot.file)); else (void)!write(2, "Unknown SLOT type", 17); mem_set_zero(slot, sizeof(*slot)); } -/* ______ _____ - | ____| __ \ +/* ______ _____ + | ____| __ \ | |__ | | | | | __| | | | | | | | |__| | - |_| |_____/ + |_| |_____/ */ -t_fd *open_fd(t_str name, t_fd_perm perms, t_file_open_option open_options, - t_file_perm file_perm) +t_fd *open_fd(t_str name, t_fd_perm perms, t_file_open_option open_options, + t_file_perm file_perm) { - t_fd *fd; - struct s_file_slot *slot; - int actual_perms; + t_fd *fd; + struct s_file_slot *slot; + int actual_perms; if (perms & FD_READ && perms & FD_WRITE) actual_perms = O_RDWR; @@ -112,8 +113,12 @@ t_fd *open_fd(t_str name, t_fd_perm perms, t_file_open_option open_options, t_error read_fd(t_fd *fd, t_u8 *buffer, t_usize size, t_isize *read_count) { t_isize ret; + t_isize false_ret; - if (fd == NULL || buffer == NULL || read_count == NULL || fd->fd == -1 || !(fd->perms & FD_READ)) + if (read_count == NULL) + read_count = &false_ret; + if (fd == NULL || buffer == NULL || fd->fd == -1 || + !(fd->perms & FD_READ)) return (ERROR); ret = read(fd->fd, buffer, size); if (ret == -1) @@ -149,13 +154,13 @@ t_error stat_fd(t_fd *fd, t_stat *stat) void close_fd(t_fd *fd) { - struct s_file_slot *slot; + struct s_file_slot *slot; if (fd == NULL) - return ; + return; if (close(fd->fd) == -1) - return ; - slot = (void*)(fd) - offsetof(struct s_file_slot, slot.fd); + return; + slot = (void *)(fd)-offsetof(struct s_file_slot, slot.fd); mem_set_zero(slot, sizeof(*slot)); } @@ -163,7 +168,7 @@ void close_fd(t_fd *fd) void put_number_fd(t_fd *fd, t_u64 number) { - t_u8 buffer[INLINE_BUFFER_SIZE]; + t_u8 buffer[INLINE_BUFFER_SIZE]; t_usize i; i = 0; @@ -178,7 +183,7 @@ void put_number_fd(t_fd *fd, t_u64 number) void put_string_fd(t_fd *fd, t_const_str string) { - write_fd(fd, (t_u8*)string, str_len(string), NULL); + write_fd(fd, (t_u8 *)string, str_len(string), NULL); } void put_char_fd(t_fd *fd, t_u8 c) @@ -188,16 +193,16 @@ void put_char_fd(t_fd *fd, t_u8 c) /* _____ _____ _____ ______ _____ _______ ____ _______ __ | __ \_ _| __ \| ____/ ____|__ __/ __ \| __ \ \ / / - | | | || | | |__) | |__ | | | | | | | | |__) \ \_/ / - | | | || | | _ /| __|| | | | | | | | _ / \ / - | |__| || |_| | \ \| |___| |____ | | | |__| | | \ \ | | - |_____/_____|_| \_\______\_____| |_| \____/|_| \_\ |_| + | | | || | | |__) | |__ | | | | | | | | |__) \ \_/ / + | | | || | | _ /| __|| | | | | | | | _ / \ / + | |__| || |_| | \ \| |___| |____ | | | |__| | | \ \ | | + |_____/_____|_| \_\______\_____| |_| \____/|_| \_\ |_| */ t_error open_dir(t_str name, t_dir **dir) { - t_dir *out; - struct s_file_slot *slot; + t_dir *out; + struct s_file_slot *slot; slot = get_unused_fd_slot(); out = &slot->slot.dir; @@ -226,28 +231,28 @@ t_error read_dir(t_dir *dir, t_dir_entry *out) void close_dir(t_dir *dir) { - struct s_file_slot *slot; + struct s_file_slot *slot; if (dir == NULL) - return ; + return; if (closedir(dir->ptr) == -1) - return ; - slot = (void*)(dir) - offsetof(struct s_file_slot, slot.dir); + return; + slot = (void *)(dir)-offsetof(struct s_file_slot, slot.dir); mem_set_zero(slot, sizeof(*slot)); } -/*______ _____ _ ______ +/*______ _____ _ ______ | ____|_ _| | | ____| - | |__ | | | | | |__ - | __| | | | | | __| - | | _| |_| |____| |____ + | |__ | | | | | |__ + | __| | | | | | __| + | | _| |_| |____| |____ |_| |_____|______|______| */ t_error open_file(t_str name, t_mode mode, t_file **file) { - t_file *out; - struct s_file_slot *slot; + t_file *out; + struct s_file_slot *slot; slot = get_unused_fd_slot(); out = &slot->slot.file; @@ -260,7 +265,8 @@ t_error open_file(t_str name, t_mode mode, t_file **file) return (NO_ERROR); } -t_error write_file(t_file *file, t_u8 *buffer, t_usize size, t_isize *write_count) +t_error write_file(t_file *file, t_u8 *buffer, t_usize size, + t_isize *write_count) { t_isize ret; t_isize fake_ret; @@ -280,7 +286,8 @@ t_error read_file(t_file *file, t_u8 *buffer, t_usize size, t_isize *read_count) { t_isize ret; - if (file == NULL || buffer == NULL || read_count == NULL || file->ptr == NULL) + if (file == NULL || buffer == NULL || read_count == NULL || + file->ptr == NULL) return (ERROR); ret = fread(buffer, size, 1, file->ptr); if (ret == -1) @@ -291,12 +298,77 @@ t_error read_file(t_file *file, t_u8 *buffer, t_usize size, t_isize *read_count) void close_file(t_file *file) { - struct s_file_slot *slot; + struct s_file_slot *slot; if (file == NULL) - return ; + return; if (fclose(file->ptr) == -1) - return ; - slot = (void*)(file) - offsetof(struct s_file_slot, slot.file); + return; + slot = (void *)(file)-offsetof(struct s_file_slot, slot.file); mem_set_zero(slot, sizeof(*slot)); } + +/* _____ ______ _______ _______ ______ _____ _____ + / ____| ____|__ __|__ __| ____| __ \ / ____| + | | __| |__ | | | | | |__ | |__) | (___ + | | |_ | __| | | | | | __| | _ / \___ \ + | |__| | |____ | | | | | |____| | \ \ ____) | + \_____|______| |_| |_| |______|_| \_\_____/ +*/ + +t_fd *get_stdin(void) +{ + t_fd *out; + struct s_file_slot *slot; + static t_fd *value = NULL; + + if (value == NULL) + { + slot = get_unused_fd_slot(); + out = &slot->slot.fd; + out->fd = STDIN_FILENO; + out->perms = FD_READ; + out->name = str_clone(""); + slot->ty = SLOT_FD; + value = out; + } + return (value); +} + +t_fd *get_stdout(void) +{ + t_fd *out; + struct s_file_slot *slot; + static t_fd *value = NULL; + + if (value == NULL) + { + slot = get_unused_fd_slot(); + out = &slot->slot.fd; + out->fd = STDOUT_FILENO; + out->perms = FD_WRITE; + out->name = str_clone(""); + slot->ty = SLOT_FD; + value = out; + } + return (value); +} + +t_fd *get_stderr(void) +{ + t_fd *out; + struct s_file_slot *slot; + static t_fd *value = NULL; + + if (value == NULL) + { + slot = get_unused_fd_slot(); + out = &slot->slot.fd; + out->fd = STDERR_FILENO; + out->perms = FD_WRITE; + out->name = str_clone(""); + slot->ty = SLOT_FD; + value = out; + } + return (value); +} diff --git a/stdme/src/fs/open.c b/stdme/src/fs/open.c index 8586dbda..01d08038 100644 --- a/stdme/src/fs/open.c +++ b/stdme/src/fs/open.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/03 15:29:38 by maiboyer #+# #+# */ -/* Updated: 2024/01/06 18:19:11 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:43:58 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,7 +16,7 @@ t_error me_open(t_const_str path, bool read, bool write, int *file_out) { int out; - int flags; + int flags; flags = 0; if (read && write) @@ -35,7 +35,7 @@ t_error me_open(t_const_str path, bool read, bool write, int *file_out) t_error me_open_truncate(t_const_str path, int *file_out) { int out; - int flags; + int flags; unlink(path); flags = O_WRONLY | O_CREAT | O_TRUNC; @@ -49,7 +49,7 @@ t_error me_open_truncate(t_const_str path, int *file_out) t_error me_open_create(t_const_str path, int *file_out) { int out; - int flags; + int flags; flags = O_WRONLY | O_CREAT | O_APPEND; out = open(path, flags, 0666); diff --git a/stdme/src/fs/read_to_vec.c b/stdme/src/fs/read_to_vec.c index 5ec6699c..0ba97906 100644 --- a/stdme/src/fs/read_to_vec.c +++ b/stdme/src/fs/read_to_vec.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/24 18:38:47 by maiboyer #+# #+# */ -/* Updated: 2023/12/30 18:15:58 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:44:22 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,7 +21,7 @@ bool read_to_vec(t_const_str path, t_vec_u8 *out) { t_u8 temp_buffer[READ_BUFFER_SIZE]; t_isize read_amount; - int f; + int f; bool eof; t_usize current_size; diff --git a/stdme/src/gnl/get_next_line.c b/stdme/src/gnl/get_next_line.c index d6b44a78..64624928 100644 --- a/stdme/src/gnl/get_next_line.c +++ b/stdme/src/gnl/get_next_line.c @@ -6,7 +6,7 @@ /* By: maix +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/23 17:38:21 by maix #+# #+# */ -/* Updated: 2024/05/14 18:39:59 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:45:42 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -101,7 +101,7 @@ static bool handle_leftovers(int fd, char *temp_buffer, t_string *buf) t_string get_next_line(int fd, bool *error) { - t_string buf; + t_string buf; char *temp_buffer; t_copy_flags flags; diff --git a/stdme/src/hash/hash_str.c b/stdme/src/hash/hash_str.c index 95b4139f..aaae8e50 100644 --- a/stdme/src/hash/hash_str.c +++ b/stdme/src/hash/hash_str.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/04 19:17:11 by maiboyer #+# #+# */ -/* Updated: 2024/05/04 19:18:26 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:46:17 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,7 +14,7 @@ #include "me/str/str.h" #include "me/types.h" -void hasher_write_str(t_hasher *hasher, t_str s) +void hasher_write_str(t_hasher *hasher, t_str s) { hasher_write_bytes(hasher, (t_u8 *)s, str_len(s)); } diff --git a/stdme/src/img/qoi/qoi_fs.c b/stdme/src/img/qoi/qoi_fs.c index db38b414..a17ebe69 100644 --- a/stdme/src/img/qoi/qoi_fs.c +++ b/stdme/src/img/qoi/qoi_fs.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/24 19:06:05 by maiboyer #+# #+# */ -/* Updated: 2024/05/14 18:40:29 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:46:34 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -21,7 +21,7 @@ t_i32 qoi_write(t_const_str filename, const void *data, const t_qoi_desc *desc) { - int f; + int f; void *encoded; t_i32 size; diff --git a/stdme/src/mem/allocator.c b/stdme/src/mem/allocator.c index 40862fc8..85102113 100644 --- a/stdme/src/mem/allocator.c +++ b/stdme/src/mem/allocator.c @@ -6,34 +6,34 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/14 18:26:27 by maiboyer #+# #+# */ -/* Updated: 2024/05/22 15:21:28 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:48:46 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#include "aq/internal_vg_funcs.h" -#include "me/types.h" #include "aq/allocator.h" +#include "aq/internal_vg_funcs.h" #include "aq/libc_wrapper.h" #include "aq/melloc.h" +#include "me/types.h" +#include - - -t_allocator *global_allocator(void) +t_allocator *global_allocator(void) { - static t_allocator global_alloc = {}; - static bool init = false; + static t_allocator global_alloc = {}; + static bool init = false; + if (!init) { init = true; global_alloc = m_init(); - // global_alloc = lc_init(); } return (&global_alloc); } -void uninit_global_allocator(void) +__attribute__((destructor(200))) +void uninit_global_allocator(void) { - t_allocator *allocator; + t_allocator *allocator; allocator = global_allocator(); vg_mem_defined(allocator, sizeof(*allocator)); diff --git a/stdme/src/mem/mem_alloc.c b/stdme/src/mem/mem_alloc.c index 772f3ef4..57ef54d5 100644 --- a/stdme/src/mem/mem_alloc.c +++ b/stdme/src/mem/mem_alloc.c @@ -6,16 +6,16 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/06 14:47:49 by maiboyer #+# #+# */ -/* Updated: 2024/05/22 15:01:06 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:48:20 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/mem/_allocator.h" #include "me/mem/mem.h" -void *mem_alloc(t_usize size) +void *mem_alloc(t_usize size) { - t_allocator *a; + t_allocator *a; void *ret; a = global_allocator(); @@ -25,9 +25,9 @@ void *mem_alloc(t_usize size) return (ret); } -void mem_free(void *ptr) +void mem_free(void *ptr) { - t_allocator *a; + t_allocator *a; a = global_allocator(); return (a->free(a, ptr)); diff --git a/stdme/src/mem/mem_alloc_array.c b/stdme/src/mem/mem_alloc_array.c index bb7a70da..e2c81a20 100644 --- a/stdme/src/mem/mem_alloc_array.c +++ b/stdme/src/mem/mem_alloc_array.c @@ -6,16 +6,16 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/06 15:53:21 by maiboyer #+# #+# */ -/* Updated: 2024/05/14 18:30:27 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:47:03 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/mem/mem.h" #include "me/mem/_allocator.h" -void *mem_alloc_array(t_usize size, t_usize count) +void *mem_alloc_array(t_usize size, t_usize count) { - t_allocator *a; + t_allocator *a; a = global_allocator(); return (a->alloc_array(a, size, count)); diff --git a/stdme/src/mem/mem_realloc.c b/stdme/src/mem/mem_realloc.c index d190be80..3647b348 100644 --- a/stdme/src/mem/mem_realloc.c +++ b/stdme/src/mem/mem_realloc.c @@ -6,23 +6,23 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/07 12:46:18 by maiboyer #+# #+# */ -/* Updated: 2024/05/14 18:32:06 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:47:21 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/mem/_allocator.h" -void *mem_realloc(void *ptr, t_usize size) +void *mem_realloc(void *ptr, t_usize size) { - t_allocator *a; + t_allocator *a; a = global_allocator(); return (a->realloc(a, ptr, size)); } -void *mem_realloc_array(void *ptr, t_usize size, t_usize count) +void *mem_realloc_array(void *ptr, t_usize size, t_usize count) { - t_allocator *a; + t_allocator *a; a = global_allocator(); return (a->realloc_array(a, ptr, size, count)); diff --git a/stdme/src/num/usize/round_up.c b/stdme/src/num/usize/round_up.c index f112b238..6adc1e2e 100644 --- a/stdme/src/num/usize/round_up.c +++ b/stdme/src/num/usize/round_up.c @@ -6,15 +6,15 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/07 11:04:51 by maiboyer #+# #+# */ -/* Updated: 2024/05/07 11:06:22 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:49:05 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/num/usize.h" -t_usize usize_round_up_to(t_usize self, t_usize mul) +t_usize usize_round_up_to(t_usize self, t_usize mul) { - t_usize mod; + t_usize mod; if (mul == 0) return (self); diff --git a/stdme/src/os/abort.c b/stdme/src/os/abort.c index f2c1cc42..da995525 100644 --- a/stdme/src/os/abort.c +++ b/stdme/src/os/abort.c @@ -6,12 +6,11 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/07 11:08:03 by maiboyer #+# #+# */ -/* Updated: 2024/05/16 17:26:27 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:54:01 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#define _GNU_SOURCE - +#include "./gnu_source.h" #include "me/fs/putendl_fd.h" #include "me/fs/putstr_fd.h" #include "me/types.h" @@ -31,24 +30,24 @@ # define BACKTRACE_DEEP 256 # endif -static size_t convert_to_vma(t_usize addr) +static size_t convert_to_vma(t_usize addr) { - Dl_info info; - struct link_map *link_map; + Dl_info info; + struct link_map *link_map; dladdr1((void *)addr, &info, (void **)&link_map, RTLD_DL_LINKMAP); return (addr - link_map->l_addr); } -static void print_trace_inner(void **trace, t_str *messages, t_usize i) +static void print_trace_inner(void **trace, t_str *messages, t_usize i) { - char syscom[1024]; - t_i32 p; + char syscom[1024]; + t_i32 p; p = 0; fprintf(stderr, "[bt] #%-4zu\t", i); while (messages[i][p] != '(' && messages[i][p] != ' ' && - messages[i][p] != 0) + messages[i][p] != 0) ++p; fflush(stderr); snprintf( @@ -60,12 +59,12 @@ static void print_trace_inner(void **trace, t_str *messages, t_usize i) fprintf(stderr, "%s\n", messages[i]); } -void print_trace(void) +void print_trace(void) { - void *trace[BACKTRACE_DEEP]; - t_str *messages; - t_i32 size; - t_i32 i; + void *trace[BACKTRACE_DEEP]; + t_str *messages; + t_i32 size; + t_i32 i; size = backtrace(trace, BACKTRACE_DEEP); messages = backtrace_symbols(trace, size); @@ -79,20 +78,18 @@ void print_trace(void) } #else -void print_trace(void) +void print_trace(void) { } #endif -void me_abort(t_str msg) +void me_abort(t_str msg) { if (msg == NULL) msg = "No message (msg was NULL)"; - me_putendl_fd("Memory information:", 2); me_putstr_fd("Abort: ", 2); me_putendl_fd(msg, 2); print_trace(); - // me_exit(1); - abort(); + me_exit(134); } diff --git a/stdme/src/os/exit.c b/stdme/src/os/exit.c index 04e0faff..dc63f570 100644 --- a/stdme/src/os/exit.c +++ b/stdme/src/os/exit.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/07 13:08:52 by maiboyer #+# #+# */ -/* Updated: 2024/05/22 15:05:19 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:54:22 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,9 +15,12 @@ #include "me/types.h" #include -void me_exit(t_i32 exit_code) +// If you are looking at why some stuff aren't closed, they are using the +// __attribute__((dtor)) to be run at exit for example: +// - close_all_slots +// - uninit global allocator +void me_exit(t_i32 exit_code) { - close_all_slots(); - uninit_global_allocator(); + (get_stdin(), get_stdout(), get_stderr()); exit(exit_code); } diff --git a/stdme/test/test-skeleton.c b/stdme/src/os/gnu_source.h similarity index 70% rename from stdme/test/test-skeleton.c rename to stdme/src/os/gnu_source.h index 8e87d1a3..848090fd 100644 --- a/stdme/test/test-skeleton.c +++ b/stdme/src/os/gnu_source.h @@ -1,18 +1,18 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* test-skeleton.c :+: :+: :+: */ +/* gnu_source.h :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2024/05/22 15:11:51 by maiboyer #+# #+# */ -/* Updated: 2024/05/22 15:12:44 by maiboyer ### ########.fr */ +/* Created: 2024/07/10 17:53:46 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 17:54:49 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -int do_test(int argc, char **argv); +#ifndef GNU_SOURCE_H +# define GNU_SOURCE_H -int main(int argc, char *argv[]) -{ - return (do_test(argc, argv)); -} +# define _GNU_SOURCE + +#endif /* GNU_SOURCE_H */ diff --git a/stdme/src/os/process.c b/stdme/src/os/process.c index 4e2befae..9b073fa2 100644 --- a/stdme/src/os/process.c +++ b/stdme/src/os/process.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/03 16:22:41 by maiboyer #+# #+# */ -/* Updated: 2024/05/19 14:57:20 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 18:04:36 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -26,11 +26,11 @@ bool find_path(const t_str *s); bool find_null(const t_str *s); bool str_start_with(t_const_str s, t_const_str prefix); -t_error handle_redirections(t_spawn_info *info, t_process *process); +t_error handle_redirections(t_spawn_info *info, t_process *process); -t_error spawn_process_exec(t_spawn_info info, t_process *process) +t_error spawn_process_exec(t_spawn_info info, t_process *process) { - bool res; + bool res; if (info.forked_free) info.forked_free(info.forked_free_args); @@ -52,11 +52,11 @@ t_error spawn_process_exec(t_spawn_info info, t_process *process) return (NO_ERROR); } -t_error in_path(t_spawn_info *info, t_process *process, t_const_str path, +t_error in_path(t_spawn_info *info, t_process *process, t_const_str path, t_string *s) { - t_str *splitted_path; - t_usize sp_index; + t_str *splitted_path; + t_usize sp_index; splitted_path = str_split(path + 5, ':'); if (splitted_path == NULL) @@ -70,7 +70,7 @@ t_error in_path(t_spawn_info *info, t_process *process, t_const_str path, string_push(s, info->binary_path); sp_index++; if (access(s->buf, X_OK | R_OK) == 0) - break; + break ; } sp_index = 0; while (splitted_path[sp_index]) @@ -79,16 +79,16 @@ t_error in_path(t_spawn_info *info, t_process *process, t_const_str path, return (NO_ERROR); } -t_error find_binary(t_spawn_info *info, t_process *process) +t_error find_binary(t_spawn_info *info, t_process *process) { - t_usize p_idx; - t_string s; + t_usize p_idx; + t_string s; (void)(process); if (info->binary_path == NULL) return (ERROR); s = string_new(256); - if (str_start_with(info->binary_path, "/") || + if (str_start_with(info->binary_path, "/") || \ str_find_chr(info->binary_path, '/') != NULL) string_push(&s, info->binary_path); else @@ -107,7 +107,8 @@ t_error find_binary(t_spawn_info *info, t_process *process) return (string_free(s), ERROR); } -static void cleanup(t_spawn_info info, t_process *process, bool cleanup_process) +static void cleanup(t_spawn_info info, t_process *process, \ + bool cleanup_process) { if (cleanup_process && process->stdin.tag != INVALID) close(process->stdin.vals.ro.fd); @@ -123,7 +124,7 @@ static void cleanup(t_spawn_info info, t_process *process, bool cleanup_process) mem_free(info.binary_path); } -t_error spawn_process(t_spawn_info info, t_process *process) +t_error spawn_process(t_spawn_info info, t_process *process) { if (handle_redirections(&info, process)) return (cleanup(info, process, true), ERROR); diff --git a/stdme/src/os/process_inner.c b/stdme/src/os/process_inner.c index 0cd77745..0f212627 100644 --- a/stdme/src/os/process_inner.c +++ b/stdme/src/os/process_inner.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/01/04 22:25:44 by maiboyer #+# #+# */ -/* Updated: 2024/05/19 14:51:07 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 18:05:03 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -14,12 +14,12 @@ #include #include -bool find_null(const t_str *s) +bool find_null(const t_str *s) { return (s == NULL); } -bool str_start_with(t_const_str s, t_const_str prefix) +bool str_start_with(t_const_str s, t_const_str prefix) { while (*prefix && *s) { @@ -29,13 +29,13 @@ bool str_start_with(t_const_str s, t_const_str prefix) return (*prefix == '\0'); } -bool find_path(const t_str *s) +bool find_path(const t_str *s) { - t_str ss; + t_str ss; if (*s == NULL) return (false); ss = *s; - return (ss[0] == 'P' && ss[1] == 'A' && ss[2] == 'T' && ss[3] == 'H' && + return (ss[0] == 'P' && ss[1] == 'A' && ss[2] == 'T' && ss[3] == 'H' && \ ss[4] == '='); } diff --git a/stdme/src/printf/callbacks.c b/stdme/src/printf/callbacks.c new file mode 100644 index 00000000..f958997b --- /dev/null +++ b/stdme/src/printf/callbacks.c @@ -0,0 +1,36 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* callbacks.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/07 18:01:52 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 17:58:04 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/fs/fs.h" +#include "me/printf/_internal_printf.h" +#include "me/string/string.h" +#include "me/types.h" + +void me_printf_append_string(t_const_str to_write, t_usize to_write_len, + void *p_args) +{ + t_sprintf_arg *arg; + + arg = p_args; + arg->total_print += to_write_len; + string_push(arg->buffer, to_write); +} + +void me_printf_write(t_const_str to_write, \ + t_usize to_write_len, void *p_args) +{ + t_fprintf_arg *arg; + + arg = (t_fprintf_arg *)p_args; + write_fd(arg->fd, (t_u8 *)to_write, to_write_len, NULL); + arg->total_print += to_write_len; +} diff --git a/stdme/src/printf/formatter/char.c b/stdme/src/printf/formatter/char.c index a239c34e..5208f1a9 100644 --- a/stdme/src/printf/formatter/char.c +++ b/stdme/src/printf/formatter/char.c @@ -6,13 +6,12 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/18 18:12:11 by maiboyer #+# #+# */ -/* Updated: 2024/05/14 18:43:13 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:39:40 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/mem/mem.h" #include "me/printf/formatter/utils.h" -#include "me/printf/printf.h" #include "me/str/str.h" #include "me/str/str.h" #include diff --git a/stdme/src/printf/formatter/decimal.c b/stdme/src/printf/formatter/decimal.c index ce5a5020..18557b27 100644 --- a/stdme/src/printf/formatter/decimal.c +++ b/stdme/src/printf/formatter/decimal.c @@ -6,14 +6,13 @@ /* By: maix +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/18 01:44:35 by maix #+# #+# */ -/* Updated: 2024/05/14 18:43:24 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:39:44 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/mem/mem.h" #include "me/mem/mem.h" #include "me/printf/formatter/utils.h" -#include "me/printf/printf.h" #include "me/str/str.h" #include "me/str/str.h" #include diff --git a/stdme/src/printf/formatter/hex.c b/stdme/src/printf/formatter/hex.c index fe2455b3..e1dc6027 100644 --- a/stdme/src/printf/formatter/hex.c +++ b/stdme/src/printf/formatter/hex.c @@ -6,13 +6,12 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 18:16:16 by maiboyer #+# #+# */ -/* Updated: 2023/12/11 19:19:03 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:40:18 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/mem/mem.h" #include "me/printf/formatter/utils.h" -#include "me/printf/printf.h" #include "me/str/str.h" #define HEX_INLINE_BUF 17 diff --git a/stdme/src/printf/formatter/oct.c b/stdme/src/printf/formatter/oct.c index a249c419..ff92b09f 100644 --- a/stdme/src/printf/formatter/oct.c +++ b/stdme/src/printf/formatter/oct.c @@ -6,13 +6,12 @@ /* By: maix +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/18 01:19:18 by maix #+# #+# */ -/* Updated: 2023/12/11 19:17:23 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:40:18 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/mem/mem.h" #include "me/printf/formatter/utils.h" -#include "me/printf/printf.h" #include "me/str/str.h" #include #define OCT_INLINE_BUF 23 diff --git a/stdme/src/printf/formatter/ptr.c b/stdme/src/printf/formatter/ptr.c index 27e65485..d0b1f7d9 100644 --- a/stdme/src/printf/formatter/ptr.c +++ b/stdme/src/printf/formatter/ptr.c @@ -6,13 +6,12 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 18:16:16 by maiboyer #+# #+# */ -/* Updated: 2023/12/11 19:20:42 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:40:18 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/mem/mem.h" #include "me/printf/formatter/utils.h" -#include "me/printf/printf.h" #include "me/str/str.h" #define PTR_INLINE_BUF 17 diff --git a/stdme/src/printf/formatter/unsigned_decimal.c b/stdme/src/printf/formatter/unsigned_decimal.c index 31900542..7f717433 100644 --- a/stdme/src/printf/formatter/unsigned_decimal.c +++ b/stdme/src/printf/formatter/unsigned_decimal.c @@ -6,14 +6,13 @@ /* By: maix +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/18 01:44:35 by maix #+# #+# */ -/* Updated: 2024/05/14 18:43:39 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:40:18 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/mem/mem.h" #include "me/mem/mem.h" #include "me/printf/formatter/utils.h" -#include "me/printf/printf.h" #include "me/str/str.h" #include "me/str/str.h" #include diff --git a/stdme/src/printf/formatter/utils.c b/stdme/src/printf/formatter/utils.c index 1b4bd5d0..88417f0b 100644 --- a/stdme/src/printf/formatter/utils.c +++ b/stdme/src/printf/formatter/utils.c @@ -6,16 +6,14 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 17:57:04 by maiboyer #+# #+# */ -/* Updated: 2024/05/14 18:43:44 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:40:18 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#include "me/string/string.h" #include "me/mem/mem.h" #include "me/convert/atoi.h" #include "me/printf/formatter/utils.h" #include "me/printf/matchers/matchers.h" -#include "me/printf/printf.h" #include "me/str/str.h" #include "me/str/str.h" #include "me/types.h" diff --git a/stdme/src/printf/formatter/utils2.c b/stdme/src/printf/formatter/utils2.c index 9976fe6d..8d83f16f 100644 --- a/stdme/src/printf/formatter/utils2.c +++ b/stdme/src/printf/formatter/utils2.c @@ -6,14 +6,12 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 18:00:07 by maiboyer #+# #+# */ -/* Updated: 2023/12/01 21:48:22 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 17:40:18 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#include "me/string/string.h" #include "me/char/char.h" #include "me/printf/formatter/utils.h" -#include "me/printf/printf.h" #include "me/types.h" void set_var_for_pad_and_stuff(t_pad_and_stuff_args *a, t_printf_arg *d) diff --git a/stdme/src/printf/formatter/utils_numbers.c b/stdme/src/printf/formatter/utils_numbers.c index 424d633a..9e174a3d 100644 --- a/stdme/src/printf/formatter/utils_numbers.c +++ b/stdme/src/printf/formatter/utils_numbers.c @@ -6,16 +6,15 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/12/01 21:05:47 by maiboyer #+# #+# */ -/* Updated: 2024/05/14 18:43:56 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:58:28 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#include "me/printf/formatter/utils.h" -#include "me/printf/printf.h" #include "me/mem/mem.h" +#include "me/printf/formatter/utils.h" void handle_weird_precision_stuff(t_printf_arg *data, t_prec_strs strs, - t_usize value) + t_usize value) { if (!value && data->extra.precision == 0 && (data->flags & PRECISION)) { diff --git a/stdme/src/printf/matchers.c b/stdme/src/printf/matchers.c index 479950d3..a088441a 100644 --- a/stdme/src/printf/matchers.c +++ b/stdme/src/printf/matchers.c @@ -6,14 +6,13 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 18:07:40 by maiboyer #+# #+# */ -/* Updated: 2023/12/11 19:11:51 by maiboyer ### ########.fr */ +/* Updated: 2024/07/08 19:37:12 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/mem/mem.h" #include "me/printf/formatter/formatter.h" #include "me/printf/matchers/matchers.h" -#include "me/printf/printf.h" #include #include #include @@ -22,15 +21,15 @@ t_matcher_list *get_matchers(void) { static t_matcher_list printf_matchers = (t_matcher_list){ .data = { - {.matcher = "o", .matcher_len = 1, .arg_type = U64, .f = &printf_o}, - {.matcher = "c", .matcher_len = 1, .arg_type = CHAR, .f = &printf_c}, - {.matcher = "s", .matcher_len = 1, .arg_type = STR, .f = &printf_s}, - {.matcher = "p", .matcher_len = 1, .arg_type = VOID_PTR, .f = &printf_p}, - {.matcher = "d", .matcher_len = 1, .arg_type = I32, .f = &printf_d}, - {.matcher = "i", .matcher_len = 1, .arg_type = I32, .f = &printf_d}, - {.matcher = "u", .matcher_len = 1, .arg_type = U32, .f = &printf_u}, - {.matcher = "x", .matcher_len = 1, .arg_type = U32, .f = &printf_x_low}, - {.matcher = "X", .matcher_len = 1, .arg_type = U32, .f = &printf_x_up}, + {.matcher = "o", .matcher_len = 1, .arg_type = U64, .f = printf_o}, + {.matcher = "c", .matcher_len = 1, .arg_type = CHAR, .f = printf_c}, + {.matcher = "s", .matcher_len = 1, .arg_type = STR, .f = printf_s}, + {.matcher = "p", .matcher_len = 1, .arg_type = VOID_PTR, .f = printf_p}, + {.matcher = "d", .matcher_len = 1, .arg_type = I32, .f = printf_d}, + {.matcher = "i", .matcher_len = 1, .arg_type = I32, .f = printf_d}, + {.matcher = "u", .matcher_len = 1, .arg_type = U32, .f = printf_u}, + {.matcher = "x", .matcher_len = 1, .arg_type = U32, .f = printf_x_low}, + {.matcher = "X", .matcher_len = 1, .arg_type = U32, .f = printf_x_up}, }, .next = NULL, }; @@ -55,7 +54,7 @@ bool insert_matcher(t_matcher matcher) return (true); } } - matchers->next = malloc(sizeof(t_matcher_list) * 1); + matchers->next = mem_alloc(sizeof(t_matcher_list)); } return (false); } @@ -74,7 +73,7 @@ t_matcher *find_matcher(t_const_str fmt, t_matcher_list *matchers, matcher = &matchers->data[matcher_index]; if (matcher->f) { - if (!mem_compare(&fmt[*c_idx], matcher->matcher, + if (mem_compare(&fmt[*c_idx], matcher->matcher, matcher->matcher_len)) { *c_idx += matcher->matcher_len; diff --git a/stdme/src/printf/printf.c b/stdme/src/printf/printf.c index 64199821..eeed9686 100644 --- a/stdme/src/printf/printf.c +++ b/stdme/src/printf/printf.c @@ -6,115 +6,32 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/11 17:50:56 by maiboyer #+# #+# */ -/* Updated: 2024/02/09 14:58:10 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:57:15 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#include "me/string/string.h" -#include "me/fs/write.h" -#include "me/printf/formatter/formatter.h" -#include "me/printf/formatter/utils.h" -#include "me/printf/matchers/matchers.h" #include "me/printf/printf.h" -#include "me/str/str.h" #include "me/types.h" -#include #include -#include -#include -// p_args is an t_string; -static void me_printf_add_to_string(t_const_str to_write, t_usize to_write_len, - void *p_args) -{ - t_string *out_buf; - - out_buf = (t_string *)p_args; - (void)(to_write_len); - string_push(out_buf, to_write); -} - -t_str me_printf_str(t_const_str fmt, va_list *arguments) -{ - t_string out; - - out = string_new(str_len(fmt)); - if (out.buf == NULL) - { - return (NULL); - } - me_printf_str_inner(fmt, &me_printf_add_to_string, arguments, (void *)&out); - return (out.buf); -} - -void me_printf_write(t_const_str to_write, t_usize to_write_len, - void *p_args) -{ - t_fprintf_arg *arg; - - arg = (t_fprintf_arg *)p_args; - me_write(arg->fd, (t_u8 *)to_write, to_write_len); - arg->total_print += to_write_len; -} - -t_usize me_printf(t_const_str fmt, ...) -{ - va_list args; - t_fprintf_arg passthru; - - passthru = (t_fprintf_arg){ - .fd = 1, - .total_print = 0, - }; - va_start(args, fmt); - me_printf_str_inner(fmt, &me_printf_write, &args, (void *)&passthru); - va_end(args); - return (passthru.total_print); -} - -t_usize me_eprintf(t_const_str fmt, ...) -{ - va_list args; - t_fprintf_arg passthru; - - passthru = (t_fprintf_arg){ - .fd = 2, - .total_print = 0, - }; - va_start(args, fmt); - me_printf_str_inner(fmt, &me_printf_write, &args, (void *)&passthru); - va_end(args); - return (passthru.total_print); -} - -/* t_usize me_printf(t_const_str fmt, ...) { va_list args; - t_str str; - t_usize len; + t_usize res; va_start(args, fmt); - str = me_printf_str(fmt, &args); + res = me_vprintf(fmt, &args); va_end(args); - len = str_len(str); - write(1, str, len); - mem_free(str); - return (len); + return (res); } t_usize me_eprintf(t_const_str fmt, ...) { va_list args; - t_str str; - t_usize len; + t_usize res; va_start(args, fmt); - str = me_printf_str(fmt, &args); + res = me_veprintf(fmt, &args); va_end(args); - len = str_len(str); - write(2, str, len); - mem_free(str); - return (len); + return (res); } -*/ diff --git a/stdme/src/printf/printf_fd.c b/stdme/src/printf/printf_fd.c index aa7856e8..c53dd089 100644 --- a/stdme/src/printf/printf_fd.c +++ b/stdme/src/printf/printf_fd.c @@ -1,4 +1,3 @@ - /* ************************************************************************** */ /* */ /* ::: :::::::: */ @@ -7,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/07/05 19:55:09 by maiboyer #+# #+# */ -/* Updated: 2024/07/05 19:57:23 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:55:18 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -17,31 +16,25 @@ #include "me/types.h" #include -void me_printf_write(t_const_str to_write, t_usize to_write_len, void *p_args); - -t_usize me_vprintf_fd(t_fd *fd, t_const_str fmt, va_list *args) +t_usize me_vprintf_fd(t_fd *fd, t_const_str fmt, va_list *args) { - t_fprintf_arg passthru; + t_fprintf_arg passthru; - passthru = (t_fprintf_arg){ - .fd = fd->fd, - .total_print = 0, - }; + if (fd == NULL || fmt == NULL || args == NULL) + return (0); + passthru.fd = fd; + passthru.total_print = 0; me_printf_str_inner(fmt, &me_printf_write, args, (void *)&passthru); return (passthru.total_print); } -t_usize me_printf_fd(t_fd *fd, t_const_str fmt, ...) +t_usize me_printf_fd(t_fd *fd, t_const_str fmt, ...) { - va_list args; - t_fprintf_arg passthru; + va_list args; + t_usize res; - passthru = (t_fprintf_arg){ - .fd = fd->fd, - .total_print = 0, - }; va_start(args, fmt); - me_printf_str_inner(fmt, &me_printf_write, &args, (void *)&passthru); + res = me_vprintf_fd(fd, fmt, &args); va_end(args); - return (passthru.total_print); + return (res); } diff --git a/stdme/src/printf/printf_str.c b/stdme/src/printf/printf_str.c new file mode 100644 index 00000000..dce59bea --- /dev/null +++ b/stdme/src/printf/printf_str.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* printf_str.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/07 17:27:50 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 17:57:32 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/printf/_internal_printf.h" +#include "me/printf/formatter/utils.h" +#include "me/printf/printf.h" +#include "me/string/string.h" +#include "me/types.h" +#include + +t_usize me_vprintf_str(t_string *buf, t_const_str fmt, va_list *args) +{ + t_sprintf_arg passthru; + + if (buf == NULL || fmt == NULL || args == NULL) + return (0); + passthru.buffer = buf; + passthru.total_print = 0; + me_printf_str_inner(fmt, &me_printf_append_string, args, &passthru); + return (passthru.total_print); +} + +t_usize me_printf_str(t_string *buf, t_const_str fmt, ...) +{ + t_usize res; + va_list args; + + va_start(args, fmt); + res = me_vprintf_str(buf, fmt, &args); + va_end(args); + return (res); +} diff --git a/stdme/src/printf/vprintf.c b/stdme/src/printf/vprintf.c index bd30f272..386ead99 100644 --- a/stdme/src/printf/vprintf.c +++ b/stdme/src/printf/vprintf.c @@ -6,34 +6,27 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/02/09 14:57:28 by maiboyer #+# #+# */ -/* Updated: 2024/02/09 15:00:39 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 17:56:24 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#include "me/string/string.h" -#include "me/fs/write.h" -#include "me/printf/formatter/formatter.h" +#include "me/fs/fs.h" #include "me/printf/formatter/utils.h" -#include "me/printf/matchers/matchers.h" #include "me/printf/printf.h" -#include "me/str/str.h" #include "me/types.h" -#include #include -#include -#include -void me_printf_write(t_const_str to_write, t_usize to_write_len, - void *p_args); +void me_printf_write(t_const_str to_write, \ + t_usize to_write_len, void *p_args); t_usize me_vprintf(t_const_str fmt, va_list *args) { t_fprintf_arg passthru; - passthru = (t_fprintf_arg){ - .fd = 1, - .total_print = 0, - }; + if (fmt == NULL || args == NULL) + return (0); + passthru.fd = get_stdout(); + passthru.total_print = 0; me_printf_str_inner(fmt, &me_printf_write, args, (void *)&passthru); return (passthru.total_print); } @@ -42,10 +35,10 @@ t_usize me_veprintf(t_const_str fmt, va_list *args) { t_fprintf_arg passthru; - passthru = (t_fprintf_arg){ - .fd = 2, - .total_print = 0, - }; + if (fmt == NULL || args == NULL) + return (0); + passthru.fd = get_stderr(); + passthru.total_print = 0; me_printf_str_inner(fmt, &me_printf_write, args, (void *)&passthru); return (passthru.total_print); } diff --git a/stdme/src/str/str_clone.c b/stdme/src/str/str_clone.c index e2e2fd19..ca02d17d 100644 --- a/stdme/src/str/str_clone.c +++ b/stdme/src/str/str_clone.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/06 16:05:48 by maiboyer #+# #+# */ -/* Updated: 2024/05/18 16:34:33 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 18:00:28 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -16,10 +16,10 @@ #include "me/str/str.h" #include -t_str str_clone(t_const_str source) +t_str str_clone(t_const_str source) { t_str res; - t_usize len; + t_usize len; len = str_len(source) + 1; res = mem_alloc_array(sizeof(*res), len); diff --git a/stdme/src/str/str_compare.c b/stdme/src/str/str_compare.c index 232540c6..7f9bcace 100644 --- a/stdme/src/str/str_compare.c +++ b/stdme/src/str/str_compare.c @@ -6,16 +6,15 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/04 18:53:47 by maiboyer #+# #+# */ -/* Updated: 2024/05/04 18:37:40 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 18:00:43 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ #include "me/str/str.h" -// PLEASE FIX THIS FUNCTION IF NEEDED ! -bool str_compare(t_const_str lhs, t_const_str rhs) +bool str_compare(t_const_str lhs, t_const_str rhs) { - t_usize index; + t_usize index; if (lhs == NULL || rhs == NULL) return (lhs == rhs); diff --git a/stdme/src/string/mod.c b/stdme/src/string/mod.c index 60617889..1b438ca1 100644 --- a/stdme/src/string/mod.c +++ b/stdme/src/string/mod.c @@ -6,7 +6,7 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/16 17:52:12 by maiboyer #+# #+# */ -/* Updated: 2024/05/18 18:06:37 by maiboyer ### ########.fr */ +/* Updated: 2024/07/10 18:02:36 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -19,10 +19,10 @@ #include "me/types.h" #include -t_error str_reserve(t_string *buf, t_usize size) +t_error str_reserve(t_string *buf, t_usize size) { t_str temp_buffer; - t_usize new_capacity; + t_usize new_capacity; if (buf == NULL) return (ERROR); @@ -42,9 +42,9 @@ t_error str_reserve(t_string *buf, t_usize size) return (NO_ERROR); } -t_error string_push(t_string *buf, t_const_str to_push) +t_error string_push(t_string *buf, t_const_str to_push) { - t_usize to_push_len; + t_usize to_push_len; if (buf == NULL || to_push == NULL) return (ERROR); @@ -56,26 +56,26 @@ t_error string_push(t_string *buf, t_const_str to_push) return (NO_ERROR); } -bool string_push_char(t_string *buf, char to_push) +bool string_push_char(t_string *buf, char to_push) { - char push_str[2]; + char push_str[2]; push_str[0] = to_push; push_str[1] = 0; return (string_push(buf, push_str)); } -void string_clear(t_string *buf) +void string_clear(t_string *buf) { mem_set_zero(buf->buf, buf->capacity); buf->len = 0; - return; + return ; } -t_string string_new(t_usize capacity) +t_string string_new(t_usize capacity) { - t_string out; - t_str buf; + t_string out; + t_str buf; if (capacity == 0) capacity = 16; diff --git a/stdme/src/string/string_insert.c b/stdme/src/string/string_insert.c new file mode 100644 index 00000000..d9eda965 --- /dev/null +++ b/stdme/src/string/string_insert.c @@ -0,0 +1,45 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* string_insert.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/08 21:32:17 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 18:01:27 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem.h" +#include "me/str/str.h" +#include "me/string/string.h" +#include "me/types.h" + +t_error string_insert(t_string *self, t_usize pos, t_str str) +{ + t_usize len; + + if (self == NULL || str == NULL || pos > self->len) + return (ERROR); + if (pos == self->len) + return (string_push(self, str)); + len = str_len(str); + if (string_reserve(self, self->len + len)) + return (ERROR); + mem_move(&self->buf[pos + len], &self->buf[pos], self->len - pos); + mem_copy(&self->buf[pos], str, len); + self->len += len; + self->buf[self->len] = '\0'; + return (NO_ERROR); +} + +t_error string_insert_char(t_string *self, t_usize pos, char chr) +{ + char tmp[2]; + + if (chr == '\0') + return (ERROR); + tmp[0] = chr; + tmp[1] = '\0'; + return (string_insert(self, pos, tmp)); +} diff --git a/stdme/src/string/string_remove.c b/stdme/src/string/string_remove.c new file mode 100644 index 00000000..f936d4e5 --- /dev/null +++ b/stdme/src/string/string_remove.c @@ -0,0 +1,41 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* string_remove.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/08 21:50:27 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 18:01:53 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ + +#include "me/mem/mem.h" +#include "me/str/str.h" +#include "me/string/string.h" +#include "me/types.h" + +t_error string_remove(t_string *self, t_usize pos, char *out) +{ + char fake_out; + + if (out == NULL) + out = &fake_out; + if (self == NULL || pos >= self->len) + return (ERROR); + *out = self->buf[pos]; + mem_move(&self->buf[pos], &self->buf[pos] + 1, self->len - pos); + self->len--; + self->buf[self->len] = '\0'; + return (NO_ERROR); +} + +t_error string_clear_after(t_string *self, t_usize pos) +{ + if (self == NULL || pos >= self->len) + return (ERROR); + mem_set_zero(&self->buf[pos], self->len - pos); + self->len = pos; + self->buf[self->len] = '\0'; + return (NO_ERROR); +} diff --git a/stdme/test/redef_alloc.h b/stdme/src/string/string_reserve.c similarity index 60% rename from stdme/test/redef_alloc.h rename to stdme/src/string/string_reserve.c index 24790d47..46a00995 100644 --- a/stdme/test/redef_alloc.h +++ b/stdme/src/string/string_reserve.c @@ -1,28 +1,25 @@ /* ************************************************************************** */ /* */ /* ::: :::::::: */ -/* redef_alloc.h :+: :+: :+: */ +/* string_reserve.c :+: :+: :+: */ /* +:+ +:+ +:+ */ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ -/* Created: 2024/05/22 15:15:52 by maiboyer #+# #+# */ -/* Updated: 2024/05/22 15:16:34 by maiboyer ### ########.fr */ +/* Created: 2024/07/08 22:02:49 by maiboyer #+# #+# */ +/* Updated: 2024/07/10 18:01:40 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ -#ifndef REDEF_ALLOC_H -#define REDEF_ALLOC_H - #include "me/mem/mem.h" +#include "me/string/string.h" +#include "me/types.h" -#undef malloc -#undef calloc -#undef realloc -#undef free - -#define malloc(s) mem_alloc((s)) -#define calloc(s, l) mem_alloc_array((s), (l)) -#define realloc(p, t) mem_realloc((p), (t)) -#define free(p) mem_free((p)) - -#endif /* REDEF_ALLOC_H */ +t_error string_reserve(t_string *self, t_usize capacity) +{ + if (self == NULL) + return (ERROR); + if (self->capacity >= capacity) + return (NO_ERROR); + self->buf = mem_realloc(self->buf, capacity); + return (NO_ERROR); +} diff --git a/stdme/test/calloc.c b/stdme/test/calloc.c deleted file mode 100644 index af336973..00000000 --- a/stdme/test/calloc.c +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright (C) 2000-2024 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - - -#include -#include -#include -#include -#include -#include - -#include "./redef_alloc.h" - -/* Number of samples per size. */ -#define N 5000 - -static void fixed_test(int size) -{ - char *ptrs[N]; - int i; - - for (i = 0; i < N; ++i) - { - int j; - - ptrs[i] = (char *)calloc(1, size); - - if (ptrs[i] == NULL) - break; - - for (j = 0; j < size; ++j) - { - if (ptrs[i][j] != '\0') - error(EXIT_FAILURE, 0, - "byte not cleared (size %d, element %d, byte %d)", size, - i, j); - ptrs[i][j] = '\xff'; - } - } - - while (i-- > 0) - free(ptrs[i]); -} - -static void random_test(void) -{ - char *ptrs[N]; - int i; - - for (i = 0; i < N; ++i) - { - int j; - int n = 1 + random() % 10; - int elem = 1 + random() % 100; - int size = n * elem; - - ptrs[i] = (char *)calloc(n, elem); - - if (ptrs[i] == NULL) - break; - - for (j = 0; j < size; ++j) - { - if (ptrs[i][j] != '\0') - error(EXIT_FAILURE, 0, - "byte not cleared (size %d, element %d, byte %d)", size, - i, j); - ptrs[i][j] = '\xff'; - } - } - - while (i-- > 0) - free(ptrs[i]); -} - -static void null_test(void) -{ - /* If the size is 0 the result is implementation defined. Just make - sure the program doesn't crash. The result of calloc is - deliberately ignored, so do not warn about that. */ - calloc(0, 0); - calloc(0, UINT_MAX); - calloc(UINT_MAX, 0); - calloc(0, ~((size_t)0)); - calloc(~((size_t)0), 0); -} - -static int do_test(int argc, char **argv) -{ - (void)(argc); - (void)(argv); - /* We are allocating blocks with `calloc' and check whether every - block is completely cleared. We first try this for some fixed - times and then with random size. */ - fixed_test(15); - fixed_test(5); - fixed_test(17); - fixed_test(6); - fixed_test(31); - fixed_test(96); - - random_test(); - - null_test(); - - return 0; -} - -#define TEST_FUNCTION do_test() -#include "./test-skeleton.c" diff --git a/stdme/test/malloc.c b/stdme/test/malloc.c deleted file mode 100644 index 62245745..00000000 --- a/stdme/test/malloc.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright (C) 1999-2024 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include - - -#include "./redef_alloc.h" - -static int errors = 0; - -static void merror(const char *msg) -{ - ++errors; - printf("Error: %s\n", msg); -} - -static int do_test(int argc, char **argv) -{ - (void)(argc); - (void)(argv); - void *p, *q; - int save; - - srandom(time(NULL)); - - errno = 0; - p = malloc(-1); - save = errno; - - if (p != NULL) - merror("malloc (-1) succeeded."); - - if (p == NULL && save != ENOMEM) - merror("errno is not set correctly"); - - p = malloc(10); - if (p == NULL) - merror("malloc (10) failed."); - - /* realloc (p, 0) == free (p). */ - p = realloc(p, 0); - if (p != NULL) - merror("realloc (p, 0) failed."); - - p = malloc(0); - if (p == NULL) - merror("malloc (0) failed."); - - p = realloc(p, 0); - if (p != NULL) - merror("realloc (p, 0) failed."); - - p = malloc(513 * 1024); - if (p == NULL) - merror("malloc (513K) failed."); - - q = malloc(-512 * 1024); - if (q != NULL) - merror("malloc (-512K) succeeded."); - - free(p); - - return errors != 0; -} - -#include "./test-skeleton.c" diff --git a/stdme/test/realloc.c b/stdme/test/realloc.c deleted file mode 100644 index fcfe27d3..00000000 --- a/stdme/test/realloc.c +++ /dev/null @@ -1,196 +0,0 @@ -/* Copyright (C) 2013-2024 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - . */ - -#include -#include -#include -#include -#include -#include - -#include "aq/melloc_interal.h" - -#include "./redef_alloc.h" - -void FAIL_EXIT1(char *fmt, ...) -{ - va_list args; - - va_start(args, fmt); - vprintf(fmt, args); - va_end(args); - exit(1); -} - -static int do_test(int argc, char **argv) -{ - (void)(argv); - (void)(argv); - void *p; - unsigned char *p1, *p2, *p3; - unsigned char *c; - int save, i, ok; - - errno = 0; - - p1 = realloc(NULL, 50); - memset(p1, 0x10, 50); - for (i = 0; i < 50; i++) - { - if (p1[i] != 0x10) - FAIL_EXIT1("memset didn't set (p[%i] = %#02x)\n", i, p1[i]); - } - - p2 = malloc(50); - p3 = realloc(p1, 150); - - if (p1 == p3) - FAIL_EXIT1("P1 == P2 \n"); - for (i = 0; i < 50; i++) - { - if (p3[i] != 0x10) - FAIL_EXIT1("realloc didn't preserve after move (p3[%i] = %#02x)\n", i, p3[i]); - } - - // /* realloc (NULL, ...) behaves similarly to malloc (C89). */ - // p = realloc(NULL, -1); - // save = errno; - // - // if (p != NULL) - // FAIL_EXIT1("realloc (NULL, -1) succeeded.\n"); - // - // /* errno should be set to ENOMEM on failure (POSIX). */ - // if (p == NULL && save != ENOMEM) - // FAIL_EXIT1("errno is not set correctly\n"); - // - // errno = 0; - // - // /* realloc (NULL, ...) behaves similarly to malloc (C89). */ - // p = realloc(NULL, 10); - // save = errno; - // - // if (p == NULL) - // FAIL_EXIT1("realloc (NULL, 10) failed.\n"); - // - // free(p); - // - // p = calloc(20, 1); - // if (p == NULL) - // FAIL_EXIT1("calloc (20, 1) failed.\n"); - // - // /* Check increasing size preserves contents (C89). */ - // p = realloc(p, 200); - // if (p == NULL) - // FAIL_EXIT1("realloc (p, 200) failed.\n"); - // - // c = p; - // ok = 1; - // - // for (i = 0; i < 20; i++) - // { - // if (c[i] != 0) - // ok = 0; - // } - // - // if (ok == 0) - // FAIL_EXIT1("first 20 bytes were not cleared\n"); - // - // free(p); - // - // p = realloc(NULL, 100); - // if (p == NULL) - // FAIL_EXIT1("realloc (NULL, 100) failed.\n"); - // - // memset(p, 0xff, 100); - // - // /* Check decreasing size preserves contents (C89). */ - // p = realloc(p, 16); - // if (p == NULL) - // FAIL_EXIT1("realloc (p, 16) failed.\n"); - // - // c = p; - // ok = 1; - // - // for (i = 0; i < 16; i++) - // { - // if (c[i] != 0xff) - // ok = 0; - // } - // - // if (ok == 0) - // FAIL_EXIT1("first 16 bytes were not correct\n"); - // - // /* Check failed realloc leaves original untouched (C89). */ - // c = realloc(p, -1); - // if (c != NULL) - // FAIL_EXIT1("realloc (p, -1) succeeded.\n"); - // - // c = p; - // ok = 1; - // - // for (i = 0; i < 16; i++) - // { - // if (c[i] != 0xff) - // ok = 0; - // } - // - // if (ok == 0) - // FAIL_EXIT1("first 16 bytes were not correct after failed realloc\n"); - // - // /* realloc (p, 0) frees p (C89) and returns NULL (glibc). */ - // p = realloc(p, 0); - // if (p != NULL) - // FAIL_EXIT1("realloc (p, 0) returned non-NULL.\n"); - // - // /* realloc (NULL, 0) acts like malloc (0) (glibc). */ - // p = realloc(NULL, 0); - // if (p == NULL) - // FAIL_EXIT1("realloc (NULL, 0) returned NULL.\n"); - // - // free(p); - // - // printf("WTF\n"); - // - // /* Smoke test to make sure that allocations do not move if they have - // enough - // space to expand in the chunk. */ - // for (size_t sz = 3; sz < 256 * 1024; sz += 2048) - // { - // p = realloc(NULL, sz); - // if (p == NULL) - // FAIL_EXIT1("realloc (NULL, %zu) returned NULL.\n", sz); - // size_t newsz = ((t_chunk *)((void *)(p) - sizeof(t_chunk)))->size; - // printf("size: %zu, usable size: %zu, extra: %zu\n", sz, newsz, - // newsz - sz); - // uintptr_t oldp = (uintptr_t)p; - // void *new_p = realloc(p, newsz); - // if ((uintptr_t)new_p != oldp) - // FAIL_EXIT1( - // "Expanding (%zu bytes) to usable size (%zu) moved block\n", sz, - // newsz); - // free(new_p); - // - // /* We encountered a large enough extra size at least once. */ - // if (newsz - sz > 1024) - // break; - // } - - return 0; -} - -#define TEST_FUNCTION do_test() -#include "./test-skeleton.c" diff --git a/valgrind_readline_leaks_ignore.txt b/valgrind_readline_leaks_ignore.txt deleted file mode 100644 index cef55ae4..00000000 --- a/valgrind_readline_leaks_ignore.txt +++ /dev/null @@ -1,12 +0,0 @@ -{ - leak readline - Memcheck:Leak - ... - fun:readline -} -{ - leak add_history - Memcheck:Leak - ... - fun:add_history -} \ No newline at end of file