diff --git a/line/src/line.c b/line/src/line.c index 8ce16f22..80e4de9a 100644 --- a/line/src/line.c +++ b/line/src/line.c @@ -1,3 +1,14 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* line.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/07 16:53:27 by maiboyer #+# #+# */ +/* Updated: 2024/07/07 19:22:53 by maiboyer ### ########.fr */ +/* */ +/* ************************************************************************** */ #include #include @@ -20,8 +31,8 @@ #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_raw_mode_state *get_raw_mode_state(void); +t_vec_str *get_history(void); t_vec_str *get_history(void) { @@ -36,75 +47,92 @@ t_vec_str *get_history(void) return (&history); } +t_raw_mode_state *get_raw_mode_state(void) +{ + static t_raw_mode_state state = {}; + + return (&state); +} + 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 */ + K_KEY_NULL = 0, /* NULL */ + K_CTRL_A = 1, /* Ctrl+a */ + K_CTRL_B = 2, /* Ctrl-b */ + K_CTRL_C = 3, /* Ctrl-c */ + K_CTRL_D = 4, /* Ctrl-d */ + K_CTRL_E = 5, /* Ctrl-e */ + K_CTRL_F = 6, /* Ctrl-f */ + K_CTRL_H = 8, /* Ctrl-h */ + K_TAB = 9, /* Tab */ + K_CTRL_K = 11, /* Ctrl+k */ + K_CTRL_L = 12, /* Ctrl+l */ + K_ENTER = 13, /* Enter */ + K_CTRL_N = 14, /* Ctrl-n */ + K_CTRL_P = 16, /* Ctrl-p */ + K_CTRL_T = 20, /* Ctrl-t */ + K_CTRL_U = 21, /* Ctrl+u */ + K_CTRL_W = 23, /* Ctrl+w */ + K_ESC = 27, /* Escape */ + K_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. +enum e_line_flags +{ + REFRESH_CLEAN = 1 << 0, // Clean the old prompt from the screen + REFRESH_WRITE = 1 << 1, // Rewrite the prompt on the screen. + 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); +typedef enum e_line_flags t_line_flags; -/* 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 +void linenoise_clear_screen(t_fd *output); +void linenoise_disable_raw_mode(t_fd *fd); +t_error linenoise_enable_raw_mode(t_fd *fd); +t_u32 linenoise_get_columns(t_fd *input, t_fd *output); +t_error linenoise_get_cursor_position(t_fd *input, t_fd *output, t_u32 *column_out); +t_error linenoise_history_add(t_const_str line); +t_str linenoise_no_tty_impl(void); +void linenoise_refresh_line(t_line_state *l); +void linenoise_refresh_line_with_flags(t_line_state *l, t_line_flags flags); +void linenoise_uninit_lib(void); + +/* 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 = get_history(); + vec_str_free(*history); +} + +/* At exit we'll try to fix the terminal to the initial conditions. */ +__attribute__((destructor)) void linenoise_uninit_lib(void) +{ + linenoise_disable_raw_mode(get_stdin()); + free_history(); +} + +#define lndebug(fmt, ...) /* ======================= Low level terminal handling ====================== */ /* 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 linenoise_get_cursor_position(t_fd *input, t_fd *output, t_u32 *column_out) { char buf[32]; int cols, rows; unsigned int i = 0; /* Report cursor location */ - if (write(ofd, "\x1b[6n", 4) != 4) - return -1; + if (write(output->fd, "\x1b[6n", 4) != 4) + return (ERROR); /* Read the response: ESC [ rows ; cols R */ while (i < sizeof(buf) - 1) { - if (read(ifd, buf + i, 1) != 1) + if (read(input->fd, buf + i, 1) != 1) break; if (buf[i] == 'R') break; @@ -113,77 +141,63 @@ static int getCursorPosition(int ifd, int ofd) 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 linenoise_get_columns(t_fd *input, t_fd *output) { struct winsize ws; - t_u32 start, cols; + 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; + if (linenoise_get_cursor_position(input, output, &start)) + 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; + me_eprintf("going to the right;\n"); + me_printf_fd(output, "\x1b[999C"); + if (linenoise_get_cursor_position(input, output, &cols)) + return (80); - /* Restore position. */ if (cols > start) { - t_u8 seq[32]; - me_printf(seq, 32, "\x1b[%dD", cols - start); - (void)!(write(ofd, seq, strlen(seq)) == -1); + me_eprintf("reseting col;\n"); + me_printf_fd(output, "\x1b[%dD", cols - start); } - return cols; + return (cols); } else - { - return ws.ws_col; - } - -failed: + return (ws.ws_col); } /* Clear the screen. Used to handle ctrl+l */ -void linenoiseClearScreen(void) +void linenoise_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_eprintf("clear screen;\n"); + me_printf_fd(output, "\x1b[H\x1b[2J"); } /* Raw mode: 1960 magic shit. */ -static t_error enableRawMode(int fd) +t_error linenoise_enable_raw_mode(t_fd *fd) { 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 */ @@ -203,18 +217,18 @@ static t_error enableRawMode(int fd) raw.c_cc[VTIME] = 0; /* 1 byte, no timer */ /* put terminal in raw mode after flushing */ - if (tcsetattr(fd, TCSAFLUSH, &raw) < 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 linenoise_disable_raw_mode(t_fd *fd) { 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,33 +238,6 @@ 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) -{ - ab->b = NULL; - ab->len = 0; -} - -static void abAppend(struct abuf *ab, const char *s, int len) -{ - char *new = mem_realloc(ab->b, ab->len + len); - - 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); -} /* Single line low level line refresh. * @@ -259,85 +246,76 @@ 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 linenoise_refresh_single_line(t_line_state *l, 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; + size_t prompt_len = strlen(l->prompt); + t_str input_buf = l->buf; + size_t input_len = l->len; + size_t cursor_pos = l->pos; + t_string str; - while ((plen + pos) >= l->columns) + while ((prompt_len + cursor_pos) >= l->columns) { - buf++; - len--; - pos--; - } - while (plen + len > l->columns) - { - len--; + input_buf++; + input_len--; + cursor_pos--; } + while (prompt_len + input_len > l->columns) + input_len--; - abInit(&ab); - /* Cursor to left edge */ - snprintf(seq, sizeof(seq), "\r"); - abAppend(&ab, seq, strlen(seq)); + str = string_new(16); + string_push_char(&str, '\r'); if (flags & REFRESH_WRITE) { /* Write the prompt and the current buffer content */ - abAppend(&ab, l->prompt, strlen(l->prompt)); - abAppend(&ab, buf, len); + string_push(&str, l->prompt); + string_push(&str, input_buf); // , len); } + string_push(&str, "\x1b[0K"); /* 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)); + // TODO: finish this line with me_printf_str + me_printf_str(&str, "\r\x1b[%dC", (int)(cursor_pos + prompt_len)); } - if (write(fd, ab.b, ab.len) == -1) - { - } /* Can't recover from write error. */ - abFree(&ab); + me_eprintf("refresh single line;\n"); + me_printf_fd(l->output_fd, "%s", str.buf); + string_free(str); } /* Calls the two low level functions refreshSingleLine() or * refreshMultiLine() according to the selected mode. */ -static void refreshLineWithFlags(struct s_line_state *l, int flags) +void linenoise_refresh_line_with_flags(t_line_state *l, t_line_flags flags) { - refreshSingleLine(l, flags); + linenoise_refresh_single_line(l, flags); } /* Utility function to avoid specifying REFRESH_ALL all the times. */ -static void refreshLine(struct s_line_state *l) +void linenoise_refresh_line(t_line_state *l) { - refreshLineWithFlags(l, REFRESH_ALL); + linenoise_refresh_line_with_flags(l, REFRESH_ALL); } /* Hide the current line, when using the multiplexing API. */ -void linenoiseHide(struct s_line_state *l) +void linenoise_hide(t_line_state *l) { - refreshSingleLine(l, REFRESH_CLEAN); + linenoise_refresh_single_line(l, REFRESH_CLEAN); } /* Show the current line, when using the multiplexing API. */ -void linenoiseShow(struct s_line_state *l) +void linenoise_show(t_line_state *l) { - refreshLineWithFlags(l, REFRESH_WRITE); + linenoise_refresh_line_with_flags(l, 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 linenoise_edit_insert(t_line_state *l, char c) { if (l->len < l->buflen) { @@ -347,7 +325,7 @@ int linenoiseEditInsert(struct s_line_state *l, char c) l->pos++; l->len++; l->buf[l->len] = '\0'; - refreshLine(l); + linenoise_refresh_line(l); } else { @@ -356,49 +334,49 @@ int linenoiseEditInsert(struct s_line_state *l, char c) l->len++; l->pos++; l->buf[l->len] = '\0'; - refreshLine(l); + linenoise_refresh_line(l); } } - return 0; + return (NO_ERROR); } /* Move cursor on the left. */ -void linenoiseEditMoveLeft(struct s_line_state *l) +void linenoise_edit_move_left(t_line_state *l) { if (l->pos > 0) { l->pos--; - refreshLine(l); + linenoise_refresh_line(l); } } /* Move cursor on the right. */ -void linenoiseEditMoveRight(struct s_line_state *l) +void linenoise_edit_move_right(t_line_state *l) { if (l->pos != l->len) { l->pos++; - refreshLine(l); + linenoise_refresh_line(l); } } /* Move cursor to the start of the line. */ -void linenoiseEditMoveHome(struct s_line_state *l) +void linenoiseEditMoveHome(t_line_state *l) { if (l->pos != 0) { l->pos = 0; - refreshLine(l); + linenoise_refresh_line(l); } } /* Move cursor to the end of the line. */ -void linenoiseEditMoveEnd(struct s_line_state *l) +void linenoise_edit_move_end(t_line_state *l) { if (l->pos != l->len) { l->pos = l->len; - refreshLine(l); + linenoise_refresh_line(l); } } @@ -406,7 +384,7 @@ void linenoiseEditMoveEnd(struct s_line_state *l) * 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 linenoise_edit_history_next(t_line_state *l, int dir) { t_vec_str *history; @@ -425,7 +403,7 @@ void linenoiseEditHistoryNext(struct s_line_state *l, int dir) l->history_index = 0; return; } - else if (l->history_index >= history->len) + else if ((t_usize)l->history_index >= history->len) { l->history_index = history->len - 1; return; @@ -433,25 +411,25 @@ void linenoiseEditHistoryNext(struct s_line_state *l, int dir) 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); + linenoise_refresh_line(l); } } /* 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 linenoise_edit_delete(t_line_state *l) { 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); + linenoise_refresh_line(l); } } /* Backspace implementation. */ -void linenoiseEditBackspace(struct s_line_state *l) +void linenoise_edit_backspace(t_line_state *l) { if (l->pos > 0 && l->len > 0) { @@ -459,13 +437,13 @@ void linenoiseEditBackspace(struct s_line_state *l) l->pos--; l->len--; l->buf[l->len] = '\0'; - refreshLine(l); + linenoise_refresh_line(l); } } /* Delete the previosu word, maintaining the cursor at the start of the * current word. */ -void linenoiseEditDeletePrevWord(struct s_line_state *l) +void linenoise_edit_delete_prev_word(t_line_state *l) { size_t old_pos = l->pos; size_t diff; @@ -477,7 +455,7 @@ void linenoiseEditDeletePrevWord(struct s_line_state *l) diff = old_pos - l->pos; memmove(l->buf + l->pos, l->buf + old_pos, l->len - old_pos + 1); l->len -= diff; - refreshLine(l); + linenoise_refresh_line(l); } /* This function is part of the multiplexed API of Linenoise, that is used @@ -504,25 +482,24 @@ 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 linenoise_edit_start(t_line_state *l, t_fd *stdin_fd, t_fd *stdout_fd, char *buf, size_t buflen, 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->input_fd = stdin_fd; + l->output_fd = stdout_fd; l->buf = buf; l->buflen = buflen; l->prompt = prompt; l->prompt_len = strlen(prompt); - l->oldpos = l->pos = 0; + l->old_pos = l->pos = 0; l->len = 0; // /* Enter raw mode. */ // if (enableRawMode(l->ifd) == -1) // return -1; - l->columns = getColumns(stdin_fd, stdout_fd); + l->columns = linenoise_get_columns(stdin_fd, stdout_fd); l->old_rows = 0; l->history_index = 0; @@ -533,16 +510,16 @@ int linenoiseEditStart(struct s_line_state *l, int stdin_fd, int stdout_fd, char /* 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)) + if (!isatty(l->input_fd->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 (write_fd(l->output_fd, (t_u8 *)prompt, l->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 " @@ -566,79 +543,64 @@ 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 linenoise_edit_feed(t_line_state *l) { /* Not a TTY, pass control to line reading without character * count limits. */ - if (!isatty(l->input_fd)) - return linenoiseNoTTY(); + if (!isatty(l->input_fd->fd)) + return linenoise_no_tty_impl(); char c; - int nread; + t_isize nread; char seq[3]; t_vec_str *history = get_history(); - - nread = read(l->input_fd, &c, 1); - if (nread <= 0) - return NULL; + if (read_fd(l->input_fd, (t_u8 *)&c, 1, &nread)) + return (printf("null1\n"), NULL); switch (c) { - case ENTER: /* enter */ + case K_ENTER: /* enter */ history->len--; mem_free(history->buffer[history->len]); return strdup(l->buf); - case CTRL_C: /* ctrl-c */ + case K_CTRL_C: /* ctrl-c */ errno = EAGAIN; return NULL; - case BACKSPACE: /* backspace */ - case 8: /* ctrl-h */ - linenoiseEditBackspace(l); + case K_BACKSPACE: /* backspace */ + case 8: /* ctrl-h */ + linenoise_edit_backspace(l); break; - case CTRL_D: /* ctrl-d, remove char at right of cursor, or if the + case K_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); - } + linenoise_edit_delete(l); else { history->len--; mem_free(history->buffer[history->len]); errno = ENOENT; - return NULL; + return (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); - } + case K_CTRL_B: /* ctrl-b */ + linenoise_edit_move_left(l); break; - case CTRL_B: /* ctrl-b */ - linenoiseEditMoveLeft(l); + case K_CTRL_F: /* ctrl-f */ + linenoise_edit_move_right(l); break; - case CTRL_F: /* ctrl-f */ - linenoiseEditMoveRight(l); + case K_CTRL_P: /* ctrl-p */ + linenoise_edit_history_next(l, LINENOISE_HISTORY_PREV); break; - case CTRL_P: /* ctrl-p */ - linenoiseEditHistoryNext(l, LINENOISE_HISTORY_PREV); + case K_CTRL_N: /* ctrl-n */ + linenoise_edit_history_next(l, LINENOISE_HISTORY_NEXT); break; - case CTRL_N: /* ctrl-n */ - linenoiseEditHistoryNext(l, LINENOISE_HISTORY_NEXT); - break; - case ESC: /* escape sequence */ + case K_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) + if (read_fd(l->input_fd, (t_u8 *)seq, 1, NULL)) break; - if (read(l->input_fd, seq + 1, 1) == -1) + if (read_fd(l->input_fd, (t_u8 *)(seq + 1), 1, NULL)) break; /* ESC [ sequences. */ @@ -647,39 +609,32 @@ char *linenoiseEditFeed(struct s_line_state *l) if (seq[1] >= '0' && seq[1] <= '9') { /* Extended escape, read additional byte. */ - if (read(l->input_fd, seq + 2, 1) == -1) + if (read_fd(l->input_fd, (t_u8 *)(seq + 2), 1, NULL)) break; - if (seq[2] == '~') - { - switch (seq[1]) - { - case '3': /* Delete key. */ - linenoiseEditDelete(l); - break; - } - } + if (seq[1] == '3' && seq[2] == '~') + linenoise_edit_delete(l); } else { switch (seq[1]) { case 'A': /* Up */ - linenoiseEditHistoryNext(l, LINENOISE_HISTORY_PREV); + linenoise_edit_history_next(l, LINENOISE_HISTORY_PREV); break; case 'B': /* Down */ - linenoiseEditHistoryNext(l, LINENOISE_HISTORY_NEXT); + linenoise_edit_history_next(l, LINENOISE_HISTORY_NEXT); break; case 'C': /* Right */ - linenoiseEditMoveRight(l); + linenoise_edit_move_right(l); break; case 'D': /* Left */ - linenoiseEditMoveLeft(l); + linenoise_edit_move_left(l); break; case 'H': /* Home */ linenoiseEditMoveHome(l); break; case 'F': /* End*/ - linenoiseEditMoveEnd(l); + linenoise_edit_move_end(l); break; } } @@ -694,37 +649,37 @@ char *linenoiseEditFeed(struct s_line_state *l) linenoiseEditMoveHome(l); break; case 'F': /* End*/ - linenoiseEditMoveEnd(l); + linenoise_edit_move_end(l); break; } } break; default: - if (linenoiseEditInsert(l, c)) + if (linenoise_edit_insert(l, c)) return NULL; break; - case CTRL_U: /* Ctrl+u, delete the whole line. */ + case K_CTRL_U: /* Ctrl+u, delete the whole line. */ l->buf[0] = '\0'; l->pos = l->len = 0; - refreshLine(l); + linenoise_refresh_line(l); break; - case CTRL_K: /* Ctrl+k, delete from current to end of line. */ + case K_CTRL_K: /* Ctrl+k, delete from current to end of line. */ l->buf[l->pos] = '\0'; l->len = l->pos; - refreshLine(l); + linenoise_refresh_line(l); break; - case CTRL_A: /* Ctrl+a, go to the start of the line */ + case K_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); + case K_CTRL_E: /* ctrl+e, go to the end of the line */ + linenoise_edit_move_end(l); break; - case CTRL_L: /* ctrl+l, clear screen */ - linenoiseClearScreen(); - refreshLine(l); + case K_CTRL_L: /* ctrl+l, clear screen */ + linenoise_clear_screen(l->output_fd); + linenoise_refresh_line(l); break; - case CTRL_W: /* ctrl+w, delete previous word */ - linenoiseEditDeletePrevWord(l); + case K_CTRL_W: /* ctrl+w, delete previous word */ + linenoise_edit_delete_prev_word(l); break; } return linenoiseEditMore; @@ -734,33 +689,30 @@ char *linenoiseEditFeed(struct s_line_state *l) * 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 linenoiseEditStop(t_line_state *l) { - if (!isatty(l->input_fd)) + if (!isatty(l->input_fd->fd)) return; - // disableRawMode(l->ifd); - printf("\n"); + linenoise_disable_raw_mode(l->input_fd); + me_printf_fd(l->output_fd, "\n"); } /* 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) +char *linenoise_blocking_edit(t_fd *stdin_fd, t_fd *stdout_fd, char *buf, size_t buflen, t_const_str prompt) { t_line_state l; /* Editing without a buffer is invalid. */ if (buflen == 0) - { - errno = EINVAL; - return (NULL); - } + return (errno = EINVAL, NULL); - linenoiseEditStart(&l, stdin_fd, stdout_fd, buf, buflen, prompt); + linenoise_edit_start(&l, stdin_fd, stdout_fd, buf, buflen, prompt); char *res; - while ((res = linenoiseEditFeed(&l)) == linenoiseEditMore) - ; + while ((res = linenoise_edit_feed(&l)) == linenoiseEditMore) + ; // printf("edit\n"); linenoiseEditStop(&l); return res; } @@ -802,7 +754,7 @@ 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 linenoise_no_tty_impl(void) { t_string line; t_isize ret; @@ -812,8 +764,7 @@ static t_str linenoiseNoTTY(void) 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') return (line.buf); @@ -827,20 +778,21 @@ 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(const char *prompt) { - char buf[4096]; + char buf[4096]; + t_str retval; - if (!isatty(STDIN_FILENO)) + if (!isatty(get_stdin()->fd)) { + printf("not_tty\n"); /* 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; + return linenoise_no_tty_impl(); } + printf("is_tty\n"); + retval = linenoise_blocking_edit(get_stdin(), get_stdout(), buf, 4096, prompt); + return (retval); } /* This is just a wrapper the user may want to call in order to make sure @@ -856,21 +808,6 @@ void linenoise_free(void *ptr) /* ================================ 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 @@ -945,6 +882,7 @@ t_error linenoise_history_load(t_str name) 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')) diff --git a/sources/main.c b/sources/main.c index d9c2acd6..51971ccc 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/07 18:25: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,7 +129,7 @@ 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); 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/src.list b/stdme/src.list index bb0e2b82..f1f7cb6d 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 diff --git a/stdme/src/fs/fs_internal.c b/stdme/src/fs/fs_internal.c index 9fbcf341..45068392 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; @@ -113,7 +114,8 @@ t_error read_fd(t_fd *fd, t_u8 *buffer, t_usize size, t_isize *read_count) { t_isize ret; - if (fd == NULL || buffer == NULL || read_count == NULL || fd->fd == -1 || !(fd->perms & FD_READ)) + if (fd == NULL || buffer == NULL || read_count == NULL || fd->fd == -1 || + !(fd->perms & FD_READ)) return (ERROR); ret = read(fd->fd, buffer, size); if (ret == -1) @@ -149,13 +151,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 +165,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 +180,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 +190,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 +228,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 +262,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 +283,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 +295,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/mem/allocator.c b/stdme/src/mem/allocator.c index 40862fc8..4f738df3 100644 --- a/stdme/src/mem/allocator.c +++ b/stdme/src/mem/allocator.c @@ -6,17 +6,16 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/05/14 18:26:27 by maiboyer #+# #+# */ -/* Updated: 2024/05/22 15:21:28 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 19:10:07 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) { @@ -31,6 +30,7 @@ t_allocator *global_allocator(void) return (&global_alloc); } +__attribute__((destructor(200))) void uninit_global_allocator(void) { t_allocator *allocator; diff --git a/stdme/src/os/exit.c b/stdme/src/os/exit.c index 04e0faff..e1c705ab 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/07 19:11:39 by maiboyer ### ########.fr */ /* */ /* ************************************************************************** */ @@ -15,9 +15,12 @@ #include "me/types.h" #include +// 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/src/printf/callbacks.c b/stdme/src/printf/callbacks.c new file mode 100644 index 00000000..fd96ae19 --- /dev/null +++ b/stdme/src/printf/callbacks.c @@ -0,0 +1,35 @@ +/* ************************************************************************** */ +/* */ +/* ::: :::::::: */ +/* callbacks.c :+: :+: :+: */ +/* +:+ +:+ +:+ */ +/* By: maiboyer +#+ +:+ +#+ */ +/* +#+#+#+#+#+ +#+ */ +/* Created: 2024/07/07 18:01:52 by maiboyer #+# #+# */ +/* Updated: 2024/07/07 18:03:28 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..c20ef39b 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/07 17:40:12 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) +void handle_weird_precision_stuff(t_printf_arg *data, t_prec_strs strs, + 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..b0b0e52f 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/07 17:39:37 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 diff --git a/stdme/src/printf/printf.c b/stdme/src/printf/printf.c index 64199821..8a446021 100644 --- a/stdme/src/printf/printf.c +++ b/stdme/src/printf/printf.c @@ -6,85 +6,37 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2023/11/11 17:50:56 by maiboyer #+# #+# */ -/* Updated: 2024/02/09 14:58:10 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 18:01:58 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/fs/fs.h" +#include "me/fs/write.h" +#include "me/printf/_internal_printf.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_usize me_printf(t_const_str fmt, ...) { - t_string *out_buf; + va_list args; + t_usize res; - 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); + res = me_vprintf(fmt, &args); va_end(args); - return (passthru.total_print); + return (res); } -t_usize me_eprintf(t_const_str fmt, ...) +t_usize me_eprintf(t_const_str fmt, ...) { - va_list args; - t_fprintf_arg passthru; + va_list args; + t_usize res; - passthru = (t_fprintf_arg){ - .fd = 2, - .total_print = 0, - }; va_start(args, fmt); - me_printf_str_inner(fmt, &me_printf_write, &args, (void *)&passthru); + res = me_veprintf(fmt, &args); va_end(args); - return (passthru.total_print); + return (res); } /* diff --git a/stdme/src/printf/printf_fd.c b/stdme/src/printf/printf_fd.c index aa7856e8..ce427a13 100644 --- a/stdme/src/printf/printf_fd.c +++ b/stdme/src/printf/printf_fd.c @@ -17,31 +17,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_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, ...) { - 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..03cab0f2 --- /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/07 18:03:40 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..0df42e18 100644 --- a/stdme/src/printf/vprintf.c +++ b/stdme/src/printf/vprintf.c @@ -6,46 +6,38 @@ /* By: maiboyer +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2024/02/09 14:57:28 by maiboyer #+# #+# */ -/* Updated: 2024/02/09 15:00:39 by maiboyer ### ########.fr */ +/* Updated: 2024/07/07 18:00:14 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_usize me_vprintf(t_const_str fmt, va_list *args) { - t_fprintf_arg passthru; + 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); } -t_usize me_veprintf(t_const_str fmt, va_list *args) +t_usize me_veprintf(t_const_str fmt, va_list *args) { - t_fprintf_arg passthru; + 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); }