diff options
Diffstat (limited to 'src/m_loop.c')
-rw-r--r-- | src/m_loop.c | 118 |
1 files changed, 107 insertions, 11 deletions
diff --git a/src/m_loop.c b/src/m_loop.c index 89b06b9..3762aac 100644 --- a/src/m_loop.c +++ b/src/m_loop.c @@ -13,48 +13,144 @@ #include <libft.h> #include <stdint.h> #include <stdlib.h> +#include <fcntl.h> #include <unistd.h> #include <signal.h> +#include <limits.h> +#include "d_define.h" #include "e_line.h" #include "m_loop_next.h" #include "m_prompt.h" #include "p_line.h" +#include "s_com.h" +#include "s_lpipes.h" #include "s_line.h" #include "c_init.h" +#include "u_utils.h" +#include "u_parse.h" +#include "u_vars.h" -void - m_parse_and_run_line(char *line, t_msh *msh) +static void + m_parse_and_run_line(char line[], t_msh *msh) { + t_line_block *ptr; + uint8_t previf; + p_line(line, msh); - ft_memdel((void*)&line); - e_line(msh); + previf = 0; + ptr = msh->curr; + while (ptr != NULL) + { + if ((previf == 0) || (previf == 1 && msh->ret == 0) || + (previf == 2 && msh->ret != 0)) + { + if ((msh->com = s_com_new(ptr->lblock, msh)) == NULL) + break ; + e_line(msh); + s_com_destroy(&msh->com); + } + else if (msh->pipes != NULL) + s_lpipes_clear(&msh->pipes); + previf = ptr->nextif; + ptr = ptr->next; + } s_line_clear(&msh->curr); } +void + m_dump_hist(char hist[], t_msh *msh) +{ + char histfile[PATH_MAX]; + int32_t fd; + + if (hist[0] != C_NUL && ft_strlen(hist) > 0) + { + u_get_var_value(histfile, "$HISTFILE", PATH_MAX, msh); + if (histfile[0] != C_NUL) + { + if ((fd = open(histfile, + O_WRONLY | O_CREAT | O_APPEND, 0644)) != -1) + { + ft_dprintf(fd, "%s", hist); + close(fd); + } + } + } +} + +static void + m_handle_hist(char hist[], char line[], t_msh *msh) +{ + static uint16_t hist_i = 0; + + if (hist_i == 0) + hist[0] = '\0'; + ft_strlcpy(hist + ft_strlen(hist), line, 4096); + hist[ft_strlen(hist) + 1] = '\0'; + hist[ft_strlen(hist)] = '\n'; + hist_i += 1; + if (hist_i == 254) + { + m_dump_hist(hist, msh); + hist_i = 0; + } +} + +static void m_delete_comments(char line[]) +{ + char *ptr; + t_quote_mode mode; + + ptr = line; + mode = Q_NONE; + while (*ptr != C_NUL) + { + if (*ptr == C_DQUOTE) + mode = u_meet_dquote(line, ptr, mode); + else if (*ptr == C_SQUOTE) + mode = u_meet_squote(line, ptr, mode); + else if (mode == Q_NONE && *ptr == C_SHARP + && u_is_not_escaped(line, ptr) == TRUE) + { + if (ptr - line == 0) + *ptr = C_NUL; + else if (ptr - line > 0 && ft_iswhitespace(*(ptr - 1)) == TRUE + && u_is_not_escaped(line, ptr - 1) == TRUE) + *ptr = C_NUL; + } + ptr++; + } +} + uint8_t m_loop(int32_t fd, t_msh *msh) { - char *line; - int8_t gnl; + static char hist[255 * 4096]; + char *line; + int8_t gnl; + msh->fd = fd; gnl = 1; while (gnl > 0) { gnl = c_gnl(fd, &line, 1, msh); - if (line[0] != '\0') + m_delete_comments(line); + if (line[0] != C_NUL) { line = m_check_multi_backslash(fd, line, msh); line = m_check_multi_pipe(fd, line, msh); + line = m_check_multi_and(fd, line, msh); + line = m_check_multi_quotes(fd, line, msh); + if (fd == STDIN_FILENO) + m_handle_hist(hist, line, msh); m_parse_and_run_line(line, msh); /* TODO: (null): Bad address on "msh ~> echo a > asd; cat < asd" but not on "msh ~> echo a > asd; cat asd" */ - /* TODO: "msh ~> some command \": re GNL into ft_nrealloc */ - /* TODO: a histfile would be nice */ } else - { ft_memdel((void*)&line); - } } + if (fd == STDIN_FILENO) + m_dump_hist(hist, msh); return (msh->ret); } |